]> git.karo-electronics.de Git - mv-sheeva.git/commitdiff
Merge branch 'master' into for-davem
authorJohn W. Linville <linville@tuxdriver.com>
Fri, 23 Apr 2010 18:43:45 +0000 (14:43 -0400)
committerJohn W. Linville <linville@tuxdriver.com>
Fri, 23 Apr 2010 18:43:45 +0000 (14:43 -0400)
Conflicts:
drivers/net/wireless/ath/ath9k/phy.c
drivers/net/wireless/iwlwifi/iwl-6000.c
drivers/net/wireless/iwlwifi/iwl-debugfs.c

127 files changed:
drivers/net/wireless/Kconfig
drivers/net/wireless/ath/ath.h
drivers/net/wireless/ath/ath5k/base.c
drivers/net/wireless/ath/ath5k/pcu.c
drivers/net/wireless/ath/ath9k/Makefile
drivers/net/wireless/ath/ath9k/ani.c
drivers/net/wireless/ath/ath9k/ar5008_initvals.h [new file with mode: 0644]
drivers/net/wireless/ath/ath9k/ar5008_phy.c [new file with mode: 0644]
drivers/net/wireless/ath/ath9k/ar9001_initvals.h [new file with mode: 0644]
drivers/net/wireless/ath/ath9k/ar9002_calib.c [new file with mode: 0644]
drivers/net/wireless/ath/ath9k/ar9002_hw.c [new file with mode: 0644]
drivers/net/wireless/ath/ath9k/ar9002_initvals.h [moved from drivers/net/wireless/ath/ath9k/initvals.h with 78% similarity]
drivers/net/wireless/ath/ath9k/ar9002_mac.c [new file with mode: 0644]
drivers/net/wireless/ath/ath9k/ar9002_phy.c [new file with mode: 0644]
drivers/net/wireless/ath/ath9k/ar9002_phy.h [new file with mode: 0644]
drivers/net/wireless/ath/ath9k/ar9003_calib.c [new file with mode: 0644]
drivers/net/wireless/ath/ath9k/ar9003_eeprom.c [new file with mode: 0644]
drivers/net/wireless/ath/ath9k/ar9003_eeprom.h [new file with mode: 0644]
drivers/net/wireless/ath/ath9k/ar9003_hw.c [new file with mode: 0644]
drivers/net/wireless/ath/ath9k/ar9003_initvals.h [new file with mode: 0644]
drivers/net/wireless/ath/ath9k/ar9003_mac.c [new file with mode: 0644]
drivers/net/wireless/ath/ath9k/ar9003_mac.h [new file with mode: 0644]
drivers/net/wireless/ath/ath9k/ar9003_phy.c [new file with mode: 0644]
drivers/net/wireless/ath/ath9k/ar9003_phy.h [new file with mode: 0644]
drivers/net/wireless/ath/ath9k/ath9k.h
drivers/net/wireless/ath/ath9k/beacon.c
drivers/net/wireless/ath/ath9k/calib.c
drivers/net/wireless/ath/ath9k/calib.h
drivers/net/wireless/ath/ath9k/common.h
drivers/net/wireless/ath/ath9k/debug.c
drivers/net/wireless/ath/ath9k/debug.h
drivers/net/wireless/ath/ath9k/eeprom.c
drivers/net/wireless/ath/ath9k/eeprom.h
drivers/net/wireless/ath/ath9k/eeprom_4k.c
drivers/net/wireless/ath/ath9k/eeprom_9287.c
drivers/net/wireless/ath/ath9k/eeprom_def.c
drivers/net/wireless/ath/ath9k/hif_usb.c
drivers/net/wireless/ath/ath9k/htc.h
drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
drivers/net/wireless/ath/ath9k/htc_drv_init.c
drivers/net/wireless/ath/ath9k/htc_drv_main.c
drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
drivers/net/wireless/ath/ath9k/htc_hst.c
drivers/net/wireless/ath/ath9k/htc_hst.h
drivers/net/wireless/ath/ath9k/hw-ops.h [new file with mode: 0644]
drivers/net/wireless/ath/ath9k/hw.c
drivers/net/wireless/ath/ath9k/hw.h
drivers/net/wireless/ath/ath9k/init.c
drivers/net/wireless/ath/ath9k/mac.c
drivers/net/wireless/ath/ath9k/mac.h
drivers/net/wireless/ath/ath9k/main.c
drivers/net/wireless/ath/ath9k/pci.c
drivers/net/wireless/ath/ath9k/phy.c [deleted file]
drivers/net/wireless/ath/ath9k/phy.h
drivers/net/wireless/ath/ath9k/rc.c
drivers/net/wireless/ath/ath9k/recv.c
drivers/net/wireless/ath/ath9k/reg.h
drivers/net/wireless/ath/ath9k/wmi.c
drivers/net/wireless/ath/ath9k/wmi.h
drivers/net/wireless/ath/ath9k/xmit.c
drivers/net/wireless/iwlwifi/Makefile
drivers/net/wireless/iwlwifi/iwl-1000.c
drivers/net/wireless/iwlwifi/iwl-3945.c
drivers/net/wireless/iwlwifi/iwl-3945.h
drivers/net/wireless/iwlwifi/iwl-4965.c
drivers/net/wireless/iwlwifi/iwl-5000.c
drivers/net/wireless/iwlwifi/iwl-6000.c
drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c [new file with mode: 0644]
drivers/net/wireless/iwlwifi/iwl-agn-debugfs.h [new file with mode: 0644]
drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c
drivers/net/wireless/iwlwifi/iwl-agn-lib.c
drivers/net/wireless/iwlwifi/iwl-agn-rs.c
drivers/net/wireless/iwlwifi/iwl-agn-tx.c
drivers/net/wireless/iwlwifi/iwl-agn-ucode.c
drivers/net/wireless/iwlwifi/iwl-agn.c
drivers/net/wireless/iwlwifi/iwl-agn.h
drivers/net/wireless/iwlwifi/iwl-commands.h
drivers/net/wireless/iwlwifi/iwl-core.c
drivers/net/wireless/iwlwifi/iwl-core.h
drivers/net/wireless/iwlwifi/iwl-csr.h
drivers/net/wireless/iwlwifi/iwl-debug.h
drivers/net/wireless/iwlwifi/iwl-debugfs.c
drivers/net/wireless/iwlwifi/iwl-dev.h
drivers/net/wireless/iwlwifi/iwl-eeprom.h
drivers/net/wireless/iwlwifi/iwl-prph.h
drivers/net/wireless/iwlwifi/iwl-scan.c
drivers/net/wireless/iwlwifi/iwl-sta.c
drivers/net/wireless/iwlwifi/iwl3945-base.c
drivers/net/wireless/iwmc3200wifi/Makefile
drivers/net/wireless/iwmc3200wifi/rx.c
drivers/net/wireless/iwmc3200wifi/trace.h
drivers/net/wireless/iwmc3200wifi/tx.c
drivers/net/wireless/libertas/if_sdio.c
drivers/net/wireless/mac80211_hwsim.c
drivers/net/wireless/orinoco/Makefile
drivers/net/wireless/orinoco/cfg.c
drivers/net/wireless/orinoco/hw.c
drivers/net/wireless/orinoco/main.h
drivers/net/wireless/orinoco/orinoco.h
drivers/net/wireless/orinoco/scan.c
drivers/net/wireless/orinoco/wext.c
drivers/net/wireless/p54/p54pci.c
drivers/net/wireless/rt2x00/rt2800pci.c
drivers/net/wireless/rt2x00/rt2800usb.c
drivers/net/wireless/rt2x00/rt2x00.h
drivers/net/wireless/rt2x00/rt2x00pci.c
drivers/net/wireless/rt2x00/rt2x00pci.h
drivers/net/wireless/rt2x00/rt2x00queue.c
drivers/net/wireless/rt2x00/rt2x00usb.c
drivers/net/wireless/rt2x00/rt2x00usb.h
drivers/net/wireless/rtl818x/Kconfig [new file with mode: 0644]
drivers/net/wireless/wl12xx/wl1251_main.c
drivers/net/wireless/wl12xx/wl1251_reg.h
drivers/net/wireless/wl12xx/wl1251_sdio.c
include/linux/ieee80211.h
include/linux/spi/wl12xx.h
include/net/cfg80211.h
include/net/mac80211.h
net/mac80211/agg-rx.c
net/mac80211/agg-tx.c
net/mac80211/cfg.c
net/mac80211/driver-ops.h
net/mac80211/key.c
net/mac80211/mlme.c
net/mac80211/sta_info.c
net/mac80211/tx.c
net/wireless/sme.c

index 588943660755fa8e15e03a3543a2196464617c74..77500cb7fd26a012ae804f87a7a81d60d3f774aa 100644 (file)
@@ -210,90 +210,7 @@ config USB_NET_RNDIS_WLAN
 
          If you choose to build a module, it'll be called rndis_wlan.
 
-config RTL8180
-       tristate "Realtek 8180/8185 PCI support"
-       depends on MAC80211 && PCI && EXPERIMENTAL
-       select EEPROM_93CX6
-       ---help---
-         This is a driver for RTL8180 and RTL8185 based cards.
-         These are PCI based chips found in cards such as:
-
-         (RTL8185 802.11g)
-         A-Link WL54PC
-
-         (RTL8180 802.11b)
-         Belkin F5D6020 v3
-         Belkin F5D6020 v3
-         Dlink DWL-610
-         Dlink DWL-510
-         Netgear MA521
-         Level-One WPC-0101
-         Acer Aspire 1357 LMi
-         VCTnet PC-11B1
-         Ovislink AirLive WL-1120PCM
-         Mentor WL-PCI
-         Linksys WPC11 v4
-         TrendNET TEW-288PI
-         D-Link DWL-520 Rev D
-         Repotec RP-WP7126
-         TP-Link TL-WN250/251
-         Zonet ZEW1000
-         Longshine LCS-8031-R
-         HomeLine HLW-PCC200
-         GigaFast WF721-AEX
-         Planet WL-3553
-         Encore ENLWI-PCI1-NT
-         TrendNET TEW-266PC
-         Gigabyte GN-WLMR101
-         Siemens-fujitsu Amilo D1840W
-         Edimax EW-7126
-         PheeNet WL-11PCIR
-         Tonze PC-2100T
-         Planet WL-8303
-         Dlink DWL-650 v M1
-         Edimax EW-7106
-         Q-Tec 770WC
-         Topcom Skyr@cer 4011b
-         Roper FreeLan 802.11b (edition 2004)
-         Wistron Neweb Corp CB-200B
-         Pentagram HorNET
-         QTec 775WC
-         TwinMOS Booming B Series
-         Micronet SP906BB
-         Sweex LC700010
-         Surecom EP-9428
-         Safecom SWLCR-1100
-
-         Thanks to Realtek for their support!
-
-config RTL8187
-       tristate "Realtek 8187 and 8187B USB support"
-       depends on MAC80211 && USB
-       select EEPROM_93CX6
-       ---help---
-         This is a driver for RTL8187 and RTL8187B based cards.
-         These are USB based chips found in devices such as:
-
-         Netgear WG111v2
-         Level 1 WNC-0301USB
-         Micronet SP907GK V5
-         Encore ENUWI-G2
-         Trendnet TEW-424UB
-         ASUS P5B Deluxe/P5K Premium motherboards
-         Toshiba Satellite Pro series of laptops
-         Asus Wireless Link
-         Linksys WUSB54GC-EU v2
-           (v1 = rt73usb; v3 is rt2070-based,
-            use staging/rt3070 or try rt2800usb)
-
-         Thanks to Realtek for their support!
-
-# If possible, automatically enable LEDs for RTL8187.
-
-config RTL8187_LEDS
-       bool
-       depends on RTL8187 && MAC80211_LEDS && (LEDS_CLASS = y || LEDS_CLASS = RTL8187)
-       default y
+source "drivers/net/wireless/rtl818x/Kconfig"
 
 config ADM8211
        tristate "ADMtek ADM8211 support"
index 1fbf6b1f9a7e0f430cc4f86164c410e9ed6a24f3..d32f2828b098ee63241e3b1e83c82d96ab2944df 100644 (file)
@@ -71,9 +71,21 @@ struct ath_regulatory {
        struct reg_dmn_pair_mapping *regpair;
 };
 
+/**
+ * struct ath_ops - Register read/write operations
+ *
+ * @read: Register read
+ * @write: Register write
+ * @enable_write_buffer: Enable multiple register writes
+ * @disable_write_buffer: Disable multiple register writes
+ * @write_flush: Flush buffered register writes
+ */
 struct ath_ops {
        unsigned int (*read)(void *, u32 reg_offset);
-        void (*write)(void *, u32 val, u32 reg_offset);
+       void (*write)(void *, u32 val, u32 reg_offset);
+       void (*enable_write_buffer)(void *);
+       void (*disable_write_buffer)(void *);
+       void (*write_flush) (void *);
 };
 
 struct ath_common;
index 93005f1d326dc9e3ce9c9694575d11afc5e363d0..c274979ada3a667a84bf82db49139830155686d0 100644 (file)
@@ -242,6 +242,8 @@ static int ath5k_set_key(struct ieee80211_hw *hw,
                struct ieee80211_key_conf *key);
 static int ath5k_get_stats(struct ieee80211_hw *hw,
                struct ieee80211_low_level_stats *stats);
+static int ath5k_get_survey(struct ieee80211_hw *hw,
+               int idx, struct survey_info *survey);
 static u64 ath5k_get_tsf(struct ieee80211_hw *hw);
 static void ath5k_set_tsf(struct ieee80211_hw *hw, u64 tsf);
 static void ath5k_reset_tsf(struct ieee80211_hw *hw);
@@ -267,6 +269,7 @@ static const struct ieee80211_ops ath5k_hw_ops = {
        .configure_filter = ath5k_configure_filter,
        .set_key        = ath5k_set_key,
        .get_stats      = ath5k_get_stats,
+       .get_survey     = ath5k_get_survey,
        .conf_tx        = NULL,
        .get_tsf        = ath5k_get_tsf,
        .set_tsf        = ath5k_set_tsf,
@@ -3292,6 +3295,22 @@ ath5k_get_stats(struct ieee80211_hw *hw,
        return 0;
 }
 
+static int ath5k_get_survey(struct ieee80211_hw *hw, int idx,
+               struct survey_info *survey)
+{
+       struct ath5k_softc *sc = hw->priv;
+       struct ieee80211_conf *conf = &hw->conf;
+
+        if (idx != 0)
+               return -ENOENT;
+
+       survey->channel = conf->channel;
+       survey->filled = SURVEY_INFO_NOISE_DBM;
+       survey->noise = sc->ah->ah_noise_floor;
+
+       return 0;
+}
+
 static u64
 ath5k_get_tsf(struct ieee80211_hw *hw)
 {
index 174412fc81f83a6823feeaeadfb2351e0ca9d6bd..5212e275f1c7795531eb6a606d8cb1cbf8853359 100644 (file)
@@ -496,6 +496,8 @@ void ath5k_hw_set_rx_filter(struct ath5k_hw *ah, u32 filter)
 * Beacon control *
 \****************/
 
+#define ATH5K_MAX_TSF_READ 10
+
 /**
  * ath5k_hw_get_tsf64 - Get the full 64bit TSF
  *
@@ -505,10 +507,35 @@ void ath5k_hw_set_rx_filter(struct ath5k_hw *ah, u32 filter)
  */
 u64 ath5k_hw_get_tsf64(struct ath5k_hw *ah)
 {
-       u64 tsf = ath5k_hw_reg_read(ah, AR5K_TSF_U32);
+       u32 tsf_lower, tsf_upper1, tsf_upper2;
+       int i;
+
+       /*
+        * While reading TSF upper and then lower part, the clock is still
+        * counting (or jumping in case of IBSS merge) so we might get
+        * inconsistent values. To avoid this, we read the upper part again
+        * and check it has not been changed. We make the hypothesis that a
+        * maximum of 3 changes can happens in a row (we use 10 as a safe
+        * value).
+        *
+        * Impact on performance is pretty small, since in most cases, only
+        * 3 register reads are needed.
+        */
+
+       tsf_upper1 = ath5k_hw_reg_read(ah, AR5K_TSF_U32);
+       for (i = 0; i < ATH5K_MAX_TSF_READ; i++) {
+               tsf_lower = ath5k_hw_reg_read(ah, AR5K_TSF_L32);
+               tsf_upper2 = ath5k_hw_reg_read(ah, AR5K_TSF_U32);
+               if (tsf_upper2 == tsf_upper1)
+                       break;
+               tsf_upper1 = tsf_upper2;
+       }
+
+       WARN_ON( i == ATH5K_MAX_TSF_READ );
+
        ATH5K_TRACE(ah->ah_sc);
 
-       return ath5k_hw_reg_read(ah, AR5K_TSF_L32) | (tsf << 32);
+       return (((u64)tsf_upper1 << 32) | tsf_lower);
 }
 
 /**
index 97133beda269c7a884c997d7f9873541b008636b..dd112be218abf951bc5875c107a43d1f9fe87ddf 100644 (file)
@@ -13,16 +13,26 @@ ath9k-$(CONFIG_ATH9K_DEBUGFS) += debug.o
 
 obj-$(CONFIG_ATH9K) += ath9k.o
 
-ath9k_hw-y:=   hw.o \
+ath9k_hw-y:=   \
+               ar9002_hw.o \
+               ar9003_hw.o \
+               hw.o \
+               ar9003_phy.o \
+               ar9002_phy.o \
+               ar5008_phy.o \
+               ar9002_calib.o \
+               ar9003_calib.o \
+               calib.o \
                eeprom.o \
                eeprom_def.o \
                eeprom_4k.o \
                eeprom_9287.o \
-               calib.o \
                ani.o \
-               phy.o \
                btcoex.o \
                mac.o \
+               ar9002_mac.o \
+               ar9003_mac.o \
+               ar9003_eeprom.o
 
 obj-$(CONFIG_ATH9K_HW) += ath9k_hw.o
 
index 2a0cd64c2bfbc64830a8a71bf714972302ebc2dc..cec62d311c78094c515b80d81712129ffd9ea4b0 100644 (file)
@@ -15,6 +15,7 @@
  */
 
 #include "hw.h"
+#include "hw-ops.h"
 
 static int ath9k_hw_get_ani_channel_idx(struct ath_hw *ah,
                                        struct ath9k_channel *chan)
@@ -37,190 +38,6 @@ static int ath9k_hw_get_ani_channel_idx(struct ath_hw *ah,
        return 0;
 }
 
-static bool ath9k_hw_ani_control(struct ath_hw *ah,
-                                enum ath9k_ani_cmd cmd, int param)
-{
-       struct ar5416AniState *aniState = ah->curani;
-       struct ath_common *common = ath9k_hw_common(ah);
-
-       switch (cmd & ah->ani_function) {
-       case ATH9K_ANI_NOISE_IMMUNITY_LEVEL:{
-               u32 level = param;
-
-               if (level >= ARRAY_SIZE(ah->totalSizeDesired)) {
-                       ath_print(common, ATH_DBG_ANI,
-                                 "level out of range (%u > %u)\n",
-                                 level,
-                                 (unsigned)ARRAY_SIZE(ah->totalSizeDesired));
-                       return false;
-               }
-
-               REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ,
-                             AR_PHY_DESIRED_SZ_TOT_DES,
-                             ah->totalSizeDesired[level]);
-               REG_RMW_FIELD(ah, AR_PHY_AGC_CTL1,
-                             AR_PHY_AGC_CTL1_COARSE_LOW,
-                             ah->coarse_low[level]);
-               REG_RMW_FIELD(ah, AR_PHY_AGC_CTL1,
-                             AR_PHY_AGC_CTL1_COARSE_HIGH,
-                             ah->coarse_high[level]);
-               REG_RMW_FIELD(ah, AR_PHY_FIND_SIG,
-                             AR_PHY_FIND_SIG_FIRPWR,
-                             ah->firpwr[level]);
-
-               if (level > aniState->noiseImmunityLevel)
-                       ah->stats.ast_ani_niup++;
-               else if (level < aniState->noiseImmunityLevel)
-                       ah->stats.ast_ani_nidown++;
-               aniState->noiseImmunityLevel = level;
-               break;
-       }
-       case ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION:{
-               const int m1ThreshLow[] = { 127, 50 };
-               const int m2ThreshLow[] = { 127, 40 };
-               const int m1Thresh[] = { 127, 0x4d };
-               const int m2Thresh[] = { 127, 0x40 };
-               const int m2CountThr[] = { 31, 16 };
-               const int m2CountThrLow[] = { 63, 48 };
-               u32 on = param ? 1 : 0;
-
-               REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
-                             AR_PHY_SFCORR_LOW_M1_THRESH_LOW,
-                             m1ThreshLow[on]);
-               REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
-                             AR_PHY_SFCORR_LOW_M2_THRESH_LOW,
-                             m2ThreshLow[on]);
-               REG_RMW_FIELD(ah, AR_PHY_SFCORR,
-                             AR_PHY_SFCORR_M1_THRESH,
-                             m1Thresh[on]);
-               REG_RMW_FIELD(ah, AR_PHY_SFCORR,
-                             AR_PHY_SFCORR_M2_THRESH,
-                             m2Thresh[on]);
-               REG_RMW_FIELD(ah, AR_PHY_SFCORR,
-                             AR_PHY_SFCORR_M2COUNT_THR,
-                             m2CountThr[on]);
-               REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
-                             AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW,
-                             m2CountThrLow[on]);
-
-               REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
-                             AR_PHY_SFCORR_EXT_M1_THRESH_LOW,
-                             m1ThreshLow[on]);
-               REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
-                             AR_PHY_SFCORR_EXT_M2_THRESH_LOW,
-                             m2ThreshLow[on]);
-               REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
-                             AR_PHY_SFCORR_EXT_M1_THRESH,
-                             m1Thresh[on]);
-               REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
-                             AR_PHY_SFCORR_EXT_M2_THRESH,
-                             m2Thresh[on]);
-
-               if (on)
-                       REG_SET_BIT(ah, AR_PHY_SFCORR_LOW,
-                                   AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW);
-               else
-                       REG_CLR_BIT(ah, AR_PHY_SFCORR_LOW,
-                                   AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW);
-
-               if (!on != aniState->ofdmWeakSigDetectOff) {
-                       if (on)
-                               ah->stats.ast_ani_ofdmon++;
-                       else
-                               ah->stats.ast_ani_ofdmoff++;
-                       aniState->ofdmWeakSigDetectOff = !on;
-               }
-               break;
-       }
-       case ATH9K_ANI_CCK_WEAK_SIGNAL_THR:{
-               const int weakSigThrCck[] = { 8, 6 };
-               u32 high = param ? 1 : 0;
-
-               REG_RMW_FIELD(ah, AR_PHY_CCK_DETECT,
-                             AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK,
-                             weakSigThrCck[high]);
-               if (high != aniState->cckWeakSigThreshold) {
-                       if (high)
-                               ah->stats.ast_ani_cckhigh++;
-                       else
-                               ah->stats.ast_ani_ccklow++;
-                       aniState->cckWeakSigThreshold = high;
-               }
-               break;
-       }
-       case ATH9K_ANI_FIRSTEP_LEVEL:{
-               const int firstep[] = { 0, 4, 8 };
-               u32 level = param;
-
-               if (level >= ARRAY_SIZE(firstep)) {
-                       ath_print(common, ATH_DBG_ANI,
-                                 "level out of range (%u > %u)\n",
-                                 level,
-                                 (unsigned) ARRAY_SIZE(firstep));
-                       return false;
-               }
-               REG_RMW_FIELD(ah, AR_PHY_FIND_SIG,
-                             AR_PHY_FIND_SIG_FIRSTEP,
-                             firstep[level]);
-               if (level > aniState->firstepLevel)
-                       ah->stats.ast_ani_stepup++;
-               else if (level < aniState->firstepLevel)
-                       ah->stats.ast_ani_stepdown++;
-               aniState->firstepLevel = level;
-               break;
-       }
-       case ATH9K_ANI_SPUR_IMMUNITY_LEVEL:{
-               const int cycpwrThr1[] =
-                       { 2, 4, 6, 8, 10, 12, 14, 16 };
-               u32 level = param;
-
-               if (level >= ARRAY_SIZE(cycpwrThr1)) {
-                       ath_print(common, ATH_DBG_ANI,
-                                 "level out of range (%u > %u)\n",
-                                 level,
-                                 (unsigned) ARRAY_SIZE(cycpwrThr1));
-                       return false;
-               }
-               REG_RMW_FIELD(ah, AR_PHY_TIMING5,
-                             AR_PHY_TIMING5_CYCPWR_THR1,
-                             cycpwrThr1[level]);
-               if (level > aniState->spurImmunityLevel)
-                       ah->stats.ast_ani_spurup++;
-               else if (level < aniState->spurImmunityLevel)
-                       ah->stats.ast_ani_spurdown++;
-               aniState->spurImmunityLevel = level;
-               break;
-       }
-       case ATH9K_ANI_PRESENT:
-               break;
-       default:
-               ath_print(common, ATH_DBG_ANI,
-                         "invalid cmd %u\n", cmd);
-               return false;
-       }
-
-       ath_print(common, ATH_DBG_ANI, "ANI parameters:\n");
-       ath_print(common, ATH_DBG_ANI,
-                 "noiseImmunityLevel=%d, spurImmunityLevel=%d, "
-                 "ofdmWeakSigDetectOff=%d\n",
-                 aniState->noiseImmunityLevel,
-                 aniState->spurImmunityLevel,
-                 !aniState->ofdmWeakSigDetectOff);
-       ath_print(common, ATH_DBG_ANI,
-                 "cckWeakSigThreshold=%d, "
-                 "firstepLevel=%d, listenTime=%d\n",
-                 aniState->cckWeakSigThreshold,
-                 aniState->firstepLevel,
-                 aniState->listenTime);
-       ath_print(common, ATH_DBG_ANI,
-               "cycleCount=%d, ofdmPhyErrCount=%d, cckPhyErrCount=%d\n\n",
-               aniState->cycleCount,
-               aniState->ofdmPhyErrCount,
-               aniState->cckPhyErrCount);
-
-       return true;
-}
-
 static void ath9k_hw_update_mibstats(struct ath_hw *ah,
                                     struct ath9k_mib_stats *stats)
 {
@@ -262,11 +79,17 @@ static void ath9k_ani_restart(struct ath_hw *ah)
                  "Writing ofdmbase=%u   cckbase=%u\n",
                  aniState->ofdmPhyErrBase,
                  aniState->cckPhyErrBase);
+
+       ENABLE_REGWRITE_BUFFER(ah);
+
        REG_WRITE(ah, AR_PHY_ERR_1, aniState->ofdmPhyErrBase);
        REG_WRITE(ah, AR_PHY_ERR_2, aniState->cckPhyErrBase);
        REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING);
        REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
 
+       REGWRITE_BUFFER_FLUSH(ah);
+       DISABLE_REGWRITE_BUFFER(ah);
+
        ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);
 
        aniState->ofdmPhyErrCount = 0;
@@ -540,8 +363,14 @@ void ath9k_ani_reset(struct ath_hw *ah)
        ath9k_hw_setrxfilter(ah, ath9k_hw_getrxfilter(ah) &
                             ~ATH9K_RX_FILTER_PHYERR);
        ath9k_ani_restart(ah);
+
+       ENABLE_REGWRITE_BUFFER(ah);
+
        REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING);
        REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
+
+       REGWRITE_BUFFER_FLUSH(ah);
+       DISABLE_REGWRITE_BUFFER(ah);
 }
 
 void ath9k_hw_ani_monitor(struct ath_hw *ah,
@@ -639,6 +468,8 @@ void ath9k_enable_mib_counters(struct ath_hw *ah)
 
        ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);
 
+       ENABLE_REGWRITE_BUFFER(ah);
+
        REG_WRITE(ah, AR_FILT_OFDM, 0);
        REG_WRITE(ah, AR_FILT_CCK, 0);
        REG_WRITE(ah, AR_MIBC,
@@ -646,6 +477,9 @@ void ath9k_enable_mib_counters(struct ath_hw *ah)
                  & 0x0f);
        REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING);
        REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
+
+       REGWRITE_BUFFER_FLUSH(ah);
+       DISABLE_REGWRITE_BUFFER(ah);
 }
 
 /* Freeze the MIB counters, get the stats and then clear them */
@@ -809,8 +643,14 @@ void ath9k_hw_ani_init(struct ath_hw *ah)
        ath_print(common, ATH_DBG_ANI, "Setting cckErrBase = 0x%08x\n",
                  ah->ani[0].cckPhyErrBase);
 
+       ENABLE_REGWRITE_BUFFER(ah);
+
        REG_WRITE(ah, AR_PHY_ERR_1, ah->ani[0].ofdmPhyErrBase);
        REG_WRITE(ah, AR_PHY_ERR_2, ah->ani[0].cckPhyErrBase);
+
+       REGWRITE_BUFFER_FLUSH(ah);
+       DISABLE_REGWRITE_BUFFER(ah);
+
        ath9k_enable_mib_counters(ah);
 
        ah->aniperiod = ATH9K_ANI_PERIOD;
diff --git a/drivers/net/wireless/ath/ath9k/ar5008_initvals.h b/drivers/net/wireless/ath/ath9k/ar5008_initvals.h
new file mode 100644 (file)
index 0000000..cd953f6
--- /dev/null
@@ -0,0 +1,742 @@
+/*
+ * Copyright (c) 2008-2009 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT 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.
+ */
+
+#ifndef INITVALS_AR5008_H
+#define INITVALS_AR5008_H
+
+static const u32 ar5416Modes[][6] = {
+    { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 },
+    { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 },
+    { 0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180 },
+    { 0x000010f0, 0x0000a000, 0x00014000, 0x00016000, 0x0000b000, 0x00014008 },
+    { 0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00, 0x06e006e0 },
+    { 0x0000801c, 0x128d93a7, 0x128d93cf, 0x12e013d7, 0x12e013ab, 0x098813cf },
+    { 0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810, 0x08f04810 },
+    { 0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a, 0x0000320a },
+    { 0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303 },
+    { 0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200 },
+    { 0x00009824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
+    { 0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001 },
+    { 0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
+    { 0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007 },
+    { 0x00009844, 0x1372161e, 0x1372161e, 0x137216a0, 0x137216a0, 0x137216a0 },
+    { 0x00009848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
+    { 0x0000a848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
+    { 0x0000b848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
+    { 0x00009850, 0x6c48b4e0, 0x6d48b4e0, 0x6d48b0de, 0x6c48b0de, 0x6c48b0de },
+    { 0x00009858, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e },
+    { 0x0000985c, 0x31395d5e, 0x3139605e, 0x3139605e, 0x31395d5e, 0x31395d5e },
+    { 0x00009860, 0x00049d18, 0x00049d18, 0x00049d18, 0x00049d18, 0x00049d18 },
+    { 0x00009864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00 },
+    { 0x00009868, 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190 },
+    { 0x0000986c, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 },
+    { 0x00009914, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898, 0x000007d0 },
+    { 0x00009918, 0x000001b8, 0x00000370, 0x00000268, 0x00000134, 0x00000134 },
+    { 0x00009924, 0xd0058a0b, 0xd0058a0b, 0xd0058a0b, 0xd0058a0b, 0xd0058a0b },
+    { 0x00009944, 0xffb81020, 0xffb81020, 0xffb81020, 0xffb81020, 0xffb81020 },
+    { 0x00009960, 0x00000900, 0x00000900, 0x00012d80, 0x00012d80, 0x00012d80 },
+    { 0x0000a960, 0x00000900, 0x00000900, 0x00012d80, 0x00012d80, 0x00012d80 },
+    { 0x0000b960, 0x00000900, 0x00000900, 0x00012d80, 0x00012d80, 0x00012d80 },
+    { 0x00009964, 0x00000000, 0x00000000, 0x00001120, 0x00001120, 0x00001120 },
+    { 0x000099bc, 0x001a0a00, 0x001a0a00, 0x001a0a00, 0x001a0a00, 0x001a0a00 },
+    { 0x000099c0, 0x038919be, 0x038919be, 0x038919be, 0x038919be, 0x038919be },
+    { 0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77 },
+    { 0x000099c8, 0x6af6532c, 0x6af6532c, 0x6af6532c, 0x6af6532c, 0x6af6532c },
+    { 0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8 },
+    { 0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, 0x00046384 },
+    { 0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+    { 0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+    { 0x0000a204, 0x00000880, 0x00000880, 0x00000880, 0x00000880, 0x00000880 },
+    { 0x0000a208, 0xd6be4788, 0xd6be4788, 0xd03e4788, 0xd03e4788, 0xd03e4788 },
+    { 0x0000a20c, 0x002ec1e0, 0x002ec1e0, 0x002ac120, 0x002ac120, 0x002ac120 },
+    { 0x0000b20c, 0x002ec1e0, 0x002ec1e0, 0x002ac120, 0x002ac120, 0x002ac120 },
+    { 0x0000c20c, 0x002ec1e0, 0x002ec1e0, 0x002ac120, 0x002ac120, 0x002ac120 },
+    { 0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a },
+    { 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000 },
+    { 0x0000a274, 0x0a1a9caa, 0x0a1a9caa, 0x0a1a7caa, 0x0a1a7caa, 0x0a1a7caa },
+    { 0x0000a300, 0x18010000, 0x18010000, 0x18010000, 0x18010000, 0x18010000 },
+    { 0x0000a304, 0x30032602, 0x30032602, 0x2e032402, 0x2e032402, 0x2e032402 },
+    { 0x0000a308, 0x48073e06, 0x48073e06, 0x4a0a3c06, 0x4a0a3c06, 0x4a0a3c06 },
+    { 0x0000a30c, 0x560b4c0a, 0x560b4c0a, 0x621a540b, 0x621a540b, 0x621a540b },
+    { 0x0000a310, 0x641a600f, 0x641a600f, 0x764f6c1b, 0x764f6c1b, 0x764f6c1b },
+    { 0x0000a314, 0x7a4f6e1b, 0x7a4f6e1b, 0x845b7a5a, 0x845b7a5a, 0x845b7a5a },
+    { 0x0000a318, 0x8c5b7e5a, 0x8c5b7e5a, 0x950f8ccf, 0x950f8ccf, 0x950f8ccf },
+    { 0x0000a31c, 0x9d0f96cf, 0x9d0f96cf, 0xa5cf9b4f, 0xa5cf9b4f, 0xa5cf9b4f },
+    { 0x0000a320, 0xb51fa69f, 0xb51fa69f, 0xbddfaf1f, 0xbddfaf1f, 0xbddfaf1f },
+    { 0x0000a324, 0xcb3fbd07, 0xcb3fbcbf, 0xd1ffc93f, 0xd1ffc93f, 0xd1ffc93f },
+    { 0x0000a328, 0x0000d7bf, 0x0000d7bf, 0x00000000, 0x00000000, 0x00000000 },
+    { 0x0000a32c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+    { 0x0000a330, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+    { 0x0000a334, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+};
+
+static const u32 ar5416Common[][2] = {
+    { 0x0000000c, 0x00000000 },
+    { 0x00000030, 0x00020015 },
+    { 0x00000034, 0x00000005 },
+    { 0x00000040, 0x00000000 },
+    { 0x00000044, 0x00000008 },
+    { 0x00000048, 0x00000008 },
+    { 0x0000004c, 0x00000010 },
+    { 0x00000050, 0x00000000 },
+    { 0x00000054, 0x0000001f },
+    { 0x00000800, 0x00000000 },
+    { 0x00000804, 0x00000000 },
+    { 0x00000808, 0x00000000 },
+    { 0x0000080c, 0x00000000 },
+    { 0x00000810, 0x00000000 },
+    { 0x00000814, 0x00000000 },
+    { 0x00000818, 0x00000000 },
+    { 0x0000081c, 0x00000000 },
+    { 0x00000820, 0x00000000 },
+    { 0x00000824, 0x00000000 },
+    { 0x00001040, 0x002ffc0f },
+    { 0x00001044, 0x002ffc0f },
+    { 0x00001048, 0x002ffc0f },
+    { 0x0000104c, 0x002ffc0f },
+    { 0x00001050, 0x002ffc0f },
+    { 0x00001054, 0x002ffc0f },
+    { 0x00001058, 0x002ffc0f },
+    { 0x0000105c, 0x002ffc0f },
+    { 0x00001060, 0x002ffc0f },
+    { 0x00001064, 0x002ffc0f },
+    { 0x00001230, 0x00000000 },
+    { 0x00001270, 0x00000000 },
+    { 0x00001038, 0x00000000 },
+    { 0x00001078, 0x00000000 },
+    { 0x000010b8, 0x00000000 },
+    { 0x000010f8, 0x00000000 },
+    { 0x00001138, 0x00000000 },
+    { 0x00001178, 0x00000000 },
+    { 0x000011b8, 0x00000000 },
+    { 0x000011f8, 0x00000000 },
+    { 0x00001238, 0x00000000 },
+    { 0x00001278, 0x00000000 },
+    { 0x000012b8, 0x00000000 },
+    { 0x000012f8, 0x00000000 },
+    { 0x00001338, 0x00000000 },
+    { 0x00001378, 0x00000000 },
+    { 0x000013b8, 0x00000000 },
+    { 0x000013f8, 0x00000000 },
+    { 0x00001438, 0x00000000 },
+    { 0x00001478, 0x00000000 },
+    { 0x000014b8, 0x00000000 },
+    { 0x000014f8, 0x00000000 },
+    { 0x00001538, 0x00000000 },
+    { 0x00001578, 0x00000000 },
+    { 0x000015b8, 0x00000000 },
+    { 0x000015f8, 0x00000000 },
+    { 0x00001638, 0x00000000 },
+    { 0x00001678, 0x00000000 },
+    { 0x000016b8, 0x00000000 },
+    { 0x000016f8, 0x00000000 },
+    { 0x00001738, 0x00000000 },
+    { 0x00001778, 0x00000000 },
+    { 0x000017b8, 0x00000000 },
+    { 0x000017f8, 0x00000000 },
+    { 0x0000103c, 0x00000000 },
+    { 0x0000107c, 0x00000000 },
+    { 0x000010bc, 0x00000000 },
+    { 0x000010fc, 0x00000000 },
+    { 0x0000113c, 0x00000000 },
+    { 0x0000117c, 0x00000000 },
+    { 0x000011bc, 0x00000000 },
+    { 0x000011fc, 0x00000000 },
+    { 0x0000123c, 0x00000000 },
+    { 0x0000127c, 0x00000000 },
+    { 0x000012bc, 0x00000000 },
+    { 0x000012fc, 0x00000000 },
+    { 0x0000133c, 0x00000000 },
+    { 0x0000137c, 0x00000000 },
+    { 0x000013bc, 0x00000000 },
+    { 0x000013fc, 0x00000000 },
+    { 0x0000143c, 0x00000000 },
+    { 0x0000147c, 0x00000000 },
+    { 0x00004030, 0x00000002 },
+    { 0x0000403c, 0x00000002 },
+    { 0x00007010, 0x00000000 },
+    { 0x00007038, 0x000004c2 },
+    { 0x00008004, 0x00000000 },
+    { 0x00008008, 0x00000000 },
+    { 0x0000800c, 0x00000000 },
+    { 0x00008018, 0x00000700 },
+    { 0x00008020, 0x00000000 },
+    { 0x00008038, 0x00000000 },
+    { 0x0000803c, 0x00000000 },
+    { 0x00008048, 0x40000000 },
+    { 0x00008054, 0x00000000 },
+    { 0x00008058, 0x00000000 },
+    { 0x0000805c, 0x000fc78f },
+    { 0x00008060, 0x0000000f },
+    { 0x00008064, 0x00000000 },
+    { 0x000080c0, 0x2a82301a },
+    { 0x000080c4, 0x05dc01e0 },
+    { 0x000080c8, 0x1f402710 },
+    { 0x000080cc, 0x01f40000 },
+    { 0x000080d0, 0x00001e00 },
+    { 0x000080d4, 0x00000000 },
+    { 0x000080d8, 0x00400000 },
+    { 0x000080e0, 0xffffffff },
+    { 0x000080e4, 0x0000ffff },
+    { 0x000080e8, 0x003f3f3f },
+    { 0x000080ec, 0x00000000 },
+    { 0x000080f0, 0x00000000 },
+    { 0x000080f4, 0x00000000 },
+    { 0x000080f8, 0x00000000 },
+    { 0x000080fc, 0x00020000 },
+    { 0x00008100, 0x00020000 },
+    { 0x00008104, 0x00000001 },
+    { 0x00008108, 0x00000052 },
+    { 0x0000810c, 0x00000000 },
+    { 0x00008110, 0x00000168 },
+    { 0x00008118, 0x000100aa },
+    { 0x0000811c, 0x00003210 },
+    { 0x00008124, 0x00000000 },
+    { 0x00008128, 0x00000000 },
+    { 0x0000812c, 0x00000000 },
+    { 0x00008130, 0x00000000 },
+    { 0x00008134, 0x00000000 },
+    { 0x00008138, 0x00000000 },
+    { 0x0000813c, 0x00000000 },
+    { 0x00008144, 0xffffffff },
+    { 0x00008168, 0x00000000 },
+    { 0x0000816c, 0x00000000 },
+    { 0x00008170, 0x32143320 },
+    { 0x00008174, 0xfaa4fa50 },
+    { 0x00008178, 0x00000100 },
+    { 0x0000817c, 0x00000000 },
+    { 0x000081c4, 0x00000000 },
+    { 0x000081ec, 0x00000000 },
+    { 0x000081f0, 0x00000000 },
+    { 0x000081f4, 0x00000000 },
+    { 0x000081f8, 0x00000000 },
+    { 0x000081fc, 0x00000000 },
+    { 0x00008200, 0x00000000 },
+    { 0x00008204, 0x00000000 },
+    { 0x00008208, 0x00000000 },
+    { 0x0000820c, 0x00000000 },
+    { 0x00008210, 0x00000000 },
+    { 0x00008214, 0x00000000 },
+    { 0x00008218, 0x00000000 },
+    { 0x0000821c, 0x00000000 },
+    { 0x00008220, 0x00000000 },
+    { 0x00008224, 0x00000000 },
+    { 0x00008228, 0x00000000 },
+    { 0x0000822c, 0x00000000 },
+    { 0x00008230, 0x00000000 },
+    { 0x00008234, 0x00000000 },
+    { 0x00008238, 0x00000000 },
+    { 0x0000823c, 0x00000000 },
+    { 0x00008240, 0x00100000 },
+    { 0x00008244, 0x0010f400 },
+    { 0x00008248, 0x00000100 },
+    { 0x0000824c, 0x0001e800 },
+    { 0x00008250, 0x00000000 },
+    { 0x00008254, 0x00000000 },
+    { 0x00008258, 0x00000000 },
+    { 0x0000825c, 0x400000ff },
+    { 0x00008260, 0x00080922 },
+    { 0x00008264, 0xa8000010 },
+    { 0x00008270, 0x00000000 },
+    { 0x00008274, 0x40000000 },
+    { 0x00008278, 0x003e4180 },
+    { 0x0000827c, 0x00000000 },
+    { 0x00008284, 0x0000002c },
+    { 0x00008288, 0x0000002c },
+    { 0x0000828c, 0x00000000 },
+    { 0x00008294, 0x00000000 },
+    { 0x00008298, 0x00000000 },
+    { 0x00008300, 0x00000000 },
+    { 0x00008304, 0x00000000 },
+    { 0x00008308, 0x00000000 },
+    { 0x0000830c, 0x00000000 },
+    { 0x00008310, 0x00000000 },
+    { 0x00008314, 0x00000000 },
+    { 0x00008318, 0x00000000 },
+    { 0x00008328, 0x00000000 },
+    { 0x0000832c, 0x00000007 },
+    { 0x00008330, 0x00000302 },
+    { 0x00008334, 0x00000e00 },
+    { 0x00008338, 0x00070000 },
+    { 0x0000833c, 0x00000000 },
+    { 0x00008340, 0x000107ff },
+    { 0x00009808, 0x00000000 },
+    { 0x0000980c, 0xad848e19 },
+    { 0x00009810, 0x7d14e000 },
+    { 0x00009814, 0x9c0a9f6b },
+    { 0x0000981c, 0x00000000 },
+    { 0x0000982c, 0x0000a000 },
+    { 0x00009830, 0x00000000 },
+    { 0x0000983c, 0x00200400 },
+    { 0x00009840, 0x206a002e },
+    { 0x0000984c, 0x1284233c },
+    { 0x00009854, 0x00000859 },
+    { 0x00009900, 0x00000000 },
+    { 0x00009904, 0x00000000 },
+    { 0x00009908, 0x00000000 },
+    { 0x0000990c, 0x00000000 },
+    { 0x0000991c, 0x10000fff },
+    { 0x00009920, 0x05100000 },
+    { 0x0000a920, 0x05100000 },
+    { 0x0000b920, 0x05100000 },
+    { 0x00009928, 0x00000001 },
+    { 0x0000992c, 0x00000004 },
+    { 0x00009934, 0x1e1f2022 },
+    { 0x00009938, 0x0a0b0c0d },
+    { 0x0000993c, 0x00000000 },
+    { 0x00009948, 0x9280b212 },
+    { 0x0000994c, 0x00020028 },
+    { 0x00009954, 0x5d50e188 },
+    { 0x00009958, 0x00081fff },
+    { 0x0000c95c, 0x004b6a8e },
+    { 0x0000c968, 0x000003ce },
+    { 0x00009970, 0x190fb515 },
+    { 0x00009974, 0x00000000 },
+    { 0x00009978, 0x00000001 },
+    { 0x0000997c, 0x00000000 },
+    { 0x00009980, 0x00000000 },
+    { 0x00009984, 0x00000000 },
+    { 0x00009988, 0x00000000 },
+    { 0x0000998c, 0x00000000 },
+    { 0x00009990, 0x00000000 },
+    { 0x00009994, 0x00000000 },
+    { 0x00009998, 0x00000000 },
+    { 0x0000999c, 0x00000000 },
+    { 0x000099a0, 0x00000000 },
+    { 0x000099a4, 0x00000001 },
+    { 0x000099a8, 0x001fff00 },
+    { 0x000099ac, 0x00000000 },
+    { 0x000099b0, 0x03051000 },
+    { 0x000099dc, 0x00000000 },
+    { 0x000099e0, 0x00000200 },
+    { 0x000099e4, 0xaaaaaaaa },
+    { 0x000099e8, 0x3c466478 },
+    { 0x000099ec, 0x000000aa },
+    { 0x000099fc, 0x00001042 },
+    { 0x00009b00, 0x00000000 },
+    { 0x00009b04, 0x00000001 },
+    { 0x00009b08, 0x00000002 },
+    { 0x00009b0c, 0x00000003 },
+    { 0x00009b10, 0x00000004 },
+    { 0x00009b14, 0x00000005 },
+    { 0x00009b18, 0x00000008 },
+    { 0x00009b1c, 0x00000009 },
+    { 0x00009b20, 0x0000000a },
+    { 0x00009b24, 0x0000000b },
+    { 0x00009b28, 0x0000000c },
+    { 0x00009b2c, 0x0000000d },
+    { 0x00009b30, 0x00000010 },
+    { 0x00009b34, 0x00000011 },
+    { 0x00009b38, 0x00000012 },
+    { 0x00009b3c, 0x00000013 },
+    { 0x00009b40, 0x00000014 },
+    { 0x00009b44, 0x00000015 },
+    { 0x00009b48, 0x00000018 },
+    { 0x00009b4c, 0x00000019 },
+    { 0x00009b50, 0x0000001a },
+    { 0x00009b54, 0x0000001b },
+    { 0x00009b58, 0x0000001c },
+    { 0x00009b5c, 0x0000001d },
+    { 0x00009b60, 0x00000020 },
+    { 0x00009b64, 0x00000021 },
+    { 0x00009b68, 0x00000022 },
+    { 0x00009b6c, 0x00000023 },
+    { 0x00009b70, 0x00000024 },
+    { 0x00009b74, 0x00000025 },
+    { 0x00009b78, 0x00000028 },
+    { 0x00009b7c, 0x00000029 },
+    { 0x00009b80, 0x0000002a },
+    { 0x00009b84, 0x0000002b },
+    { 0x00009b88, 0x0000002c },
+    { 0x00009b8c, 0x0000002d },
+    { 0x00009b90, 0x00000030 },
+    { 0x00009b94, 0x00000031 },
+    { 0x00009b98, 0x00000032 },
+    { 0x00009b9c, 0x00000033 },
+    { 0x00009ba0, 0x00000034 },
+    { 0x00009ba4, 0x00000035 },
+    { 0x00009ba8, 0x00000035 },
+    { 0x00009bac, 0x00000035 },
+    { 0x00009bb0, 0x00000035 },
+    { 0x00009bb4, 0x00000035 },
+    { 0x00009bb8, 0x00000035 },
+    { 0x00009bbc, 0x00000035 },
+    { 0x00009bc0, 0x00000035 },
+    { 0x00009bc4, 0x00000035 },
+    { 0x00009bc8, 0x00000035 },
+    { 0x00009bcc, 0x00000035 },
+    { 0x00009bd0, 0x00000035 },
+    { 0x00009bd4, 0x00000035 },
+    { 0x00009bd8, 0x00000035 },
+    { 0x00009bdc, 0x00000035 },
+    { 0x00009be0, 0x00000035 },
+    { 0x00009be4, 0x00000035 },
+    { 0x00009be8, 0x00000035 },
+    { 0x00009bec, 0x00000035 },
+    { 0x00009bf0, 0x00000035 },
+    { 0x00009bf4, 0x00000035 },
+    { 0x00009bf8, 0x00000010 },
+    { 0x00009bfc, 0x0000001a },
+    { 0x0000a210, 0x40806333 },
+    { 0x0000a214, 0x00106c10 },
+    { 0x0000a218, 0x009c4060 },
+    { 0x0000a220, 0x018830c6 },
+    { 0x0000a224, 0x00000400 },
+    { 0x0000a228, 0x00000bb5 },
+    { 0x0000a22c, 0x00000011 },
+    { 0x0000a234, 0x20202020 },
+    { 0x0000a238, 0x20202020 },
+    { 0x0000a23c, 0x13c889af },
+    { 0x0000a240, 0x38490a20 },
+    { 0x0000a244, 0x00007bb6 },
+    { 0x0000a248, 0x0fff3ffc },
+    { 0x0000a24c, 0x00000001 },
+    { 0x0000a250, 0x0000a000 },
+    { 0x0000a254, 0x00000000 },
+    { 0x0000a258, 0x0cc75380 },
+    { 0x0000a25c, 0x0f0f0f01 },
+    { 0x0000a260, 0xdfa91f01 },
+    { 0x0000a268, 0x00000000 },
+    { 0x0000a26c, 0x0e79e5c6 },
+    { 0x0000b26c, 0x0e79e5c6 },
+    { 0x0000c26c, 0x0e79e5c6 },
+    { 0x0000d270, 0x00820820 },
+    { 0x0000a278, 0x1ce739ce },
+    { 0x0000a27c, 0x051701ce },
+    { 0x0000a338, 0x00000000 },
+    { 0x0000a33c, 0x00000000 },
+    { 0x0000a340, 0x00000000 },
+    { 0x0000a344, 0x00000000 },
+    { 0x0000a348, 0x3fffffff },
+    { 0x0000a34c, 0x3fffffff },
+    { 0x0000a350, 0x3fffffff },
+    { 0x0000a354, 0x0003ffff },
+    { 0x0000a358, 0x79a8aa1f },
+    { 0x0000d35c, 0x07ffffef },
+    { 0x0000d360, 0x0fffffe7 },
+    { 0x0000d364, 0x17ffffe5 },
+    { 0x0000d368, 0x1fffffe4 },
+    { 0x0000d36c, 0x37ffffe3 },
+    { 0x0000d370, 0x3fffffe3 },
+    { 0x0000d374, 0x57ffffe3 },
+    { 0x0000d378, 0x5fffffe2 },
+    { 0x0000d37c, 0x7fffffe2 },
+    { 0x0000d380, 0x7f3c7bba },
+    { 0x0000d384, 0xf3307ff0 },
+    { 0x0000a388, 0x08000000 },
+    { 0x0000a38c, 0x20202020 },
+    { 0x0000a390, 0x20202020 },
+    { 0x0000a394, 0x1ce739ce },
+    { 0x0000a398, 0x000001ce },
+    { 0x0000a39c, 0x00000001 },
+    { 0x0000a3a0, 0x00000000 },
+    { 0x0000a3a4, 0x00000000 },
+    { 0x0000a3a8, 0x00000000 },
+    { 0x0000a3ac, 0x00000000 },
+    { 0x0000a3b0, 0x00000000 },
+    { 0x0000a3b4, 0x00000000 },
+    { 0x0000a3b8, 0x00000000 },
+    { 0x0000a3bc, 0x00000000 },
+    { 0x0000a3c0, 0x00000000 },
+    { 0x0000a3c4, 0x00000000 },
+    { 0x0000a3c8, 0x00000246 },
+    { 0x0000a3cc, 0x20202020 },
+    { 0x0000a3d0, 0x20202020 },
+    { 0x0000a3d4, 0x20202020 },
+    { 0x0000a3dc, 0x1ce739ce },
+    { 0x0000a3e0, 0x000001ce },
+};
+
+static const u32 ar5416Bank0[][2] = {
+    { 0x000098b0, 0x1e5795e5 },
+    { 0x000098e0, 0x02008020 },
+};
+
+static const u32 ar5416BB_RfGain[][3] = {
+    { 0x00009a00, 0x00000000, 0x00000000 },
+    { 0x00009a04, 0x00000040, 0x00000040 },
+    { 0x00009a08, 0x00000080, 0x00000080 },
+    { 0x00009a0c, 0x000001a1, 0x00000141 },
+    { 0x00009a10, 0x000001e1, 0x00000181 },
+    { 0x00009a14, 0x00000021, 0x000001c1 },
+    { 0x00009a18, 0x00000061, 0x00000001 },
+    { 0x00009a1c, 0x00000168, 0x00000041 },
+    { 0x00009a20, 0x000001a8, 0x000001a8 },
+    { 0x00009a24, 0x000001e8, 0x000001e8 },
+    { 0x00009a28, 0x00000028, 0x00000028 },
+    { 0x00009a2c, 0x00000068, 0x00000068 },
+    { 0x00009a30, 0x00000189, 0x000000a8 },
+    { 0x00009a34, 0x000001c9, 0x00000169 },
+    { 0x00009a38, 0x00000009, 0x000001a9 },
+    { 0x00009a3c, 0x00000049, 0x000001e9 },
+    { 0x00009a40, 0x00000089, 0x00000029 },
+    { 0x00009a44, 0x00000170, 0x00000069 },
+    { 0x00009a48, 0x000001b0, 0x00000190 },
+    { 0x00009a4c, 0x000001f0, 0x000001d0 },
+    { 0x00009a50, 0x00000030, 0x00000010 },
+    { 0x00009a54, 0x00000070, 0x00000050 },
+    { 0x00009a58, 0x00000191, 0x00000090 },
+    { 0x00009a5c, 0x000001d1, 0x00000151 },
+    { 0x00009a60, 0x00000011, 0x00000191 },
+    { 0x00009a64, 0x00000051, 0x000001d1 },
+    { 0x00009a68, 0x00000091, 0x00000011 },
+    { 0x00009a6c, 0x000001b8, 0x00000051 },
+    { 0x00009a70, 0x000001f8, 0x00000198 },
+    { 0x00009a74, 0x00000038, 0x000001d8 },
+    { 0x00009a78, 0x00000078, 0x00000018 },
+    { 0x00009a7c, 0x00000199, 0x00000058 },
+    { 0x00009a80, 0x000001d9, 0x00000098 },
+    { 0x00009a84, 0x00000019, 0x00000159 },
+    { 0x00009a88, 0x00000059, 0x00000199 },
+    { 0x00009a8c, 0x00000099, 0x000001d9 },
+    { 0x00009a90, 0x000000d9, 0x00000019 },
+    { 0x00009a94, 0x000000f9, 0x00000059 },
+    { 0x00009a98, 0x000000f9, 0x00000099 },
+    { 0x00009a9c, 0x000000f9, 0x000000d9 },
+    { 0x00009aa0, 0x000000f9, 0x000000f9 },
+    { 0x00009aa4, 0x000000f9, 0x000000f9 },
+    { 0x00009aa8, 0x000000f9, 0x000000f9 },
+    { 0x00009aac, 0x000000f9, 0x000000f9 },
+    { 0x00009ab0, 0x000000f9, 0x000000f9 },
+    { 0x00009ab4, 0x000000f9, 0x000000f9 },
+    { 0x00009ab8, 0x000000f9, 0x000000f9 },
+    { 0x00009abc, 0x000000f9, 0x000000f9 },
+    { 0x00009ac0, 0x000000f9, 0x000000f9 },
+    { 0x00009ac4, 0x000000f9, 0x000000f9 },
+    { 0x00009ac8, 0x000000f9, 0x000000f9 },
+    { 0x00009acc, 0x000000f9, 0x000000f9 },
+    { 0x00009ad0, 0x000000f9, 0x000000f9 },
+    { 0x00009ad4, 0x000000f9, 0x000000f9 },
+    { 0x00009ad8, 0x000000f9, 0x000000f9 },
+    { 0x00009adc, 0x000000f9, 0x000000f9 },
+    { 0x00009ae0, 0x000000f9, 0x000000f9 },
+    { 0x00009ae4, 0x000000f9, 0x000000f9 },
+    { 0x00009ae8, 0x000000f9, 0x000000f9 },
+    { 0x00009aec, 0x000000f9, 0x000000f9 },
+    { 0x00009af0, 0x000000f9, 0x000000f9 },
+    { 0x00009af4, 0x000000f9, 0x000000f9 },
+    { 0x00009af8, 0x000000f9, 0x000000f9 },
+    { 0x00009afc, 0x000000f9, 0x000000f9 },
+};
+
+static const u32 ar5416Bank1[][2] = {
+    { 0x000098b0, 0x02108421 },
+    { 0x000098ec, 0x00000008 },
+};
+
+static const u32 ar5416Bank2[][2] = {
+    { 0x000098b0, 0x0e73ff17 },
+    { 0x000098e0, 0x00000420 },
+};
+
+static const u32 ar5416Bank3[][3] = {
+    { 0x000098f0, 0x01400018, 0x01c00018 },
+};
+
+static const u32 ar5416Bank6[][3] = {
+
+    { 0x0000989c, 0x00000000, 0x00000000 },
+    { 0x0000989c, 0x00000000, 0x00000000 },
+    { 0x0000989c, 0x00000000, 0x00000000 },
+    { 0x0000989c, 0x00e00000, 0x00e00000 },
+    { 0x0000989c, 0x005e0000, 0x005e0000 },
+    { 0x0000989c, 0x00120000, 0x00120000 },
+    { 0x0000989c, 0x00620000, 0x00620000 },
+    { 0x0000989c, 0x00020000, 0x00020000 },
+    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
+    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
+    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
+    { 0x0000989c, 0x40ff0000, 0x40ff0000 },
+    { 0x0000989c, 0x005f0000, 0x005f0000 },
+    { 0x0000989c, 0x00870000, 0x00870000 },
+    { 0x0000989c, 0x00f90000, 0x00f90000 },
+    { 0x0000989c, 0x007b0000, 0x007b0000 },
+    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
+    { 0x0000989c, 0x00f50000, 0x00f50000 },
+    { 0x0000989c, 0x00dc0000, 0x00dc0000 },
+    { 0x0000989c, 0x00110000, 0x00110000 },
+    { 0x0000989c, 0x006100a8, 0x006100a8 },
+    { 0x0000989c, 0x004210a2, 0x004210a2 },
+    { 0x0000989c, 0x0014008f, 0x0014008f },
+    { 0x0000989c, 0x00c40003, 0x00c40003 },
+    { 0x0000989c, 0x003000f2, 0x003000f2 },
+    { 0x0000989c, 0x00440016, 0x00440016 },
+    { 0x0000989c, 0x00410040, 0x00410040 },
+    { 0x0000989c, 0x0001805e, 0x0001805e },
+    { 0x0000989c, 0x0000c0ab, 0x0000c0ab },
+    { 0x0000989c, 0x000000f1, 0x000000f1 },
+    { 0x0000989c, 0x00002081, 0x00002081 },
+    { 0x0000989c, 0x000000d4, 0x000000d4 },
+    { 0x000098d0, 0x0000000f, 0x0010000f },
+};
+
+static const u32 ar5416Bank6TPC[][3] = {
+    { 0x0000989c, 0x00000000, 0x00000000 },
+    { 0x0000989c, 0x00000000, 0x00000000 },
+    { 0x0000989c, 0x00000000, 0x00000000 },
+    { 0x0000989c, 0x00e00000, 0x00e00000 },
+    { 0x0000989c, 0x005e0000, 0x005e0000 },
+    { 0x0000989c, 0x00120000, 0x00120000 },
+    { 0x0000989c, 0x00620000, 0x00620000 },
+    { 0x0000989c, 0x00020000, 0x00020000 },
+    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
+    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
+    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
+    { 0x0000989c, 0x40ff0000, 0x40ff0000 },
+    { 0x0000989c, 0x005f0000, 0x005f0000 },
+    { 0x0000989c, 0x00870000, 0x00870000 },
+    { 0x0000989c, 0x00f90000, 0x00f90000 },
+    { 0x0000989c, 0x007b0000, 0x007b0000 },
+    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
+    { 0x0000989c, 0x00f50000, 0x00f50000 },
+    { 0x0000989c, 0x00dc0000, 0x00dc0000 },
+    { 0x0000989c, 0x00110000, 0x00110000 },
+    { 0x0000989c, 0x006100a8, 0x006100a8 },
+    { 0x0000989c, 0x00423022, 0x00423022 },
+    { 0x0000989c, 0x201400df, 0x201400df },
+    { 0x0000989c, 0x00c40002, 0x00c40002 },
+    { 0x0000989c, 0x003000f2, 0x003000f2 },
+    { 0x0000989c, 0x00440016, 0x00440016 },
+    { 0x0000989c, 0x00410040, 0x00410040 },
+    { 0x0000989c, 0x0001805e, 0x0001805e },
+    { 0x0000989c, 0x0000c0ab, 0x0000c0ab },
+    { 0x0000989c, 0x000000e1, 0x000000e1 },
+    { 0x0000989c, 0x00007081, 0x00007081 },
+    { 0x0000989c, 0x000000d4, 0x000000d4 },
+    { 0x000098d0, 0x0000000f, 0x0010000f },
+};
+
+static const u32 ar5416Bank7[][2] = {
+    { 0x0000989c, 0x00000500 },
+    { 0x0000989c, 0x00000800 },
+    { 0x000098cc, 0x0000000e },
+};
+
+static const u32 ar5416Addac[][2] = {
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000003 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x0000000c },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000030 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000060 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000058 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x000098cc,  0x00000000 },
+};
+
+static const u32 ar5416Modes_9100[][6] = {
+    { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 },
+    { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 },
+    { 0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180 },
+    { 0x000010f0, 0x0000a000, 0x00014000, 0x00016000, 0x0000b000, 0x00014008 },
+    { 0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00, 0x06e006e0 },
+    { 0x0000801c, 0x128d93a7, 0x128d93cf, 0x12e013d7, 0x12e013ab, 0x098813cf },
+    { 0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303 },
+    { 0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200 },
+    { 0x00009824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
+    { 0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001 },
+    { 0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
+    { 0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007 },
+    { 0x00009844, 0x0372161e, 0x0372161e, 0x037216a0, 0x037216a0, 0x037216a0 },
+    { 0x00009848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
+    { 0x0000a848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
+    { 0x0000b848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
+    { 0x00009850, 0x6d48b4e2, 0x6d48b4e2, 0x6d48b0e2, 0x6d48b0e2, 0x6d48b0e2 },
+    { 0x00009858, 0x7ec82d2e, 0x7ec82d2e, 0x7ec86d2e, 0x7ec84d2e, 0x7ec82d2e },
+    { 0x0000985c, 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e },
+    { 0x00009860, 0x00048d18, 0x00048d18, 0x00048d20, 0x00048d20, 0x00048d18 },
+    { 0x0000c864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00 },
+    { 0x00009868, 0x409a40d0, 0x409a40d0, 0x409a40d0, 0x409a40d0, 0x409a40d0 },
+    { 0x0000986c, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 },
+    { 0x00009914, 0x000007d0, 0x000007d0, 0x00000898, 0x00000898, 0x000007d0 },
+    { 0x00009918, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b, 0x00000016 },
+    { 0x00009924, 0xd00a8a07, 0xd00a8a07, 0xd00a8a11, 0xd00a8a0d, 0xd00a8a0d },
+    { 0x00009940, 0x00754604, 0x00754604, 0xfff81204, 0xfff81204, 0xfff81204 },
+    { 0x00009944, 0xdfb81020, 0xdfb81020, 0xdfb81020, 0xdfb81020, 0xdfb81020 },
+    { 0x00009954, 0x5f3ca3de, 0x5f3ca3de, 0xe250a51e, 0xe250a51e, 0xe250a51e },
+    { 0x00009958, 0x2108ecff, 0x2108ecff, 0x3388ffff, 0x3388ffff, 0x3388ffff },
+#ifdef TB243
+    { 0x00009960, 0x00000900, 0x00000900, 0x00009b40, 0x00009b40, 0x00012d80 },
+    { 0x0000a960, 0x00000900, 0x00000900, 0x00009b40, 0x00009b40, 0x00012d80 },
+    { 0x0000b960, 0x00000900, 0x00000900, 0x00009b40, 0x00009b40, 0x00012d80 },
+    { 0x00009964, 0x00000000, 0x00000000, 0x00002210, 0x00002210, 0x00001120 },
+#else
+    { 0x00009960, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0 },
+    { 0x0000a960, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0 },
+    { 0x0000b960, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0 },
+    { 0x00009964, 0x00001120, 0x00001120, 0x00001120, 0x00001120, 0x00001120 },
+#endif
+    { 0x0000c9bc, 0x001a0600, 0x001a0600, 0x001a1000, 0x001a0c00, 0x001a0c00 },
+    { 0x000099c0, 0x038919be, 0x038919be, 0x038919be, 0x038919be, 0x038919be },
+    { 0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77 },
+    { 0x000099c8, 0x60f65329, 0x60f65329, 0x60f65329, 0x60f65329, 0x60f65329 },
+    { 0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8 },
+    { 0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, 0x00046384 },
+    { 0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+    { 0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+    { 0x0000a204, 0x00000880, 0x00000880, 0x00000880, 0x00000880, 0x00000880 },
+    { 0x0000a208, 0xd6be4788, 0xd6be4788, 0xd03e4788, 0xd03e4788, 0xd03e4788 },
+    { 0x0000a20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120 },
+    { 0x0000b20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120 },
+    { 0x0000c20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120 },
+    { 0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a },
+    { 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000 },
+    { 0x0000a274, 0x0a1a9caa, 0x0a1a9caa, 0x0a1a7caa, 0x0a1a7caa, 0x0a1a7caa },
+    { 0x0000a300, 0x18010000, 0x18010000, 0x18010000, 0x18010000, 0x18010000 },
+    { 0x0000a304, 0x30032602, 0x30032602, 0x2e032402, 0x2e032402, 0x2e032402 },
+    { 0x0000a308, 0x48073e06, 0x48073e06, 0x4a0a3c06, 0x4a0a3c06, 0x4a0a3c06 },
+    { 0x0000a30c, 0x560b4c0a, 0x560b4c0a, 0x621a540b, 0x621a540b, 0x621a540b },
+    { 0x0000a310, 0x641a600f, 0x641a600f, 0x764f6c1b, 0x764f6c1b, 0x764f6c1b },
+    { 0x0000a314, 0x7a4f6e1b, 0x7a4f6e1b, 0x845b7a5a, 0x845b7a5a, 0x845b7a5a },
+    { 0x0000a318, 0x8c5b7e5a, 0x8c5b7e5a, 0x950f8ccf, 0x950f8ccf, 0x950f8ccf },
+    { 0x0000a31c, 0x9d0f96cf, 0x9d0f96cf, 0xa5cf9b4f, 0xa5cf9b4f, 0xa5cf9b4f },
+    { 0x0000a320, 0xb51fa69f, 0xb51fa69f, 0xbddfaf1f, 0xbddfaf1f, 0xbddfaf1f },
+    { 0x0000a324, 0xcb3fbd07, 0xcb3fbcbf, 0xd1ffc93f, 0xd1ffc93f, 0xd1ffc93f },
+    { 0x0000a328, 0x0000d7bf, 0x0000d7bf, 0x00000000, 0x00000000, 0x00000000 },
+    { 0x0000a32c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+    { 0x0000a330, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+    { 0x0000a334, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+};
+
+#endif /* INITVALS_AR5008_H */
diff --git a/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
new file mode 100644 (file)
index 0000000..de8ce12
--- /dev/null
@@ -0,0 +1,1375 @@
+/*
+ * Copyright (c) 2008-2010 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT 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 "hw.h"
+#include "hw-ops.h"
+#include "../regd.h"
+#include "ar9002_phy.h"
+
+/* All code below is for non single-chip solutions */
+
+/**
+ * ar5008_hw_phy_modify_rx_buffer() - perform analog swizzling of parameters
+ * @rfbuf:
+ * @reg32:
+ * @numBits:
+ * @firstBit:
+ * @column:
+ *
+ * Performs analog "swizzling" of parameters into their location.
+ * Used on external AR2133/AR5133 radios.
+ */
+static void ar5008_hw_phy_modify_rx_buffer(u32 *rfBuf, u32 reg32,
+                                          u32 numBits, u32 firstBit,
+                                          u32 column)
+{
+       u32 tmp32, mask, arrayEntry, lastBit;
+       int32_t bitPosition, bitsLeft;
+
+       tmp32 = ath9k_hw_reverse_bits(reg32, numBits);
+       arrayEntry = (firstBit - 1) / 8;
+       bitPosition = (firstBit - 1) % 8;
+       bitsLeft = numBits;
+       while (bitsLeft > 0) {
+               lastBit = (bitPosition + bitsLeft > 8) ?
+                   8 : bitPosition + bitsLeft;
+               mask = (((1 << lastBit) - 1) ^ ((1 << bitPosition) - 1)) <<
+                   (column * 8);
+               rfBuf[arrayEntry] &= ~mask;
+               rfBuf[arrayEntry] |= ((tmp32 << bitPosition) <<
+                                     (column * 8)) & mask;
+               bitsLeft -= 8 - bitPosition;
+               tmp32 = tmp32 >> (8 - bitPosition);
+               bitPosition = 0;
+               arrayEntry++;
+       }
+}
+
+/*
+ * Fix on 2.4 GHz band for orientation sensitivity issue by increasing
+ * rf_pwd_icsyndiv.
+ *
+ * Theoretical Rules:
+ *   if 2 GHz band
+ *      if forceBiasAuto
+ *         if synth_freq < 2412
+ *            bias = 0
+ *         else if 2412 <= synth_freq <= 2422
+ *            bias = 1
+ *         else // synth_freq > 2422
+ *            bias = 2
+ *      else if forceBias > 0
+ *         bias = forceBias & 7
+ *      else
+ *         no change, use value from ini file
+ *   else
+ *      no change, invalid band
+ *
+ *  1st Mod:
+ *    2422 also uses value of 2
+ *    <approved>
+ *
+ *  2nd Mod:
+ *    Less than 2412 uses value of 0, 2412 and above uses value of 2
+ */
+static void ar5008_hw_force_bias(struct ath_hw *ah, u16 synth_freq)
+{
+       struct ath_common *common = ath9k_hw_common(ah);
+       u32 tmp_reg;
+       int reg_writes = 0;
+       u32 new_bias = 0;
+
+       if (!AR_SREV_5416(ah) || synth_freq >= 3000)
+               return;
+
+       BUG_ON(AR_SREV_9280_10_OR_LATER(ah));
+
+       if (synth_freq < 2412)
+               new_bias = 0;
+       else if (synth_freq < 2422)
+               new_bias = 1;
+       else
+               new_bias = 2;
+
+       /* pre-reverse this field */
+       tmp_reg = ath9k_hw_reverse_bits(new_bias, 3);
+
+       ath_print(common, ATH_DBG_CONFIG,
+                 "Force rf_pwd_icsyndiv to %1d on %4d\n",
+                 new_bias, synth_freq);
+
+       /* swizzle rf_pwd_icsyndiv */
+       ar5008_hw_phy_modify_rx_buffer(ah->analogBank6Data, tmp_reg, 3, 181, 3);
+
+       /* write Bank 6 with new params */
+       REG_WRITE_RF_ARRAY(&ah->iniBank6, ah->analogBank6Data, reg_writes);
+}
+
+/**
+ * ar5008_hw_set_channel - tune to a channel on the external AR2133/AR5133 radios
+ * @ah: atheros hardware stucture
+ * @chan:
+ *
+ * For the external AR2133/AR5133 radios, takes the MHz channel value and set
+ * the channel value. Assumes writes enabled to analog bus and bank6 register
+ * cache in ah->analogBank6Data.
+ */
+static int ar5008_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan)
+{
+       struct ath_common *common = ath9k_hw_common(ah);
+       u32 channelSel = 0;
+       u32 bModeSynth = 0;
+       u32 aModeRefSel = 0;
+       u32 reg32 = 0;
+       u16 freq;
+       struct chan_centers centers;
+
+       ath9k_hw_get_channel_centers(ah, chan, &centers);
+       freq = centers.synth_center;
+
+       if (freq < 4800) {
+               u32 txctl;
+
+               if (((freq - 2192) % 5) == 0) {
+                       channelSel = ((freq - 672) * 2 - 3040) / 10;
+                       bModeSynth = 0;
+               } else if (((freq - 2224) % 5) == 0) {
+                       channelSel = ((freq - 704) * 2 - 3040) / 10;
+                       bModeSynth = 1;
+               } else {
+                       ath_print(common, ATH_DBG_FATAL,
+                                 "Invalid channel %u MHz\n", freq);
+                       return -EINVAL;
+               }
+
+               channelSel = (channelSel << 2) & 0xff;
+               channelSel = ath9k_hw_reverse_bits(channelSel, 8);
+
+               txctl = REG_READ(ah, AR_PHY_CCK_TX_CTRL);
+               if (freq == 2484) {
+
+                       REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
+                                 txctl | AR_PHY_CCK_TX_CTRL_JAPAN);
+               } else {
+                       REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
+                                 txctl & ~AR_PHY_CCK_TX_CTRL_JAPAN);
+               }
+
+       } else if ((freq % 20) == 0 && freq >= 5120) {
+               channelSel =
+                   ath9k_hw_reverse_bits(((freq - 4800) / 20 << 2), 8);
+               aModeRefSel = ath9k_hw_reverse_bits(1, 2);
+       } else if ((freq % 10) == 0) {
+               channelSel =
+                   ath9k_hw_reverse_bits(((freq - 4800) / 10 << 1), 8);
+               if (AR_SREV_9100(ah) || AR_SREV_9160_10_OR_LATER(ah))
+                       aModeRefSel = ath9k_hw_reverse_bits(2, 2);
+               else
+                       aModeRefSel = ath9k_hw_reverse_bits(1, 2);
+       } else if ((freq % 5) == 0) {
+               channelSel = ath9k_hw_reverse_bits((freq - 4800) / 5, 8);
+               aModeRefSel = ath9k_hw_reverse_bits(1, 2);
+       } else {
+               ath_print(common, ATH_DBG_FATAL,
+                         "Invalid channel %u MHz\n", freq);
+               return -EINVAL;
+       }
+
+       ar5008_hw_force_bias(ah, freq);
+
+       reg32 =
+           (channelSel << 8) | (aModeRefSel << 2) | (bModeSynth << 1) |
+           (1 << 5) | 0x1;
+
+       REG_WRITE(ah, AR_PHY(0x37), reg32);
+
+       ah->curchan = chan;
+       ah->curchan_rad_index = -1;
+
+       return 0;
+}
+
+/**
+ * ar5008_hw_spur_mitigate - convert baseband spur frequency for external radios
+ * @ah: atheros hardware structure
+ * @chan:
+ *
+ * For non single-chip solutions. Converts to baseband spur frequency given the
+ * input channel frequency and compute register settings below.
+ */
+static void ar5008_hw_spur_mitigate(struct ath_hw *ah,
+                                   struct ath9k_channel *chan)
+{
+       int bb_spur = AR_NO_SPUR;
+       int bin, cur_bin;
+       int spur_freq_sd;
+       int spur_delta_phase;
+       int denominator;
+       int upper, lower, cur_vit_mask;
+       int tmp, new;
+       int i;
+       int pilot_mask_reg[4] = { AR_PHY_TIMING7, AR_PHY_TIMING8,
+                         AR_PHY_PILOT_MASK_01_30, AR_PHY_PILOT_MASK_31_60
+       };
+       int chan_mask_reg[4] = { AR_PHY_TIMING9, AR_PHY_TIMING10,
+                        AR_PHY_CHANNEL_MASK_01_30, AR_PHY_CHANNEL_MASK_31_60
+       };
+       int inc[4] = { 0, 100, 0, 0 };
+
+       int8_t mask_m[123];
+       int8_t mask_p[123];
+       int8_t mask_amt;
+       int tmp_mask;
+       int cur_bb_spur;
+       bool is2GHz = IS_CHAN_2GHZ(chan);
+
+       memset(&mask_m, 0, sizeof(int8_t) * 123);
+       memset(&mask_p, 0, sizeof(int8_t) * 123);
+
+       for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
+               cur_bb_spur = ah->eep_ops->get_spur_channel(ah, i, is2GHz);
+               if (AR_NO_SPUR == cur_bb_spur)
+                       break;
+               cur_bb_spur = cur_bb_spur - (chan->channel * 10);
+               if ((cur_bb_spur > -95) && (cur_bb_spur < 95)) {
+                       bb_spur = cur_bb_spur;
+                       break;
+               }
+       }
+
+       if (AR_NO_SPUR == bb_spur)
+               return;
+
+       bin = bb_spur * 32;
+
+       tmp = REG_READ(ah, AR_PHY_TIMING_CTRL4(0));
+       new = tmp | (AR_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI |
+                    AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER |
+                    AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK |
+                    AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK);
+
+       REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0), new);
+
+       new = (AR_PHY_SPUR_REG_MASK_RATE_CNTL |
+              AR_PHY_SPUR_REG_ENABLE_MASK_PPM |
+              AR_PHY_SPUR_REG_MASK_RATE_SELECT |
+              AR_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI |
+              SM(SPUR_RSSI_THRESH, AR_PHY_SPUR_REG_SPUR_RSSI_THRESH));
+       REG_WRITE(ah, AR_PHY_SPUR_REG, new);
+
+       spur_delta_phase = ((bb_spur * 524288) / 100) &
+               AR_PHY_TIMING11_SPUR_DELTA_PHASE;
+
+       denominator = IS_CHAN_2GHZ(chan) ? 440 : 400;
+       spur_freq_sd = ((bb_spur * 2048) / denominator) & 0x3ff;
+
+       new = (AR_PHY_TIMING11_USE_SPUR_IN_AGC |
+              SM(spur_freq_sd, AR_PHY_TIMING11_SPUR_FREQ_SD) |
+              SM(spur_delta_phase, AR_PHY_TIMING11_SPUR_DELTA_PHASE));
+       REG_WRITE(ah, AR_PHY_TIMING11, new);
+
+       cur_bin = -6000;
+       upper = bin + 100;
+       lower = bin - 100;
+
+       for (i = 0; i < 4; i++) {
+               int pilot_mask = 0;
+               int chan_mask = 0;
+               int bp = 0;
+               for (bp = 0; bp < 30; bp++) {
+                       if ((cur_bin > lower) && (cur_bin < upper)) {
+                               pilot_mask = pilot_mask | 0x1 << bp;
+                               chan_mask = chan_mask | 0x1 << bp;
+                       }
+                       cur_bin += 100;
+               }
+               cur_bin += inc[i];
+               REG_WRITE(ah, pilot_mask_reg[i], pilot_mask);
+               REG_WRITE(ah, chan_mask_reg[i], chan_mask);
+       }
+
+       cur_vit_mask = 6100;
+       upper = bin + 120;
+       lower = bin - 120;
+
+       for (i = 0; i < 123; i++) {
+               if ((cur_vit_mask > lower) && (cur_vit_mask < upper)) {
+
+                       /* workaround for gcc bug #37014 */
+                       volatile int tmp_v = abs(cur_vit_mask - bin);
+
+                       if (tmp_v < 75)
+                               mask_amt = 1;
+                       else
+                               mask_amt = 0;
+                       if (cur_vit_mask < 0)
+                               mask_m[abs(cur_vit_mask / 100)] = mask_amt;
+                       else
+                               mask_p[cur_vit_mask / 100] = mask_amt;
+               }
+               cur_vit_mask -= 100;
+       }
+
+       tmp_mask = (mask_m[46] << 30) | (mask_m[47] << 28)
+               | (mask_m[48] << 26) | (mask_m[49] << 24)
+               | (mask_m[50] << 22) | (mask_m[51] << 20)
+               | (mask_m[52] << 18) | (mask_m[53] << 16)
+               | (mask_m[54] << 14) | (mask_m[55] << 12)
+               | (mask_m[56] << 10) | (mask_m[57] << 8)
+               | (mask_m[58] << 6) | (mask_m[59] << 4)
+               | (mask_m[60] << 2) | (mask_m[61] << 0);
+       REG_WRITE(ah, AR_PHY_BIN_MASK_1, tmp_mask);
+       REG_WRITE(ah, AR_PHY_VIT_MASK2_M_46_61, tmp_mask);
+
+       tmp_mask = (mask_m[31] << 28)
+               | (mask_m[32] << 26) | (mask_m[33] << 24)
+               | (mask_m[34] << 22) | (mask_m[35] << 20)
+               | (mask_m[36] << 18) | (mask_m[37] << 16)
+               | (mask_m[48] << 14) | (mask_m[39] << 12)
+               | (mask_m[40] << 10) | (mask_m[41] << 8)
+               | (mask_m[42] << 6) | (mask_m[43] << 4)
+               | (mask_m[44] << 2) | (mask_m[45] << 0);
+       REG_WRITE(ah, AR_PHY_BIN_MASK_2, tmp_mask);
+       REG_WRITE(ah, AR_PHY_MASK2_M_31_45, tmp_mask);
+
+       tmp_mask = (mask_m[16] << 30) | (mask_m[16] << 28)
+               | (mask_m[18] << 26) | (mask_m[18] << 24)
+               | (mask_m[20] << 22) | (mask_m[20] << 20)
+               | (mask_m[22] << 18) | (mask_m[22] << 16)
+               | (mask_m[24] << 14) | (mask_m[24] << 12)
+               | (mask_m[25] << 10) | (mask_m[26] << 8)
+               | (mask_m[27] << 6) | (mask_m[28] << 4)
+               | (mask_m[29] << 2) | (mask_m[30] << 0);
+       REG_WRITE(ah, AR_PHY_BIN_MASK_3, tmp_mask);
+       REG_WRITE(ah, AR_PHY_MASK2_M_16_30, tmp_mask);
+
+       tmp_mask = (mask_m[0] << 30) | (mask_m[1] << 28)
+               | (mask_m[2] << 26) | (mask_m[3] << 24)
+               | (mask_m[4] << 22) | (mask_m[5] << 20)
+               | (mask_m[6] << 18) | (mask_m[7] << 16)
+               | (mask_m[8] << 14) | (mask_m[9] << 12)
+               | (mask_m[10] << 10) | (mask_m[11] << 8)
+               | (mask_m[12] << 6) | (mask_m[13] << 4)
+               | (mask_m[14] << 2) | (mask_m[15] << 0);
+       REG_WRITE(ah, AR_PHY_MASK_CTL, tmp_mask);
+       REG_WRITE(ah, AR_PHY_MASK2_M_00_15, tmp_mask);
+
+       tmp_mask = (mask_p[15] << 28)
+               | (mask_p[14] << 26) | (mask_p[13] << 24)
+               | (mask_p[12] << 22) | (mask_p[11] << 20)
+               | (mask_p[10] << 18) | (mask_p[9] << 16)
+               | (mask_p[8] << 14) | (mask_p[7] << 12)
+               | (mask_p[6] << 10) | (mask_p[5] << 8)
+               | (mask_p[4] << 6) | (mask_p[3] << 4)
+               | (mask_p[2] << 2) | (mask_p[1] << 0);
+       REG_WRITE(ah, AR_PHY_BIN_MASK2_1, tmp_mask);
+       REG_WRITE(ah, AR_PHY_MASK2_P_15_01, tmp_mask);
+
+       tmp_mask = (mask_p[30] << 28)
+               | (mask_p[29] << 26) | (mask_p[28] << 24)
+               | (mask_p[27] << 22) | (mask_p[26] << 20)
+               | (mask_p[25] << 18) | (mask_p[24] << 16)
+               | (mask_p[23] << 14) | (mask_p[22] << 12)
+               | (mask_p[21] << 10) | (mask_p[20] << 8)
+               | (mask_p[19] << 6) | (mask_p[18] << 4)
+               | (mask_p[17] << 2) | (mask_p[16] << 0);
+       REG_WRITE(ah, AR_PHY_BIN_MASK2_2, tmp_mask);
+       REG_WRITE(ah, AR_PHY_MASK2_P_30_16, tmp_mask);
+
+       tmp_mask = (mask_p[45] << 28)
+               | (mask_p[44] << 26) | (mask_p[43] << 24)
+               | (mask_p[42] << 22) | (mask_p[41] << 20)
+               | (mask_p[40] << 18) | (mask_p[39] << 16)
+               | (mask_p[38] << 14) | (mask_p[37] << 12)
+               | (mask_p[36] << 10) | (mask_p[35] << 8)
+               | (mask_p[34] << 6) | (mask_p[33] << 4)
+               | (mask_p[32] << 2) | (mask_p[31] << 0);
+       REG_WRITE(ah, AR_PHY_BIN_MASK2_3, tmp_mask);
+       REG_WRITE(ah, AR_PHY_MASK2_P_45_31, tmp_mask);
+
+       tmp_mask = (mask_p[61] << 30) | (mask_p[60] << 28)
+               | (mask_p[59] << 26) | (mask_p[58] << 24)
+               | (mask_p[57] << 22) | (mask_p[56] << 20)
+               | (mask_p[55] << 18) | (mask_p[54] << 16)
+               | (mask_p[53] << 14) | (mask_p[52] << 12)
+               | (mask_p[51] << 10) | (mask_p[50] << 8)
+               | (mask_p[49] << 6) | (mask_p[48] << 4)
+               | (mask_p[47] << 2) | (mask_p[46] << 0);
+       REG_WRITE(ah, AR_PHY_BIN_MASK2_4, tmp_mask);
+       REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask);
+}
+
+/**
+ * ar5008_hw_rf_alloc_ext_banks - allocates banks for external radio programming
+ * @ah: atheros hardware structure
+ *
+ * Only required for older devices with external AR2133/AR5133 radios.
+ */
+static int ar5008_hw_rf_alloc_ext_banks(struct ath_hw *ah)
+{
+#define ATH_ALLOC_BANK(bank, size) do { \
+               bank = kzalloc((sizeof(u32) * size), GFP_KERNEL); \
+               if (!bank) { \
+                       ath_print(common, ATH_DBG_FATAL, \
+                                 "Cannot allocate RF banks\n"); \
+                       return -ENOMEM; \
+               } \
+       } while (0);
+
+       struct ath_common *common = ath9k_hw_common(ah);
+
+       BUG_ON(AR_SREV_9280_10_OR_LATER(ah));
+
+       ATH_ALLOC_BANK(ah->analogBank0Data, ah->iniBank0.ia_rows);
+       ATH_ALLOC_BANK(ah->analogBank1Data, ah->iniBank1.ia_rows);
+       ATH_ALLOC_BANK(ah->analogBank2Data, ah->iniBank2.ia_rows);
+       ATH_ALLOC_BANK(ah->analogBank3Data, ah->iniBank3.ia_rows);
+       ATH_ALLOC_BANK(ah->analogBank6Data, ah->iniBank6.ia_rows);
+       ATH_ALLOC_BANK(ah->analogBank6TPCData, ah->iniBank6TPC.ia_rows);
+       ATH_ALLOC_BANK(ah->analogBank7Data, ah->iniBank7.ia_rows);
+       ATH_ALLOC_BANK(ah->addac5416_21,
+                      ah->iniAddac.ia_rows * ah->iniAddac.ia_columns);
+       ATH_ALLOC_BANK(ah->bank6Temp, ah->iniBank6.ia_rows);
+
+       return 0;
+#undef ATH_ALLOC_BANK
+}
+
+
+/**
+ * ar5008_hw_rf_free_ext_banks - Free memory for analog bank scratch buffers
+ * @ah: atheros hardware struture
+ * For the external AR2133/AR5133 radios banks.
+ */
+static void ar5008_hw_rf_free_ext_banks(struct ath_hw *ah)
+{
+#define ATH_FREE_BANK(bank) do { \
+               kfree(bank); \
+               bank = NULL; \
+       } while (0);
+
+       BUG_ON(AR_SREV_9280_10_OR_LATER(ah));
+
+       ATH_FREE_BANK(ah->analogBank0Data);
+       ATH_FREE_BANK(ah->analogBank1Data);
+       ATH_FREE_BANK(ah->analogBank2Data);
+       ATH_FREE_BANK(ah->analogBank3Data);
+       ATH_FREE_BANK(ah->analogBank6Data);
+       ATH_FREE_BANK(ah->analogBank6TPCData);
+       ATH_FREE_BANK(ah->analogBank7Data);
+       ATH_FREE_BANK(ah->addac5416_21);
+       ATH_FREE_BANK(ah->bank6Temp);
+
+#undef ATH_FREE_BANK
+}
+
+/* *
+ * ar5008_hw_set_rf_regs - programs rf registers based on EEPROM
+ * @ah: atheros hardware structure
+ * @chan:
+ * @modesIndex:
+ *
+ * Used for the external AR2133/AR5133 radios.
+ *
+ * Reads the EEPROM header info from the device structure and programs
+ * all rf registers. This routine requires access to the analog
+ * rf device. This is not required for single-chip devices.
+ */
+static bool ar5008_hw_set_rf_regs(struct ath_hw *ah,
+                                 struct ath9k_channel *chan,
+                                 u16 modesIndex)
+{
+       u32 eepMinorRev;
+       u32 ob5GHz = 0, db5GHz = 0;
+       u32 ob2GHz = 0, db2GHz = 0;
+       int regWrites = 0;
+
+       /*
+        * Software does not need to program bank data
+        * for single chip devices, that is AR9280 or anything
+        * after that.
+        */
+       if (AR_SREV_9280_10_OR_LATER(ah))
+               return true;
+
+       /* Setup rf parameters */
+       eepMinorRev = ah->eep_ops->get_eeprom(ah, EEP_MINOR_REV);
+
+       /* Setup Bank 0 Write */
+       RF_BANK_SETUP(ah->analogBank0Data, &ah->iniBank0, 1);
+
+       /* Setup Bank 1 Write */
+       RF_BANK_SETUP(ah->analogBank1Data, &ah->iniBank1, 1);
+
+       /* Setup Bank 2 Write */
+       RF_BANK_SETUP(ah->analogBank2Data, &ah->iniBank2, 1);
+
+       /* Setup Bank 6 Write */
+       RF_BANK_SETUP(ah->analogBank3Data, &ah->iniBank3,
+                     modesIndex);
+       {
+               int i;
+               for (i = 0; i < ah->iniBank6TPC.ia_rows; i++) {
+                       ah->analogBank6Data[i] =
+                           INI_RA(&ah->iniBank6TPC, i, modesIndex);
+               }
+       }
+
+       /* Only the 5 or 2 GHz OB/DB need to be set for a mode */
+       if (eepMinorRev >= 2) {
+               if (IS_CHAN_2GHZ(chan)) {
+                       ob2GHz = ah->eep_ops->get_eeprom(ah, EEP_OB_2);
+                       db2GHz = ah->eep_ops->get_eeprom(ah, EEP_DB_2);
+                       ar5008_hw_phy_modify_rx_buffer(ah->analogBank6Data,
+                                                      ob2GHz, 3, 197, 0);
+                       ar5008_hw_phy_modify_rx_buffer(ah->analogBank6Data,
+                                                      db2GHz, 3, 194, 0);
+               } else {
+                       ob5GHz = ah->eep_ops->get_eeprom(ah, EEP_OB_5);
+                       db5GHz = ah->eep_ops->get_eeprom(ah, EEP_DB_5);
+                       ar5008_hw_phy_modify_rx_buffer(ah->analogBank6Data,
+                                                      ob5GHz, 3, 203, 0);
+                       ar5008_hw_phy_modify_rx_buffer(ah->analogBank6Data,
+                                                      db5GHz, 3, 200, 0);
+               }
+       }
+
+       /* Setup Bank 7 Setup */
+       RF_BANK_SETUP(ah->analogBank7Data, &ah->iniBank7, 1);
+
+       /* Write Analog registers */
+       REG_WRITE_RF_ARRAY(&ah->iniBank0, ah->analogBank0Data,
+                          regWrites);
+       REG_WRITE_RF_ARRAY(&ah->iniBank1, ah->analogBank1Data,
+                          regWrites);
+       REG_WRITE_RF_ARRAY(&ah->iniBank2, ah->analogBank2Data,
+                          regWrites);
+       REG_WRITE_RF_ARRAY(&ah->iniBank3, ah->analogBank3Data,
+                          regWrites);
+       REG_WRITE_RF_ARRAY(&ah->iniBank6TPC, ah->analogBank6Data,
+                          regWrites);
+       REG_WRITE_RF_ARRAY(&ah->iniBank7, ah->analogBank7Data,
+                          regWrites);
+
+       return true;
+}
+
+static void ar5008_hw_init_bb(struct ath_hw *ah,
+                             struct ath9k_channel *chan)
+{
+       u32 synthDelay;
+
+       synthDelay = REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY;
+       if (IS_CHAN_B(chan))
+               synthDelay = (4 * synthDelay) / 22;
+       else
+               synthDelay /= 10;
+
+       REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
+
+       udelay(synthDelay + BASE_ACTIVATE_DELAY);
+}
+
+static void ar5008_hw_init_chain_masks(struct ath_hw *ah)
+{
+       int rx_chainmask, tx_chainmask;
+
+       rx_chainmask = ah->rxchainmask;
+       tx_chainmask = ah->txchainmask;
+
+       ENABLE_REGWRITE_BUFFER(ah);
+
+       switch (rx_chainmask) {
+       case 0x5:
+               DISABLE_REGWRITE_BUFFER(ah);
+               REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP,
+                           AR_PHY_SWAP_ALT_CHAIN);
+               ENABLE_REGWRITE_BUFFER(ah);
+       case 0x3:
+               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;
+               }
+       case 0x1:
+       case 0x2:
+       case 0x7:
+               REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx_chainmask);
+               REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx_chainmask);
+               break;
+       default:
+               break;
+       }
+
+       REG_WRITE(ah, AR_SELFGEN_MASK, tx_chainmask);
+
+       REGWRITE_BUFFER_FLUSH(ah);
+       DISABLE_REGWRITE_BUFFER(ah);
+
+       if (tx_chainmask == 0x5) {
+               REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP,
+                           AR_PHY_SWAP_ALT_CHAIN);
+       }
+       if (AR_SREV_9100(ah))
+               REG_WRITE(ah, AR_PHY_ANALOG_SWAP,
+                         REG_READ(ah, AR_PHY_ANALOG_SWAP) | 0x00000001);
+}
+
+static void ar5008_hw_override_ini(struct ath_hw *ah,
+                                  struct ath9k_channel *chan)
+{
+       u32 val;
+
+       /*
+        * Set the RX_ABORT and RX_DIS and clear if off only after
+        * RXE is set for MAC. This prevents frames with corrupted
+        * descriptor status.
+        */
+       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);
+
+               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);
+
+               REG_WRITE(ah, AR_PCU_MISC_MODE2, val);
+       }
+
+       if (!AR_SREV_5416_20_OR_LATER(ah) ||
+           AR_SREV_9280_10_OR_LATER(ah))
+               return;
+       /*
+        * Disable BB clock gating
+        * 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 void ar5008_hw_set_channel_regs(struct ath_hw *ah,
+                                      struct ath9k_channel *chan)
+{
+       u32 phymode;
+       u32 enableDacFifo = 0;
+
+       if (AR_SREV_9285_10_OR_LATER(ah))
+               enableDacFifo = (REG_READ(ah, AR_PHY_TURBO) &
+                                        AR_PHY_FC_ENABLE_DAC_FIFO);
+
+       phymode = AR_PHY_FC_HT_EN | AR_PHY_FC_SHORT_GI_40
+               | AR_PHY_FC_SINGLE_HT_LTF1 | AR_PHY_FC_WALSH | enableDacFifo;
+
+       if (IS_CHAN_HT40(chan)) {
+               phymode |= AR_PHY_FC_DYN2040_EN;
+
+               if ((chan->chanmode == CHANNEL_A_HT40PLUS) ||
+                   (chan->chanmode == CHANNEL_G_HT40PLUS))
+                       phymode |= AR_PHY_FC_DYN2040_PRI_CH;
+
+       }
+       REG_WRITE(ah, AR_PHY_TURBO, phymode);
+
+       ath9k_hw_set11nmac2040(ah);
+
+       ENABLE_REGWRITE_BUFFER(ah);
+
+       REG_WRITE(ah, AR_GTXTO, 25 << AR_GTXTO_TIMEOUT_LIMIT_S);
+       REG_WRITE(ah, AR_CST, 0xF << AR_CST_TIMEOUT_LIMIT_S);
+
+       REGWRITE_BUFFER_FLUSH(ah);
+       DISABLE_REGWRITE_BUFFER(ah);
+}
+
+
+static int ar5008_hw_process_ini(struct ath_hw *ah,
+                                struct ath9k_channel *chan)
+{
+       struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
+       int i, regWrites = 0;
+       struct ieee80211_channel *channel = chan->chan;
+       u32 modesIndex, freqIndex;
+
+       switch (chan->chanmode) {
+       case CHANNEL_A:
+       case CHANNEL_A_HT20:
+               modesIndex = 1;
+               freqIndex = 1;
+               break;
+       case CHANNEL_A_HT40PLUS:
+       case CHANNEL_A_HT40MINUS:
+               modesIndex = 2;
+               freqIndex = 1;
+               break;
+       case CHANNEL_G:
+       case CHANNEL_G_HT20:
+       case CHANNEL_B:
+               modesIndex = 4;
+               freqIndex = 2;
+               break;
+       case CHANNEL_G_HT40PLUS:
+       case CHANNEL_G_HT40MINUS:
+               modesIndex = 3;
+               freqIndex = 2;
+               break;
+
+       default:
+               return -EINVAL;
+       }
+
+       if (AR_SREV_9287_12_OR_LATER(ah)) {
+               /* Enable ASYNC FIFO */
+               REG_SET_BIT(ah, AR_MAC_PCU_ASYNC_FIFO_REG3,
+                               AR_MAC_PCU_ASYNC_FIFO_REG3_DATAPATH_SEL);
+               REG_SET_BIT(ah, AR_PHY_MODE, AR_PHY_MODE_ASYNCFIFO);
+               REG_CLR_BIT(ah, AR_MAC_PCU_ASYNC_FIFO_REG3,
+                               AR_MAC_PCU_ASYNC_FIFO_REG3_SOFT_RESET);
+               REG_SET_BIT(ah, AR_MAC_PCU_ASYNC_FIFO_REG3,
+                               AR_MAC_PCU_ASYNC_FIFO_REG3_SOFT_RESET);
+       }
+
+       /*
+        * 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);
+
+       if (AR_SREV_5416_22_OR_LATER(ah)) {
+               REG_WRITE_ARRAY(&ah->iniAddac, 1, regWrites);
+       } else {
+               struct ar5416IniArray temp;
+               u32 addacSize =
+                       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;
+               temp.ia_columns = ah->iniAddac.ia_columns;
+               temp.ia_rows = ah->iniAddac.ia_rows;
+               REG_WRITE_ARRAY(&temp, 1, regWrites);
+       }
+
+       REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_INTERNAL_ADDAC);
+
+       ENABLE_REGWRITE_BUFFER(ah);
+
+       for (i = 0; i < ah->iniModes.ia_rows; i++) {
+               u32 reg = INI_RA(&ah->iniModes, i, 0);
+               u32 val = INI_RA(&ah->iniModes, i, modesIndex);
+
+               if (reg == AR_AN_TOP2 && ah->need_an_top2_fixup)
+                       val &= ~AR_AN_TOP2_PWDCLKIND;
+
+               REG_WRITE(ah, reg, val);
+
+               if (reg >= 0x7800 && reg < 0x78a0
+                   && ah->config.analog_shiftreg) {
+                       udelay(100);
+               }
+
+               DO_DELAY(regWrites);
+       }
+
+       REGWRITE_BUFFER_FLUSH(ah);
+       DISABLE_REGWRITE_BUFFER(ah);
+
+       if (AR_SREV_9280(ah) || AR_SREV_9287_10_OR_LATER(ah))
+               REG_WRITE_ARRAY(&ah->iniModesRxGain, modesIndex, regWrites);
+
+       if (AR_SREV_9280(ah) || AR_SREV_9285_12_OR_LATER(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);
+
+       ENABLE_REGWRITE_BUFFER(ah);
+
+       /* 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);
+
+               REG_WRITE(ah, reg, val);
+
+               if (reg >= 0x7800 && reg < 0x78a0
+                   && ah->config.analog_shiftreg) {
+                       udelay(100);
+               }
+
+               DO_DELAY(regWrites);
+       }
+
+       REGWRITE_BUFFER_FLUSH(ah);
+       DISABLE_REGWRITE_BUFFER(ah);
+
+       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);
+       }
+
+       REG_WRITE_ARRAY(&ah->iniBB_RfGain, freqIndex, regWrites);
+
+       if (AR_SREV_9280_20(ah) && IS_CHAN_A_5MHZ_SPACED(chan)) {
+               REG_WRITE_ARRAY(&ah->iniModesAdditional, modesIndex,
+                               regWrites);
+       }
+
+       ar5008_hw_override_ini(ah, chan);
+       ar5008_hw_set_channel_regs(ah, chan);
+       ar5008_hw_init_chain_masks(ah);
+       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,
+                                channel->max_power * 2,
+                                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");
+               return -EIO;
+       }
+
+       return 0;
+}
+
+static void ar5008_hw_set_rfmode(struct ath_hw *ah, struct ath9k_channel *chan)
+{
+       u32 rfMode = 0;
+
+       if (chan == NULL)
+               return;
+
+       rfMode |= (IS_CHAN_B(chan) || IS_CHAN_G(chan))
+               ? AR_PHY_MODE_DYNAMIC : AR_PHY_MODE_OFDM;
+
+       if (!AR_SREV_9280_10_OR_LATER(ah))
+               rfMode |= (IS_CHAN_5GHZ(chan)) ?
+                       AR_PHY_MODE_RF5GHZ : AR_PHY_MODE_RF2GHZ;
+
+       if ((AR_SREV_9280_20(ah) || AR_SREV_9300_20_OR_LATER(ah))
+           && IS_CHAN_A_5MHZ_SPACED(chan))
+               rfMode |= (AR_PHY_MODE_DYNAMIC | AR_PHY_MODE_DYN_CCK_DISABLE);
+
+       REG_WRITE(ah, AR_PHY_MODE, rfMode);
+}
+
+static void ar5008_hw_mark_phy_inactive(struct ath_hw *ah)
+{
+       REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS);
+}
+
+static void ar5008_hw_set_delta_slope(struct ath_hw *ah,
+                                     struct ath9k_channel *chan)
+{
+       u32 coef_scaled, ds_coef_exp, ds_coef_man;
+       u32 clockMhzScaled = 0x64000000;
+       struct chan_centers centers;
+
+       if (IS_CHAN_HALF_RATE(chan))
+               clockMhzScaled = clockMhzScaled >> 1;
+       else if (IS_CHAN_QUARTER_RATE(chan))
+               clockMhzScaled = clockMhzScaled >> 2;
+
+       ath9k_hw_get_channel_centers(ah, chan, &centers);
+       coef_scaled = clockMhzScaled / centers.synth_center;
+
+       ath9k_hw_get_delta_slope_vals(ah, coef_scaled, &ds_coef_man,
+                                     &ds_coef_exp);
+
+       REG_RMW_FIELD(ah, AR_PHY_TIMING3,
+                     AR_PHY_TIMING3_DSC_MAN, ds_coef_man);
+       REG_RMW_FIELD(ah, AR_PHY_TIMING3,
+                     AR_PHY_TIMING3_DSC_EXP, ds_coef_exp);
+
+       coef_scaled = (9 * coef_scaled) / 10;
+
+       ath9k_hw_get_delta_slope_vals(ah, coef_scaled, &ds_coef_man,
+                                     &ds_coef_exp);
+
+       REG_RMW_FIELD(ah, AR_PHY_HALFGI,
+                     AR_PHY_HALFGI_DSC_MAN, ds_coef_man);
+       REG_RMW_FIELD(ah, AR_PHY_HALFGI,
+                     AR_PHY_HALFGI_DSC_EXP, ds_coef_exp);
+}
+
+static bool ar5008_hw_rfbus_req(struct ath_hw *ah)
+{
+       REG_WRITE(ah, AR_PHY_RFBUS_REQ, AR_PHY_RFBUS_REQ_EN);
+       return ath9k_hw_wait(ah, AR_PHY_RFBUS_GRANT, AR_PHY_RFBUS_GRANT_EN,
+                          AR_PHY_RFBUS_GRANT_EN, AH_WAIT_TIMEOUT);
+}
+
+static void ar5008_hw_rfbus_done(struct ath_hw *ah)
+{
+       u32 synthDelay = REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY;
+       if (IS_CHAN_B(ah->curchan))
+               synthDelay = (4 * synthDelay) / 22;
+       else
+               synthDelay /= 10;
+
+       udelay(synthDelay + BASE_ACTIVATE_DELAY);
+
+       REG_WRITE(ah, AR_PHY_RFBUS_REQ, 0);
+}
+
+static void ar5008_hw_enable_rfkill(struct ath_hw *ah)
+{
+       REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL,
+                   AR_GPIO_INPUT_EN_VAL_RFSILENT_BB);
+
+       REG_CLR_BIT(ah, AR_GPIO_INPUT_MUX2,
+                   AR_GPIO_INPUT_MUX2_RFSILENT);
+
+       ath9k_hw_cfg_gpio_input(ah, ah->rfkill_gpio);
+       REG_SET_BIT(ah, AR_PHY_TEST, RFSILENT_BB);
+}
+
+static void ar5008_restore_chainmask(struct ath_hw *ah)
+{
+       int rx_chainmask = ah->rxchainmask;
+
+       if ((rx_chainmask == 0x5) || (rx_chainmask == 0x3)) {
+               REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx_chainmask);
+               REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx_chainmask);
+       }
+}
+
+static void ar5008_set_diversity(struct ath_hw *ah, bool value)
+{
+       u32 v = REG_READ(ah, AR_PHY_CCK_DETECT);
+       if (value)
+               v |= AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV;
+       else
+               v &= ~AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV;
+       REG_WRITE(ah, AR_PHY_CCK_DETECT, v);
+}
+
+static u32 ar9100_hw_compute_pll_control(struct ath_hw *ah,
+                                        struct ath9k_channel *chan)
+{
+       if (chan && IS_CHAN_5GHZ(chan))
+               return 0x1450;
+       return 0x1458;
+}
+
+static u32 ar9160_hw_compute_pll_control(struct ath_hw *ah,
+                                        struct ath9k_channel *chan)
+{
+       u32 pll;
+
+       pll = SM(0x5, AR_RTC_9160_PLL_REFDIV);
+
+       if (chan && IS_CHAN_HALF_RATE(chan))
+               pll |= SM(0x1, AR_RTC_9160_PLL_CLKSEL);
+       else if (chan && IS_CHAN_QUARTER_RATE(chan))
+               pll |= SM(0x2, AR_RTC_9160_PLL_CLKSEL);
+
+       if (chan && IS_CHAN_5GHZ(chan))
+               pll |= SM(0x50, AR_RTC_9160_PLL_DIV);
+       else
+               pll |= SM(0x58, AR_RTC_9160_PLL_DIV);
+
+       return pll;
+}
+
+static u32 ar5008_hw_compute_pll_control(struct ath_hw *ah,
+                                        struct ath9k_channel *chan)
+{
+       u32 pll;
+
+       pll = AR_RTC_PLL_REFDIV_5 | AR_RTC_PLL_DIV2;
+
+       if (chan && IS_CHAN_HALF_RATE(chan))
+               pll |= SM(0x1, AR_RTC_PLL_CLKSEL);
+       else if (chan && IS_CHAN_QUARTER_RATE(chan))
+               pll |= SM(0x2, AR_RTC_PLL_CLKSEL);
+
+       if (chan && IS_CHAN_5GHZ(chan))
+               pll |= SM(0xa, AR_RTC_PLL_DIV);
+       else
+               pll |= SM(0xb, AR_RTC_PLL_DIV);
+
+       return pll;
+}
+
+static bool ar5008_hw_ani_control(struct ath_hw *ah,
+                                 enum ath9k_ani_cmd cmd, int param)
+{
+       struct ar5416AniState *aniState = ah->curani;
+       struct ath_common *common = ath9k_hw_common(ah);
+
+       switch (cmd & ah->ani_function) {
+       case ATH9K_ANI_NOISE_IMMUNITY_LEVEL:{
+               u32 level = param;
+
+               if (level >= ARRAY_SIZE(ah->totalSizeDesired)) {
+                       ath_print(common, ATH_DBG_ANI,
+                                 "level out of range (%u > %u)\n",
+                                 level,
+                                 (unsigned)ARRAY_SIZE(ah->totalSizeDesired));
+                       return false;
+               }
+
+               REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ,
+                             AR_PHY_DESIRED_SZ_TOT_DES,
+                             ah->totalSizeDesired[level]);
+               REG_RMW_FIELD(ah, AR_PHY_AGC_CTL1,
+                             AR_PHY_AGC_CTL1_COARSE_LOW,
+                             ah->coarse_low[level]);
+               REG_RMW_FIELD(ah, AR_PHY_AGC_CTL1,
+                             AR_PHY_AGC_CTL1_COARSE_HIGH,
+                             ah->coarse_high[level]);
+               REG_RMW_FIELD(ah, AR_PHY_FIND_SIG,
+                             AR_PHY_FIND_SIG_FIRPWR,
+                             ah->firpwr[level]);
+
+               if (level > aniState->noiseImmunityLevel)
+                       ah->stats.ast_ani_niup++;
+               else if (level < aniState->noiseImmunityLevel)
+                       ah->stats.ast_ani_nidown++;
+               aniState->noiseImmunityLevel = level;
+               break;
+       }
+       case ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION:{
+               const int m1ThreshLow[] = { 127, 50 };
+               const int m2ThreshLow[] = { 127, 40 };
+               const int m1Thresh[] = { 127, 0x4d };
+               const int m2Thresh[] = { 127, 0x40 };
+               const int m2CountThr[] = { 31, 16 };
+               const int m2CountThrLow[] = { 63, 48 };
+               u32 on = param ? 1 : 0;
+
+               REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
+                             AR_PHY_SFCORR_LOW_M1_THRESH_LOW,
+                             m1ThreshLow[on]);
+               REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
+                             AR_PHY_SFCORR_LOW_M2_THRESH_LOW,
+                             m2ThreshLow[on]);
+               REG_RMW_FIELD(ah, AR_PHY_SFCORR,
+                             AR_PHY_SFCORR_M1_THRESH,
+                             m1Thresh[on]);
+               REG_RMW_FIELD(ah, AR_PHY_SFCORR,
+                             AR_PHY_SFCORR_M2_THRESH,
+                             m2Thresh[on]);
+               REG_RMW_FIELD(ah, AR_PHY_SFCORR,
+                             AR_PHY_SFCORR_M2COUNT_THR,
+                             m2CountThr[on]);
+               REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
+                             AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW,
+                             m2CountThrLow[on]);
+
+               REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
+                             AR_PHY_SFCORR_EXT_M1_THRESH_LOW,
+                             m1ThreshLow[on]);
+               REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
+                             AR_PHY_SFCORR_EXT_M2_THRESH_LOW,
+                             m2ThreshLow[on]);
+               REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
+                             AR_PHY_SFCORR_EXT_M1_THRESH,
+                             m1Thresh[on]);
+               REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
+                             AR_PHY_SFCORR_EXT_M2_THRESH,
+                             m2Thresh[on]);
+
+               if (on)
+                       REG_SET_BIT(ah, AR_PHY_SFCORR_LOW,
+                                   AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW);
+               else
+                       REG_CLR_BIT(ah, AR_PHY_SFCORR_LOW,
+                                   AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW);
+
+               if (!on != aniState->ofdmWeakSigDetectOff) {
+                       if (on)
+                               ah->stats.ast_ani_ofdmon++;
+                       else
+                               ah->stats.ast_ani_ofdmoff++;
+                       aniState->ofdmWeakSigDetectOff = !on;
+               }
+               break;
+       }
+       case ATH9K_ANI_CCK_WEAK_SIGNAL_THR:{
+               const int weakSigThrCck[] = { 8, 6 };
+               u32 high = param ? 1 : 0;
+
+               REG_RMW_FIELD(ah, AR_PHY_CCK_DETECT,
+                             AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK,
+                             weakSigThrCck[high]);
+               if (high != aniState->cckWeakSigThreshold) {
+                       if (high)
+                               ah->stats.ast_ani_cckhigh++;
+                       else
+                               ah->stats.ast_ani_ccklow++;
+                       aniState->cckWeakSigThreshold = high;
+               }
+               break;
+       }
+       case ATH9K_ANI_FIRSTEP_LEVEL:{
+               const int firstep[] = { 0, 4, 8 };
+               u32 level = param;
+
+               if (level >= ARRAY_SIZE(firstep)) {
+                       ath_print(common, ATH_DBG_ANI,
+                                 "level out of range (%u > %u)\n",
+                                 level,
+                                 (unsigned) ARRAY_SIZE(firstep));
+                       return false;
+               }
+               REG_RMW_FIELD(ah, AR_PHY_FIND_SIG,
+                             AR_PHY_FIND_SIG_FIRSTEP,
+                             firstep[level]);
+               if (level > aniState->firstepLevel)
+                       ah->stats.ast_ani_stepup++;
+               else if (level < aniState->firstepLevel)
+                       ah->stats.ast_ani_stepdown++;
+               aniState->firstepLevel = level;
+               break;
+       }
+       case ATH9K_ANI_SPUR_IMMUNITY_LEVEL:{
+               const int cycpwrThr1[] = { 2, 4, 6, 8, 10, 12, 14, 16 };
+               u32 level = param;
+
+               if (level >= ARRAY_SIZE(cycpwrThr1)) {
+                       ath_print(common, ATH_DBG_ANI,
+                                 "level out of range (%u > %u)\n",
+                                 level,
+                                 (unsigned) ARRAY_SIZE(cycpwrThr1));
+                       return false;
+               }
+               REG_RMW_FIELD(ah, AR_PHY_TIMING5,
+                             AR_PHY_TIMING5_CYCPWR_THR1,
+                             cycpwrThr1[level]);
+               if (level > aniState->spurImmunityLevel)
+                       ah->stats.ast_ani_spurup++;
+               else if (level < aniState->spurImmunityLevel)
+                       ah->stats.ast_ani_spurdown++;
+               aniState->spurImmunityLevel = level;
+               break;
+       }
+       case ATH9K_ANI_PRESENT:
+               break;
+       default:
+               ath_print(common, ATH_DBG_ANI,
+                         "invalid cmd %u\n", cmd);
+               return false;
+       }
+
+       ath_print(common, ATH_DBG_ANI, "ANI parameters:\n");
+       ath_print(common, ATH_DBG_ANI,
+                 "noiseImmunityLevel=%d, spurImmunityLevel=%d, "
+                 "ofdmWeakSigDetectOff=%d\n",
+                 aniState->noiseImmunityLevel,
+                 aniState->spurImmunityLevel,
+                 !aniState->ofdmWeakSigDetectOff);
+       ath_print(common, ATH_DBG_ANI,
+                 "cckWeakSigThreshold=%d, "
+                 "firstepLevel=%d, listenTime=%d\n",
+                 aniState->cckWeakSigThreshold,
+                 aniState->firstepLevel,
+                 aniState->listenTime);
+       ath_print(common, ATH_DBG_ANI,
+               "cycleCount=%d, ofdmPhyErrCount=%d, cckPhyErrCount=%d\n\n",
+               aniState->cycleCount,
+               aniState->ofdmPhyErrCount,
+               aniState->cckPhyErrCount);
+
+       return true;
+}
+
+static void ar5008_hw_do_getnf(struct ath_hw *ah,
+                             int16_t nfarray[NUM_NF_READINGS])
+{
+       struct ath_common *common = ath9k_hw_common(ah);
+       int16_t nf;
+
+       nf = MS(REG_READ(ah, AR_PHY_CCA), AR_PHY_MINCCA_PWR);
+       if (nf & 0x100)
+               nf = 0 - ((nf ^ 0x1ff) + 1);
+       ath_print(common, ATH_DBG_CALIBRATE,
+                 "NF calibrated [ctl] [chain 0] is %d\n", nf);
+       nfarray[0] = nf;
+
+       nf = MS(REG_READ(ah, AR_PHY_CH1_CCA), AR_PHY_CH1_MINCCA_PWR);
+       if (nf & 0x100)
+               nf = 0 - ((nf ^ 0x1ff) + 1);
+       ath_print(common, ATH_DBG_CALIBRATE,
+                 "NF calibrated [ctl] [chain 1] is %d\n", nf);
+       nfarray[1] = nf;
+
+       nf = MS(REG_READ(ah, AR_PHY_CH2_CCA), AR_PHY_CH2_MINCCA_PWR);
+       if (nf & 0x100)
+               nf = 0 - ((nf ^ 0x1ff) + 1);
+       ath_print(common, ATH_DBG_CALIBRATE,
+                 "NF calibrated [ctl] [chain 2] is %d\n", nf);
+       nfarray[2] = nf;
+
+       nf = MS(REG_READ(ah, AR_PHY_EXT_CCA), AR_PHY_EXT_MINCCA_PWR);
+       if (nf & 0x100)
+               nf = 0 - ((nf ^ 0x1ff) + 1);
+       ath_print(common, ATH_DBG_CALIBRATE,
+                 "NF calibrated [ext] [chain 0] is %d\n", nf);
+       nfarray[3] = nf;
+
+       nf = MS(REG_READ(ah, AR_PHY_CH1_EXT_CCA), AR_PHY_CH1_EXT_MINCCA_PWR);
+       if (nf & 0x100)
+               nf = 0 - ((nf ^ 0x1ff) + 1);
+       ath_print(common, ATH_DBG_CALIBRATE,
+                 "NF calibrated [ext] [chain 1] is %d\n", nf);
+       nfarray[4] = nf;
+
+       nf = MS(REG_READ(ah, AR_PHY_CH2_EXT_CCA), AR_PHY_CH2_EXT_MINCCA_PWR);
+       if (nf & 0x100)
+               nf = 0 - ((nf ^ 0x1ff) + 1);
+       ath_print(common, ATH_DBG_CALIBRATE,
+                 "NF calibrated [ext] [chain 2] is %d\n", nf);
+       nfarray[5] = nf;
+}
+
+static void ar5008_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)
+{
+       struct ath9k_nfcal_hist *h;
+       int i, j;
+       int32_t val;
+       const u32 ar5416_cca_regs[6] = {
+               AR_PHY_CCA,
+               AR_PHY_CH1_CCA,
+               AR_PHY_CH2_CCA,
+               AR_PHY_EXT_CCA,
+               AR_PHY_CH1_EXT_CCA,
+               AR_PHY_CH2_EXT_CCA
+       };
+       u8 chainmask, rx_chain_status;
+
+       rx_chain_status = REG_READ(ah, AR_PHY_RX_CHAINMASK);
+       if (AR_SREV_9285(ah) || AR_SREV_9271(ah))
+               chainmask = 0x9;
+       else if (AR_SREV_9280(ah) || AR_SREV_9287(ah)) {
+               if ((rx_chain_status & 0x2) || (rx_chain_status & 0x4))
+                       chainmask = 0x1B;
+               else
+                       chainmask = 0x09;
+       } else {
+               if (rx_chain_status & 0x4)
+                       chainmask = 0x3F;
+               else if (rx_chain_status & 0x2)
+                       chainmask = 0x1B;
+               else
+                       chainmask = 0x09;
+       }
+
+       h = ah->nfCalHist;
+
+       for (i = 0; i < NUM_NF_READINGS; i++) {
+               if (chainmask & (1 << i)) {
+                       val = REG_READ(ah, ar5416_cca_regs[i]);
+                       val &= 0xFFFFFE00;
+                       val |= (((u32) (h[i].privNF) << 1) & 0x1ff);
+                       REG_WRITE(ah, ar5416_cca_regs[i], val);
+               }
+       }
+
+       REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
+                   AR_PHY_AGC_CONTROL_ENABLE_NF);
+       REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
+                   AR_PHY_AGC_CONTROL_NO_UPDATE_NF);
+       REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
+
+       for (j = 0; j < 5; j++) {
+               if ((REG_READ(ah, AR_PHY_AGC_CONTROL) &
+                    AR_PHY_AGC_CONTROL_NF) == 0)
+                       break;
+               udelay(50);
+       }
+
+       ENABLE_REGWRITE_BUFFER(ah);
+
+       for (i = 0; i < NUM_NF_READINGS; i++) {
+               if (chainmask & (1 << i)) {
+                       val = REG_READ(ah, ar5416_cca_regs[i]);
+                       val &= 0xFFFFFE00;
+                       val |= (((u32) (-50) << 1) & 0x1ff);
+                       REG_WRITE(ah, ar5416_cca_regs[i], val);
+               }
+       }
+
+       REGWRITE_BUFFER_FLUSH(ah);
+       DISABLE_REGWRITE_BUFFER(ah);
+}
+
+void ar5008_hw_attach_phy_ops(struct ath_hw *ah)
+{
+       struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
+
+       priv_ops->rf_set_freq = ar5008_hw_set_channel;
+       priv_ops->spur_mitigate_freq = ar5008_hw_spur_mitigate;
+
+       priv_ops->rf_alloc_ext_banks = ar5008_hw_rf_alloc_ext_banks;
+       priv_ops->rf_free_ext_banks = ar5008_hw_rf_free_ext_banks;
+       priv_ops->set_rf_regs = ar5008_hw_set_rf_regs;
+       priv_ops->set_channel_regs = ar5008_hw_set_channel_regs;
+       priv_ops->init_bb = ar5008_hw_init_bb;
+       priv_ops->process_ini = ar5008_hw_process_ini;
+       priv_ops->set_rfmode = ar5008_hw_set_rfmode;
+       priv_ops->mark_phy_inactive = ar5008_hw_mark_phy_inactive;
+       priv_ops->set_delta_slope = ar5008_hw_set_delta_slope;
+       priv_ops->rfbus_req = ar5008_hw_rfbus_req;
+       priv_ops->rfbus_done = ar5008_hw_rfbus_done;
+       priv_ops->enable_rfkill = ar5008_hw_enable_rfkill;
+       priv_ops->restore_chainmask = ar5008_restore_chainmask;
+       priv_ops->set_diversity = ar5008_set_diversity;
+       priv_ops->ani_control = ar5008_hw_ani_control;
+       priv_ops->do_getnf = ar5008_hw_do_getnf;
+       priv_ops->loadnf = ar5008_hw_loadnf;
+
+       if (AR_SREV_9100(ah))
+               priv_ops->compute_pll_control = ar9100_hw_compute_pll_control;
+       else if (AR_SREV_9160_10_OR_LATER(ah))
+               priv_ops->compute_pll_control = ar9160_hw_compute_pll_control;
+       else
+               priv_ops->compute_pll_control = ar5008_hw_compute_pll_control;
+}
diff --git a/drivers/net/wireless/ath/ath9k/ar9001_initvals.h b/drivers/net/wireless/ath/ath9k/ar9001_initvals.h
new file mode 100644 (file)
index 0000000..0b94bd3
--- /dev/null
@@ -0,0 +1,1254 @@
+
+static const u32 ar5416Common_9100[][2] = {
+    { 0x0000000c, 0x00000000 },
+    { 0x00000030, 0x00020015 },
+    { 0x00000034, 0x00000005 },
+    { 0x00000040, 0x00000000 },
+    { 0x00000044, 0x00000008 },
+    { 0x00000048, 0x00000008 },
+    { 0x0000004c, 0x00000010 },
+    { 0x00000050, 0x00000000 },
+    { 0x00000054, 0x0000001f },
+    { 0x00000800, 0x00000000 },
+    { 0x00000804, 0x00000000 },
+    { 0x00000808, 0x00000000 },
+    { 0x0000080c, 0x00000000 },
+    { 0x00000810, 0x00000000 },
+    { 0x00000814, 0x00000000 },
+    { 0x00000818, 0x00000000 },
+    { 0x0000081c, 0x00000000 },
+    { 0x00000820, 0x00000000 },
+    { 0x00000824, 0x00000000 },
+    { 0x00001040, 0x002ffc0f },
+    { 0x00001044, 0x002ffc0f },
+    { 0x00001048, 0x002ffc0f },
+    { 0x0000104c, 0x002ffc0f },
+    { 0x00001050, 0x002ffc0f },
+    { 0x00001054, 0x002ffc0f },
+    { 0x00001058, 0x002ffc0f },
+    { 0x0000105c, 0x002ffc0f },
+    { 0x00001060, 0x002ffc0f },
+    { 0x00001064, 0x002ffc0f },
+    { 0x00001230, 0x00000000 },
+    { 0x00001270, 0x00000000 },
+    { 0x00001038, 0x00000000 },
+    { 0x00001078, 0x00000000 },
+    { 0x000010b8, 0x00000000 },
+    { 0x000010f8, 0x00000000 },
+    { 0x00001138, 0x00000000 },
+    { 0x00001178, 0x00000000 },
+    { 0x000011b8, 0x00000000 },
+    { 0x000011f8, 0x00000000 },
+    { 0x00001238, 0x00000000 },
+    { 0x00001278, 0x00000000 },
+    { 0x000012b8, 0x00000000 },
+    { 0x000012f8, 0x00000000 },
+    { 0x00001338, 0x00000000 },
+    { 0x00001378, 0x00000000 },
+    { 0x000013b8, 0x00000000 },
+    { 0x000013f8, 0x00000000 },
+    { 0x00001438, 0x00000000 },
+    { 0x00001478, 0x00000000 },
+    { 0x000014b8, 0x00000000 },
+    { 0x000014f8, 0x00000000 },
+    { 0x00001538, 0x00000000 },
+    { 0x00001578, 0x00000000 },
+    { 0x000015b8, 0x00000000 },
+    { 0x000015f8, 0x00000000 },
+    { 0x00001638, 0x00000000 },
+    { 0x00001678, 0x00000000 },
+    { 0x000016b8, 0x00000000 },
+    { 0x000016f8, 0x00000000 },
+    { 0x00001738, 0x00000000 },
+    { 0x00001778, 0x00000000 },
+    { 0x000017b8, 0x00000000 },
+    { 0x000017f8, 0x00000000 },
+    { 0x0000103c, 0x00000000 },
+    { 0x0000107c, 0x00000000 },
+    { 0x000010bc, 0x00000000 },
+    { 0x000010fc, 0x00000000 },
+    { 0x0000113c, 0x00000000 },
+    { 0x0000117c, 0x00000000 },
+    { 0x000011bc, 0x00000000 },
+    { 0x000011fc, 0x00000000 },
+    { 0x0000123c, 0x00000000 },
+    { 0x0000127c, 0x00000000 },
+    { 0x000012bc, 0x00000000 },
+    { 0x000012fc, 0x00000000 },
+    { 0x0000133c, 0x00000000 },
+    { 0x0000137c, 0x00000000 },
+    { 0x000013bc, 0x00000000 },
+    { 0x000013fc, 0x00000000 },
+    { 0x0000143c, 0x00000000 },
+    { 0x0000147c, 0x00000000 },
+    { 0x00020010, 0x00000003 },
+    { 0x00020038, 0x000004c2 },
+    { 0x00008004, 0x00000000 },
+    { 0x00008008, 0x00000000 },
+    { 0x0000800c, 0x00000000 },
+    { 0x00008018, 0x00000700 },
+    { 0x00008020, 0x00000000 },
+    { 0x00008038, 0x00000000 },
+    { 0x0000803c, 0x00000000 },
+    { 0x00008048, 0x40000000 },
+    { 0x00008054, 0x00004000 },
+    { 0x00008058, 0x00000000 },
+    { 0x0000805c, 0x000fc78f },
+    { 0x00008060, 0x0000000f },
+    { 0x00008064, 0x00000000 },
+    { 0x000080c0, 0x2a82301a },
+    { 0x000080c4, 0x05dc01e0 },
+    { 0x000080c8, 0x1f402710 },
+    { 0x000080cc, 0x01f40000 },
+    { 0x000080d0, 0x00001e00 },
+    { 0x000080d4, 0x00000000 },
+    { 0x000080d8, 0x00400000 },
+    { 0x000080e0, 0xffffffff },
+    { 0x000080e4, 0x0000ffff },
+    { 0x000080e8, 0x003f3f3f },
+    { 0x000080ec, 0x00000000 },
+    { 0x000080f0, 0x00000000 },
+    { 0x000080f4, 0x00000000 },
+    { 0x000080f8, 0x00000000 },
+    { 0x000080fc, 0x00020000 },
+    { 0x00008100, 0x00020000 },
+    { 0x00008104, 0x00000001 },
+    { 0x00008108, 0x00000052 },
+    { 0x0000810c, 0x00000000 },
+    { 0x00008110, 0x00000168 },
+    { 0x00008118, 0x000100aa },
+    { 0x0000811c, 0x00003210 },
+    { 0x00008120, 0x08f04800 },
+    { 0x00008124, 0x00000000 },
+    { 0x00008128, 0x00000000 },
+    { 0x0000812c, 0x00000000 },
+    { 0x00008130, 0x00000000 },
+    { 0x00008134, 0x00000000 },
+    { 0x00008138, 0x00000000 },
+    { 0x0000813c, 0x00000000 },
+    { 0x00008144, 0x00000000 },
+    { 0x00008168, 0x00000000 },
+    { 0x0000816c, 0x00000000 },
+    { 0x00008170, 0x32143320 },
+    { 0x00008174, 0xfaa4fa50 },
+    { 0x00008178, 0x00000100 },
+    { 0x0000817c, 0x00000000 },
+    { 0x000081c4, 0x00000000 },
+    { 0x000081d0, 0x00003210 },
+    { 0x000081ec, 0x00000000 },
+    { 0x000081f0, 0x00000000 },
+    { 0x000081f4, 0x00000000 },
+    { 0x000081f8, 0x00000000 },
+    { 0x000081fc, 0x00000000 },
+    { 0x00008200, 0x00000000 },
+    { 0x00008204, 0x00000000 },
+    { 0x00008208, 0x00000000 },
+    { 0x0000820c, 0x00000000 },
+    { 0x00008210, 0x00000000 },
+    { 0x00008214, 0x00000000 },
+    { 0x00008218, 0x00000000 },
+    { 0x0000821c, 0x00000000 },
+    { 0x00008220, 0x00000000 },
+    { 0x00008224, 0x00000000 },
+    { 0x00008228, 0x00000000 },
+    { 0x0000822c, 0x00000000 },
+    { 0x00008230, 0x00000000 },
+    { 0x00008234, 0x00000000 },
+    { 0x00008238, 0x00000000 },
+    { 0x0000823c, 0x00000000 },
+    { 0x00008240, 0x00100000 },
+    { 0x00008244, 0x0010f400 },
+    { 0x00008248, 0x00000100 },
+    { 0x0000824c, 0x0001e800 },
+    { 0x00008250, 0x00000000 },
+    { 0x00008254, 0x00000000 },
+    { 0x00008258, 0x00000000 },
+    { 0x0000825c, 0x400000ff },
+    { 0x00008260, 0x00080922 },
+    { 0x00008270, 0x00000000 },
+    { 0x00008274, 0x40000000 },
+    { 0x00008278, 0x003e4180 },
+    { 0x0000827c, 0x00000000 },
+    { 0x00008284, 0x0000002c },
+    { 0x00008288, 0x0000002c },
+    { 0x0000828c, 0x00000000 },
+    { 0x00008294, 0x00000000 },
+    { 0x00008298, 0x00000000 },
+    { 0x00008300, 0x00000000 },
+    { 0x00008304, 0x00000000 },
+    { 0x00008308, 0x00000000 },
+    { 0x0000830c, 0x00000000 },
+    { 0x00008310, 0x00000000 },
+    { 0x00008314, 0x00000000 },
+    { 0x00008318, 0x00000000 },
+    { 0x00008328, 0x00000000 },
+    { 0x0000832c, 0x00000007 },
+    { 0x00008330, 0x00000302 },
+    { 0x00008334, 0x00000e00 },
+    { 0x00008338, 0x00000000 },
+    { 0x0000833c, 0x00000000 },
+    { 0x00008340, 0x000107ff },
+    { 0x00009808, 0x00000000 },
+    { 0x0000980c, 0xad848e19 },
+    { 0x00009810, 0x7d14e000 },
+    { 0x00009814, 0x9c0a9f6b },
+    { 0x0000981c, 0x00000000 },
+    { 0x0000982c, 0x0000a000 },
+    { 0x00009830, 0x00000000 },
+    { 0x0000983c, 0x00200400 },
+    { 0x00009840, 0x206a01ae },
+    { 0x0000984c, 0x1284233c },
+    { 0x00009854, 0x00000859 },
+    { 0x00009900, 0x00000000 },
+    { 0x00009904, 0x00000000 },
+    { 0x00009908, 0x00000000 },
+    { 0x0000990c, 0x00000000 },
+    { 0x0000991c, 0x10000fff },
+    { 0x00009920, 0x05100000 },
+    { 0x0000a920, 0x05100000 },
+    { 0x0000b920, 0x05100000 },
+    { 0x00009928, 0x00000001 },
+    { 0x0000992c, 0x00000004 },
+    { 0x00009934, 0x1e1f2022 },
+    { 0x00009938, 0x0a0b0c0d },
+    { 0x0000993c, 0x00000000 },
+    { 0x00009948, 0x9280b212 },
+    { 0x0000994c, 0x00020028 },
+    { 0x0000c95c, 0x004b6a8e },
+    { 0x0000c968, 0x000003ce },
+    { 0x00009970, 0x190fb515 },
+    { 0x00009974, 0x00000000 },
+    { 0x00009978, 0x00000001 },
+    { 0x0000997c, 0x00000000 },
+    { 0x00009980, 0x00000000 },
+    { 0x00009984, 0x00000000 },
+    { 0x00009988, 0x00000000 },
+    { 0x0000998c, 0x00000000 },
+    { 0x00009990, 0x00000000 },
+    { 0x00009994, 0x00000000 },
+    { 0x00009998, 0x00000000 },
+    { 0x0000999c, 0x00000000 },
+    { 0x000099a0, 0x00000000 },
+    { 0x000099a4, 0x00000001 },
+    { 0x000099a8, 0x201fff00 },
+    { 0x000099ac, 0x006f0000 },
+    { 0x000099b0, 0x03051000 },
+    { 0x000099dc, 0x00000000 },
+    { 0x000099e0, 0x00000200 },
+    { 0x000099e4, 0xaaaaaaaa },
+    { 0x000099e8, 0x3c466478 },
+    { 0x000099ec, 0x0cc80caa },
+    { 0x000099fc, 0x00001042 },
+    { 0x00009b00, 0x00000000 },
+    { 0x00009b04, 0x00000001 },
+    { 0x00009b08, 0x00000002 },
+    { 0x00009b0c, 0x00000003 },
+    { 0x00009b10, 0x00000004 },
+    { 0x00009b14, 0x00000005 },
+    { 0x00009b18, 0x00000008 },
+    { 0x00009b1c, 0x00000009 },
+    { 0x00009b20, 0x0000000a },
+    { 0x00009b24, 0x0000000b },
+    { 0x00009b28, 0x0000000c },
+    { 0x00009b2c, 0x0000000d },
+    { 0x00009b30, 0x00000010 },
+    { 0x00009b34, 0x00000011 },
+    { 0x00009b38, 0x00000012 },
+    { 0x00009b3c, 0x00000013 },
+    { 0x00009b40, 0x00000014 },
+    { 0x00009b44, 0x00000015 },
+    { 0x00009b48, 0x00000018 },
+    { 0x00009b4c, 0x00000019 },
+    { 0x00009b50, 0x0000001a },
+    { 0x00009b54, 0x0000001b },
+    { 0x00009b58, 0x0000001c },
+    { 0x00009b5c, 0x0000001d },
+    { 0x00009b60, 0x00000020 },
+    { 0x00009b64, 0x00000021 },
+    { 0x00009b68, 0x00000022 },
+    { 0x00009b6c, 0x00000023 },
+    { 0x00009b70, 0x00000024 },
+    { 0x00009b74, 0x00000025 },
+    { 0x00009b78, 0x00000028 },
+    { 0x00009b7c, 0x00000029 },
+    { 0x00009b80, 0x0000002a },
+    { 0x00009b84, 0x0000002b },
+    { 0x00009b88, 0x0000002c },
+    { 0x00009b8c, 0x0000002d },
+    { 0x00009b90, 0x00000030 },
+    { 0x00009b94, 0x00000031 },
+    { 0x00009b98, 0x00000032 },
+    { 0x00009b9c, 0x00000033 },
+    { 0x00009ba0, 0x00000034 },
+    { 0x00009ba4, 0x00000035 },
+    { 0x00009ba8, 0x00000035 },
+    { 0x00009bac, 0x00000035 },
+    { 0x00009bb0, 0x00000035 },
+    { 0x00009bb4, 0x00000035 },
+    { 0x00009bb8, 0x00000035 },
+    { 0x00009bbc, 0x00000035 },
+    { 0x00009bc0, 0x00000035 },
+    { 0x00009bc4, 0x00000035 },
+    { 0x00009bc8, 0x00000035 },
+    { 0x00009bcc, 0x00000035 },
+    { 0x00009bd0, 0x00000035 },
+    { 0x00009bd4, 0x00000035 },
+    { 0x00009bd8, 0x00000035 },
+    { 0x00009bdc, 0x00000035 },
+    { 0x00009be0, 0x00000035 },
+    { 0x00009be4, 0x00000035 },
+    { 0x00009be8, 0x00000035 },
+    { 0x00009bec, 0x00000035 },
+    { 0x00009bf0, 0x00000035 },
+    { 0x00009bf4, 0x00000035 },
+    { 0x00009bf8, 0x00000010 },
+    { 0x00009bfc, 0x0000001a },
+    { 0x0000a210, 0x40806333 },
+    { 0x0000a214, 0x00106c10 },
+    { 0x0000a218, 0x009c4060 },
+    { 0x0000a220, 0x018830c6 },
+    { 0x0000a224, 0x00000400 },
+    { 0x0000a228, 0x001a0bb5 },
+    { 0x0000a22c, 0x00000000 },
+    { 0x0000a234, 0x20202020 },
+    { 0x0000a238, 0x20202020 },
+    { 0x0000a23c, 0x13c889ae },
+    { 0x0000a240, 0x38490a20 },
+    { 0x0000a244, 0x00007bb6 },
+    { 0x0000a248, 0x0fff3ffc },
+    { 0x0000a24c, 0x00000001 },
+    { 0x0000a250, 0x0000a000 },
+    { 0x0000a254, 0x00000000 },
+    { 0x0000a258, 0x0cc75380 },
+    { 0x0000a25c, 0x0f0f0f01 },
+    { 0x0000a260, 0xdfa91f01 },
+    { 0x0000a268, 0x00000001 },
+    { 0x0000a26c, 0x0ebae9c6 },
+    { 0x0000b26c, 0x0ebae9c6 },
+    { 0x0000c26c, 0x0ebae9c6 },
+    { 0x0000d270, 0x00820820 },
+    { 0x0000a278, 0x1ce739ce },
+    { 0x0000a27c, 0x050701ce },
+    { 0x0000a338, 0x00000000 },
+    { 0x0000a33c, 0x00000000 },
+    { 0x0000a340, 0x00000000 },
+    { 0x0000a344, 0x00000000 },
+    { 0x0000a348, 0x3fffffff },
+    { 0x0000a34c, 0x3fffffff },
+    { 0x0000a350, 0x3fffffff },
+    { 0x0000a354, 0x0003ffff },
+    { 0x0000a358, 0x79a8aa33 },
+    { 0x0000d35c, 0x07ffffef },
+    { 0x0000d360, 0x0fffffe7 },
+    { 0x0000d364, 0x17ffffe5 },
+    { 0x0000d368, 0x1fffffe4 },
+    { 0x0000d36c, 0x37ffffe3 },
+    { 0x0000d370, 0x3fffffe3 },
+    { 0x0000d374, 0x57ffffe3 },
+    { 0x0000d378, 0x5fffffe2 },
+    { 0x0000d37c, 0x7fffffe2 },
+    { 0x0000d380, 0x7f3c7bba },
+    { 0x0000d384, 0xf3307ff0 },
+    { 0x0000a388, 0x0c000000 },
+    { 0x0000a38c, 0x20202020 },
+    { 0x0000a390, 0x20202020 },
+    { 0x0000a394, 0x1ce739ce },
+    { 0x0000a398, 0x000001ce },
+    { 0x0000a39c, 0x00000001 },
+    { 0x0000a3a0, 0x00000000 },
+    { 0x0000a3a4, 0x00000000 },
+    { 0x0000a3a8, 0x00000000 },
+    { 0x0000a3ac, 0x00000000 },
+    { 0x0000a3b0, 0x00000000 },
+    { 0x0000a3b4, 0x00000000 },
+    { 0x0000a3b8, 0x00000000 },
+    { 0x0000a3bc, 0x00000000 },
+    { 0x0000a3c0, 0x00000000 },
+    { 0x0000a3c4, 0x00000000 },
+    { 0x0000a3c8, 0x00000246 },
+    { 0x0000a3cc, 0x20202020 },
+    { 0x0000a3d0, 0x20202020 },
+    { 0x0000a3d4, 0x20202020 },
+    { 0x0000a3dc, 0x1ce739ce },
+    { 0x0000a3e0, 0x000001ce },
+};
+
+static const u32 ar5416Bank0_9100[][2] = {
+    { 0x000098b0, 0x1e5795e5 },
+    { 0x000098e0, 0x02008020 },
+};
+
+static const u32 ar5416BB_RfGain_9100[][3] = {
+    { 0x00009a00, 0x00000000, 0x00000000 },
+    { 0x00009a04, 0x00000040, 0x00000040 },
+    { 0x00009a08, 0x00000080, 0x00000080 },
+    { 0x00009a0c, 0x000001a1, 0x00000141 },
+    { 0x00009a10, 0x000001e1, 0x00000181 },
+    { 0x00009a14, 0x00000021, 0x000001c1 },
+    { 0x00009a18, 0x00000061, 0x00000001 },
+    { 0x00009a1c, 0x00000168, 0x00000041 },
+    { 0x00009a20, 0x000001a8, 0x000001a8 },
+    { 0x00009a24, 0x000001e8, 0x000001e8 },
+    { 0x00009a28, 0x00000028, 0x00000028 },
+    { 0x00009a2c, 0x00000068, 0x00000068 },
+    { 0x00009a30, 0x00000189, 0x000000a8 },
+    { 0x00009a34, 0x000001c9, 0x00000169 },
+    { 0x00009a38, 0x00000009, 0x000001a9 },
+    { 0x00009a3c, 0x00000049, 0x000001e9 },
+    { 0x00009a40, 0x00000089, 0x00000029 },
+    { 0x00009a44, 0x00000170, 0x00000069 },
+    { 0x00009a48, 0x000001b0, 0x00000190 },
+    { 0x00009a4c, 0x000001f0, 0x000001d0 },
+    { 0x00009a50, 0x00000030, 0x00000010 },
+    { 0x00009a54, 0x00000070, 0x00000050 },
+    { 0x00009a58, 0x00000191, 0x00000090 },
+    { 0x00009a5c, 0x000001d1, 0x00000151 },
+    { 0x00009a60, 0x00000011, 0x00000191 },
+    { 0x00009a64, 0x00000051, 0x000001d1 },
+    { 0x00009a68, 0x00000091, 0x00000011 },
+    { 0x00009a6c, 0x000001b8, 0x00000051 },
+    { 0x00009a70, 0x000001f8, 0x00000198 },
+    { 0x00009a74, 0x00000038, 0x000001d8 },
+    { 0x00009a78, 0x00000078, 0x00000018 },
+    { 0x00009a7c, 0x00000199, 0x00000058 },
+    { 0x00009a80, 0x000001d9, 0x00000098 },
+    { 0x00009a84, 0x00000019, 0x00000159 },
+    { 0x00009a88, 0x00000059, 0x00000199 },
+    { 0x00009a8c, 0x00000099, 0x000001d9 },
+    { 0x00009a90, 0x000000d9, 0x00000019 },
+    { 0x00009a94, 0x000000f9, 0x00000059 },
+    { 0x00009a98, 0x000000f9, 0x00000099 },
+    { 0x00009a9c, 0x000000f9, 0x000000d9 },
+    { 0x00009aa0, 0x000000f9, 0x000000f9 },
+    { 0x00009aa4, 0x000000f9, 0x000000f9 },
+    { 0x00009aa8, 0x000000f9, 0x000000f9 },
+    { 0x00009aac, 0x000000f9, 0x000000f9 },
+    { 0x00009ab0, 0x000000f9, 0x000000f9 },
+    { 0x00009ab4, 0x000000f9, 0x000000f9 },
+    { 0x00009ab8, 0x000000f9, 0x000000f9 },
+    { 0x00009abc, 0x000000f9, 0x000000f9 },
+    { 0x00009ac0, 0x000000f9, 0x000000f9 },
+    { 0x00009ac4, 0x000000f9, 0x000000f9 },
+    { 0x00009ac8, 0x000000f9, 0x000000f9 },
+    { 0x00009acc, 0x000000f9, 0x000000f9 },
+    { 0x00009ad0, 0x000000f9, 0x000000f9 },
+    { 0x00009ad4, 0x000000f9, 0x000000f9 },
+    { 0x00009ad8, 0x000000f9, 0x000000f9 },
+    { 0x00009adc, 0x000000f9, 0x000000f9 },
+    { 0x00009ae0, 0x000000f9, 0x000000f9 },
+    { 0x00009ae4, 0x000000f9, 0x000000f9 },
+    { 0x00009ae8, 0x000000f9, 0x000000f9 },
+    { 0x00009aec, 0x000000f9, 0x000000f9 },
+    { 0x00009af0, 0x000000f9, 0x000000f9 },
+    { 0x00009af4, 0x000000f9, 0x000000f9 },
+    { 0x00009af8, 0x000000f9, 0x000000f9 },
+    { 0x00009afc, 0x000000f9, 0x000000f9 },
+};
+
+static const u32 ar5416Bank1_9100[][2] = {
+    { 0x000098b0, 0x02108421},
+    { 0x000098ec, 0x00000008},
+};
+
+static const u32 ar5416Bank2_9100[][2] = {
+    { 0x000098b0, 0x0e73ff17},
+    { 0x000098e0, 0x00000420},
+};
+
+static const u32 ar5416Bank3_9100[][3] = {
+    { 0x000098f0, 0x01400018, 0x01c00018 },
+};
+
+static const u32 ar5416Bank6_9100[][3] = {
+
+    { 0x0000989c, 0x00000000, 0x00000000 },
+    { 0x0000989c, 0x00000000, 0x00000000 },
+    { 0x0000989c, 0x00000000, 0x00000000 },
+    { 0x0000989c, 0x00e00000, 0x00e00000 },
+    { 0x0000989c, 0x005e0000, 0x005e0000 },
+    { 0x0000989c, 0x00120000, 0x00120000 },
+    { 0x0000989c, 0x00620000, 0x00620000 },
+    { 0x0000989c, 0x00020000, 0x00020000 },
+    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
+    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
+    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
+    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
+    { 0x0000989c, 0x005f0000, 0x005f0000 },
+    { 0x0000989c, 0x00870000, 0x00870000 },
+    { 0x0000989c, 0x00f90000, 0x00f90000 },
+    { 0x0000989c, 0x007b0000, 0x007b0000 },
+    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
+    { 0x0000989c, 0x00f50000, 0x00f50000 },
+    { 0x0000989c, 0x00dc0000, 0x00dc0000 },
+    { 0x0000989c, 0x00110000, 0x00110000 },
+    { 0x0000989c, 0x006100a8, 0x006100a8 },
+    { 0x0000989c, 0x004210a2, 0x004210a2 },
+    { 0x0000989c, 0x0014000f, 0x0014000f },
+    { 0x0000989c, 0x00c40002, 0x00c40002 },
+    { 0x0000989c, 0x003000f2, 0x003000f2 },
+    { 0x0000989c, 0x00440016, 0x00440016 },
+    { 0x0000989c, 0x00410040, 0x00410040 },
+    { 0x0000989c, 0x000180d6, 0x000180d6 },
+    { 0x0000989c, 0x0000c0aa, 0x0000c0aa },
+    { 0x0000989c, 0x000000b1, 0x000000b1 },
+    { 0x0000989c, 0x00002000, 0x00002000 },
+    { 0x0000989c, 0x000000d4, 0x000000d4 },
+    { 0x000098d0, 0x0000000f, 0x0010000f },
+};
+
+
+static const u32 ar5416Bank6TPC_9100[][3] = {
+
+    { 0x0000989c, 0x00000000, 0x00000000 },
+    { 0x0000989c, 0x00000000, 0x00000000 },
+    { 0x0000989c, 0x00000000, 0x00000000 },
+    { 0x0000989c, 0x00e00000, 0x00e00000 },
+    { 0x0000989c, 0x005e0000, 0x005e0000 },
+    { 0x0000989c, 0x00120000, 0x00120000 },
+    { 0x0000989c, 0x00620000, 0x00620000 },
+    { 0x0000989c, 0x00020000, 0x00020000 },
+    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
+    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
+    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
+    { 0x0000989c, 0x40ff0000, 0x40ff0000 },
+    { 0x0000989c, 0x005f0000, 0x005f0000 },
+    { 0x0000989c, 0x00870000, 0x00870000 },
+    { 0x0000989c, 0x00f90000, 0x00f90000 },
+    { 0x0000989c, 0x007b0000, 0x007b0000 },
+    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
+    { 0x0000989c, 0x00f50000, 0x00f50000 },
+    { 0x0000989c, 0x00dc0000, 0x00dc0000 },
+    { 0x0000989c, 0x00110000, 0x00110000 },
+    { 0x0000989c, 0x006100a8, 0x006100a8 },
+    { 0x0000989c, 0x00423022, 0x00423022 },
+    { 0x0000989c, 0x2014008f, 0x2014008f },
+    { 0x0000989c, 0x00c40002, 0x00c40002 },
+    { 0x0000989c, 0x003000f2, 0x003000f2 },
+    { 0x0000989c, 0x00440016, 0x00440016 },
+    { 0x0000989c, 0x00410040, 0x00410040 },
+    { 0x0000989c, 0x0001805e, 0x0001805e },
+    { 0x0000989c, 0x0000c0ab, 0x0000c0ab },
+    { 0x0000989c, 0x000000e1, 0x000000e1 },
+    { 0x0000989c, 0x00007080, 0x00007080 },
+    { 0x0000989c, 0x000000d4, 0x000000d4 },
+    { 0x000098d0, 0x0000000f, 0x0010000f },
+};
+
+static const u32 ar5416Bank7_9100[][2] = {
+    { 0x0000989c, 0x00000500 },
+    { 0x0000989c, 0x00000800 },
+    { 0x000098cc, 0x0000000e },
+};
+
+static const u32 ar5416Addac_9100[][2] = {
+    {0x0000989c, 0x00000000 },
+    {0x0000989c, 0x00000000 },
+    {0x0000989c, 0x00000000 },
+    {0x0000989c, 0x00000000 },
+    {0x0000989c, 0x00000000 },
+    {0x0000989c, 0x00000000 },
+    {0x0000989c, 0x00000000 },
+    {0x0000989c, 0x00000010 },
+    {0x0000989c, 0x00000000 },
+    {0x0000989c, 0x00000000 },
+    {0x0000989c, 0x00000000 },
+    {0x0000989c, 0x00000000 },
+    {0x0000989c, 0x00000000 },
+    {0x0000989c, 0x00000000 },
+    {0x0000989c, 0x00000000 },
+    {0x0000989c, 0x00000000 },
+    {0x0000989c, 0x00000000 },
+    {0x0000989c, 0x00000000 },
+    {0x0000989c, 0x00000000 },
+    {0x0000989c, 0x00000000 },
+    {0x0000989c, 0x00000000 },
+    {0x0000989c, 0x000000c0 },
+    {0x0000989c, 0x00000015 },
+    {0x0000989c, 0x00000000 },
+    {0x0000989c, 0x00000000 },
+    {0x0000989c, 0x00000000 },
+    {0x0000989c, 0x00000000 },
+    {0x0000989c, 0x00000000 },
+    {0x0000989c, 0x00000000 },
+    {0x0000989c, 0x00000000 },
+    {0x0000989c, 0x00000000 },
+    {0x000098cc, 0x00000000 },
+};
+
+static const u32 ar5416Modes_9160[][6] = {
+    { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 },
+    { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 },
+    { 0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180 },
+    { 0x000010f0, 0x0000a000, 0x00014000, 0x00016000, 0x0000b000, 0x00014008 },
+    { 0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00, 0x06e006e0 },
+    { 0x0000801c, 0x128d93a7, 0x128d93cf, 0x12e013d7, 0x12e013ab, 0x098813cf },
+    { 0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303 },
+    { 0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200 },
+    { 0x00009824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
+    { 0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001 },
+    { 0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
+    { 0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007 },
+    { 0x00009844, 0x0372161e, 0x0372161e, 0x037216a0, 0x037216a0, 0x037216a0 },
+    { 0x00009848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
+    { 0x0000a848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
+    { 0x0000b848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
+    { 0x00009850, 0x6c48b4e2, 0x6c48b4e2, 0x6c48b0e2, 0x6c48b0e2, 0x6c48b0e2 },
+    { 0x00009858, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e },
+    { 0x0000985c, 0x31395d5e, 0x31395d5e, 0x31395d5e, 0x31395d5e, 0x31395d5e },
+    { 0x00009860, 0x00048d18, 0x00048d18, 0x00048d20, 0x00048d20, 0x00048d18 },
+    { 0x0000c864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00 },
+    { 0x00009868, 0x409a40d0, 0x409a40d0, 0x409a40d0, 0x409a40d0, 0x409a40d0 },
+    { 0x0000986c, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 },
+    { 0x00009914, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898, 0x000007d0 },
+    { 0x00009918, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b, 0x00000016 },
+    { 0x00009924, 0xd00a8a07, 0xd00a8a07, 0xd00a8a0d, 0xd00a8a0d, 0xd00a8a0d },
+    { 0x00009944, 0xffb81020, 0xffb81020, 0xffb81020, 0xffb81020, 0xffb81020 },
+    { 0x00009960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40 },
+    { 0x0000a960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40 },
+    { 0x0000b960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40 },
+    { 0x00009964, 0x00001120, 0x00001120, 0x00001120, 0x00001120, 0x00001120 },
+    { 0x0000c968, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce, 0x000003ce },
+    { 0x0000c9bc, 0x001a0600, 0x001a0600, 0x001a0c00, 0x001a0c00, 0x001a0c00 },
+    { 0x000099c0, 0x038919be, 0x038919be, 0x038919be, 0x038919be, 0x038919be },
+    { 0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77 },
+    { 0x000099c8, 0x60f65329, 0x60f65329, 0x60f65329, 0x60f65329, 0x60f65329 },
+    { 0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8 },
+    { 0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, 0x00046384 },
+    { 0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+    { 0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+    { 0x0000a204, 0x00000880, 0x00000880, 0x00000880, 0x00000880, 0x00000880 },
+    { 0x0000a208, 0xd6be4788, 0xd6be4788, 0xd03e4788, 0xd03e4788, 0xd03e4788 },
+    { 0x0000a20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120 },
+    { 0x0000b20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120 },
+    { 0x0000c20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120 },
+    { 0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a },
+    { 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000 },
+    { 0x0000a274, 0x0a1a9caa, 0x0a1a9caa, 0x0a1a7caa, 0x0a1a7caa, 0x0a1a7caa },
+    { 0x0000a300, 0x18010000, 0x18010000, 0x18010000, 0x18010000, 0x18010000 },
+    { 0x0000a304, 0x30032602, 0x30032602, 0x2e032402, 0x2e032402, 0x2e032402 },
+    { 0x0000a308, 0x48073e06, 0x48073e06, 0x4a0a3c06, 0x4a0a3c06, 0x4a0a3c06 },
+    { 0x0000a30c, 0x560b4c0a, 0x560b4c0a, 0x621a540b, 0x621a540b, 0x621a540b },
+    { 0x0000a310, 0x641a600f, 0x641a600f, 0x764f6c1b, 0x764f6c1b, 0x764f6c1b },
+    { 0x0000a314, 0x7a4f6e1b, 0x7a4f6e1b, 0x845b7a5a, 0x845b7a5a, 0x845b7a5a },
+    { 0x0000a318, 0x8c5b7e5a, 0x8c5b7e5a, 0x950f8ccf, 0x950f8ccf, 0x950f8ccf },
+    { 0x0000a31c, 0x9d0f96cf, 0x9d0f96cf, 0xa5cf9b4f, 0xa5cf9b4f, 0xa5cf9b4f },
+    { 0x0000a320, 0xb51fa69f, 0xb51fa69f, 0xbddfaf1f, 0xbddfaf1f, 0xbddfaf1f },
+    { 0x0000a324, 0xcb3fbd07, 0xcb3fbcbf, 0xd1ffc93f, 0xd1ffc93f, 0xd1ffc93f },
+    { 0x0000a328, 0x0000d7bf, 0x0000d7bf, 0x00000000, 0x00000000, 0x00000000 },
+    { 0x0000a32c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+    { 0x0000a330, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+    { 0x0000a334, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+};
+
+static const u32 ar5416Common_9160[][2] = {
+    { 0x0000000c, 0x00000000 },
+    { 0x00000030, 0x00020015 },
+    { 0x00000034, 0x00000005 },
+    { 0x00000040, 0x00000000 },
+    { 0x00000044, 0x00000008 },
+    { 0x00000048, 0x00000008 },
+    { 0x0000004c, 0x00000010 },
+    { 0x00000050, 0x00000000 },
+    { 0x00000054, 0x0000001f },
+    { 0x00000800, 0x00000000 },
+    { 0x00000804, 0x00000000 },
+    { 0x00000808, 0x00000000 },
+    { 0x0000080c, 0x00000000 },
+    { 0x00000810, 0x00000000 },
+    { 0x00000814, 0x00000000 },
+    { 0x00000818, 0x00000000 },
+    { 0x0000081c, 0x00000000 },
+    { 0x00000820, 0x00000000 },
+    { 0x00000824, 0x00000000 },
+    { 0x00001040, 0x002ffc0f },
+    { 0x00001044, 0x002ffc0f },
+    { 0x00001048, 0x002ffc0f },
+    { 0x0000104c, 0x002ffc0f },
+    { 0x00001050, 0x002ffc0f },
+    { 0x00001054, 0x002ffc0f },
+    { 0x00001058, 0x002ffc0f },
+    { 0x0000105c, 0x002ffc0f },
+    { 0x00001060, 0x002ffc0f },
+    { 0x00001064, 0x002ffc0f },
+    { 0x00001230, 0x00000000 },
+    { 0x00001270, 0x00000000 },
+    { 0x00001038, 0x00000000 },
+    { 0x00001078, 0x00000000 },
+    { 0x000010b8, 0x00000000 },
+    { 0x000010f8, 0x00000000 },
+    { 0x00001138, 0x00000000 },
+    { 0x00001178, 0x00000000 },
+    { 0x000011b8, 0x00000000 },
+    { 0x000011f8, 0x00000000 },
+    { 0x00001238, 0x00000000 },
+    { 0x00001278, 0x00000000 },
+    { 0x000012b8, 0x00000000 },
+    { 0x000012f8, 0x00000000 },
+    { 0x00001338, 0x00000000 },
+    { 0x00001378, 0x00000000 },
+    { 0x000013b8, 0x00000000 },
+    { 0x000013f8, 0x00000000 },
+    { 0x00001438, 0x00000000 },
+    { 0x00001478, 0x00000000 },
+    { 0x000014b8, 0x00000000 },
+    { 0x000014f8, 0x00000000 },
+    { 0x00001538, 0x00000000 },
+    { 0x00001578, 0x00000000 },
+    { 0x000015b8, 0x00000000 },
+    { 0x000015f8, 0x00000000 },
+    { 0x00001638, 0x00000000 },
+    { 0x00001678, 0x00000000 },
+    { 0x000016b8, 0x00000000 },
+    { 0x000016f8, 0x00000000 },
+    { 0x00001738, 0x00000000 },
+    { 0x00001778, 0x00000000 },
+    { 0x000017b8, 0x00000000 },
+    { 0x000017f8, 0x00000000 },
+    { 0x0000103c, 0x00000000 },
+    { 0x0000107c, 0x00000000 },
+    { 0x000010bc, 0x00000000 },
+    { 0x000010fc, 0x00000000 },
+    { 0x0000113c, 0x00000000 },
+    { 0x0000117c, 0x00000000 },
+    { 0x000011bc, 0x00000000 },
+    { 0x000011fc, 0x00000000 },
+    { 0x0000123c, 0x00000000 },
+    { 0x0000127c, 0x00000000 },
+    { 0x000012bc, 0x00000000 },
+    { 0x000012fc, 0x00000000 },
+    { 0x0000133c, 0x00000000 },
+    { 0x0000137c, 0x00000000 },
+    { 0x000013bc, 0x00000000 },
+    { 0x000013fc, 0x00000000 },
+    { 0x0000143c, 0x00000000 },
+    { 0x0000147c, 0x00000000 },
+    { 0x00004030, 0x00000002 },
+    { 0x0000403c, 0x00000002 },
+    { 0x00007010, 0x00000020 },
+    { 0x00007038, 0x000004c2 },
+    { 0x00008004, 0x00000000 },
+    { 0x00008008, 0x00000000 },
+    { 0x0000800c, 0x00000000 },
+    { 0x00008018, 0x00000700 },
+    { 0x00008020, 0x00000000 },
+    { 0x00008038, 0x00000000 },
+    { 0x0000803c, 0x00000000 },
+    { 0x00008048, 0x40000000 },
+    { 0x00008054, 0x00000000 },
+    { 0x00008058, 0x00000000 },
+    { 0x0000805c, 0x000fc78f },
+    { 0x00008060, 0x0000000f },
+    { 0x00008064, 0x00000000 },
+    { 0x000080c0, 0x2a82301a },
+    { 0x000080c4, 0x05dc01e0 },
+    { 0x000080c8, 0x1f402710 },
+    { 0x000080cc, 0x01f40000 },
+    { 0x000080d0, 0x00001e00 },
+    { 0x000080d4, 0x00000000 },
+    { 0x000080d8, 0x00400000 },
+    { 0x000080e0, 0xffffffff },
+    { 0x000080e4, 0x0000ffff },
+    { 0x000080e8, 0x003f3f3f },
+    { 0x000080ec, 0x00000000 },
+    { 0x000080f0, 0x00000000 },
+    { 0x000080f4, 0x00000000 },
+    { 0x000080f8, 0x00000000 },
+    { 0x000080fc, 0x00020000 },
+    { 0x00008100, 0x00020000 },
+    { 0x00008104, 0x00000001 },
+    { 0x00008108, 0x00000052 },
+    { 0x0000810c, 0x00000000 },
+    { 0x00008110, 0x00000168 },
+    { 0x00008118, 0x000100aa },
+    { 0x0000811c, 0x00003210 },
+    { 0x00008120, 0x08f04800 },
+    { 0x00008124, 0x00000000 },
+    { 0x00008128, 0x00000000 },
+    { 0x0000812c, 0x00000000 },
+    { 0x00008130, 0x00000000 },
+    { 0x00008134, 0x00000000 },
+    { 0x00008138, 0x00000000 },
+    { 0x0000813c, 0x00000000 },
+    { 0x00008144, 0xffffffff },
+    { 0x00008168, 0x00000000 },
+    { 0x0000816c, 0x00000000 },
+    { 0x00008170, 0x32143320 },
+    { 0x00008174, 0xfaa4fa50 },
+    { 0x00008178, 0x00000100 },
+    { 0x0000817c, 0x00000000 },
+    { 0x000081c4, 0x00000000 },
+    { 0x000081d0, 0x00003210 },
+    { 0x000081ec, 0x00000000 },
+    { 0x000081f0, 0x00000000 },
+    { 0x000081f4, 0x00000000 },
+    { 0x000081f8, 0x00000000 },
+    { 0x000081fc, 0x00000000 },
+    { 0x00008200, 0x00000000 },
+    { 0x00008204, 0x00000000 },
+    { 0x00008208, 0x00000000 },
+    { 0x0000820c, 0x00000000 },
+    { 0x00008210, 0x00000000 },
+    { 0x00008214, 0x00000000 },
+    { 0x00008218, 0x00000000 },
+    { 0x0000821c, 0x00000000 },
+    { 0x00008220, 0x00000000 },
+    { 0x00008224, 0x00000000 },
+    { 0x00008228, 0x00000000 },
+    { 0x0000822c, 0x00000000 },
+    { 0x00008230, 0x00000000 },
+    { 0x00008234, 0x00000000 },
+    { 0x00008238, 0x00000000 },
+    { 0x0000823c, 0x00000000 },
+    { 0x00008240, 0x00100000 },
+    { 0x00008244, 0x0010f400 },
+    { 0x00008248, 0x00000100 },
+    { 0x0000824c, 0x0001e800 },
+    { 0x00008250, 0x00000000 },
+    { 0x00008254, 0x00000000 },
+    { 0x00008258, 0x00000000 },
+    { 0x0000825c, 0x400000ff },
+    { 0x00008260, 0x00080922 },
+    { 0x00008270, 0x00000000 },
+    { 0x00008274, 0x40000000 },
+    { 0x00008278, 0x003e4180 },
+    { 0x0000827c, 0x00000000 },
+    { 0x00008284, 0x0000002c },
+    { 0x00008288, 0x0000002c },
+    { 0x0000828c, 0x00000000 },
+    { 0x00008294, 0x00000000 },
+    { 0x00008298, 0x00000000 },
+    { 0x00008300, 0x00000000 },
+    { 0x00008304, 0x00000000 },
+    { 0x00008308, 0x00000000 },
+    { 0x0000830c, 0x00000000 },
+    { 0x00008310, 0x00000000 },
+    { 0x00008314, 0x00000000 },
+    { 0x00008318, 0x00000000 },
+    { 0x00008328, 0x00000000 },
+    { 0x0000832c, 0x00000007 },
+    { 0x00008330, 0x00000302 },
+    { 0x00008334, 0x00000e00 },
+    { 0x00008338, 0x00ff0000 },
+    { 0x0000833c, 0x00000000 },
+    { 0x00008340, 0x000107ff },
+    { 0x00009808, 0x00000000 },
+    { 0x0000980c, 0xad848e19 },
+    { 0x00009810, 0x7d14e000 },
+    { 0x00009814, 0x9c0a9f6b },
+    { 0x0000981c, 0x00000000 },
+    { 0x0000982c, 0x0000a000 },
+    { 0x00009830, 0x00000000 },
+    { 0x0000983c, 0x00200400 },
+    { 0x00009840, 0x206a01ae },
+    { 0x0000984c, 0x1284233c },
+    { 0x00009854, 0x00000859 },
+    { 0x00009900, 0x00000000 },
+    { 0x00009904, 0x00000000 },
+    { 0x00009908, 0x00000000 },
+    { 0x0000990c, 0x00000000 },
+    { 0x0000991c, 0x10000fff },
+    { 0x00009920, 0x05100000 },
+    { 0x0000a920, 0x05100000 },
+    { 0x0000b920, 0x05100000 },
+    { 0x00009928, 0x00000001 },
+    { 0x0000992c, 0x00000004 },
+    { 0x00009934, 0x1e1f2022 },
+    { 0x00009938, 0x0a0b0c0d },
+    { 0x0000993c, 0x00000000 },
+    { 0x00009948, 0x9280b212 },
+    { 0x0000994c, 0x00020028 },
+    { 0x00009954, 0x5f3ca3de },
+    { 0x00009958, 0x2108ecff },
+    { 0x00009940, 0x00750604 },
+    { 0x0000c95c, 0x004b6a8e },
+    { 0x00009970, 0x190fb515 },
+    { 0x00009974, 0x00000000 },
+    { 0x00009978, 0x00000001 },
+    { 0x0000997c, 0x00000000 },
+    { 0x00009980, 0x00000000 },
+    { 0x00009984, 0x00000000 },
+    { 0x00009988, 0x00000000 },
+    { 0x0000998c, 0x00000000 },
+    { 0x00009990, 0x00000000 },
+    { 0x00009994, 0x00000000 },
+    { 0x00009998, 0x00000000 },
+    { 0x0000999c, 0x00000000 },
+    { 0x000099a0, 0x00000000 },
+    { 0x000099a4, 0x00000001 },
+    { 0x000099a8, 0x201fff00 },
+    { 0x000099ac, 0x006f0000 },
+    { 0x000099b0, 0x03051000 },
+    { 0x000099dc, 0x00000000 },
+    { 0x000099e0, 0x00000200 },
+    { 0x000099e4, 0xaaaaaaaa },
+    { 0x000099e8, 0x3c466478 },
+    { 0x000099ec, 0x0cc80caa },
+    { 0x000099fc, 0x00001042 },
+    { 0x00009b00, 0x00000000 },
+    { 0x00009b04, 0x00000001 },
+    { 0x00009b08, 0x00000002 },
+    { 0x00009b0c, 0x00000003 },
+    { 0x00009b10, 0x00000004 },
+    { 0x00009b14, 0x00000005 },
+    { 0x00009b18, 0x00000008 },
+    { 0x00009b1c, 0x00000009 },
+    { 0x00009b20, 0x0000000a },
+    { 0x00009b24, 0x0000000b },
+    { 0x00009b28, 0x0000000c },
+    { 0x00009b2c, 0x0000000d },
+    { 0x00009b30, 0x00000010 },
+    { 0x00009b34, 0x00000011 },
+    { 0x00009b38, 0x00000012 },
+    { 0x00009b3c, 0x00000013 },
+    { 0x00009b40, 0x00000014 },
+    { 0x00009b44, 0x00000015 },
+    { 0x00009b48, 0x00000018 },
+    { 0x00009b4c, 0x00000019 },
+    { 0x00009b50, 0x0000001a },
+    { 0x00009b54, 0x0000001b },
+    { 0x00009b58, 0x0000001c },
+    { 0x00009b5c, 0x0000001d },
+    { 0x00009b60, 0x00000020 },
+    { 0x00009b64, 0x00000021 },
+    { 0x00009b68, 0x00000022 },
+    { 0x00009b6c, 0x00000023 },
+    { 0x00009b70, 0x00000024 },
+    { 0x00009b74, 0x00000025 },
+    { 0x00009b78, 0x00000028 },
+    { 0x00009b7c, 0x00000029 },
+    { 0x00009b80, 0x0000002a },
+    { 0x00009b84, 0x0000002b },
+    { 0x00009b88, 0x0000002c },
+    { 0x00009b8c, 0x0000002d },
+    { 0x00009b90, 0x00000030 },
+    { 0x00009b94, 0x00000031 },
+    { 0x00009b98, 0x00000032 },
+    { 0x00009b9c, 0x00000033 },
+    { 0x00009ba0, 0x00000034 },
+    { 0x00009ba4, 0x00000035 },
+    { 0x00009ba8, 0x00000035 },
+    { 0x00009bac, 0x00000035 },
+    { 0x00009bb0, 0x00000035 },
+    { 0x00009bb4, 0x00000035 },
+    { 0x00009bb8, 0x00000035 },
+    { 0x00009bbc, 0x00000035 },
+    { 0x00009bc0, 0x00000035 },
+    { 0x00009bc4, 0x00000035 },
+    { 0x00009bc8, 0x00000035 },
+    { 0x00009bcc, 0x00000035 },
+    { 0x00009bd0, 0x00000035 },
+    { 0x00009bd4, 0x00000035 },
+    { 0x00009bd8, 0x00000035 },
+    { 0x00009bdc, 0x00000035 },
+    { 0x00009be0, 0x00000035 },
+    { 0x00009be4, 0x00000035 },
+    { 0x00009be8, 0x00000035 },
+    { 0x00009bec, 0x00000035 },
+    { 0x00009bf0, 0x00000035 },
+    { 0x00009bf4, 0x00000035 },
+    { 0x00009bf8, 0x00000010 },
+    { 0x00009bfc, 0x0000001a },
+    { 0x0000a210, 0x40806333 },
+    { 0x0000a214, 0x00106c10 },
+    { 0x0000a218, 0x009c4060 },
+    { 0x0000a220, 0x018830c6 },
+    { 0x0000a224, 0x00000400 },
+    { 0x0000a228, 0x001a0bb5 },
+    { 0x0000a22c, 0x00000000 },
+    { 0x0000a234, 0x20202020 },
+    { 0x0000a238, 0x20202020 },
+    { 0x0000a23c, 0x13c889af },
+    { 0x0000a240, 0x38490a20 },
+    { 0x0000a244, 0x00007bb6 },
+    { 0x0000a248, 0x0fff3ffc },
+    { 0x0000a24c, 0x00000001 },
+    { 0x0000a250, 0x0000e000 },
+    { 0x0000a254, 0x00000000 },
+    { 0x0000a258, 0x0cc75380 },
+    { 0x0000a25c, 0x0f0f0f01 },
+    { 0x0000a260, 0xdfa91f01 },
+    { 0x0000a268, 0x00000001 },
+    { 0x0000a26c, 0x0ebae9c6 },
+    { 0x0000b26c, 0x0ebae9c6 },
+    { 0x0000c26c, 0x0ebae9c6 },
+    { 0x0000d270, 0x00820820 },
+    { 0x0000a278, 0x1ce739ce },
+    { 0x0000a27c, 0x050701ce },
+    { 0x0000a338, 0x00000000 },
+    { 0x0000a33c, 0x00000000 },
+    { 0x0000a340, 0x00000000 },
+    { 0x0000a344, 0x00000000 },
+    { 0x0000a348, 0x3fffffff },
+    { 0x0000a34c, 0x3fffffff },
+    { 0x0000a350, 0x3fffffff },
+    { 0x0000a354, 0x0003ffff },
+    { 0x0000a358, 0x79bfaa03 },
+    { 0x0000d35c, 0x07ffffef },
+    { 0x0000d360, 0x0fffffe7 },
+    { 0x0000d364, 0x17ffffe5 },
+    { 0x0000d368, 0x1fffffe4 },
+    { 0x0000d36c, 0x37ffffe3 },
+    { 0x0000d370, 0x3fffffe3 },
+    { 0x0000d374, 0x57ffffe3 },
+    { 0x0000d378, 0x5fffffe2 },
+    { 0x0000d37c, 0x7fffffe2 },
+    { 0x0000d380, 0x7f3c7bba },
+    { 0x0000d384, 0xf3307ff0 },
+    { 0x0000a388, 0x0c000000 },
+    { 0x0000a38c, 0x20202020 },
+    { 0x0000a390, 0x20202020 },
+    { 0x0000a394, 0x1ce739ce },
+    { 0x0000a398, 0x000001ce },
+    { 0x0000a39c, 0x00000001 },
+    { 0x0000a3a0, 0x00000000 },
+    { 0x0000a3a4, 0x00000000 },
+    { 0x0000a3a8, 0x00000000 },
+    { 0x0000a3ac, 0x00000000 },
+    { 0x0000a3b0, 0x00000000 },
+    { 0x0000a3b4, 0x00000000 },
+    { 0x0000a3b8, 0x00000000 },
+    { 0x0000a3bc, 0x00000000 },
+    { 0x0000a3c0, 0x00000000 },
+    { 0x0000a3c4, 0x00000000 },
+    { 0x0000a3c8, 0x00000246 },
+    { 0x0000a3cc, 0x20202020 },
+    { 0x0000a3d0, 0x20202020 },
+    { 0x0000a3d4, 0x20202020 },
+    { 0x0000a3dc, 0x1ce739ce },
+    { 0x0000a3e0, 0x000001ce },
+};
+
+static const u32 ar5416Bank0_9160[][2] = {
+    { 0x000098b0, 0x1e5795e5 },
+    { 0x000098e0, 0x02008020 },
+};
+
+static const u32 ar5416BB_RfGain_9160[][3] = {
+    { 0x00009a00, 0x00000000, 0x00000000 },
+    { 0x00009a04, 0x00000040, 0x00000040 },
+    { 0x00009a08, 0x00000080, 0x00000080 },
+    { 0x00009a0c, 0x000001a1, 0x00000141 },
+    { 0x00009a10, 0x000001e1, 0x00000181 },
+    { 0x00009a14, 0x00000021, 0x000001c1 },
+    { 0x00009a18, 0x00000061, 0x00000001 },
+    { 0x00009a1c, 0x00000168, 0x00000041 },
+    { 0x00009a20, 0x000001a8, 0x000001a8 },
+    { 0x00009a24, 0x000001e8, 0x000001e8 },
+    { 0x00009a28, 0x00000028, 0x00000028 },
+    { 0x00009a2c, 0x00000068, 0x00000068 },
+    { 0x00009a30, 0x00000189, 0x000000a8 },
+    { 0x00009a34, 0x000001c9, 0x00000169 },
+    { 0x00009a38, 0x00000009, 0x000001a9 },
+    { 0x00009a3c, 0x00000049, 0x000001e9 },
+    { 0x00009a40, 0x00000089, 0x00000029 },
+    { 0x00009a44, 0x00000170, 0x00000069 },
+    { 0x00009a48, 0x000001b0, 0x00000190 },
+    { 0x00009a4c, 0x000001f0, 0x000001d0 },
+    { 0x00009a50, 0x00000030, 0x00000010 },
+    { 0x00009a54, 0x00000070, 0x00000050 },
+    { 0x00009a58, 0x00000191, 0x00000090 },
+    { 0x00009a5c, 0x000001d1, 0x00000151 },
+    { 0x00009a60, 0x00000011, 0x00000191 },
+    { 0x00009a64, 0x00000051, 0x000001d1 },
+    { 0x00009a68, 0x00000091, 0x00000011 },
+    { 0x00009a6c, 0x000001b8, 0x00000051 },
+    { 0x00009a70, 0x000001f8, 0x00000198 },
+    { 0x00009a74, 0x00000038, 0x000001d8 },
+    { 0x00009a78, 0x00000078, 0x00000018 },
+    { 0x00009a7c, 0x00000199, 0x00000058 },
+    { 0x00009a80, 0x000001d9, 0x00000098 },
+    { 0x00009a84, 0x00000019, 0x00000159 },
+    { 0x00009a88, 0x00000059, 0x00000199 },
+    { 0x00009a8c, 0x00000099, 0x000001d9 },
+    { 0x00009a90, 0x000000d9, 0x00000019 },
+    { 0x00009a94, 0x000000f9, 0x00000059 },
+    { 0x00009a98, 0x000000f9, 0x00000099 },
+    { 0x00009a9c, 0x000000f9, 0x000000d9 },
+    { 0x00009aa0, 0x000000f9, 0x000000f9 },
+    { 0x00009aa4, 0x000000f9, 0x000000f9 },
+    { 0x00009aa8, 0x000000f9, 0x000000f9 },
+    { 0x00009aac, 0x000000f9, 0x000000f9 },
+    { 0x00009ab0, 0x000000f9, 0x000000f9 },
+    { 0x00009ab4, 0x000000f9, 0x000000f9 },
+    { 0x00009ab8, 0x000000f9, 0x000000f9 },
+    { 0x00009abc, 0x000000f9, 0x000000f9 },
+    { 0x00009ac0, 0x000000f9, 0x000000f9 },
+    { 0x00009ac4, 0x000000f9, 0x000000f9 },
+    { 0x00009ac8, 0x000000f9, 0x000000f9 },
+    { 0x00009acc, 0x000000f9, 0x000000f9 },
+    { 0x00009ad0, 0x000000f9, 0x000000f9 },
+    { 0x00009ad4, 0x000000f9, 0x000000f9 },
+    { 0x00009ad8, 0x000000f9, 0x000000f9 },
+    { 0x00009adc, 0x000000f9, 0x000000f9 },
+    { 0x00009ae0, 0x000000f9, 0x000000f9 },
+    { 0x00009ae4, 0x000000f9, 0x000000f9 },
+    { 0x00009ae8, 0x000000f9, 0x000000f9 },
+    { 0x00009aec, 0x000000f9, 0x000000f9 },
+    { 0x00009af0, 0x000000f9, 0x000000f9 },
+    { 0x00009af4, 0x000000f9, 0x000000f9 },
+    { 0x00009af8, 0x000000f9, 0x000000f9 },
+    { 0x00009afc, 0x000000f9, 0x000000f9 },
+};
+
+static const u32 ar5416Bank1_9160[][2] = {
+    { 0x000098b0, 0x02108421 },
+    { 0x000098ec, 0x00000008 },
+};
+
+static const u32 ar5416Bank2_9160[][2] = {
+    { 0x000098b0, 0x0e73ff17 },
+    { 0x000098e0, 0x00000420 },
+};
+
+static const u32 ar5416Bank3_9160[][3] = {
+    { 0x000098f0, 0x01400018, 0x01c00018 },
+};
+
+static const u32 ar5416Bank6_9160[][3] = {
+    { 0x0000989c, 0x00000000, 0x00000000 },
+    { 0x0000989c, 0x00000000, 0x00000000 },
+    { 0x0000989c, 0x00000000, 0x00000000 },
+    { 0x0000989c, 0x00e00000, 0x00e00000 },
+    { 0x0000989c, 0x005e0000, 0x005e0000 },
+    { 0x0000989c, 0x00120000, 0x00120000 },
+    { 0x0000989c, 0x00620000, 0x00620000 },
+    { 0x0000989c, 0x00020000, 0x00020000 },
+    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
+    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
+    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
+    { 0x0000989c, 0x40ff0000, 0x40ff0000 },
+    { 0x0000989c, 0x005f0000, 0x005f0000 },
+    { 0x0000989c, 0x00870000, 0x00870000 },
+    { 0x0000989c, 0x00f90000, 0x00f90000 },
+    { 0x0000989c, 0x007b0000, 0x007b0000 },
+    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
+    { 0x0000989c, 0x00f50000, 0x00f50000 },
+    { 0x0000989c, 0x00dc0000, 0x00dc0000 },
+    { 0x0000989c, 0x00110000, 0x00110000 },
+    { 0x0000989c, 0x006100a8, 0x006100a8 },
+    { 0x0000989c, 0x004210a2, 0x004210a2 },
+    { 0x0000989c, 0x0014008f, 0x0014008f },
+    { 0x0000989c, 0x00c40003, 0x00c40003 },
+    { 0x0000989c, 0x003000f2, 0x003000f2 },
+    { 0x0000989c, 0x00440016, 0x00440016 },
+    { 0x0000989c, 0x00410040, 0x00410040 },
+    { 0x0000989c, 0x0001805e, 0x0001805e },
+    { 0x0000989c, 0x0000c0ab, 0x0000c0ab },
+    { 0x0000989c, 0x000000f1, 0x000000f1 },
+    { 0x0000989c, 0x00002081, 0x00002081 },
+    { 0x0000989c, 0x000000d4, 0x000000d4 },
+    { 0x000098d0, 0x0000000f, 0x0010000f },
+};
+
+static const u32 ar5416Bank6TPC_9160[][3] = {
+    { 0x0000989c, 0x00000000, 0x00000000 },
+    { 0x0000989c, 0x00000000, 0x00000000 },
+    { 0x0000989c, 0x00000000, 0x00000000 },
+    { 0x0000989c, 0x00e00000, 0x00e00000 },
+    { 0x0000989c, 0x005e0000, 0x005e0000 },
+    { 0x0000989c, 0x00120000, 0x00120000 },
+    { 0x0000989c, 0x00620000, 0x00620000 },
+    { 0x0000989c, 0x00020000, 0x00020000 },
+    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
+    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
+    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
+    { 0x0000989c, 0x40ff0000, 0x40ff0000 },
+    { 0x0000989c, 0x005f0000, 0x005f0000 },
+    { 0x0000989c, 0x00870000, 0x00870000 },
+    { 0x0000989c, 0x00f90000, 0x00f90000 },
+    { 0x0000989c, 0x007b0000, 0x007b0000 },
+    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
+    { 0x0000989c, 0x00f50000, 0x00f50000 },
+    { 0x0000989c, 0x00dc0000, 0x00dc0000 },
+    { 0x0000989c, 0x00110000, 0x00110000 },
+    { 0x0000989c, 0x006100a8, 0x006100a8 },
+    { 0x0000989c, 0x00423022, 0x00423022 },
+    { 0x0000989c, 0x2014008f, 0x2014008f },
+    { 0x0000989c, 0x00c40002, 0x00c40002 },
+    { 0x0000989c, 0x003000f2, 0x003000f2 },
+    { 0x0000989c, 0x00440016, 0x00440016 },
+    { 0x0000989c, 0x00410040, 0x00410040 },
+    { 0x0000989c, 0x0001805e, 0x0001805e },
+    { 0x0000989c, 0x0000c0ab, 0x0000c0ab },
+    { 0x0000989c, 0x000000e1, 0x000000e1 },
+    { 0x0000989c, 0x00007080, 0x00007080 },
+    { 0x0000989c, 0x000000d4, 0x000000d4 },
+    { 0x000098d0, 0x0000000f, 0x0010000f },
+};
+
+static const u32 ar5416Bank7_9160[][2] = {
+    { 0x0000989c, 0x00000500 },
+    { 0x0000989c, 0x00000800 },
+    { 0x000098cc, 0x0000000e },
+};
+
+static const u32 ar5416Addac_9160[][2] = {
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x000000c0 },
+    {0x0000989c,  0x00000018 },
+    {0x0000989c,  0x00000004 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x000000c0 },
+    {0x0000989c,  0x00000019 },
+    {0x0000989c,  0x00000004 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000004 },
+    {0x0000989c,  0x00000003 },
+    {0x0000989c,  0x00000008 },
+    {0x0000989c,  0x00000000 },
+    {0x000098cc,  0x00000000 },
+};
+
+static const u32 ar5416Addac_91601_1[][2] = {
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x000000c0 },
+    {0x0000989c,  0x00000018 },
+    {0x0000989c,  0x00000004 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x000000c0 },
+    {0x0000989c,  0x00000019 },
+    {0x0000989c,  0x00000004 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x000098cc,  0x00000000 },
+};
+
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_calib.c b/drivers/net/wireless/ath/ath9k/ar9002_calib.c
new file mode 100644 (file)
index 0000000..5fdbb53
--- /dev/null
@@ -0,0 +1,1000 @@
+/*
+ * Copyright (c) 2008-2010 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT 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 "hw.h"
+#include "hw-ops.h"
+#include "ar9002_phy.h"
+
+#define AR9285_CLCAL_REDO_THRESH    1
+
+static void ar9002_hw_setup_calibration(struct ath_hw *ah,
+                                       struct ath9k_cal_list *currCal)
+{
+       struct ath_common *common = ath9k_hw_common(ah);
+
+       REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(0),
+                     AR_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX,
+                     currCal->calData->calCountMax);
+
+       switch (currCal->calData->calType) {
+       case IQ_MISMATCH_CAL:
+               REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_IQ);
+               ath_print(common, ATH_DBG_CALIBRATE,
+                         "starting IQ Mismatch Calibration\n");
+               break;
+       case ADC_GAIN_CAL:
+               REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_GAIN);
+               ath_print(common, ATH_DBG_CALIBRATE,
+                         "starting ADC Gain Calibration\n");
+               break;
+       case ADC_DC_CAL:
+               REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_DC_PER);
+               ath_print(common, ATH_DBG_CALIBRATE,
+                         "starting ADC DC Calibration\n");
+               break;
+       case ADC_DC_INIT_CAL:
+               REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_DC_INIT);
+               ath_print(common, ATH_DBG_CALIBRATE,
+                         "starting Init ADC DC Calibration\n");
+               break;
+       case TEMP_COMP_CAL:
+               break; /* Not supported */
+       }
+
+       REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4(0),
+                   AR_PHY_TIMING_CTRL4_DO_CAL);
+}
+
+static bool ar9002_hw_per_calibration(struct ath_hw *ah,
+                                     struct ath9k_channel *ichan,
+                                     u8 rxchainmask,
+                                     struct ath9k_cal_list *currCal)
+{
+       bool iscaldone = false;
+
+       if (currCal->calState == CAL_RUNNING) {
+               if (!(REG_READ(ah, AR_PHY_TIMING_CTRL4(0)) &
+                     AR_PHY_TIMING_CTRL4_DO_CAL)) {
+
+                       currCal->calData->calCollect(ah);
+                       ah->cal_samples++;
+
+                       if (ah->cal_samples >=
+                           currCal->calData->calNumSamples) {
+                               int i, numChains = 0;
+                               for (i = 0; i < AR5416_MAX_CHAINS; i++) {
+                                       if (rxchainmask & (1 << i))
+                                               numChains++;
+                               }
+
+                               currCal->calData->calPostProc(ah, numChains);
+                               ichan->CalValid |= currCal->calData->calType;
+                               currCal->calState = CAL_DONE;
+                               iscaldone = true;
+                       } else {
+                               ar9002_hw_setup_calibration(ah, currCal);
+                       }
+               }
+       } else if (!(ichan->CalValid & currCal->calData->calType)) {
+               ath9k_hw_reset_calibration(ah, currCal);
+       }
+
+       return iscaldone;
+}
+
+/* Assumes you are talking about the currently configured channel */
+static bool ar9002_hw_iscal_supported(struct ath_hw *ah,
+                                     enum ath9k_cal_types calType)
+{
+       struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;
+
+       switch (calType & ah->supp_cals) {
+       case IQ_MISMATCH_CAL: /* Both 2 GHz and 5 GHz support OFDM */
+               return true;
+       case ADC_GAIN_CAL:
+       case ADC_DC_CAL:
+               if (!(conf->channel->band == IEEE80211_BAND_2GHZ &&
+                     conf_is_ht20(conf)))
+                       return true;
+               break;
+       }
+       return false;
+}
+
+static void ar9002_hw_iqcal_collect(struct ath_hw *ah)
+{
+       int i;
+
+       for (i = 0; i < AR5416_MAX_CHAINS; i++) {
+               ah->totalPowerMeasI[i] +=
+                       REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
+               ah->totalPowerMeasQ[i] +=
+                       REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
+               ah->totalIqCorrMeas[i] +=
+                       (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
+               ath_print(ath9k_hw_common(ah), ATH_DBG_CALIBRATE,
+                         "%d: Chn %d pmi=0x%08x;pmq=0x%08x;iqcm=0x%08x;\n",
+                         ah->cal_samples, i, ah->totalPowerMeasI[i],
+                         ah->totalPowerMeasQ[i],
+                         ah->totalIqCorrMeas[i]);
+       }
+}
+
+static void ar9002_hw_adc_gaincal_collect(struct ath_hw *ah)
+{
+       int i;
+
+       for (i = 0; i < AR5416_MAX_CHAINS; i++) {
+               ah->totalAdcIOddPhase[i] +=
+                       REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
+               ah->totalAdcIEvenPhase[i] +=
+                       REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
+               ah->totalAdcQOddPhase[i] +=
+                       REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
+               ah->totalAdcQEvenPhase[i] +=
+                       REG_READ(ah, AR_PHY_CAL_MEAS_3(i));
+
+               ath_print(ath9k_hw_common(ah), ATH_DBG_CALIBRATE,
+                         "%d: Chn %d oddi=0x%08x; eveni=0x%08x; "
+                         "oddq=0x%08x; evenq=0x%08x;\n",
+                         ah->cal_samples, i,
+                         ah->totalAdcIOddPhase[i],
+                         ah->totalAdcIEvenPhase[i],
+                         ah->totalAdcQOddPhase[i],
+                         ah->totalAdcQEvenPhase[i]);
+       }
+}
+
+static void ar9002_hw_adc_dccal_collect(struct ath_hw *ah)
+{
+       int i;
+
+       for (i = 0; i < AR5416_MAX_CHAINS; i++) {
+               ah->totalAdcDcOffsetIOddPhase[i] +=
+                       (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
+               ah->totalAdcDcOffsetIEvenPhase[i] +=
+                       (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
+               ah->totalAdcDcOffsetQOddPhase[i] +=
+                       (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
+               ah->totalAdcDcOffsetQEvenPhase[i] +=
+                       (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_3(i));
+
+               ath_print(ath9k_hw_common(ah), ATH_DBG_CALIBRATE,
+                         "%d: Chn %d oddi=0x%08x; eveni=0x%08x; "
+                         "oddq=0x%08x; evenq=0x%08x;\n",
+                         ah->cal_samples, i,
+                         ah->totalAdcDcOffsetIOddPhase[i],
+                         ah->totalAdcDcOffsetIEvenPhase[i],
+                         ah->totalAdcDcOffsetQOddPhase[i],
+                         ah->totalAdcDcOffsetQEvenPhase[i]);
+       }
+}
+
+static void ar9002_hw_iqcalibrate(struct ath_hw *ah, u8 numChains)
+{
+       struct ath_common *common = ath9k_hw_common(ah);
+       u32 powerMeasQ, powerMeasI, iqCorrMeas;
+       u32 qCoffDenom, iCoffDenom;
+       int32_t qCoff, iCoff;
+       int iqCorrNeg, i;
+
+       for (i = 0; i < numChains; i++) {
+               powerMeasI = ah->totalPowerMeasI[i];
+               powerMeasQ = ah->totalPowerMeasQ[i];
+               iqCorrMeas = ah->totalIqCorrMeas[i];
+
+               ath_print(common, ATH_DBG_CALIBRATE,
+                         "Starting IQ Cal and Correction for Chain %d\n",
+                         i);
+
+               ath_print(common, ATH_DBG_CALIBRATE,
+                         "Orignal: Chn %diq_corr_meas = 0x%08x\n",
+                         i, ah->totalIqCorrMeas[i]);
+
+               iqCorrNeg = 0;
+
+               if (iqCorrMeas > 0x80000000) {
+                       iqCorrMeas = (0xffffffff - iqCorrMeas) + 1;
+                       iqCorrNeg = 1;
+               }
+
+               ath_print(common, ATH_DBG_CALIBRATE,
+                         "Chn %d pwr_meas_i = 0x%08x\n", i, powerMeasI);
+               ath_print(common, ATH_DBG_CALIBRATE,
+                         "Chn %d pwr_meas_q = 0x%08x\n", i, powerMeasQ);
+               ath_print(common, ATH_DBG_CALIBRATE, "iqCorrNeg is 0x%08x\n",
+                         iqCorrNeg);
+
+               iCoffDenom = (powerMeasI / 2 + powerMeasQ / 2) / 128;
+               qCoffDenom = powerMeasQ / 64;
+
+               if ((powerMeasQ != 0) && (iCoffDenom != 0) &&
+                   (qCoffDenom != 0)) {
+                       iCoff = iqCorrMeas / iCoffDenom;
+                       qCoff = powerMeasI / qCoffDenom - 64;
+                       ath_print(common, ATH_DBG_CALIBRATE,
+                                 "Chn %d iCoff = 0x%08x\n", i, iCoff);
+                       ath_print(common, ATH_DBG_CALIBRATE,
+                                 "Chn %d qCoff = 0x%08x\n", i, qCoff);
+
+                       iCoff = iCoff & 0x3f;
+                       ath_print(common, ATH_DBG_CALIBRATE,
+                                 "New: Chn %d iCoff = 0x%08x\n", i, iCoff);
+                       if (iqCorrNeg == 0x0)
+                               iCoff = 0x40 - iCoff;
+
+                       if (qCoff > 15)
+                               qCoff = 15;
+                       else if (qCoff <= -16)
+                               qCoff = 16;
+
+                       ath_print(common, ATH_DBG_CALIBRATE,
+                                 "Chn %d : iCoff = 0x%x  qCoff = 0x%x\n",
+                                 i, iCoff, qCoff);
+
+                       REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(i),
+                                     AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF,
+                                     iCoff);
+                       REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(i),
+                                     AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF,
+                                     qCoff);
+                       ath_print(common, ATH_DBG_CALIBRATE,
+                                 "IQ Cal and Correction done for Chain %d\n",
+                                 i);
+               }
+       }
+
+       REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4(0),
+                   AR_PHY_TIMING_CTRL4_IQCORR_ENABLE);
+}
+
+static void ar9002_hw_adc_gaincal_calibrate(struct ath_hw *ah, u8 numChains)
+{
+       struct ath_common *common = ath9k_hw_common(ah);
+       u32 iOddMeasOffset, iEvenMeasOffset, qOddMeasOffset, qEvenMeasOffset;
+       u32 qGainMismatch, iGainMismatch, val, i;
+
+       for (i = 0; i < numChains; i++) {
+               iOddMeasOffset = ah->totalAdcIOddPhase[i];
+               iEvenMeasOffset = ah->totalAdcIEvenPhase[i];
+               qOddMeasOffset = ah->totalAdcQOddPhase[i];
+               qEvenMeasOffset = ah->totalAdcQEvenPhase[i];
+
+               ath_print(common, ATH_DBG_CALIBRATE,
+                         "Starting ADC Gain Cal for Chain %d\n", i);
+
+               ath_print(common, ATH_DBG_CALIBRATE,
+                         "Chn %d pwr_meas_odd_i = 0x%08x\n", i,
+                         iOddMeasOffset);
+               ath_print(common, ATH_DBG_CALIBRATE,
+                         "Chn %d pwr_meas_even_i = 0x%08x\n", i,
+                         iEvenMeasOffset);
+               ath_print(common, ATH_DBG_CALIBRATE,
+                         "Chn %d pwr_meas_odd_q = 0x%08x\n", i,
+                         qOddMeasOffset);
+               ath_print(common, ATH_DBG_CALIBRATE,
+                         "Chn %d pwr_meas_even_q = 0x%08x\n", i,
+                         qEvenMeasOffset);
+
+               if (iOddMeasOffset != 0 && qEvenMeasOffset != 0) {
+                       iGainMismatch =
+                               ((iEvenMeasOffset * 32) /
+                                iOddMeasOffset) & 0x3f;
+                       qGainMismatch =
+                               ((qOddMeasOffset * 32) /
+                                qEvenMeasOffset) & 0x3f;
+
+                       ath_print(common, ATH_DBG_CALIBRATE,
+                                 "Chn %d gain_mismatch_i = 0x%08x\n", i,
+                                 iGainMismatch);
+                       ath_print(common, ATH_DBG_CALIBRATE,
+                                 "Chn %d gain_mismatch_q = 0x%08x\n", i,
+                                 qGainMismatch);
+
+                       val = REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i));
+                       val &= 0xfffff000;
+                       val |= (qGainMismatch) | (iGainMismatch << 6);
+                       REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i), val);
+
+                       ath_print(common, ATH_DBG_CALIBRATE,
+                                 "ADC Gain Cal done for Chain %d\n", i);
+               }
+       }
+
+       REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0),
+                 REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0)) |
+                 AR_PHY_NEW_ADC_GAIN_CORR_ENABLE);
+}
+
+static void ar9002_hw_adc_dccal_calibrate(struct ath_hw *ah, u8 numChains)
+{
+       struct ath_common *common = ath9k_hw_common(ah);
+       u32 iOddMeasOffset, iEvenMeasOffset, val, i;
+       int32_t qOddMeasOffset, qEvenMeasOffset, qDcMismatch, iDcMismatch;
+       const struct ath9k_percal_data *calData =
+               ah->cal_list_curr->calData;
+       u32 numSamples =
+               (1 << (calData->calCountMax + 5)) * calData->calNumSamples;
+
+       for (i = 0; i < numChains; i++) {
+               iOddMeasOffset = ah->totalAdcDcOffsetIOddPhase[i];
+               iEvenMeasOffset = ah->totalAdcDcOffsetIEvenPhase[i];
+               qOddMeasOffset = ah->totalAdcDcOffsetQOddPhase[i];
+               qEvenMeasOffset = ah->totalAdcDcOffsetQEvenPhase[i];
+
+               ath_print(common, ATH_DBG_CALIBRATE,
+                          "Starting ADC DC Offset Cal for Chain %d\n", i);
+
+               ath_print(common, ATH_DBG_CALIBRATE,
+                         "Chn %d pwr_meas_odd_i = %d\n", i,
+                         iOddMeasOffset);
+               ath_print(common, ATH_DBG_CALIBRATE,
+                         "Chn %d pwr_meas_even_i = %d\n", i,
+                         iEvenMeasOffset);
+               ath_print(common, ATH_DBG_CALIBRATE,
+                         "Chn %d pwr_meas_odd_q = %d\n", i,
+                         qOddMeasOffset);
+               ath_print(common, ATH_DBG_CALIBRATE,
+                         "Chn %d pwr_meas_even_q = %d\n", i,
+                         qEvenMeasOffset);
+
+               iDcMismatch = (((iEvenMeasOffset - iOddMeasOffset) * 2) /
+                              numSamples) & 0x1ff;
+               qDcMismatch = (((qOddMeasOffset - qEvenMeasOffset) * 2) /
+                              numSamples) & 0x1ff;
+
+               ath_print(common, ATH_DBG_CALIBRATE,
+                         "Chn %d dc_offset_mismatch_i = 0x%08x\n", i,
+                         iDcMismatch);
+               ath_print(common, ATH_DBG_CALIBRATE,
+                         "Chn %d dc_offset_mismatch_q = 0x%08x\n", i,
+                         qDcMismatch);
+
+               val = REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i));
+               val &= 0xc0000fff;
+               val |= (qDcMismatch << 12) | (iDcMismatch << 21);
+               REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i), val);
+
+               ath_print(common, ATH_DBG_CALIBRATE,
+                         "ADC DC Offset Cal done for Chain %d\n", i);
+       }
+
+       REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0),
+                 REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0)) |
+                 AR_PHY_NEW_ADC_DC_OFFSET_CORR_ENABLE);
+}
+
+static void ar9287_hw_olc_temp_compensation(struct ath_hw *ah)
+{
+       u32 rddata;
+       int32_t delta, currPDADC, slope;
+
+       rddata = REG_READ(ah, AR_PHY_TX_PWRCTRL4);
+       currPDADC = MS(rddata, AR_PHY_TX_PWRCTRL_PD_AVG_OUT);
+
+       if (ah->initPDADC == 0 || currPDADC == 0) {
+               /*
+                * Zero value indicates that no frames have been transmitted
+                * yet, can't do temperature compensation until frames are
+                * transmitted.
+                */
+               return;
+       } else {
+               slope = ah->eep_ops->get_eeprom(ah, EEP_TEMPSENSE_SLOPE);
+
+               if (slope == 0) { /* to avoid divide by zero case */
+                       delta = 0;
+               } else {
+                       delta = ((currPDADC - ah->initPDADC)*4) / slope;
+               }
+               REG_RMW_FIELD(ah, AR_PHY_CH0_TX_PWRCTRL11,
+                             AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP, delta);
+               REG_RMW_FIELD(ah, AR_PHY_CH1_TX_PWRCTRL11,
+                             AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP, delta);
+       }
+}
+
+static void ar9280_hw_olc_temp_compensation(struct ath_hw *ah)
+{
+       u32 rddata, i;
+       int delta, currPDADC, regval;
+
+       rddata = REG_READ(ah, AR_PHY_TX_PWRCTRL4);
+       currPDADC = MS(rddata, AR_PHY_TX_PWRCTRL_PD_AVG_OUT);
+
+       if (ah->initPDADC == 0 || currPDADC == 0)
+               return;
+
+       if (ah->eep_ops->get_eeprom(ah, EEP_DAC_HPWR_5G))
+               delta = (currPDADC - ah->initPDADC + 4) / 8;
+       else
+               delta = (currPDADC - ah->initPDADC + 5) / 10;
+
+       if (delta != ah->PDADCdelta) {
+               ah->PDADCdelta = delta;
+               for (i = 1; i < AR9280_TX_GAIN_TABLE_SIZE; i++) {
+                       regval = ah->originalGain[i] - delta;
+                       if (regval < 0)
+                               regval = 0;
+
+                       REG_RMW_FIELD(ah,
+                                     AR_PHY_TX_GAIN_TBL1 + i * 4,
+                                     AR_PHY_TX_GAIN, regval);
+               }
+       }
+}
+
+static void ar9271_hw_pa_cal(struct ath_hw *ah, bool is_reset)
+{
+       u32 regVal;
+       unsigned int i;
+       u32 regList[][2] = {
+               { 0x786c, 0 },
+               { 0x7854, 0 },
+               { 0x7820, 0 },
+               { 0x7824, 0 },
+               { 0x7868, 0 },
+               { 0x783c, 0 },
+               { 0x7838, 0 } ,
+               { 0x7828, 0 } ,
+       };
+
+       for (i = 0; i < ARRAY_SIZE(regList); i++)
+               regList[i][1] = REG_READ(ah, regList[i][0]);
+
+       regVal = REG_READ(ah, 0x7834);
+       regVal &= (~(0x1));
+       REG_WRITE(ah, 0x7834, regVal);
+       regVal = REG_READ(ah, 0x9808);
+       regVal |= (0x1 << 27);
+       REG_WRITE(ah, 0x9808, regVal);
+
+       /* 786c,b23,1, pwddac=1 */
+       REG_RMW_FIELD(ah, AR9285_AN_TOP3, AR9285_AN_TOP3_PWDDAC, 1);
+       /* 7854, b5,1, pdrxtxbb=1 */
+       REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDRXTXBB1, 1);
+       /* 7854, b7,1, pdv2i=1 */
+       REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDV2I, 1);
+       /* 7854, b8,1, pddacinterface=1 */
+       REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDDACIF, 1);
+       /* 7824,b12,0, offcal=0 */
+       REG_RMW_FIELD(ah, AR9285_AN_RF2G2, AR9285_AN_RF2G2_OFFCAL, 0);
+       /* 7838, b1,0, pwddb=0 */
+       REG_RMW_FIELD(ah, AR9285_AN_RF2G7, AR9285_AN_RF2G7_PWDDB, 0);
+       /* 7820,b11,0, enpacal=0 */
+       REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_ENPACAL, 0);
+       /* 7820,b25,1, pdpadrv1=0 */
+       REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPADRV1, 0);
+       /* 7820,b24,0, pdpadrv2=0 */
+       REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPADRV2, 0);
+       /* 7820,b23,0, pdpaout=0 */
+       REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPAOUT, 0);
+       /* 783c,b14-16,7, padrvgn2tab_0=7 */
+       REG_RMW_FIELD(ah, AR9285_AN_RF2G8, AR9285_AN_RF2G8_PADRVGN2TAB0, 7);
+       /*
+        * 7838,b29-31,0, padrvgn1tab_0=0
+        * does not matter since we turn it off
+        */
+       REG_RMW_FIELD(ah, AR9285_AN_RF2G7, AR9285_AN_RF2G7_PADRVGN2TAB0, 0);
+
+       REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9271_AN_RF2G3_CCOMP, 0xfff);
+
+       /* Set:
+        * localmode=1,bmode=1,bmoderxtx=1,synthon=1,
+        * txon=1,paon=1,oscon=1,synthon_force=1
+        */
+       REG_WRITE(ah, AR9285_AN_TOP2, 0xca0358a0);
+       udelay(30);
+       REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9271_AN_RF2G6_OFFS, 0);
+
+       /* find off_6_1; */
+       for (i = 6; i > 0; i--) {
+               regVal = REG_READ(ah, 0x7834);
+               regVal |= (1 << (20 + i));
+               REG_WRITE(ah, 0x7834, regVal);
+               udelay(1);
+               /* regVal = REG_READ(ah, 0x7834); */
+               regVal &= (~(0x1 << (20 + i)));
+               regVal |= (MS(REG_READ(ah, 0x7840), AR9285_AN_RXTXBB1_SPARE9)
+                           << (20 + i));
+               REG_WRITE(ah, 0x7834, regVal);
+       }
+
+       regVal = (regVal >> 20) & 0x7f;
+
+       /* Update PA cal info */
+       if ((!is_reset) && (ah->pacal_info.prev_offset == regVal)) {
+               if (ah->pacal_info.max_skipcount < MAX_PACAL_SKIPCOUNT)
+                       ah->pacal_info.max_skipcount =
+                               2 * ah->pacal_info.max_skipcount;
+               ah->pacal_info.skipcount = ah->pacal_info.max_skipcount;
+       } else {
+               ah->pacal_info.max_skipcount = 1;
+               ah->pacal_info.skipcount = 0;
+               ah->pacal_info.prev_offset = regVal;
+       }
+
+       ENABLE_REGWRITE_BUFFER(ah);
+
+       regVal = REG_READ(ah, 0x7834);
+       regVal |= 0x1;
+       REG_WRITE(ah, 0x7834, regVal);
+       regVal = REG_READ(ah, 0x9808);
+       regVal &= (~(0x1 << 27));
+       REG_WRITE(ah, 0x9808, regVal);
+
+       for (i = 0; i < ARRAY_SIZE(regList); i++)
+               REG_WRITE(ah, regList[i][0], regList[i][1]);
+
+       REGWRITE_BUFFER_FLUSH(ah);
+       DISABLE_REGWRITE_BUFFER(ah);
+}
+
+static inline void ar9285_hw_pa_cal(struct ath_hw *ah, bool is_reset)
+{
+       struct ath_common *common = ath9k_hw_common(ah);
+       u32 regVal;
+       int i, offset, offs_6_1, offs_0;
+       u32 ccomp_org, reg_field;
+       u32 regList[][2] = {
+               { 0x786c, 0 },
+               { 0x7854, 0 },
+               { 0x7820, 0 },
+               { 0x7824, 0 },
+               { 0x7868, 0 },
+               { 0x783c, 0 },
+               { 0x7838, 0 },
+       };
+
+       ath_print(common, ATH_DBG_CALIBRATE, "Running PA Calibration\n");
+
+       /* PA CAL is not needed for high power solution */
+       if (ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE) ==
+           AR5416_EEP_TXGAIN_HIGH_POWER)
+               return;
+
+       if (AR_SREV_9285_11(ah)) {
+               REG_WRITE(ah, AR9285_AN_TOP4, (AR9285_AN_TOP4_DEFAULT | 0x14));
+               udelay(10);
+       }
+
+       for (i = 0; i < ARRAY_SIZE(regList); i++)
+               regList[i][1] = REG_READ(ah, regList[i][0]);
+
+       regVal = REG_READ(ah, 0x7834);
+       regVal &= (~(0x1));
+       REG_WRITE(ah, 0x7834, regVal);
+       regVal = REG_READ(ah, 0x9808);
+       regVal |= (0x1 << 27);
+       REG_WRITE(ah, 0x9808, regVal);
+
+       REG_RMW_FIELD(ah, AR9285_AN_TOP3, AR9285_AN_TOP3_PWDDAC, 1);
+       REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDRXTXBB1, 1);
+       REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDV2I, 1);
+       REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDDACIF, 1);
+       REG_RMW_FIELD(ah, AR9285_AN_RF2G2, AR9285_AN_RF2G2_OFFCAL, 0);
+       REG_RMW_FIELD(ah, AR9285_AN_RF2G7, AR9285_AN_RF2G7_PWDDB, 0);
+       REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_ENPACAL, 0);
+       REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPADRV1, 0);
+       REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPADRV2, 0);
+       REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPAOUT, 0);
+       REG_RMW_FIELD(ah, AR9285_AN_RF2G8, AR9285_AN_RF2G8_PADRVGN2TAB0, 7);
+       REG_RMW_FIELD(ah, AR9285_AN_RF2G7, AR9285_AN_RF2G7_PADRVGN2TAB0, 0);
+       ccomp_org = MS(REG_READ(ah, AR9285_AN_RF2G6), AR9285_AN_RF2G6_CCOMP);
+       REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9285_AN_RF2G6_CCOMP, 0xf);
+
+       REG_WRITE(ah, AR9285_AN_TOP2, 0xca0358a0);
+       udelay(30);
+       REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9285_AN_RF2G6_OFFS, 0);
+       REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9285_AN_RF2G3_PDVCCOMP, 0);
+
+       for (i = 6; i > 0; i--) {
+               regVal = REG_READ(ah, 0x7834);
+               regVal |= (1 << (19 + i));
+               REG_WRITE(ah, 0x7834, regVal);
+               udelay(1);
+               regVal = REG_READ(ah, 0x7834);
+               regVal &= (~(0x1 << (19 + i)));
+               reg_field = MS(REG_READ(ah, 0x7840), AR9285_AN_RXTXBB1_SPARE9);
+               regVal |= (reg_field << (19 + i));
+               REG_WRITE(ah, 0x7834, regVal);
+       }
+
+       REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9285_AN_RF2G3_PDVCCOMP, 1);
+       udelay(1);
+       reg_field = MS(REG_READ(ah, AR9285_AN_RF2G9), AR9285_AN_RXTXBB1_SPARE9);
+       REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9285_AN_RF2G3_PDVCCOMP, reg_field);
+       offs_6_1 = MS(REG_READ(ah, AR9285_AN_RF2G6), AR9285_AN_RF2G6_OFFS);
+       offs_0   = MS(REG_READ(ah, AR9285_AN_RF2G3), AR9285_AN_RF2G3_PDVCCOMP);
+
+       offset = (offs_6_1<<1) | offs_0;
+       offset = offset - 0;
+       offs_6_1 = offset>>1;
+       offs_0 = offset & 1;
+
+       if ((!is_reset) && (ah->pacal_info.prev_offset == offset)) {
+               if (ah->pacal_info.max_skipcount < MAX_PACAL_SKIPCOUNT)
+                       ah->pacal_info.max_skipcount =
+                               2 * ah->pacal_info.max_skipcount;
+               ah->pacal_info.skipcount = ah->pacal_info.max_skipcount;
+       } else {
+               ah->pacal_info.max_skipcount = 1;
+               ah->pacal_info.skipcount = 0;
+               ah->pacal_info.prev_offset = offset;
+       }
+
+       REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9285_AN_RF2G6_OFFS, offs_6_1);
+       REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9285_AN_RF2G3_PDVCCOMP, offs_0);
+
+       regVal = REG_READ(ah, 0x7834);
+       regVal |= 0x1;
+       REG_WRITE(ah, 0x7834, regVal);
+       regVal = REG_READ(ah, 0x9808);
+       regVal &= (~(0x1 << 27));
+       REG_WRITE(ah, 0x9808, regVal);
+
+       for (i = 0; i < ARRAY_SIZE(regList); i++)
+               REG_WRITE(ah, regList[i][0], regList[i][1]);
+
+       REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9285_AN_RF2G6_CCOMP, ccomp_org);
+
+       if (AR_SREV_9285_11(ah))
+               REG_WRITE(ah, AR9285_AN_TOP4, AR9285_AN_TOP4_DEFAULT);
+
+}
+
+static void ar9002_hw_pa_cal(struct ath_hw *ah, bool is_reset)
+{
+       if (AR_SREV_9271(ah)) {
+               if (is_reset || !ah->pacal_info.skipcount)
+                       ar9271_hw_pa_cal(ah, is_reset);
+               else
+                       ah->pacal_info.skipcount--;
+       } else if (AR_SREV_9285_11_OR_LATER(ah)) {
+               if (is_reset || !ah->pacal_info.skipcount)
+                       ar9285_hw_pa_cal(ah, is_reset);
+               else
+                       ah->pacal_info.skipcount--;
+       }
+}
+
+static void ar9002_hw_olc_temp_compensation(struct ath_hw *ah)
+{
+       if (OLC_FOR_AR9287_10_LATER)
+               ar9287_hw_olc_temp_compensation(ah);
+       else if (OLC_FOR_AR9280_20_LATER)
+               ar9280_hw_olc_temp_compensation(ah);
+}
+
+static bool ar9002_hw_calibrate(struct ath_hw *ah,
+                               struct ath9k_channel *chan,
+                               u8 rxchainmask,
+                               bool longcal)
+{
+       bool iscaldone = true;
+       struct ath9k_cal_list *currCal = ah->cal_list_curr;
+
+       if (currCal &&
+           (currCal->calState == CAL_RUNNING ||
+            currCal->calState == CAL_WAITING)) {
+               iscaldone = ar9002_hw_per_calibration(ah, chan,
+                                                     rxchainmask, currCal);
+               if (iscaldone) {
+                       ah->cal_list_curr = currCal = currCal->calNext;
+
+                       if (currCal->calState == CAL_WAITING) {
+                               iscaldone = false;
+                               ath9k_hw_reset_calibration(ah, currCal);
+                       }
+               }
+       }
+
+       /* Do NF cal only at longer intervals */
+       if (longcal) {
+               /* Do periodic PAOffset Cal */
+               ar9002_hw_pa_cal(ah, false);
+               ar9002_hw_olc_temp_compensation(ah);
+
+               /*
+                * Get the value from the previous NF cal and update
+                * history buffer.
+                */
+               ath9k_hw_getnf(ah, chan);
+
+               /*
+                * Load the NF from history buffer of the current channel.
+                * NF is slow time-variant, so it is OK to use a historical
+                * value.
+                */
+               ath9k_hw_loadnf(ah, ah->curchan);
+
+               ath9k_hw_start_nfcal(ah);
+       }
+
+       return iscaldone;
+}
+
+/* Carrier leakage Calibration fix */
+static bool ar9285_hw_cl_cal(struct ath_hw *ah, struct ath9k_channel *chan)
+{
+       struct ath_common *common = ath9k_hw_common(ah);
+
+       REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
+       if (IS_CHAN_HT20(chan)) {
+               REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_PARALLEL_CAL_ENABLE);
+               REG_SET_BIT(ah, AR_PHY_TURBO, AR_PHY_FC_DYN2040_EN);
+               REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
+                           AR_PHY_AGC_CONTROL_FLTR_CAL);
+               REG_CLR_BIT(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_CAL_ENABLE);
+               REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL);
+               if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL,
+                                 AR_PHY_AGC_CONTROL_CAL, 0, AH_WAIT_TIMEOUT)) {
+                       ath_print(common, ATH_DBG_CALIBRATE, "offset "
+                                 "calibration failed to complete in "
+                                 "1ms; noisy ??\n");
+                       return false;
+               }
+               REG_CLR_BIT(ah, AR_PHY_TURBO, AR_PHY_FC_DYN2040_EN);
+               REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_PARALLEL_CAL_ENABLE);
+               REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
+       }
+       REG_CLR_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC);
+       REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL);
+       REG_SET_BIT(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_CAL_ENABLE);
+       REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL);
+       if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL,
+                         0, AH_WAIT_TIMEOUT)) {
+               ath_print(common, ATH_DBG_CALIBRATE, "offset calibration "
+                         "failed to complete in 1ms; noisy ??\n");
+               return false;
+       }
+
+       REG_SET_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC);
+       REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
+       REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL);
+
+       return true;
+}
+
+static bool ar9285_hw_clc(struct ath_hw *ah, struct ath9k_channel *chan)
+{
+       int i;
+       u_int32_t txgain_max;
+       u_int32_t clc_gain, gain_mask = 0, clc_num = 0;
+       u_int32_t reg_clc_I0, reg_clc_Q0;
+       u_int32_t i0_num = 0;
+       u_int32_t q0_num = 0;
+       u_int32_t total_num = 0;
+       u_int32_t reg_rf2g5_org;
+       bool retv = true;
+
+       if (!(ar9285_hw_cl_cal(ah, chan)))
+               return false;
+
+       txgain_max = MS(REG_READ(ah, AR_PHY_TX_PWRCTRL7),
+                       AR_PHY_TX_PWRCTRL_TX_GAIN_TAB_MAX);
+
+       for (i = 0; i < (txgain_max+1); i++) {
+               clc_gain = (REG_READ(ah, (AR_PHY_TX_GAIN_TBL1+(i<<2))) &
+                          AR_PHY_TX_GAIN_CLC) >> AR_PHY_TX_GAIN_CLC_S;
+               if (!(gain_mask & (1 << clc_gain))) {
+                       gain_mask |= (1 << clc_gain);
+                       clc_num++;
+               }
+       }
+
+       for (i = 0; i < clc_num; i++) {
+               reg_clc_I0 = (REG_READ(ah, (AR_PHY_CLC_TBL1 + (i << 2)))
+                             & AR_PHY_CLC_I0) >> AR_PHY_CLC_I0_S;
+               reg_clc_Q0 = (REG_READ(ah, (AR_PHY_CLC_TBL1 + (i << 2)))
+                             & AR_PHY_CLC_Q0) >> AR_PHY_CLC_Q0_S;
+               if (reg_clc_I0 == 0)
+                       i0_num++;
+
+               if (reg_clc_Q0 == 0)
+                       q0_num++;
+       }
+       total_num = i0_num + q0_num;
+       if (total_num > AR9285_CLCAL_REDO_THRESH) {
+               reg_rf2g5_org = REG_READ(ah, AR9285_RF2G5);
+               if (AR_SREV_9285E_20(ah)) {
+                       REG_WRITE(ah, AR9285_RF2G5,
+                                 (reg_rf2g5_org & AR9285_RF2G5_IC50TX) |
+                                 AR9285_RF2G5_IC50TX_XE_SET);
+               } else {
+                       REG_WRITE(ah, AR9285_RF2G5,
+                                 (reg_rf2g5_org & AR9285_RF2G5_IC50TX) |
+                                 AR9285_RF2G5_IC50TX_SET);
+               }
+               retv = ar9285_hw_cl_cal(ah, chan);
+               REG_WRITE(ah, AR9285_RF2G5, reg_rf2g5_org);
+       }
+       return retv;
+}
+
+static bool ar9002_hw_init_cal(struct ath_hw *ah, struct ath9k_channel *chan)
+{
+       struct ath_common *common = ath9k_hw_common(ah);
+
+       if (AR_SREV_9271(ah) || AR_SREV_9285_12_OR_LATER(ah)) {
+               if (!ar9285_hw_clc(ah, chan))
+                       return false;
+       } else {
+               if (AR_SREV_9280_10_OR_LATER(ah)) {
+                       if (!AR_SREV_9287_10_OR_LATER(ah))
+                               REG_CLR_BIT(ah, AR_PHY_ADC_CTL,
+                                           AR_PHY_ADC_CTL_OFF_PWDADC);
+                       REG_SET_BIT(ah, AR_PHY_AGC_CONTROL,
+                                   AR_PHY_AGC_CONTROL_FLTR_CAL);
+               }
+
+               /* Calibrate the AGC */
+               REG_WRITE(ah, AR_PHY_AGC_CONTROL,
+                         REG_READ(ah, AR_PHY_AGC_CONTROL) |
+                         AR_PHY_AGC_CONTROL_CAL);
+
+               /* Poll for offset calibration complete */
+               if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL,
+                                  AR_PHY_AGC_CONTROL_CAL,
+                                  0, AH_WAIT_TIMEOUT)) {
+                       ath_print(common, ATH_DBG_CALIBRATE,
+                                 "offset calibration failed to "
+                                 "complete in 1ms; noisy environment?\n");
+                       return false;
+               }
+
+               if (AR_SREV_9280_10_OR_LATER(ah)) {
+                       if (!AR_SREV_9287_10_OR_LATER(ah))
+                               REG_SET_BIT(ah, AR_PHY_ADC_CTL,
+                                           AR_PHY_ADC_CTL_OFF_PWDADC);
+                       REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
+                                   AR_PHY_AGC_CONTROL_FLTR_CAL);
+               }
+       }
+
+       /* Do PA Calibration */
+       ar9002_hw_pa_cal(ah, true);
+
+       /* Do NF Calibration after DC offset and other calibrations */
+       REG_WRITE(ah, AR_PHY_AGC_CONTROL,
+                 REG_READ(ah, AR_PHY_AGC_CONTROL) | AR_PHY_AGC_CONTROL_NF);
+
+       ah->cal_list = ah->cal_list_last = ah->cal_list_curr = NULL;
+
+       /* Enable IQ, ADC Gain and ADC DC offset CALs */
+       if (AR_SREV_9100(ah) || AR_SREV_9160_10_OR_LATER(ah)) {
+               if (ar9002_hw_iscal_supported(ah, ADC_GAIN_CAL)) {
+                       INIT_CAL(&ah->adcgain_caldata);
+                       INSERT_CAL(ah, &ah->adcgain_caldata);
+                       ath_print(common, ATH_DBG_CALIBRATE,
+                                 "enabling ADC Gain Calibration.\n");
+               }
+               if (ar9002_hw_iscal_supported(ah, ADC_DC_CAL)) {
+                       INIT_CAL(&ah->adcdc_caldata);
+                       INSERT_CAL(ah, &ah->adcdc_caldata);
+                       ath_print(common, ATH_DBG_CALIBRATE,
+                                 "enabling ADC DC Calibration.\n");
+               }
+               if (ar9002_hw_iscal_supported(ah, IQ_MISMATCH_CAL)) {
+                       INIT_CAL(&ah->iq_caldata);
+                       INSERT_CAL(ah, &ah->iq_caldata);
+                       ath_print(common, ATH_DBG_CALIBRATE,
+                                 "enabling IQ Calibration.\n");
+               }
+
+               ah->cal_list_curr = ah->cal_list;
+
+               if (ah->cal_list_curr)
+                       ath9k_hw_reset_calibration(ah, ah->cal_list_curr);
+       }
+
+       chan->CalValid = 0;
+
+       return true;
+}
+
+static const struct ath9k_percal_data iq_cal_multi_sample = {
+       IQ_MISMATCH_CAL,
+       MAX_CAL_SAMPLES,
+       PER_MIN_LOG_COUNT,
+       ar9002_hw_iqcal_collect,
+       ar9002_hw_iqcalibrate
+};
+static const struct ath9k_percal_data iq_cal_single_sample = {
+       IQ_MISMATCH_CAL,
+       MIN_CAL_SAMPLES,
+       PER_MAX_LOG_COUNT,
+       ar9002_hw_iqcal_collect,
+       ar9002_hw_iqcalibrate
+};
+static const struct ath9k_percal_data adc_gain_cal_multi_sample = {
+       ADC_GAIN_CAL,
+       MAX_CAL_SAMPLES,
+       PER_MIN_LOG_COUNT,
+       ar9002_hw_adc_gaincal_collect,
+       ar9002_hw_adc_gaincal_calibrate
+};
+static const struct ath9k_percal_data adc_gain_cal_single_sample = {
+       ADC_GAIN_CAL,
+       MIN_CAL_SAMPLES,
+       PER_MAX_LOG_COUNT,
+       ar9002_hw_adc_gaincal_collect,
+       ar9002_hw_adc_gaincal_calibrate
+};
+static const struct ath9k_percal_data adc_dc_cal_multi_sample = {
+       ADC_DC_CAL,
+       MAX_CAL_SAMPLES,
+       PER_MIN_LOG_COUNT,
+       ar9002_hw_adc_dccal_collect,
+       ar9002_hw_adc_dccal_calibrate
+};
+static const struct ath9k_percal_data adc_dc_cal_single_sample = {
+       ADC_DC_CAL,
+       MIN_CAL_SAMPLES,
+       PER_MAX_LOG_COUNT,
+       ar9002_hw_adc_dccal_collect,
+       ar9002_hw_adc_dccal_calibrate
+};
+static const struct ath9k_percal_data adc_init_dc_cal = {
+       ADC_DC_INIT_CAL,
+       MIN_CAL_SAMPLES,
+       INIT_LOG_COUNT,
+       ar9002_hw_adc_dccal_collect,
+       ar9002_hw_adc_dccal_calibrate
+};
+
+static void ar9002_hw_init_cal_settings(struct ath_hw *ah)
+{
+       if (AR_SREV_9100(ah)) {
+               ah->iq_caldata.calData = &iq_cal_multi_sample;
+               ah->supp_cals = IQ_MISMATCH_CAL;
+               return;
+       }
+
+       if (AR_SREV_9160_10_OR_LATER(ah)) {
+               if (AR_SREV_9280_10_OR_LATER(ah)) {
+                       ah->iq_caldata.calData = &iq_cal_single_sample;
+                       ah->adcgain_caldata.calData =
+                               &adc_gain_cal_single_sample;
+                       ah->adcdc_caldata.calData =
+                               &adc_dc_cal_single_sample;
+                       ah->adcdc_calinitdata.calData =
+                               &adc_init_dc_cal;
+               } else {
+                       ah->iq_caldata.calData = &iq_cal_multi_sample;
+                       ah->adcgain_caldata.calData =
+                               &adc_gain_cal_multi_sample;
+                       ah->adcdc_caldata.calData =
+                               &adc_dc_cal_multi_sample;
+                       ah->adcdc_calinitdata.calData =
+                               &adc_init_dc_cal;
+               }
+               ah->supp_cals = ADC_GAIN_CAL | ADC_DC_CAL | IQ_MISMATCH_CAL;
+       }
+}
+
+void ar9002_hw_attach_calib_ops(struct ath_hw *ah)
+{
+       struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
+       struct ath_hw_ops *ops = ath9k_hw_ops(ah);
+
+       priv_ops->init_cal_settings = ar9002_hw_init_cal_settings;
+       priv_ops->init_cal = ar9002_hw_init_cal;
+       priv_ops->setup_calibration = ar9002_hw_setup_calibration;
+       priv_ops->iscal_supported = ar9002_hw_iscal_supported;
+
+       ops->calibrate = ar9002_hw_calibrate;
+}
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_hw.c b/drivers/net/wireless/ath/ath9k/ar9002_hw.c
new file mode 100644 (file)
index 0000000..adb33b3
--- /dev/null
@@ -0,0 +1,593 @@
+/*
+ * Copyright (c) 2008-2010 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT 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 "hw.h"
+#include "ar5008_initvals.h"
+#include "ar9001_initvals.h"
+#include "ar9002_initvals.h"
+
+/* General hardware code for the A5008/AR9001/AR9002 hadware families */
+
+static bool ar9002_hw_macversion_supported(u32 macversion)
+{
+       switch (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:
+               return true;
+       default:
+               break;
+       }
+       return false;
+}
+
+static void ar9002_hw_init_mode_regs(struct ath_hw *ah)
+{
+       if (AR_SREV_9271(ah)) {
+               INIT_INI_ARRAY(&ah->iniModes, ar9271Modes_9271,
+                              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;
+       }
+
+       if (AR_SREV_9287_11_OR_LATER(ah)) {
+               INIT_INI_ARRAY(&ah->iniModes, ar9287Modes_9287_1_1,
+                               ARRAY_SIZE(ar9287Modes_9287_1_1), 6);
+               INIT_INI_ARRAY(&ah->iniCommon, ar9287Common_9287_1_1,
+                               ARRAY_SIZE(ar9287Common_9287_1_1), 2);
+               if (ah->config.pcie_clock_req)
+                       INIT_INI_ARRAY(&ah->iniPcieSerdes,
+                       ar9287PciePhy_clkreq_off_L1_9287_1_1,
+                       ARRAY_SIZE(ar9287PciePhy_clkreq_off_L1_9287_1_1), 2);
+               else
+                       INIT_INI_ARRAY(&ah->iniPcieSerdes,
+                       ar9287PciePhy_clkreq_always_on_L1_9287_1_1,
+                       ARRAY_SIZE(ar9287PciePhy_clkreq_always_on_L1_9287_1_1),
+                                       2);
+       } else if (AR_SREV_9287_10_OR_LATER(ah)) {
+               INIT_INI_ARRAY(&ah->iniModes, ar9287Modes_9287_1_0,
+                               ARRAY_SIZE(ar9287Modes_9287_1_0), 6);
+               INIT_INI_ARRAY(&ah->iniCommon, ar9287Common_9287_1_0,
+                               ARRAY_SIZE(ar9287Common_9287_1_0), 2);
+
+               if (ah->config.pcie_clock_req)
+                       INIT_INI_ARRAY(&ah->iniPcieSerdes,
+                       ar9287PciePhy_clkreq_off_L1_9287_1_0,
+                       ARRAY_SIZE(ar9287PciePhy_clkreq_off_L1_9287_1_0), 2);
+               else
+                       INIT_INI_ARRAY(&ah->iniPcieSerdes,
+                       ar9287PciePhy_clkreq_always_on_L1_9287_1_0,
+                       ARRAY_SIZE(ar9287PciePhy_clkreq_always_on_L1_9287_1_0),
+                                 2);
+       } else if (AR_SREV_9285_12_OR_LATER(ah)) {
+
+
+               INIT_INI_ARRAY(&ah->iniModes, ar9285Modes_9285_1_2,
+                              ARRAY_SIZE(ar9285Modes_9285_1_2), 6);
+               INIT_INI_ARRAY(&ah->iniCommon, ar9285Common_9285_1_2,
+                              ARRAY_SIZE(ar9285Common_9285_1_2), 2);
+
+               if (ah->config.pcie_clock_req) {
+                       INIT_INI_ARRAY(&ah->iniPcieSerdes,
+                       ar9285PciePhy_clkreq_off_L1_9285_1_2,
+                       ARRAY_SIZE(ar9285PciePhy_clkreq_off_L1_9285_1_2), 2);
+               } else {
+                       INIT_INI_ARRAY(&ah->iniPcieSerdes,
+                       ar9285PciePhy_clkreq_always_on_L1_9285_1_2,
+                       ARRAY_SIZE(ar9285PciePhy_clkreq_always_on_L1_9285_1_2),
+                                 2);
+               }
+       } else if (AR_SREV_9285_10_OR_LATER(ah)) {
+               INIT_INI_ARRAY(&ah->iniModes, ar9285Modes_9285,
+                              ARRAY_SIZE(ar9285Modes_9285), 6);
+               INIT_INI_ARRAY(&ah->iniCommon, ar9285Common_9285,
+                              ARRAY_SIZE(ar9285Common_9285), 2);
+
+               if (ah->config.pcie_clock_req) {
+                       INIT_INI_ARRAY(&ah->iniPcieSerdes,
+                       ar9285PciePhy_clkreq_off_L1_9285,
+                       ARRAY_SIZE(ar9285PciePhy_clkreq_off_L1_9285), 2);
+               } else {
+                       INIT_INI_ARRAY(&ah->iniPcieSerdes,
+                       ar9285PciePhy_clkreq_always_on_L1_9285,
+                       ARRAY_SIZE(ar9285PciePhy_clkreq_always_on_L1_9285), 2);
+               }
+       } else if (AR_SREV_9280_20_OR_LATER(ah)) {
+               INIT_INI_ARRAY(&ah->iniModes, ar9280Modes_9280_2,
+                              ARRAY_SIZE(ar9280Modes_9280_2), 6);
+               INIT_INI_ARRAY(&ah->iniCommon, ar9280Common_9280_2,
+                              ARRAY_SIZE(ar9280Common_9280_2), 2);
+
+               if (ah->config.pcie_clock_req) {
+                       INIT_INI_ARRAY(&ah->iniPcieSerdes,
+                              ar9280PciePhy_clkreq_off_L1_9280,
+                              ARRAY_SIZE(ar9280PciePhy_clkreq_off_L1_9280), 2);
+               } else {
+                       INIT_INI_ARRAY(&ah->iniPcieSerdes,
+                              ar9280PciePhy_clkreq_always_on_L1_9280,
+                              ARRAY_SIZE(ar9280PciePhy_clkreq_always_on_L1_9280), 2);
+               }
+               INIT_INI_ARRAY(&ah->iniModesAdditional,
+                              ar9280Modes_fast_clock_9280_2,
+                              ARRAY_SIZE(ar9280Modes_fast_clock_9280_2), 3);
+       } else if (AR_SREV_9280_10_OR_LATER(ah)) {
+               INIT_INI_ARRAY(&ah->iniModes, ar9280Modes_9280,
+                              ARRAY_SIZE(ar9280Modes_9280), 6);
+               INIT_INI_ARRAY(&ah->iniCommon, ar9280Common_9280,
+                              ARRAY_SIZE(ar9280Common_9280), 2);
+       } else if (AR_SREV_9160_10_OR_LATER(ah)) {
+               INIT_INI_ARRAY(&ah->iniModes, ar5416Modes_9160,
+                              ARRAY_SIZE(ar5416Modes_9160), 6);
+               INIT_INI_ARRAY(&ah->iniCommon, ar5416Common_9160,
+                              ARRAY_SIZE(ar5416Common_9160), 2);
+               INIT_INI_ARRAY(&ah->iniBank0, ar5416Bank0_9160,
+                              ARRAY_SIZE(ar5416Bank0_9160), 2);
+               INIT_INI_ARRAY(&ah->iniBB_RfGain, ar5416BB_RfGain_9160,
+                              ARRAY_SIZE(ar5416BB_RfGain_9160), 3);
+               INIT_INI_ARRAY(&ah->iniBank1, ar5416Bank1_9160,
+                              ARRAY_SIZE(ar5416Bank1_9160), 2);
+               INIT_INI_ARRAY(&ah->iniBank2, ar5416Bank2_9160,
+                              ARRAY_SIZE(ar5416Bank2_9160), 2);
+               INIT_INI_ARRAY(&ah->iniBank3, ar5416Bank3_9160,
+                              ARRAY_SIZE(ar5416Bank3_9160), 3);
+               INIT_INI_ARRAY(&ah->iniBank6, ar5416Bank6_9160,
+                              ARRAY_SIZE(ar5416Bank6_9160), 3);
+               INIT_INI_ARRAY(&ah->iniBank6TPC, ar5416Bank6TPC_9160,
+                              ARRAY_SIZE(ar5416Bank6TPC_9160), 3);
+               INIT_INI_ARRAY(&ah->iniBank7, ar5416Bank7_9160,
+                              ARRAY_SIZE(ar5416Bank7_9160), 2);
+               if (AR_SREV_9160_11(ah)) {
+                       INIT_INI_ARRAY(&ah->iniAddac,
+                                      ar5416Addac_91601_1,
+                                      ARRAY_SIZE(ar5416Addac_91601_1), 2);
+               } else {
+                       INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac_9160,
+                                      ARRAY_SIZE(ar5416Addac_9160), 2);
+               }
+       } else if (AR_SREV_9100_OR_LATER(ah)) {
+               INIT_INI_ARRAY(&ah->iniModes, ar5416Modes_9100,
+                              ARRAY_SIZE(ar5416Modes_9100), 6);
+               INIT_INI_ARRAY(&ah->iniCommon, ar5416Common_9100,
+                              ARRAY_SIZE(ar5416Common_9100), 2);
+               INIT_INI_ARRAY(&ah->iniBank0, ar5416Bank0_9100,
+                              ARRAY_SIZE(ar5416Bank0_9100), 2);
+               INIT_INI_ARRAY(&ah->iniBB_RfGain, ar5416BB_RfGain_9100,
+                              ARRAY_SIZE(ar5416BB_RfGain_9100), 3);
+               INIT_INI_ARRAY(&ah->iniBank1, ar5416Bank1_9100,
+                              ARRAY_SIZE(ar5416Bank1_9100), 2);
+               INIT_INI_ARRAY(&ah->iniBank2, ar5416Bank2_9100,
+                              ARRAY_SIZE(ar5416Bank2_9100), 2);
+               INIT_INI_ARRAY(&ah->iniBank3, ar5416Bank3_9100,
+                              ARRAY_SIZE(ar5416Bank3_9100), 3);
+               INIT_INI_ARRAY(&ah->iniBank6, ar5416Bank6_9100,
+                              ARRAY_SIZE(ar5416Bank6_9100), 3);
+               INIT_INI_ARRAY(&ah->iniBank6TPC, ar5416Bank6TPC_9100,
+                              ARRAY_SIZE(ar5416Bank6TPC_9100), 3);
+               INIT_INI_ARRAY(&ah->iniBank7, ar5416Bank7_9100,
+                              ARRAY_SIZE(ar5416Bank7_9100), 2);
+               INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac_9100,
+                              ARRAY_SIZE(ar5416Addac_9100), 2);
+       } else {
+               INIT_INI_ARRAY(&ah->iniModes, ar5416Modes,
+                              ARRAY_SIZE(ar5416Modes), 6);
+               INIT_INI_ARRAY(&ah->iniCommon, ar5416Common,
+                              ARRAY_SIZE(ar5416Common), 2);
+               INIT_INI_ARRAY(&ah->iniBank0, ar5416Bank0,
+                              ARRAY_SIZE(ar5416Bank0), 2);
+               INIT_INI_ARRAY(&ah->iniBB_RfGain, ar5416BB_RfGain,
+                              ARRAY_SIZE(ar5416BB_RfGain), 3);
+               INIT_INI_ARRAY(&ah->iniBank1, ar5416Bank1,
+                              ARRAY_SIZE(ar5416Bank1), 2);
+               INIT_INI_ARRAY(&ah->iniBank2, ar5416Bank2,
+                              ARRAY_SIZE(ar5416Bank2), 2);
+               INIT_INI_ARRAY(&ah->iniBank3, ar5416Bank3,
+                              ARRAY_SIZE(ar5416Bank3), 3);
+               INIT_INI_ARRAY(&ah->iniBank6, ar5416Bank6,
+                              ARRAY_SIZE(ar5416Bank6), 3);
+               INIT_INI_ARRAY(&ah->iniBank6TPC, ar5416Bank6TPC,
+                              ARRAY_SIZE(ar5416Bank6TPC), 3);
+               INIT_INI_ARRAY(&ah->iniBank7, ar5416Bank7,
+                              ARRAY_SIZE(ar5416Bank7), 2);
+               INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac,
+                              ARRAY_SIZE(ar5416Addac), 2);
+       }
+}
+
+/* Support for Japan ch.14 (2484) spread */
+void ar9002_hw_cck_chan14_spread(struct ath_hw *ah)
+{
+       if (AR_SREV_9287_11_OR_LATER(ah)) {
+               INIT_INI_ARRAY(&ah->iniCckfirNormal,
+                      ar9287Common_normal_cck_fir_coeff_92871_1,
+                      ARRAY_SIZE(ar9287Common_normal_cck_fir_coeff_92871_1),
+                      2);
+               INIT_INI_ARRAY(&ah->iniCckfirJapan2484,
+                      ar9287Common_japan_2484_cck_fir_coeff_92871_1,
+                      ARRAY_SIZE(ar9287Common_japan_2484_cck_fir_coeff_92871_1),
+                      2);
+       }
+}
+
+static void ar9280_20_hw_init_rxgain_ini(struct ath_hw *ah)
+{
+       u32 rxgain_type;
+
+       if (ah->eep_ops->get_eeprom(ah, EEP_MINOR_REV) >=
+           AR5416_EEP_MINOR_VER_17) {
+               rxgain_type = ah->eep_ops->get_eeprom(ah, EEP_RXGAIN_TYPE);
+
+               if (rxgain_type == AR5416_EEP_RXGAIN_13DB_BACKOFF)
+                       INIT_INI_ARRAY(&ah->iniModesRxGain,
+                       ar9280Modes_backoff_13db_rxgain_9280_2,
+                       ARRAY_SIZE(ar9280Modes_backoff_13db_rxgain_9280_2), 6);
+               else if (rxgain_type == AR5416_EEP_RXGAIN_23DB_BACKOFF)
+                       INIT_INI_ARRAY(&ah->iniModesRxGain,
+                       ar9280Modes_backoff_23db_rxgain_9280_2,
+                       ARRAY_SIZE(ar9280Modes_backoff_23db_rxgain_9280_2), 6);
+               else
+                       INIT_INI_ARRAY(&ah->iniModesRxGain,
+                       ar9280Modes_original_rxgain_9280_2,
+                       ARRAY_SIZE(ar9280Modes_original_rxgain_9280_2), 6);
+       } else {
+               INIT_INI_ARRAY(&ah->iniModesRxGain,
+                       ar9280Modes_original_rxgain_9280_2,
+                       ARRAY_SIZE(ar9280Modes_original_rxgain_9280_2), 6);
+       }
+}
+
+static void ar9280_20_hw_init_txgain_ini(struct ath_hw *ah)
+{
+       u32 txgain_type;
+
+       if (ah->eep_ops->get_eeprom(ah, EEP_MINOR_REV) >=
+           AR5416_EEP_MINOR_VER_19) {
+               txgain_type = ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE);
+
+               if (txgain_type == AR5416_EEP_TXGAIN_HIGH_POWER)
+                       INIT_INI_ARRAY(&ah->iniModesTxGain,
+                       ar9280Modes_high_power_tx_gain_9280_2,
+                       ARRAY_SIZE(ar9280Modes_high_power_tx_gain_9280_2), 6);
+               else
+                       INIT_INI_ARRAY(&ah->iniModesTxGain,
+                       ar9280Modes_original_tx_gain_9280_2,
+                       ARRAY_SIZE(ar9280Modes_original_tx_gain_9280_2), 6);
+       } else {
+               INIT_INI_ARRAY(&ah->iniModesTxGain,
+               ar9280Modes_original_tx_gain_9280_2,
+               ARRAY_SIZE(ar9280Modes_original_tx_gain_9280_2), 6);
+       }
+}
+
+static void ar9002_hw_init_mode_gain_regs(struct ath_hw *ah)
+{
+       if (AR_SREV_9287_11_OR_LATER(ah))
+               INIT_INI_ARRAY(&ah->iniModesRxGain,
+               ar9287Modes_rx_gain_9287_1_1,
+               ARRAY_SIZE(ar9287Modes_rx_gain_9287_1_1), 6);
+       else if (AR_SREV_9287_10(ah))
+               INIT_INI_ARRAY(&ah->iniModesRxGain,
+               ar9287Modes_rx_gain_9287_1_0,
+               ARRAY_SIZE(ar9287Modes_rx_gain_9287_1_0), 6);
+       else if (AR_SREV_9280_20(ah))
+               ar9280_20_hw_init_rxgain_ini(ah);
+
+       if (AR_SREV_9287_11_OR_LATER(ah)) {
+               INIT_INI_ARRAY(&ah->iniModesTxGain,
+               ar9287Modes_tx_gain_9287_1_1,
+               ARRAY_SIZE(ar9287Modes_tx_gain_9287_1_1), 6);
+       } else if (AR_SREV_9287_10(ah)) {
+               INIT_INI_ARRAY(&ah->iniModesTxGain,
+               ar9287Modes_tx_gain_9287_1_0,
+               ARRAY_SIZE(ar9287Modes_tx_gain_9287_1_0), 6);
+       } else if (AR_SREV_9280_20(ah)) {
+               ar9280_20_hw_init_txgain_ini(ah);
+       } else if (AR_SREV_9285_12_OR_LATER(ah)) {
+               u32 txgain_type = ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE);
+
+               /* txgain table */
+               if (txgain_type == AR5416_EEP_TXGAIN_HIGH_POWER) {
+                       if (AR_SREV_9285E_20(ah)) {
+                               INIT_INI_ARRAY(&ah->iniModesTxGain,
+                               ar9285Modes_XE2_0_high_power,
+                               ARRAY_SIZE(
+                                 ar9285Modes_XE2_0_high_power), 6);
+                       } else {
+                               INIT_INI_ARRAY(&ah->iniModesTxGain,
+                               ar9285Modes_high_power_tx_gain_9285_1_2,
+                               ARRAY_SIZE(
+                                 ar9285Modes_high_power_tx_gain_9285_1_2), 6);
+                       }
+               } else {
+                       if (AR_SREV_9285E_20(ah)) {
+                               INIT_INI_ARRAY(&ah->iniModesTxGain,
+                               ar9285Modes_XE2_0_normal_power,
+                               ARRAY_SIZE(
+                                 ar9285Modes_XE2_0_normal_power), 6);
+                       } else {
+                               INIT_INI_ARRAY(&ah->iniModesTxGain,
+                               ar9285Modes_original_tx_gain_9285_1_2,
+                               ARRAY_SIZE(
+                                 ar9285Modes_original_tx_gain_9285_1_2), 6);
+                       }
+               }
+       }
+}
+
+/*
+ * Helper for ASPM support.
+ *
+ * Disable PLL when in L0s as well as receiver clock when in L1.
+ * This power saving option must be enabled through the SerDes.
+ *
+ * Programming the SerDes must go through the same 288 bit serial shift
+ * register as the other analog registers.  Hence the 9 writes.
+ */
+static void ar9002_hw_configpcipowersave(struct ath_hw *ah,
+                                        int restore,
+                                        int power_off)
+{
+       u8 i;
+       u32 val;
+
+       if (ah->is_pciexpress != true)
+               return;
+
+       /* Do not touch SerDes registers */
+       if (ah->config.pcie_powersave_enable == 2)
+               return;
+
+       /* Nothing to do on restore for 11N */
+       if (!restore) {
+               if (AR_SREV_9280_20_OR_LATER(ah)) {
+                       /*
+                        * AR9280 2.0 or later chips use SerDes values from the
+                        * initvals.h initialized depending on chipset during
+                        * __ath9k_hw_init()
+                        */
+                       for (i = 0; i < ah->iniPcieSerdes.ia_rows; i++) {
+                               REG_WRITE(ah, INI_RA(&ah->iniPcieSerdes, i, 0),
+                                         INI_RA(&ah->iniPcieSerdes, i, 1));
+                       }
+               } else if (AR_SREV_9280(ah) &&
+                          (ah->hw_version.macRev == AR_SREV_REVISION_9280_10)) {
+                       REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fd00);
+                       REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924);
+
+                       /* RX shut off when elecidle is asserted */
+                       REG_WRITE(ah, AR_PCIE_SERDES, 0xa8000019);
+                       REG_WRITE(ah, AR_PCIE_SERDES, 0x13160820);
+                       REG_WRITE(ah, AR_PCIE_SERDES, 0xe5980560);
+
+                       /* Shut off CLKREQ active in L1 */
+                       if (ah->config.pcie_clock_req)
+                               REG_WRITE(ah, AR_PCIE_SERDES, 0x401deffc);
+                       else
+                               REG_WRITE(ah, AR_PCIE_SERDES, 0x401deffd);
+
+                       REG_WRITE(ah, AR_PCIE_SERDES, 0x1aaabe40);
+                       REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554);
+                       REG_WRITE(ah, AR_PCIE_SERDES, 0x00043007);
+
+                       /* Load the new settings */
+                       REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
+
+               } else {
+                       REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fc00);
+                       REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924);
+
+                       /* RX shut off when elecidle is asserted */
+                       REG_WRITE(ah, AR_PCIE_SERDES, 0x28000039);
+                       REG_WRITE(ah, AR_PCIE_SERDES, 0x53160824);
+                       REG_WRITE(ah, AR_PCIE_SERDES, 0xe5980579);
+
+                       /*
+                        * Ignore ah->ah_config.pcie_clock_req setting for
+                        * pre-AR9280 11n
+                        */
+                       REG_WRITE(ah, AR_PCIE_SERDES, 0x001defff);
+
+                       REG_WRITE(ah, AR_PCIE_SERDES, 0x1aaabe40);
+                       REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554);
+                       REG_WRITE(ah, AR_PCIE_SERDES, 0x000e3007);
+
+                       /* Load the new settings */
+                       REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
+               }
+
+               udelay(1000);
+
+               /* set bit 19 to allow forcing of pcie core into L1 state */
+               REG_SET_BIT(ah, AR_PCIE_PM_CTRL, AR_PCIE_PM_CTRL_ENA);
+
+               /* Several PCIe massages to ensure proper behaviour */
+               if (ah->config.pcie_waen) {
+                       val = ah->config.pcie_waen;
+                       if (!power_off)
+                               val &= (~AR_WA_D3_L1_DISABLE);
+               } else {
+                       if (AR_SREV_9285(ah) || AR_SREV_9271(ah) ||
+                           AR_SREV_9287(ah)) {
+                               val = AR9285_WA_DEFAULT;
+                               if (!power_off)
+                                       val &= (~AR_WA_D3_L1_DISABLE);
+                       } else if (AR_SREV_9280(ah)) {
+                               /*
+                                * On AR9280 chips bit 22 of 0x4004 needs to be
+                                * set otherwise card may disappear.
+                                */
+                               val = AR9280_WA_DEFAULT;
+                               if (!power_off)
+                                       val &= (~AR_WA_D3_L1_DISABLE);
+                       } else
+                               val = AR_WA_DEFAULT;
+               }
+
+               REG_WRITE(ah, AR_WA, val);
+       }
+
+       if (power_off) {
+               /*
+                * Set PCIe workaround bits
+                * bit 14 in WA register (disable L1) should only
+                * be set when device enters D3 and be cleared
+                * when device comes back to D0.
+                */
+               if (ah->config.pcie_waen) {
+                       if (ah->config.pcie_waen & AR_WA_D3_L1_DISABLE)
+                               REG_SET_BIT(ah, AR_WA, AR_WA_D3_L1_DISABLE);
+               } else {
+                       if (((AR_SREV_9285(ah) || AR_SREV_9271(ah) ||
+                             AR_SREV_9287(ah)) &&
+                            (AR9285_WA_DEFAULT & AR_WA_D3_L1_DISABLE)) ||
+                           (AR_SREV_9280(ah) &&
+                            (AR9280_WA_DEFAULT & AR_WA_D3_L1_DISABLE))) {
+                               REG_SET_BIT(ah, AR_WA, AR_WA_D3_L1_DISABLE);
+                       }
+               }
+       }
+}
+
+static int ar9002_hw_get_radiorev(struct ath_hw *ah)
+{
+       u32 val;
+       int i;
+
+       ENABLE_REGWRITE_BUFFER(ah);
+
+       REG_WRITE(ah, AR_PHY(0x36), 0x00007058);
+       for (i = 0; i < 8; i++)
+               REG_WRITE(ah, AR_PHY(0x20), 0x00010000);
+
+       REGWRITE_BUFFER_FLUSH(ah);
+       DISABLE_REGWRITE_BUFFER(ah);
+
+       val = (REG_READ(ah, AR_PHY(256)) >> 24) & 0xff;
+       val = ((val & 0xf0) >> 4) | ((val & 0x0f) << 4);
+
+       return ath9k_hw_reverse_bits(val, 8);
+}
+
+int ar9002_hw_rf_claim(struct ath_hw *ah)
+{
+       u32 val;
+
+       REG_WRITE(ah, AR_PHY(0), 0x00000007);
+
+       val = ar9002_hw_get_radiorev(ah);
+       switch (val & AR_RADIO_SREV_MAJOR) {
+       case 0:
+               val = AR_RAD5133_SREV_MAJOR;
+               break;
+       case AR_RAD5133_SREV_MAJOR:
+       case AR_RAD5122_SREV_MAJOR:
+       case AR_RAD2133_SREV_MAJOR:
+       case AR_RAD2122_SREV_MAJOR:
+               break;
+       default:
+               ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL,
+                         "Radio Chip Rev 0x%02X not supported\n",
+                         val & AR_RADIO_SREV_MAJOR);
+               return -EOPNOTSUPP;
+       }
+
+       ah->hw_version.analog5GhzRev = val;
+
+       return 0;
+}
+
+/*
+ * Enable ASYNC FIFO
+ *
+ * If Async FIFO is enabled, the following counters change as MAC now runs
+ * at 117 Mhz instead of 88/44MHz when async FIFO is disabled.
+ *
+ * The values below tested for ht40 2 chain.
+ * Overwrite the delay/timeouts initialized in process ini.
+ */
+void ar9002_hw_enable_async_fifo(struct ath_hw *ah)
+{
+       if (AR_SREV_9287_12_OR_LATER(ah)) {
+               REG_WRITE(ah, AR_D_GBL_IFS_SIFS,
+                         AR_D_GBL_IFS_SIFS_ASYNC_FIFO_DUR);
+               REG_WRITE(ah, AR_D_GBL_IFS_SLOT,
+                         AR_D_GBL_IFS_SLOT_ASYNC_FIFO_DUR);
+               REG_WRITE(ah, AR_D_GBL_IFS_EIFS,
+                         AR_D_GBL_IFS_EIFS_ASYNC_FIFO_DUR);
+
+               REG_WRITE(ah, AR_TIME_OUT, AR_TIME_OUT_ACK_CTS_ASYNC_FIFO_DUR);
+               REG_WRITE(ah, AR_USEC, AR_USEC_ASYNC_FIFO_DUR);
+
+               REG_SET_BIT(ah, AR_MAC_PCU_LOGIC_ANALYZER,
+                           AR_MAC_PCU_LOGIC_ANALYZER_DISBUG20768);
+               REG_RMW_FIELD(ah, AR_AHB_MODE, AR_AHB_CUSTOM_BURST_EN,
+                             AR_AHB_CUSTOM_BURST_ASYNC_FIFO_VAL);
+       }
+}
+
+/*
+ * We don't enable WEP aggregation on mac80211 but we keep this
+ * around for HAL unification purposes.
+ */
+void ar9002_hw_enable_wep_aggregation(struct ath_hw *ah)
+{
+       if (AR_SREV_9287_12_OR_LATER(ah)) {
+               REG_SET_BIT(ah, AR_PCU_MISC_MODE2,
+                               AR_PCU_MISC_MODE2_ENABLE_AGGWEP);
+       }
+}
+
+/* Sets up the AR5008/AR9001/AR9002 hardware familiy callbacks */
+void ar9002_hw_attach_ops(struct ath_hw *ah)
+{
+       struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
+       struct ath_hw_ops *ops = ath9k_hw_ops(ah);
+
+       priv_ops->init_mode_regs = ar9002_hw_init_mode_regs;
+       priv_ops->init_mode_gain_regs = ar9002_hw_init_mode_gain_regs;
+       priv_ops->macversion_supported = ar9002_hw_macversion_supported;
+
+       ops->config_pci_powersave = ar9002_hw_configpcipowersave;
+
+       ar5008_hw_attach_phy_ops(ah);
+       if (AR_SREV_9280_10_OR_LATER(ah))
+               ar9002_hw_attach_phy_ops(ah);
+
+       ar9002_hw_attach_calib_ops(ah);
+       ar9002_hw_attach_mac_ops(ah);
+}
similarity index 78%
rename from drivers/net/wireless/ath/ath9k/initvals.h
rename to drivers/net/wireless/ath/ath9k/ar9002_initvals.h
index 455e9d3b3f13cc47d5cd1acb51094e4f5f85cd34..f06313d3bad6458076aedfec79f5c870a470ba7e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008-2009 Atheros Communications Inc.
+ * Copyright (c) 2010 Atheros Communications Inc.
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-static const u32 ar5416Modes[][6] = {
-    { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 },
-    { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 },
-    { 0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180 },
-    { 0x000010f0, 0x0000a000, 0x00014000, 0x00016000, 0x0000b000, 0x00014008 },
-    { 0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00, 0x06e006e0 },
-    { 0x0000801c, 0x128d93a7, 0x128d93cf, 0x12e013d7, 0x12e013ab, 0x098813cf },
-    { 0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810, 0x08f04810 },
-    { 0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a, 0x0000320a },
-    { 0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303 },
-    { 0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200 },
-    { 0x00009824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
-    { 0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001 },
-    { 0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
-    { 0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007 },
-    { 0x00009844, 0x1372161e, 0x1372161e, 0x137216a0, 0x137216a0, 0x137216a0 },
-    { 0x00009848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
-    { 0x0000a848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
-    { 0x0000b848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
-    { 0x00009850, 0x6c48b4e0, 0x6d48b4e0, 0x6d48b0de, 0x6c48b0de, 0x6c48b0de },
-    { 0x00009858, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e },
-    { 0x0000985c, 0x31395d5e, 0x3139605e, 0x3139605e, 0x31395d5e, 0x31395d5e },
-    { 0x00009860, 0x00049d18, 0x00049d18, 0x00049d18, 0x00049d18, 0x00049d18 },
-    { 0x00009864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00 },
-    { 0x00009868, 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190 },
-    { 0x0000986c, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 },
-    { 0x00009914, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898, 0x000007d0 },
-    { 0x00009918, 0x000001b8, 0x00000370, 0x00000268, 0x00000134, 0x00000134 },
-    { 0x00009924, 0xd0058a0b, 0xd0058a0b, 0xd0058a0b, 0xd0058a0b, 0xd0058a0b },
-    { 0x00009944, 0xffb81020, 0xffb81020, 0xffb81020, 0xffb81020, 0xffb81020 },
-    { 0x00009960, 0x00000900, 0x00000900, 0x00012d80, 0x00012d80, 0x00012d80 },
-    { 0x0000a960, 0x00000900, 0x00000900, 0x00012d80, 0x00012d80, 0x00012d80 },
-    { 0x0000b960, 0x00000900, 0x00000900, 0x00012d80, 0x00012d80, 0x00012d80 },
-    { 0x00009964, 0x00000000, 0x00000000, 0x00001120, 0x00001120, 0x00001120 },
-    { 0x000099bc, 0x001a0a00, 0x001a0a00, 0x001a0a00, 0x001a0a00, 0x001a0a00 },
-    { 0x000099c0, 0x038919be, 0x038919be, 0x038919be, 0x038919be, 0x038919be },
-    { 0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77 },
-    { 0x000099c8, 0x6af6532c, 0x6af6532c, 0x6af6532c, 0x6af6532c, 0x6af6532c },
-    { 0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8 },
-    { 0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, 0x00046384 },
-    { 0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
-    { 0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
-    { 0x0000a204, 0x00000880, 0x00000880, 0x00000880, 0x00000880, 0x00000880 },
-    { 0x0000a208, 0xd6be4788, 0xd6be4788, 0xd03e4788, 0xd03e4788, 0xd03e4788 },
-    { 0x0000a20c, 0x002ec1e0, 0x002ec1e0, 0x002ac120, 0x002ac120, 0x002ac120 },
-    { 0x0000b20c, 0x002ec1e0, 0x002ec1e0, 0x002ac120, 0x002ac120, 0x002ac120 },
-    { 0x0000c20c, 0x002ec1e0, 0x002ec1e0, 0x002ac120, 0x002ac120, 0x002ac120 },
-    { 0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a },
-    { 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000 },
-    { 0x0000a274, 0x0a1a9caa, 0x0a1a9caa, 0x0a1a7caa, 0x0a1a7caa, 0x0a1a7caa },
-    { 0x0000a300, 0x18010000, 0x18010000, 0x18010000, 0x18010000, 0x18010000 },
-    { 0x0000a304, 0x30032602, 0x30032602, 0x2e032402, 0x2e032402, 0x2e032402 },
-    { 0x0000a308, 0x48073e06, 0x48073e06, 0x4a0a3c06, 0x4a0a3c06, 0x4a0a3c06 },
-    { 0x0000a30c, 0x560b4c0a, 0x560b4c0a, 0x621a540b, 0x621a540b, 0x621a540b },
-    { 0x0000a310, 0x641a600f, 0x641a600f, 0x764f6c1b, 0x764f6c1b, 0x764f6c1b },
-    { 0x0000a314, 0x7a4f6e1b, 0x7a4f6e1b, 0x845b7a5a, 0x845b7a5a, 0x845b7a5a },
-    { 0x0000a318, 0x8c5b7e5a, 0x8c5b7e5a, 0x950f8ccf, 0x950f8ccf, 0x950f8ccf },
-    { 0x0000a31c, 0x9d0f96cf, 0x9d0f96cf, 0xa5cf9b4f, 0xa5cf9b4f, 0xa5cf9b4f },
-    { 0x0000a320, 0xb51fa69f, 0xb51fa69f, 0xbddfaf1f, 0xbddfaf1f, 0xbddfaf1f },
-    { 0x0000a324, 0xcb3fbd07, 0xcb3fbcbf, 0xd1ffc93f, 0xd1ffc93f, 0xd1ffc93f },
-    { 0x0000a328, 0x0000d7bf, 0x0000d7bf, 0x00000000, 0x00000000, 0x00000000 },
-    { 0x0000a32c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
-    { 0x0000a330, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
-    { 0x0000a334, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
-};
-
-static const u32 ar5416Common[][2] = {
-    { 0x0000000c, 0x00000000 },
-    { 0x00000030, 0x00020015 },
-    { 0x00000034, 0x00000005 },
-    { 0x00000040, 0x00000000 },
-    { 0x00000044, 0x00000008 },
-    { 0x00000048, 0x00000008 },
-    { 0x0000004c, 0x00000010 },
-    { 0x00000050, 0x00000000 },
-    { 0x00000054, 0x0000001f },
-    { 0x00000800, 0x00000000 },
-    { 0x00000804, 0x00000000 },
-    { 0x00000808, 0x00000000 },
-    { 0x0000080c, 0x00000000 },
-    { 0x00000810, 0x00000000 },
-    { 0x00000814, 0x00000000 },
-    { 0x00000818, 0x00000000 },
-    { 0x0000081c, 0x00000000 },
-    { 0x00000820, 0x00000000 },
-    { 0x00000824, 0x00000000 },
-    { 0x00001040, 0x002ffc0f },
-    { 0x00001044, 0x002ffc0f },
-    { 0x00001048, 0x002ffc0f },
-    { 0x0000104c, 0x002ffc0f },
-    { 0x00001050, 0x002ffc0f },
-    { 0x00001054, 0x002ffc0f },
-    { 0x00001058, 0x002ffc0f },
-    { 0x0000105c, 0x002ffc0f },
-    { 0x00001060, 0x002ffc0f },
-    { 0x00001064, 0x002ffc0f },
-    { 0x00001230, 0x00000000 },
-    { 0x00001270, 0x00000000 },
-    { 0x00001038, 0x00000000 },
-    { 0x00001078, 0x00000000 },
-    { 0x000010b8, 0x00000000 },
-    { 0x000010f8, 0x00000000 },
-    { 0x00001138, 0x00000000 },
-    { 0x00001178, 0x00000000 },
-    { 0x000011b8, 0x00000000 },
-    { 0x000011f8, 0x00000000 },
-    { 0x00001238, 0x00000000 },
-    { 0x00001278, 0x00000000 },
-    { 0x000012b8, 0x00000000 },
-    { 0x000012f8, 0x00000000 },
-    { 0x00001338, 0x00000000 },
-    { 0x00001378, 0x00000000 },
-    { 0x000013b8, 0x00000000 },
-    { 0x000013f8, 0x00000000 },
-    { 0x00001438, 0x00000000 },
-    { 0x00001478, 0x00000000 },
-    { 0x000014b8, 0x00000000 },
-    { 0x000014f8, 0x00000000 },
-    { 0x00001538, 0x00000000 },
-    { 0x00001578, 0x00000000 },
-    { 0x000015b8, 0x00000000 },
-    { 0x000015f8, 0x00000000 },
-    { 0x00001638, 0x00000000 },
-    { 0x00001678, 0x00000000 },
-    { 0x000016b8, 0x00000000 },
-    { 0x000016f8, 0x00000000 },
-    { 0x00001738, 0x00000000 },
-    { 0x00001778, 0x00000000 },
-    { 0x000017b8, 0x00000000 },
-    { 0x000017f8, 0x00000000 },
-    { 0x0000103c, 0x00000000 },
-    { 0x0000107c, 0x00000000 },
-    { 0x000010bc, 0x00000000 },
-    { 0x000010fc, 0x00000000 },
-    { 0x0000113c, 0x00000000 },
-    { 0x0000117c, 0x00000000 },
-    { 0x000011bc, 0x00000000 },
-    { 0x000011fc, 0x00000000 },
-    { 0x0000123c, 0x00000000 },
-    { 0x0000127c, 0x00000000 },
-    { 0x000012bc, 0x00000000 },
-    { 0x000012fc, 0x00000000 },
-    { 0x0000133c, 0x00000000 },
-    { 0x0000137c, 0x00000000 },
-    { 0x000013bc, 0x00000000 },
-    { 0x000013fc, 0x00000000 },
-    { 0x0000143c, 0x00000000 },
-    { 0x0000147c, 0x00000000 },
-    { 0x00004030, 0x00000002 },
-    { 0x0000403c, 0x00000002 },
-    { 0x00007010, 0x00000000 },
-    { 0x00007038, 0x000004c2 },
-    { 0x00008004, 0x00000000 },
-    { 0x00008008, 0x00000000 },
-    { 0x0000800c, 0x00000000 },
-    { 0x00008018, 0x00000700 },
-    { 0x00008020, 0x00000000 },
-    { 0x00008038, 0x00000000 },
-    { 0x0000803c, 0x00000000 },
-    { 0x00008048, 0x40000000 },
-    { 0x00008054, 0x00000000 },
-    { 0x00008058, 0x00000000 },
-    { 0x0000805c, 0x000fc78f },
-    { 0x00008060, 0x0000000f },
-    { 0x00008064, 0x00000000 },
-    { 0x000080c0, 0x2a82301a },
-    { 0x000080c4, 0x05dc01e0 },
-    { 0x000080c8, 0x1f402710 },
-    { 0x000080cc, 0x01f40000 },
-    { 0x000080d0, 0x00001e00 },
-    { 0x000080d4, 0x00000000 },
-    { 0x000080d8, 0x00400000 },
-    { 0x000080e0, 0xffffffff },
-    { 0x000080e4, 0x0000ffff },
-    { 0x000080e8, 0x003f3f3f },
-    { 0x000080ec, 0x00000000 },
-    { 0x000080f0, 0x00000000 },
-    { 0x000080f4, 0x00000000 },
-    { 0x000080f8, 0x00000000 },
-    { 0x000080fc, 0x00020000 },
-    { 0x00008100, 0x00020000 },
-    { 0x00008104, 0x00000001 },
-    { 0x00008108, 0x00000052 },
-    { 0x0000810c, 0x00000000 },
-    { 0x00008110, 0x00000168 },
-    { 0x00008118, 0x000100aa },
-    { 0x0000811c, 0x00003210 },
-    { 0x00008124, 0x00000000 },
-    { 0x00008128, 0x00000000 },
-    { 0x0000812c, 0x00000000 },
-    { 0x00008130, 0x00000000 },
-    { 0x00008134, 0x00000000 },
-    { 0x00008138, 0x00000000 },
-    { 0x0000813c, 0x00000000 },
-    { 0x00008144, 0xffffffff },
-    { 0x00008168, 0x00000000 },
-    { 0x0000816c, 0x00000000 },
-    { 0x00008170, 0x32143320 },
-    { 0x00008174, 0xfaa4fa50 },
-    { 0x00008178, 0x00000100 },
-    { 0x0000817c, 0x00000000 },
-    { 0x000081c4, 0x00000000 },
-    { 0x000081ec, 0x00000000 },
-    { 0x000081f0, 0x00000000 },
-    { 0x000081f4, 0x00000000 },
-    { 0x000081f8, 0x00000000 },
-    { 0x000081fc, 0x00000000 },
-    { 0x00008200, 0x00000000 },
-    { 0x00008204, 0x00000000 },
-    { 0x00008208, 0x00000000 },
-    { 0x0000820c, 0x00000000 },
-    { 0x00008210, 0x00000000 },
-    { 0x00008214, 0x00000000 },
-    { 0x00008218, 0x00000000 },
-    { 0x0000821c, 0x00000000 },
-    { 0x00008220, 0x00000000 },
-    { 0x00008224, 0x00000000 },
-    { 0x00008228, 0x00000000 },
-    { 0x0000822c, 0x00000000 },
-    { 0x00008230, 0x00000000 },
-    { 0x00008234, 0x00000000 },
-    { 0x00008238, 0x00000000 },
-    { 0x0000823c, 0x00000000 },
-    { 0x00008240, 0x00100000 },
-    { 0x00008244, 0x0010f400 },
-    { 0x00008248, 0x00000100 },
-    { 0x0000824c, 0x0001e800 },
-    { 0x00008250, 0x00000000 },
-    { 0x00008254, 0x00000000 },
-    { 0x00008258, 0x00000000 },
-    { 0x0000825c, 0x400000ff },
-    { 0x00008260, 0x00080922 },
-    { 0x00008264, 0xa8000010 },
-    { 0x00008270, 0x00000000 },
-    { 0x00008274, 0x40000000 },
-    { 0x00008278, 0x003e4180 },
-    { 0x0000827c, 0x00000000 },
-    { 0x00008284, 0x0000002c },
-    { 0x00008288, 0x0000002c },
-    { 0x0000828c, 0x00000000 },
-    { 0x00008294, 0x00000000 },
-    { 0x00008298, 0x00000000 },
-    { 0x00008300, 0x00000000 },
-    { 0x00008304, 0x00000000 },
-    { 0x00008308, 0x00000000 },
-    { 0x0000830c, 0x00000000 },
-    { 0x00008310, 0x00000000 },
-    { 0x00008314, 0x00000000 },
-    { 0x00008318, 0x00000000 },
-    { 0x00008328, 0x00000000 },
-    { 0x0000832c, 0x00000007 },
-    { 0x00008330, 0x00000302 },
-    { 0x00008334, 0x00000e00 },
-    { 0x00008338, 0x00070000 },
-    { 0x0000833c, 0x00000000 },
-    { 0x00008340, 0x000107ff },
-    { 0x00009808, 0x00000000 },
-    { 0x0000980c, 0xad848e19 },
-    { 0x00009810, 0x7d14e000 },
-    { 0x00009814, 0x9c0a9f6b },
-    { 0x0000981c, 0x00000000 },
-    { 0x0000982c, 0x0000a000 },
-    { 0x00009830, 0x00000000 },
-    { 0x0000983c, 0x00200400 },
-    { 0x00009840, 0x206a002e },
-    { 0x0000984c, 0x1284233c },
-    { 0x00009854, 0x00000859 },
-    { 0x00009900, 0x00000000 },
-    { 0x00009904, 0x00000000 },
-    { 0x00009908, 0x00000000 },
-    { 0x0000990c, 0x00000000 },
-    { 0x0000991c, 0x10000fff },
-    { 0x00009920, 0x05100000 },
-    { 0x0000a920, 0x05100000 },
-    { 0x0000b920, 0x05100000 },
-    { 0x00009928, 0x00000001 },
-    { 0x0000992c, 0x00000004 },
-    { 0x00009934, 0x1e1f2022 },
-    { 0x00009938, 0x0a0b0c0d },
-    { 0x0000993c, 0x00000000 },
-    { 0x00009948, 0x9280b212 },
-    { 0x0000994c, 0x00020028 },
-    { 0x00009954, 0x5d50e188 },
-    { 0x00009958, 0x00081fff },
-    { 0x0000c95c, 0x004b6a8e },
-    { 0x0000c968, 0x000003ce },
-    { 0x00009970, 0x190fb515 },
-    { 0x00009974, 0x00000000 },
-    { 0x00009978, 0x00000001 },
-    { 0x0000997c, 0x00000000 },
-    { 0x00009980, 0x00000000 },
-    { 0x00009984, 0x00000000 },
-    { 0x00009988, 0x00000000 },
-    { 0x0000998c, 0x00000000 },
-    { 0x00009990, 0x00000000 },
-    { 0x00009994, 0x00000000 },
-    { 0x00009998, 0x00000000 },
-    { 0x0000999c, 0x00000000 },
-    { 0x000099a0, 0x00000000 },
-    { 0x000099a4, 0x00000001 },
-    { 0x000099a8, 0x001fff00 },
-    { 0x000099ac, 0x00000000 },
-    { 0x000099b0, 0x03051000 },
-    { 0x000099dc, 0x00000000 },
-    { 0x000099e0, 0x00000200 },
-    { 0x000099e4, 0xaaaaaaaa },
-    { 0x000099e8, 0x3c466478 },
-    { 0x000099ec, 0x000000aa },
-    { 0x000099fc, 0x00001042 },
-    { 0x00009b00, 0x00000000 },
-    { 0x00009b04, 0x00000001 },
-    { 0x00009b08, 0x00000002 },
-    { 0x00009b0c, 0x00000003 },
-    { 0x00009b10, 0x00000004 },
-    { 0x00009b14, 0x00000005 },
-    { 0x00009b18, 0x00000008 },
-    { 0x00009b1c, 0x00000009 },
-    { 0x00009b20, 0x0000000a },
-    { 0x00009b24, 0x0000000b },
-    { 0x00009b28, 0x0000000c },
-    { 0x00009b2c, 0x0000000d },
-    { 0x00009b30, 0x00000010 },
-    { 0x00009b34, 0x00000011 },
-    { 0x00009b38, 0x00000012 },
-    { 0x00009b3c, 0x00000013 },
-    { 0x00009b40, 0x00000014 },
-    { 0x00009b44, 0x00000015 },
-    { 0x00009b48, 0x00000018 },
-    { 0x00009b4c, 0x00000019 },
-    { 0x00009b50, 0x0000001a },
-    { 0x00009b54, 0x0000001b },
-    { 0x00009b58, 0x0000001c },
-    { 0x00009b5c, 0x0000001d },
-    { 0x00009b60, 0x00000020 },
-    { 0x00009b64, 0x00000021 },
-    { 0x00009b68, 0x00000022 },
-    { 0x00009b6c, 0x00000023 },
-    { 0x00009b70, 0x00000024 },
-    { 0x00009b74, 0x00000025 },
-    { 0x00009b78, 0x00000028 },
-    { 0x00009b7c, 0x00000029 },
-    { 0x00009b80, 0x0000002a },
-    { 0x00009b84, 0x0000002b },
-    { 0x00009b88, 0x0000002c },
-    { 0x00009b8c, 0x0000002d },
-    { 0x00009b90, 0x00000030 },
-    { 0x00009b94, 0x00000031 },
-    { 0x00009b98, 0x00000032 },
-    { 0x00009b9c, 0x00000033 },
-    { 0x00009ba0, 0x00000034 },
-    { 0x00009ba4, 0x00000035 },
-    { 0x00009ba8, 0x00000035 },
-    { 0x00009bac, 0x00000035 },
-    { 0x00009bb0, 0x00000035 },
-    { 0x00009bb4, 0x00000035 },
-    { 0x00009bb8, 0x00000035 },
-    { 0x00009bbc, 0x00000035 },
-    { 0x00009bc0, 0x00000035 },
-    { 0x00009bc4, 0x00000035 },
-    { 0x00009bc8, 0x00000035 },
-    { 0x00009bcc, 0x00000035 },
-    { 0x00009bd0, 0x00000035 },
-    { 0x00009bd4, 0x00000035 },
-    { 0x00009bd8, 0x00000035 },
-    { 0x00009bdc, 0x00000035 },
-    { 0x00009be0, 0x00000035 },
-    { 0x00009be4, 0x00000035 },
-    { 0x00009be8, 0x00000035 },
-    { 0x00009bec, 0x00000035 },
-    { 0x00009bf0, 0x00000035 },
-    { 0x00009bf4, 0x00000035 },
-    { 0x00009bf8, 0x00000010 },
-    { 0x00009bfc, 0x0000001a },
-    { 0x0000a210, 0x40806333 },
-    { 0x0000a214, 0x00106c10 },
-    { 0x0000a218, 0x009c4060 },
-    { 0x0000a220, 0x018830c6 },
-    { 0x0000a224, 0x00000400 },
-    { 0x0000a228, 0x00000bb5 },
-    { 0x0000a22c, 0x00000011 },
-    { 0x0000a234, 0x20202020 },
-    { 0x0000a238, 0x20202020 },
-    { 0x0000a23c, 0x13c889af },
-    { 0x0000a240, 0x38490a20 },
-    { 0x0000a244, 0x00007bb6 },
-    { 0x0000a248, 0x0fff3ffc },
-    { 0x0000a24c, 0x00000001 },
-    { 0x0000a250, 0x0000a000 },
-    { 0x0000a254, 0x00000000 },
-    { 0x0000a258, 0x0cc75380 },
-    { 0x0000a25c, 0x0f0f0f01 },
-    { 0x0000a260, 0xdfa91f01 },
-    { 0x0000a268, 0x00000000 },
-    { 0x0000a26c, 0x0e79e5c6 },
-    { 0x0000b26c, 0x0e79e5c6 },
-    { 0x0000c26c, 0x0e79e5c6 },
-    { 0x0000d270, 0x00820820 },
-    { 0x0000a278, 0x1ce739ce },
-    { 0x0000a27c, 0x051701ce },
-    { 0x0000a338, 0x00000000 },
-    { 0x0000a33c, 0x00000000 },
-    { 0x0000a340, 0x00000000 },
-    { 0x0000a344, 0x00000000 },
-    { 0x0000a348, 0x3fffffff },
-    { 0x0000a34c, 0x3fffffff },
-    { 0x0000a350, 0x3fffffff },
-    { 0x0000a354, 0x0003ffff },
-    { 0x0000a358, 0x79a8aa1f },
-    { 0x0000d35c, 0x07ffffef },
-    { 0x0000d360, 0x0fffffe7 },
-    { 0x0000d364, 0x17ffffe5 },
-    { 0x0000d368, 0x1fffffe4 },
-    { 0x0000d36c, 0x37ffffe3 },
-    { 0x0000d370, 0x3fffffe3 },
-    { 0x0000d374, 0x57ffffe3 },
-    { 0x0000d378, 0x5fffffe2 },
-    { 0x0000d37c, 0x7fffffe2 },
-    { 0x0000d380, 0x7f3c7bba },
-    { 0x0000d384, 0xf3307ff0 },
-    { 0x0000a388, 0x08000000 },
-    { 0x0000a38c, 0x20202020 },
-    { 0x0000a390, 0x20202020 },
-    { 0x0000a394, 0x1ce739ce },
-    { 0x0000a398, 0x000001ce },
-    { 0x0000a39c, 0x00000001 },
-    { 0x0000a3a0, 0x00000000 },
-    { 0x0000a3a4, 0x00000000 },
-    { 0x0000a3a8, 0x00000000 },
-    { 0x0000a3ac, 0x00000000 },
-    { 0x0000a3b0, 0x00000000 },
-    { 0x0000a3b4, 0x00000000 },
-    { 0x0000a3b8, 0x00000000 },
-    { 0x0000a3bc, 0x00000000 },
-    { 0x0000a3c0, 0x00000000 },
-    { 0x0000a3c4, 0x00000000 },
-    { 0x0000a3c8, 0x00000246 },
-    { 0x0000a3cc, 0x20202020 },
-    { 0x0000a3d0, 0x20202020 },
-    { 0x0000a3d4, 0x20202020 },
-    { 0x0000a3dc, 0x1ce739ce },
-    { 0x0000a3e0, 0x000001ce },
-};
-
-static const u32 ar5416Bank0[][2] = {
-    { 0x000098b0, 0x1e5795e5 },
-    { 0x000098e0, 0x02008020 },
-};
-
-static const u32 ar5416BB_RfGain[][3] = {
-    { 0x00009a00, 0x00000000, 0x00000000 },
-    { 0x00009a04, 0x00000040, 0x00000040 },
-    { 0x00009a08, 0x00000080, 0x00000080 },
-    { 0x00009a0c, 0x000001a1, 0x00000141 },
-    { 0x00009a10, 0x000001e1, 0x00000181 },
-    { 0x00009a14, 0x00000021, 0x000001c1 },
-    { 0x00009a18, 0x00000061, 0x00000001 },
-    { 0x00009a1c, 0x00000168, 0x00000041 },
-    { 0x00009a20, 0x000001a8, 0x000001a8 },
-    { 0x00009a24, 0x000001e8, 0x000001e8 },
-    { 0x00009a28, 0x00000028, 0x00000028 },
-    { 0x00009a2c, 0x00000068, 0x00000068 },
-    { 0x00009a30, 0x00000189, 0x000000a8 },
-    { 0x00009a34, 0x000001c9, 0x00000169 },
-    { 0x00009a38, 0x00000009, 0x000001a9 },
-    { 0x00009a3c, 0x00000049, 0x000001e9 },
-    { 0x00009a40, 0x00000089, 0x00000029 },
-    { 0x00009a44, 0x00000170, 0x00000069 },
-    { 0x00009a48, 0x000001b0, 0x00000190 },
-    { 0x00009a4c, 0x000001f0, 0x000001d0 },
-    { 0x00009a50, 0x00000030, 0x00000010 },
-    { 0x00009a54, 0x00000070, 0x00000050 },
-    { 0x00009a58, 0x00000191, 0x00000090 },
-    { 0x00009a5c, 0x000001d1, 0x00000151 },
-    { 0x00009a60, 0x00000011, 0x00000191 },
-    { 0x00009a64, 0x00000051, 0x000001d1 },
-    { 0x00009a68, 0x00000091, 0x00000011 },
-    { 0x00009a6c, 0x000001b8, 0x00000051 },
-    { 0x00009a70, 0x000001f8, 0x00000198 },
-    { 0x00009a74, 0x00000038, 0x000001d8 },
-    { 0x00009a78, 0x00000078, 0x00000018 },
-    { 0x00009a7c, 0x00000199, 0x00000058 },
-    { 0x00009a80, 0x000001d9, 0x00000098 },
-    { 0x00009a84, 0x00000019, 0x00000159 },
-    { 0x00009a88, 0x00000059, 0x00000199 },
-    { 0x00009a8c, 0x00000099, 0x000001d9 },
-    { 0x00009a90, 0x000000d9, 0x00000019 },
-    { 0x00009a94, 0x000000f9, 0x00000059 },
-    { 0x00009a98, 0x000000f9, 0x00000099 },
-    { 0x00009a9c, 0x000000f9, 0x000000d9 },
-    { 0x00009aa0, 0x000000f9, 0x000000f9 },
-    { 0x00009aa4, 0x000000f9, 0x000000f9 },
-    { 0x00009aa8, 0x000000f9, 0x000000f9 },
-    { 0x00009aac, 0x000000f9, 0x000000f9 },
-    { 0x00009ab0, 0x000000f9, 0x000000f9 },
-    { 0x00009ab4, 0x000000f9, 0x000000f9 },
-    { 0x00009ab8, 0x000000f9, 0x000000f9 },
-    { 0x00009abc, 0x000000f9, 0x000000f9 },
-    { 0x00009ac0, 0x000000f9, 0x000000f9 },
-    { 0x00009ac4, 0x000000f9, 0x000000f9 },
-    { 0x00009ac8, 0x000000f9, 0x000000f9 },
-    { 0x00009acc, 0x000000f9, 0x000000f9 },
-    { 0x00009ad0, 0x000000f9, 0x000000f9 },
-    { 0x00009ad4, 0x000000f9, 0x000000f9 },
-    { 0x00009ad8, 0x000000f9, 0x000000f9 },
-    { 0x00009adc, 0x000000f9, 0x000000f9 },
-    { 0x00009ae0, 0x000000f9, 0x000000f9 },
-    { 0x00009ae4, 0x000000f9, 0x000000f9 },
-    { 0x00009ae8, 0x000000f9, 0x000000f9 },
-    { 0x00009aec, 0x000000f9, 0x000000f9 },
-    { 0x00009af0, 0x000000f9, 0x000000f9 },
-    { 0x00009af4, 0x000000f9, 0x000000f9 },
-    { 0x00009af8, 0x000000f9, 0x000000f9 },
-    { 0x00009afc, 0x000000f9, 0x000000f9 },
-};
-
-static const u32 ar5416Bank1[][2] = {
-    { 0x000098b0, 0x02108421 },
-    { 0x000098ec, 0x00000008 },
-};
-
-static const u32 ar5416Bank2[][2] = {
-    { 0x000098b0, 0x0e73ff17 },
-    { 0x000098e0, 0x00000420 },
-};
-
-static const u32 ar5416Bank3[][3] = {
-    { 0x000098f0, 0x01400018, 0x01c00018 },
-};
-
-static const u32 ar5416Bank6[][3] = {
-
-    { 0x0000989c, 0x00000000, 0x00000000 },
-    { 0x0000989c, 0x00000000, 0x00000000 },
-    { 0x0000989c, 0x00000000, 0x00000000 },
-    { 0x0000989c, 0x00e00000, 0x00e00000 },
-    { 0x0000989c, 0x005e0000, 0x005e0000 },
-    { 0x0000989c, 0x00120000, 0x00120000 },
-    { 0x0000989c, 0x00620000, 0x00620000 },
-    { 0x0000989c, 0x00020000, 0x00020000 },
-    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
-    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
-    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
-    { 0x0000989c, 0x40ff0000, 0x40ff0000 },
-    { 0x0000989c, 0x005f0000, 0x005f0000 },
-    { 0x0000989c, 0x00870000, 0x00870000 },
-    { 0x0000989c, 0x00f90000, 0x00f90000 },
-    { 0x0000989c, 0x007b0000, 0x007b0000 },
-    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
-    { 0x0000989c, 0x00f50000, 0x00f50000 },
-    { 0x0000989c, 0x00dc0000, 0x00dc0000 },
-    { 0x0000989c, 0x00110000, 0x00110000 },
-    { 0x0000989c, 0x006100a8, 0x006100a8 },
-    { 0x0000989c, 0x004210a2, 0x004210a2 },
-    { 0x0000989c, 0x0014008f, 0x0014008f },
-    { 0x0000989c, 0x00c40003, 0x00c40003 },
-    { 0x0000989c, 0x003000f2, 0x003000f2 },
-    { 0x0000989c, 0x00440016, 0x00440016 },
-    { 0x0000989c, 0x00410040, 0x00410040 },
-    { 0x0000989c, 0x0001805e, 0x0001805e },
-    { 0x0000989c, 0x0000c0ab, 0x0000c0ab },
-    { 0x0000989c, 0x000000f1, 0x000000f1 },
-    { 0x0000989c, 0x00002081, 0x00002081 },
-    { 0x0000989c, 0x000000d4, 0x000000d4 },
-    { 0x000098d0, 0x0000000f, 0x0010000f },
-};
-
-static const u32 ar5416Bank6TPC[][3] = {
-    { 0x0000989c, 0x00000000, 0x00000000 },
-    { 0x0000989c, 0x00000000, 0x00000000 },
-    { 0x0000989c, 0x00000000, 0x00000000 },
-    { 0x0000989c, 0x00e00000, 0x00e00000 },
-    { 0x0000989c, 0x005e0000, 0x005e0000 },
-    { 0x0000989c, 0x00120000, 0x00120000 },
-    { 0x0000989c, 0x00620000, 0x00620000 },
-    { 0x0000989c, 0x00020000, 0x00020000 },
-    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
-    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
-    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
-    { 0x0000989c, 0x40ff0000, 0x40ff0000 },
-    { 0x0000989c, 0x005f0000, 0x005f0000 },
-    { 0x0000989c, 0x00870000, 0x00870000 },
-    { 0x0000989c, 0x00f90000, 0x00f90000 },
-    { 0x0000989c, 0x007b0000, 0x007b0000 },
-    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
-    { 0x0000989c, 0x00f50000, 0x00f50000 },
-    { 0x0000989c, 0x00dc0000, 0x00dc0000 },
-    { 0x0000989c, 0x00110000, 0x00110000 },
-    { 0x0000989c, 0x006100a8, 0x006100a8 },
-    { 0x0000989c, 0x00423022, 0x00423022 },
-    { 0x0000989c, 0x201400df, 0x201400df },
-    { 0x0000989c, 0x00c40002, 0x00c40002 },
-    { 0x0000989c, 0x003000f2, 0x003000f2 },
-    { 0x0000989c, 0x00440016, 0x00440016 },
-    { 0x0000989c, 0x00410040, 0x00410040 },
-    { 0x0000989c, 0x0001805e, 0x0001805e },
-    { 0x0000989c, 0x0000c0ab, 0x0000c0ab },
-    { 0x0000989c, 0x000000e1, 0x000000e1 },
-    { 0x0000989c, 0x00007081, 0x00007081 },
-    { 0x0000989c, 0x000000d4, 0x000000d4 },
-    { 0x000098d0, 0x0000000f, 0x0010000f },
-};
-
-static const u32 ar5416Bank7[][2] = {
-    { 0x0000989c, 0x00000500 },
-    { 0x0000989c, 0x00000800 },
-    { 0x000098cc, 0x0000000e },
-};
-
-static const u32 ar5416Addac[][2] = {
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000003 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x0000000c },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000030 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000060 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000058 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x000098cc,  0x00000000 },
-};
-
-static const u32 ar5416Modes_9100[][6] = {
-    { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 },
-    { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 },
-    { 0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180 },
-    { 0x000010f0, 0x0000a000, 0x00014000, 0x00016000, 0x0000b000, 0x00014008 },
-    { 0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00, 0x06e006e0 },
-    { 0x0000801c, 0x128d93a7, 0x128d93cf, 0x12e013d7, 0x12e013ab, 0x098813cf },
-    { 0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303 },
-    { 0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200 },
-    { 0x00009824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
-    { 0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001 },
-    { 0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
-    { 0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007 },
-    { 0x00009844, 0x0372161e, 0x0372161e, 0x037216a0, 0x037216a0, 0x037216a0 },
-    { 0x00009848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
-    { 0x0000a848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
-    { 0x0000b848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
-    { 0x00009850, 0x6d48b4e2, 0x6d48b4e2, 0x6d48b0e2, 0x6d48b0e2, 0x6d48b0e2 },
-    { 0x00009858, 0x7ec82d2e, 0x7ec82d2e, 0x7ec86d2e, 0x7ec84d2e, 0x7ec82d2e },
-    { 0x0000985c, 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e },
-    { 0x00009860, 0x00048d18, 0x00048d18, 0x00048d20, 0x00048d20, 0x00048d18 },
-    { 0x0000c864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00 },
-    { 0x00009868, 0x409a40d0, 0x409a40d0, 0x409a40d0, 0x409a40d0, 0x409a40d0 },
-    { 0x0000986c, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 },
-    { 0x00009914, 0x000007d0, 0x000007d0, 0x00000898, 0x00000898, 0x000007d0 },
-    { 0x00009918, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b, 0x00000016 },
-    { 0x00009924, 0xd00a8a07, 0xd00a8a07, 0xd00a8a11, 0xd00a8a0d, 0xd00a8a0d },
-    { 0x00009940, 0x00754604, 0x00754604, 0xfff81204, 0xfff81204, 0xfff81204 },
-    { 0x00009944, 0xdfb81020, 0xdfb81020, 0xdfb81020, 0xdfb81020, 0xdfb81020 },
-    { 0x00009954, 0x5f3ca3de, 0x5f3ca3de, 0xe250a51e, 0xe250a51e, 0xe250a51e },
-    { 0x00009958, 0x2108ecff, 0x2108ecff, 0x3388ffff, 0x3388ffff, 0x3388ffff },
-#ifdef TB243
-    { 0x00009960, 0x00000900, 0x00000900, 0x00009b40, 0x00009b40, 0x00012d80 },
-    { 0x0000a960, 0x00000900, 0x00000900, 0x00009b40, 0x00009b40, 0x00012d80 },
-    { 0x0000b960, 0x00000900, 0x00000900, 0x00009b40, 0x00009b40, 0x00012d80 },
-    { 0x00009964, 0x00000000, 0x00000000, 0x00002210, 0x00002210, 0x00001120 },
-#else
-    { 0x00009960, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0 },
-    { 0x0000a960, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0 },
-    { 0x0000b960, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0 },
-    { 0x00009964, 0x00001120, 0x00001120, 0x00001120, 0x00001120, 0x00001120 },
-#endif
-    { 0x0000c9bc, 0x001a0600, 0x001a0600, 0x001a1000, 0x001a0c00, 0x001a0c00 },
-    { 0x000099c0, 0x038919be, 0x038919be, 0x038919be, 0x038919be, 0x038919be },
-    { 0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77 },
-    { 0x000099c8, 0x60f65329, 0x60f65329, 0x60f65329, 0x60f65329, 0x60f65329 },
-    { 0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8 },
-    { 0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, 0x00046384 },
-    { 0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
-    { 0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
-    { 0x0000a204, 0x00000880, 0x00000880, 0x00000880, 0x00000880, 0x00000880 },
-    { 0x0000a208, 0xd6be4788, 0xd6be4788, 0xd03e4788, 0xd03e4788, 0xd03e4788 },
-    { 0x0000a20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120 },
-    { 0x0000b20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120 },
-    { 0x0000c20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120 },
-    { 0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a },
-    { 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000 },
-    { 0x0000a274, 0x0a1a9caa, 0x0a1a9caa, 0x0a1a7caa, 0x0a1a7caa, 0x0a1a7caa },
-    { 0x0000a300, 0x18010000, 0x18010000, 0x18010000, 0x18010000, 0x18010000 },
-    { 0x0000a304, 0x30032602, 0x30032602, 0x2e032402, 0x2e032402, 0x2e032402 },
-    { 0x0000a308, 0x48073e06, 0x48073e06, 0x4a0a3c06, 0x4a0a3c06, 0x4a0a3c06 },
-    { 0x0000a30c, 0x560b4c0a, 0x560b4c0a, 0x621a540b, 0x621a540b, 0x621a540b },
-    { 0x0000a310, 0x641a600f, 0x641a600f, 0x764f6c1b, 0x764f6c1b, 0x764f6c1b },
-    { 0x0000a314, 0x7a4f6e1b, 0x7a4f6e1b, 0x845b7a5a, 0x845b7a5a, 0x845b7a5a },
-    { 0x0000a318, 0x8c5b7e5a, 0x8c5b7e5a, 0x950f8ccf, 0x950f8ccf, 0x950f8ccf },
-    { 0x0000a31c, 0x9d0f96cf, 0x9d0f96cf, 0xa5cf9b4f, 0xa5cf9b4f, 0xa5cf9b4f },
-    { 0x0000a320, 0xb51fa69f, 0xb51fa69f, 0xbddfaf1f, 0xbddfaf1f, 0xbddfaf1f },
-    { 0x0000a324, 0xcb3fbd07, 0xcb3fbcbf, 0xd1ffc93f, 0xd1ffc93f, 0xd1ffc93f },
-    { 0x0000a328, 0x0000d7bf, 0x0000d7bf, 0x00000000, 0x00000000, 0x00000000 },
-    { 0x0000a32c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
-    { 0x0000a330, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
-    { 0x0000a334, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
-};
-
-static const u32 ar5416Common_9100[][2] = {
-    { 0x0000000c, 0x00000000 },
-    { 0x00000030, 0x00020015 },
-    { 0x00000034, 0x00000005 },
-    { 0x00000040, 0x00000000 },
-    { 0x00000044, 0x00000008 },
-    { 0x00000048, 0x00000008 },
-    { 0x0000004c, 0x00000010 },
-    { 0x00000050, 0x00000000 },
-    { 0x00000054, 0x0000001f },
-    { 0x00000800, 0x00000000 },
-    { 0x00000804, 0x00000000 },
-    { 0x00000808, 0x00000000 },
-    { 0x0000080c, 0x00000000 },
-    { 0x00000810, 0x00000000 },
-    { 0x00000814, 0x00000000 },
-    { 0x00000818, 0x00000000 },
-    { 0x0000081c, 0x00000000 },
-    { 0x00000820, 0x00000000 },
-    { 0x00000824, 0x00000000 },
-    { 0x00001040, 0x002ffc0f },
-    { 0x00001044, 0x002ffc0f },
-    { 0x00001048, 0x002ffc0f },
-    { 0x0000104c, 0x002ffc0f },
-    { 0x00001050, 0x002ffc0f },
-    { 0x00001054, 0x002ffc0f },
-    { 0x00001058, 0x002ffc0f },
-    { 0x0000105c, 0x002ffc0f },
-    { 0x00001060, 0x002ffc0f },
-    { 0x00001064, 0x002ffc0f },
-    { 0x00001230, 0x00000000 },
-    { 0x00001270, 0x00000000 },
-    { 0x00001038, 0x00000000 },
-    { 0x00001078, 0x00000000 },
-    { 0x000010b8, 0x00000000 },
-    { 0x000010f8, 0x00000000 },
-    { 0x00001138, 0x00000000 },
-    { 0x00001178, 0x00000000 },
-    { 0x000011b8, 0x00000000 },
-    { 0x000011f8, 0x00000000 },
-    { 0x00001238, 0x00000000 },
-    { 0x00001278, 0x00000000 },
-    { 0x000012b8, 0x00000000 },
-    { 0x000012f8, 0x00000000 },
-    { 0x00001338, 0x00000000 },
-    { 0x00001378, 0x00000000 },
-    { 0x000013b8, 0x00000000 },
-    { 0x000013f8, 0x00000000 },
-    { 0x00001438, 0x00000000 },
-    { 0x00001478, 0x00000000 },
-    { 0x000014b8, 0x00000000 },
-    { 0x000014f8, 0x00000000 },
-    { 0x00001538, 0x00000000 },
-    { 0x00001578, 0x00000000 },
-    { 0x000015b8, 0x00000000 },
-    { 0x000015f8, 0x00000000 },
-    { 0x00001638, 0x00000000 },
-    { 0x00001678, 0x00000000 },
-    { 0x000016b8, 0x00000000 },
-    { 0x000016f8, 0x00000000 },
-    { 0x00001738, 0x00000000 },
-    { 0x00001778, 0x00000000 },
-    { 0x000017b8, 0x00000000 },
-    { 0x000017f8, 0x00000000 },
-    { 0x0000103c, 0x00000000 },
-    { 0x0000107c, 0x00000000 },
-    { 0x000010bc, 0x00000000 },
-    { 0x000010fc, 0x00000000 },
-    { 0x0000113c, 0x00000000 },
-    { 0x0000117c, 0x00000000 },
-    { 0x000011bc, 0x00000000 },
-    { 0x000011fc, 0x00000000 },
-    { 0x0000123c, 0x00000000 },
-    { 0x0000127c, 0x00000000 },
-    { 0x000012bc, 0x00000000 },
-    { 0x000012fc, 0x00000000 },
-    { 0x0000133c, 0x00000000 },
-    { 0x0000137c, 0x00000000 },
-    { 0x000013bc, 0x00000000 },
-    { 0x000013fc, 0x00000000 },
-    { 0x0000143c, 0x00000000 },
-    { 0x0000147c, 0x00000000 },
-    { 0x00020010, 0x00000003 },
-    { 0x00020038, 0x000004c2 },
-    { 0x00008004, 0x00000000 },
-    { 0x00008008, 0x00000000 },
-    { 0x0000800c, 0x00000000 },
-    { 0x00008018, 0x00000700 },
-    { 0x00008020, 0x00000000 },
-    { 0x00008038, 0x00000000 },
-    { 0x0000803c, 0x00000000 },
-    { 0x00008048, 0x40000000 },
-    { 0x00008054, 0x00004000 },
-    { 0x00008058, 0x00000000 },
-    { 0x0000805c, 0x000fc78f },
-    { 0x00008060, 0x0000000f },
-    { 0x00008064, 0x00000000 },
-    { 0x000080c0, 0x2a82301a },
-    { 0x000080c4, 0x05dc01e0 },
-    { 0x000080c8, 0x1f402710 },
-    { 0x000080cc, 0x01f40000 },
-    { 0x000080d0, 0x00001e00 },
-    { 0x000080d4, 0x00000000 },
-    { 0x000080d8, 0x00400000 },
-    { 0x000080e0, 0xffffffff },
-    { 0x000080e4, 0x0000ffff },
-    { 0x000080e8, 0x003f3f3f },
-    { 0x000080ec, 0x00000000 },
-    { 0x000080f0, 0x00000000 },
-    { 0x000080f4, 0x00000000 },
-    { 0x000080f8, 0x00000000 },
-    { 0x000080fc, 0x00020000 },
-    { 0x00008100, 0x00020000 },
-    { 0x00008104, 0x00000001 },
-    { 0x00008108, 0x00000052 },
-    { 0x0000810c, 0x00000000 },
-    { 0x00008110, 0x00000168 },
-    { 0x00008118, 0x000100aa },
-    { 0x0000811c, 0x00003210 },
-    { 0x00008120, 0x08f04800 },
-    { 0x00008124, 0x00000000 },
-    { 0x00008128, 0x00000000 },
-    { 0x0000812c, 0x00000000 },
-    { 0x00008130, 0x00000000 },
-    { 0x00008134, 0x00000000 },
-    { 0x00008138, 0x00000000 },
-    { 0x0000813c, 0x00000000 },
-    { 0x00008144, 0x00000000 },
-    { 0x00008168, 0x00000000 },
-    { 0x0000816c, 0x00000000 },
-    { 0x00008170, 0x32143320 },
-    { 0x00008174, 0xfaa4fa50 },
-    { 0x00008178, 0x00000100 },
-    { 0x0000817c, 0x00000000 },
-    { 0x000081c4, 0x00000000 },
-    { 0x000081d0, 0x00003210 },
-    { 0x000081ec, 0x00000000 },
-    { 0x000081f0, 0x00000000 },
-    { 0x000081f4, 0x00000000 },
-    { 0x000081f8, 0x00000000 },
-    { 0x000081fc, 0x00000000 },
-    { 0x00008200, 0x00000000 },
-    { 0x00008204, 0x00000000 },
-    { 0x00008208, 0x00000000 },
-    { 0x0000820c, 0x00000000 },
-    { 0x00008210, 0x00000000 },
-    { 0x00008214, 0x00000000 },
-    { 0x00008218, 0x00000000 },
-    { 0x0000821c, 0x00000000 },
-    { 0x00008220, 0x00000000 },
-    { 0x00008224, 0x00000000 },
-    { 0x00008228, 0x00000000 },
-    { 0x0000822c, 0x00000000 },
-    { 0x00008230, 0x00000000 },
-    { 0x00008234, 0x00000000 },
-    { 0x00008238, 0x00000000 },
-    { 0x0000823c, 0x00000000 },
-    { 0x00008240, 0x00100000 },
-    { 0x00008244, 0x0010f400 },
-    { 0x00008248, 0x00000100 },
-    { 0x0000824c, 0x0001e800 },
-    { 0x00008250, 0x00000000 },
-    { 0x00008254, 0x00000000 },
-    { 0x00008258, 0x00000000 },
-    { 0x0000825c, 0x400000ff },
-    { 0x00008260, 0x00080922 },
-    { 0x00008270, 0x00000000 },
-    { 0x00008274, 0x40000000 },
-    { 0x00008278, 0x003e4180 },
-    { 0x0000827c, 0x00000000 },
-    { 0x00008284, 0x0000002c },
-    { 0x00008288, 0x0000002c },
-    { 0x0000828c, 0x00000000 },
-    { 0x00008294, 0x00000000 },
-    { 0x00008298, 0x00000000 },
-    { 0x00008300, 0x00000000 },
-    { 0x00008304, 0x00000000 },
-    { 0x00008308, 0x00000000 },
-    { 0x0000830c, 0x00000000 },
-    { 0x00008310, 0x00000000 },
-    { 0x00008314, 0x00000000 },
-    { 0x00008318, 0x00000000 },
-    { 0x00008328, 0x00000000 },
-    { 0x0000832c, 0x00000007 },
-    { 0x00008330, 0x00000302 },
-    { 0x00008334, 0x00000e00 },
-    { 0x00008338, 0x00000000 },
-    { 0x0000833c, 0x00000000 },
-    { 0x00008340, 0x000107ff },
-    { 0x00009808, 0x00000000 },
-    { 0x0000980c, 0xad848e19 },
-    { 0x00009810, 0x7d14e000 },
-    { 0x00009814, 0x9c0a9f6b },
-    { 0x0000981c, 0x00000000 },
-    { 0x0000982c, 0x0000a000 },
-    { 0x00009830, 0x00000000 },
-    { 0x0000983c, 0x00200400 },
-    { 0x00009840, 0x206a01ae },
-    { 0x0000984c, 0x1284233c },
-    { 0x00009854, 0x00000859 },
-    { 0x00009900, 0x00000000 },
-    { 0x00009904, 0x00000000 },
-    { 0x00009908, 0x00000000 },
-    { 0x0000990c, 0x00000000 },
-    { 0x0000991c, 0x10000fff },
-    { 0x00009920, 0x05100000 },
-    { 0x0000a920, 0x05100000 },
-    { 0x0000b920, 0x05100000 },
-    { 0x00009928, 0x00000001 },
-    { 0x0000992c, 0x00000004 },
-    { 0x00009934, 0x1e1f2022 },
-    { 0x00009938, 0x0a0b0c0d },
-    { 0x0000993c, 0x00000000 },
-    { 0x00009948, 0x9280b212 },
-    { 0x0000994c, 0x00020028 },
-    { 0x0000c95c, 0x004b6a8e },
-    { 0x0000c968, 0x000003ce },
-    { 0x00009970, 0x190fb515 },
-    { 0x00009974, 0x00000000 },
-    { 0x00009978, 0x00000001 },
-    { 0x0000997c, 0x00000000 },
-    { 0x00009980, 0x00000000 },
-    { 0x00009984, 0x00000000 },
-    { 0x00009988, 0x00000000 },
-    { 0x0000998c, 0x00000000 },
-    { 0x00009990, 0x00000000 },
-    { 0x00009994, 0x00000000 },
-    { 0x00009998, 0x00000000 },
-    { 0x0000999c, 0x00000000 },
-    { 0x000099a0, 0x00000000 },
-    { 0x000099a4, 0x00000001 },
-    { 0x000099a8, 0x201fff00 },
-    { 0x000099ac, 0x006f0000 },
-    { 0x000099b0, 0x03051000 },
-    { 0x000099dc, 0x00000000 },
-    { 0x000099e0, 0x00000200 },
-    { 0x000099e4, 0xaaaaaaaa },
-    { 0x000099e8, 0x3c466478 },
-    { 0x000099ec, 0x0cc80caa },
-    { 0x000099fc, 0x00001042 },
-    { 0x00009b00, 0x00000000 },
-    { 0x00009b04, 0x00000001 },
-    { 0x00009b08, 0x00000002 },
-    { 0x00009b0c, 0x00000003 },
-    { 0x00009b10, 0x00000004 },
-    { 0x00009b14, 0x00000005 },
-    { 0x00009b18, 0x00000008 },
-    { 0x00009b1c, 0x00000009 },
-    { 0x00009b20, 0x0000000a },
-    { 0x00009b24, 0x0000000b },
-    { 0x00009b28, 0x0000000c },
-    { 0x00009b2c, 0x0000000d },
-    { 0x00009b30, 0x00000010 },
-    { 0x00009b34, 0x00000011 },
-    { 0x00009b38, 0x00000012 },
-    { 0x00009b3c, 0x00000013 },
-    { 0x00009b40, 0x00000014 },
-    { 0x00009b44, 0x00000015 },
-    { 0x00009b48, 0x00000018 },
-    { 0x00009b4c, 0x00000019 },
-    { 0x00009b50, 0x0000001a },
-    { 0x00009b54, 0x0000001b },
-    { 0x00009b58, 0x0000001c },
-    { 0x00009b5c, 0x0000001d },
-    { 0x00009b60, 0x00000020 },
-    { 0x00009b64, 0x00000021 },
-    { 0x00009b68, 0x00000022 },
-    { 0x00009b6c, 0x00000023 },
-    { 0x00009b70, 0x00000024 },
-    { 0x00009b74, 0x00000025 },
-    { 0x00009b78, 0x00000028 },
-    { 0x00009b7c, 0x00000029 },
-    { 0x00009b80, 0x0000002a },
-    { 0x00009b84, 0x0000002b },
-    { 0x00009b88, 0x0000002c },
-    { 0x00009b8c, 0x0000002d },
-    { 0x00009b90, 0x00000030 },
-    { 0x00009b94, 0x00000031 },
-    { 0x00009b98, 0x00000032 },
-    { 0x00009b9c, 0x00000033 },
-    { 0x00009ba0, 0x00000034 },
-    { 0x00009ba4, 0x00000035 },
-    { 0x00009ba8, 0x00000035 },
-    { 0x00009bac, 0x00000035 },
-    { 0x00009bb0, 0x00000035 },
-    { 0x00009bb4, 0x00000035 },
-    { 0x00009bb8, 0x00000035 },
-    { 0x00009bbc, 0x00000035 },
-    { 0x00009bc0, 0x00000035 },
-    { 0x00009bc4, 0x00000035 },
-    { 0x00009bc8, 0x00000035 },
-    { 0x00009bcc, 0x00000035 },
-    { 0x00009bd0, 0x00000035 },
-    { 0x00009bd4, 0x00000035 },
-    { 0x00009bd8, 0x00000035 },
-    { 0x00009bdc, 0x00000035 },
-    { 0x00009be0, 0x00000035 },
-    { 0x00009be4, 0x00000035 },
-    { 0x00009be8, 0x00000035 },
-    { 0x00009bec, 0x00000035 },
-    { 0x00009bf0, 0x00000035 },
-    { 0x00009bf4, 0x00000035 },
-    { 0x00009bf8, 0x00000010 },
-    { 0x00009bfc, 0x0000001a },
-    { 0x0000a210, 0x40806333 },
-    { 0x0000a214, 0x00106c10 },
-    { 0x0000a218, 0x009c4060 },
-    { 0x0000a220, 0x018830c6 },
-    { 0x0000a224, 0x00000400 },
-    { 0x0000a228, 0x001a0bb5 },
-    { 0x0000a22c, 0x00000000 },
-    { 0x0000a234, 0x20202020 },
-    { 0x0000a238, 0x20202020 },
-    { 0x0000a23c, 0x13c889ae },
-    { 0x0000a240, 0x38490a20 },
-    { 0x0000a244, 0x00007bb6 },
-    { 0x0000a248, 0x0fff3ffc },
-    { 0x0000a24c, 0x00000001 },
-    { 0x0000a250, 0x0000a000 },
-    { 0x0000a254, 0x00000000 },
-    { 0x0000a258, 0x0cc75380 },
-    { 0x0000a25c, 0x0f0f0f01 },
-    { 0x0000a260, 0xdfa91f01 },
-    { 0x0000a268, 0x00000001 },
-    { 0x0000a26c, 0x0ebae9c6 },
-    { 0x0000b26c, 0x0ebae9c6 },
-    { 0x0000c26c, 0x0ebae9c6 },
-    { 0x0000d270, 0x00820820 },
-    { 0x0000a278, 0x1ce739ce },
-    { 0x0000a27c, 0x050701ce },
-    { 0x0000a338, 0x00000000 },
-    { 0x0000a33c, 0x00000000 },
-    { 0x0000a340, 0x00000000 },
-    { 0x0000a344, 0x00000000 },
-    { 0x0000a348, 0x3fffffff },
-    { 0x0000a34c, 0x3fffffff },
-    { 0x0000a350, 0x3fffffff },
-    { 0x0000a354, 0x0003ffff },
-    { 0x0000a358, 0x79a8aa33 },
-    { 0x0000d35c, 0x07ffffef },
-    { 0x0000d360, 0x0fffffe7 },
-    { 0x0000d364, 0x17ffffe5 },
-    { 0x0000d368, 0x1fffffe4 },
-    { 0x0000d36c, 0x37ffffe3 },
-    { 0x0000d370, 0x3fffffe3 },
-    { 0x0000d374, 0x57ffffe3 },
-    { 0x0000d378, 0x5fffffe2 },
-    { 0x0000d37c, 0x7fffffe2 },
-    { 0x0000d380, 0x7f3c7bba },
-    { 0x0000d384, 0xf3307ff0 },
-    { 0x0000a388, 0x0c000000 },
-    { 0x0000a38c, 0x20202020 },
-    { 0x0000a390, 0x20202020 },
-    { 0x0000a394, 0x1ce739ce },
-    { 0x0000a398, 0x000001ce },
-    { 0x0000a39c, 0x00000001 },
-    { 0x0000a3a0, 0x00000000 },
-    { 0x0000a3a4, 0x00000000 },
-    { 0x0000a3a8, 0x00000000 },
-    { 0x0000a3ac, 0x00000000 },
-    { 0x0000a3b0, 0x00000000 },
-    { 0x0000a3b4, 0x00000000 },
-    { 0x0000a3b8, 0x00000000 },
-    { 0x0000a3bc, 0x00000000 },
-    { 0x0000a3c0, 0x00000000 },
-    { 0x0000a3c4, 0x00000000 },
-    { 0x0000a3c8, 0x00000246 },
-    { 0x0000a3cc, 0x20202020 },
-    { 0x0000a3d0, 0x20202020 },
-    { 0x0000a3d4, 0x20202020 },
-    { 0x0000a3dc, 0x1ce739ce },
-    { 0x0000a3e0, 0x000001ce },
-};
-
-static const u32 ar5416Bank0_9100[][2] = {
-    { 0x000098b0, 0x1e5795e5 },
-    { 0x000098e0, 0x02008020 },
-};
-
-static const u32 ar5416BB_RfGain_9100[][3] = {
-    { 0x00009a00, 0x00000000, 0x00000000 },
-    { 0x00009a04, 0x00000040, 0x00000040 },
-    { 0x00009a08, 0x00000080, 0x00000080 },
-    { 0x00009a0c, 0x000001a1, 0x00000141 },
-    { 0x00009a10, 0x000001e1, 0x00000181 },
-    { 0x00009a14, 0x00000021, 0x000001c1 },
-    { 0x00009a18, 0x00000061, 0x00000001 },
-    { 0x00009a1c, 0x00000168, 0x00000041 },
-    { 0x00009a20, 0x000001a8, 0x000001a8 },
-    { 0x00009a24, 0x000001e8, 0x000001e8 },
-    { 0x00009a28, 0x00000028, 0x00000028 },
-    { 0x00009a2c, 0x00000068, 0x00000068 },
-    { 0x00009a30, 0x00000189, 0x000000a8 },
-    { 0x00009a34, 0x000001c9, 0x00000169 },
-    { 0x00009a38, 0x00000009, 0x000001a9 },
-    { 0x00009a3c, 0x00000049, 0x000001e9 },
-    { 0x00009a40, 0x00000089, 0x00000029 },
-    { 0x00009a44, 0x00000170, 0x00000069 },
-    { 0x00009a48, 0x000001b0, 0x00000190 },
-    { 0x00009a4c, 0x000001f0, 0x000001d0 },
-    { 0x00009a50, 0x00000030, 0x00000010 },
-    { 0x00009a54, 0x00000070, 0x00000050 },
-    { 0x00009a58, 0x00000191, 0x00000090 },
-    { 0x00009a5c, 0x000001d1, 0x00000151 },
-    { 0x00009a60, 0x00000011, 0x00000191 },
-    { 0x00009a64, 0x00000051, 0x000001d1 },
-    { 0x00009a68, 0x00000091, 0x00000011 },
-    { 0x00009a6c, 0x000001b8, 0x00000051 },
-    { 0x00009a70, 0x000001f8, 0x00000198 },
-    { 0x00009a74, 0x00000038, 0x000001d8 },
-    { 0x00009a78, 0x00000078, 0x00000018 },
-    { 0x00009a7c, 0x00000199, 0x00000058 },
-    { 0x00009a80, 0x000001d9, 0x00000098 },
-    { 0x00009a84, 0x00000019, 0x00000159 },
-    { 0x00009a88, 0x00000059, 0x00000199 },
-    { 0x00009a8c, 0x00000099, 0x000001d9 },
-    { 0x00009a90, 0x000000d9, 0x00000019 },
-    { 0x00009a94, 0x000000f9, 0x00000059 },
-    { 0x00009a98, 0x000000f9, 0x00000099 },
-    { 0x00009a9c, 0x000000f9, 0x000000d9 },
-    { 0x00009aa0, 0x000000f9, 0x000000f9 },
-    { 0x00009aa4, 0x000000f9, 0x000000f9 },
-    { 0x00009aa8, 0x000000f9, 0x000000f9 },
-    { 0x00009aac, 0x000000f9, 0x000000f9 },
-    { 0x00009ab0, 0x000000f9, 0x000000f9 },
-    { 0x00009ab4, 0x000000f9, 0x000000f9 },
-    { 0x00009ab8, 0x000000f9, 0x000000f9 },
-    { 0x00009abc, 0x000000f9, 0x000000f9 },
-    { 0x00009ac0, 0x000000f9, 0x000000f9 },
-    { 0x00009ac4, 0x000000f9, 0x000000f9 },
-    { 0x00009ac8, 0x000000f9, 0x000000f9 },
-    { 0x00009acc, 0x000000f9, 0x000000f9 },
-    { 0x00009ad0, 0x000000f9, 0x000000f9 },
-    { 0x00009ad4, 0x000000f9, 0x000000f9 },
-    { 0x00009ad8, 0x000000f9, 0x000000f9 },
-    { 0x00009adc, 0x000000f9, 0x000000f9 },
-    { 0x00009ae0, 0x000000f9, 0x000000f9 },
-    { 0x00009ae4, 0x000000f9, 0x000000f9 },
-    { 0x00009ae8, 0x000000f9, 0x000000f9 },
-    { 0x00009aec, 0x000000f9, 0x000000f9 },
-    { 0x00009af0, 0x000000f9, 0x000000f9 },
-    { 0x00009af4, 0x000000f9, 0x000000f9 },
-    { 0x00009af8, 0x000000f9, 0x000000f9 },
-    { 0x00009afc, 0x000000f9, 0x000000f9 },
-};
-
-static const u32 ar5416Bank1_9100[][2] = {
-    { 0x000098b0, 0x02108421},
-    { 0x000098ec, 0x00000008},
-};
-
-static const u32 ar5416Bank2_9100[][2] = {
-    { 0x000098b0, 0x0e73ff17},
-    { 0x000098e0, 0x00000420},
-};
-
-static const u32 ar5416Bank3_9100[][3] = {
-    { 0x000098f0, 0x01400018, 0x01c00018 },
-};
-
-static const u32 ar5416Bank6_9100[][3] = {
-
-    { 0x0000989c, 0x00000000, 0x00000000 },
-    { 0x0000989c, 0x00000000, 0x00000000 },
-    { 0x0000989c, 0x00000000, 0x00000000 },
-    { 0x0000989c, 0x00e00000, 0x00e00000 },
-    { 0x0000989c, 0x005e0000, 0x005e0000 },
-    { 0x0000989c, 0x00120000, 0x00120000 },
-    { 0x0000989c, 0x00620000, 0x00620000 },
-    { 0x0000989c, 0x00020000, 0x00020000 },
-    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
-    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
-    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
-    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
-    { 0x0000989c, 0x005f0000, 0x005f0000 },
-    { 0x0000989c, 0x00870000, 0x00870000 },
-    { 0x0000989c, 0x00f90000, 0x00f90000 },
-    { 0x0000989c, 0x007b0000, 0x007b0000 },
-    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
-    { 0x0000989c, 0x00f50000, 0x00f50000 },
-    { 0x0000989c, 0x00dc0000, 0x00dc0000 },
-    { 0x0000989c, 0x00110000, 0x00110000 },
-    { 0x0000989c, 0x006100a8, 0x006100a8 },
-    { 0x0000989c, 0x004210a2, 0x004210a2 },
-    { 0x0000989c, 0x0014000f, 0x0014000f },
-    { 0x0000989c, 0x00c40002, 0x00c40002 },
-    { 0x0000989c, 0x003000f2, 0x003000f2 },
-    { 0x0000989c, 0x00440016, 0x00440016 },
-    { 0x0000989c, 0x00410040, 0x00410040 },
-    { 0x0000989c, 0x000180d6, 0x000180d6 },
-    { 0x0000989c, 0x0000c0aa, 0x0000c0aa },
-    { 0x0000989c, 0x000000b1, 0x000000b1 },
-    { 0x0000989c, 0x00002000, 0x00002000 },
-    { 0x0000989c, 0x000000d4, 0x000000d4 },
-    { 0x000098d0, 0x0000000f, 0x0010000f },
-};
-
-
-static const u32 ar5416Bank6TPC_9100[][3] = {
-
-    { 0x0000989c, 0x00000000, 0x00000000 },
-    { 0x0000989c, 0x00000000, 0x00000000 },
-    { 0x0000989c, 0x00000000, 0x00000000 },
-    { 0x0000989c, 0x00e00000, 0x00e00000 },
-    { 0x0000989c, 0x005e0000, 0x005e0000 },
-    { 0x0000989c, 0x00120000, 0x00120000 },
-    { 0x0000989c, 0x00620000, 0x00620000 },
-    { 0x0000989c, 0x00020000, 0x00020000 },
-    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
-    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
-    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
-    { 0x0000989c, 0x40ff0000, 0x40ff0000 },
-    { 0x0000989c, 0x005f0000, 0x005f0000 },
-    { 0x0000989c, 0x00870000, 0x00870000 },
-    { 0x0000989c, 0x00f90000, 0x00f90000 },
-    { 0x0000989c, 0x007b0000, 0x007b0000 },
-    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
-    { 0x0000989c, 0x00f50000, 0x00f50000 },
-    { 0x0000989c, 0x00dc0000, 0x00dc0000 },
-    { 0x0000989c, 0x00110000, 0x00110000 },
-    { 0x0000989c, 0x006100a8, 0x006100a8 },
-    { 0x0000989c, 0x00423022, 0x00423022 },
-    { 0x0000989c, 0x2014008f, 0x2014008f },
-    { 0x0000989c, 0x00c40002, 0x00c40002 },
-    { 0x0000989c, 0x003000f2, 0x003000f2 },
-    { 0x0000989c, 0x00440016, 0x00440016 },
-    { 0x0000989c, 0x00410040, 0x00410040 },
-    { 0x0000989c, 0x0001805e, 0x0001805e },
-    { 0x0000989c, 0x0000c0ab, 0x0000c0ab },
-    { 0x0000989c, 0x000000e1, 0x000000e1 },
-    { 0x0000989c, 0x00007080, 0x00007080 },
-    { 0x0000989c, 0x000000d4, 0x000000d4 },
-    { 0x000098d0, 0x0000000f, 0x0010000f },
-};
-
-static const u32 ar5416Bank7_9100[][2] = {
-    { 0x0000989c, 0x00000500 },
-    { 0x0000989c, 0x00000800 },
-    { 0x000098cc, 0x0000000e },
-};
-
-static const u32 ar5416Addac_9100[][2] = {
-    {0x0000989c, 0x00000000 },
-    {0x0000989c, 0x00000000 },
-    {0x0000989c, 0x00000000 },
-    {0x0000989c, 0x00000000 },
-    {0x0000989c, 0x00000000 },
-    {0x0000989c, 0x00000000 },
-    {0x0000989c, 0x00000000 },
-    {0x0000989c, 0x00000010 },
-    {0x0000989c, 0x00000000 },
-    {0x0000989c, 0x00000000 },
-    {0x0000989c, 0x00000000 },
-    {0x0000989c, 0x00000000 },
-    {0x0000989c, 0x00000000 },
-    {0x0000989c, 0x00000000 },
-    {0x0000989c, 0x00000000 },
-    {0x0000989c, 0x00000000 },
-    {0x0000989c, 0x00000000 },
-    {0x0000989c, 0x00000000 },
-    {0x0000989c, 0x00000000 },
-    {0x0000989c, 0x00000000 },
-    {0x0000989c, 0x00000000 },
-    {0x0000989c, 0x000000c0 },
-    {0x0000989c, 0x00000015 },
-    {0x0000989c, 0x00000000 },
-    {0x0000989c, 0x00000000 },
-    {0x0000989c, 0x00000000 },
-    {0x0000989c, 0x00000000 },
-    {0x0000989c, 0x00000000 },
-    {0x0000989c, 0x00000000 },
-    {0x0000989c, 0x00000000 },
-    {0x0000989c, 0x00000000 },
-    {0x000098cc, 0x00000000 },
-};
-
-static const u32 ar5416Modes_9160[][6] = {
-    { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 },
-    { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 },
-    { 0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180 },
-    { 0x000010f0, 0x0000a000, 0x00014000, 0x00016000, 0x0000b000, 0x00014008 },
-    { 0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00, 0x06e006e0 },
-    { 0x0000801c, 0x128d93a7, 0x128d93cf, 0x12e013d7, 0x12e013ab, 0x098813cf },
-    { 0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303 },
-    { 0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200 },
-    { 0x00009824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
-    { 0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001 },
-    { 0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
-    { 0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007 },
-    { 0x00009844, 0x0372161e, 0x0372161e, 0x037216a0, 0x037216a0, 0x037216a0 },
-    { 0x00009848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
-    { 0x0000a848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
-    { 0x0000b848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
-    { 0x00009850, 0x6c48b4e2, 0x6c48b4e2, 0x6c48b0e2, 0x6c48b0e2, 0x6c48b0e2 },
-    { 0x00009858, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e },
-    { 0x0000985c, 0x31395d5e, 0x31395d5e, 0x31395d5e, 0x31395d5e, 0x31395d5e },
-    { 0x00009860, 0x00048d18, 0x00048d18, 0x00048d20, 0x00048d20, 0x00048d18 },
-    { 0x0000c864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00 },
-    { 0x00009868, 0x409a40d0, 0x409a40d0, 0x409a40d0, 0x409a40d0, 0x409a40d0 },
-    { 0x0000986c, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 },
-    { 0x00009914, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898, 0x000007d0 },
-    { 0x00009918, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b, 0x00000016 },
-    { 0x00009924, 0xd00a8a07, 0xd00a8a07, 0xd00a8a0d, 0xd00a8a0d, 0xd00a8a0d },
-    { 0x00009944, 0xffb81020, 0xffb81020, 0xffb81020, 0xffb81020, 0xffb81020 },
-    { 0x00009960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40 },
-    { 0x0000a960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40 },
-    { 0x0000b960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40 },
-    { 0x00009964, 0x00001120, 0x00001120, 0x00001120, 0x00001120, 0x00001120 },
-    { 0x0000c968, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce, 0x000003ce },
-    { 0x0000c9bc, 0x001a0600, 0x001a0600, 0x001a0c00, 0x001a0c00, 0x001a0c00 },
-    { 0x000099c0, 0x038919be, 0x038919be, 0x038919be, 0x038919be, 0x038919be },
-    { 0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77 },
-    { 0x000099c8, 0x60f65329, 0x60f65329, 0x60f65329, 0x60f65329, 0x60f65329 },
-    { 0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8 },
-    { 0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, 0x00046384 },
-    { 0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
-    { 0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
-    { 0x0000a204, 0x00000880, 0x00000880, 0x00000880, 0x00000880, 0x00000880 },
-    { 0x0000a208, 0xd6be4788, 0xd6be4788, 0xd03e4788, 0xd03e4788, 0xd03e4788 },
-    { 0x0000a20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120 },
-    { 0x0000b20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120 },
-    { 0x0000c20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120 },
-    { 0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a },
-    { 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000 },
-    { 0x0000a274, 0x0a1a9caa, 0x0a1a9caa, 0x0a1a7caa, 0x0a1a7caa, 0x0a1a7caa },
-    { 0x0000a300, 0x18010000, 0x18010000, 0x18010000, 0x18010000, 0x18010000 },
-    { 0x0000a304, 0x30032602, 0x30032602, 0x2e032402, 0x2e032402, 0x2e032402 },
-    { 0x0000a308, 0x48073e06, 0x48073e06, 0x4a0a3c06, 0x4a0a3c06, 0x4a0a3c06 },
-    { 0x0000a30c, 0x560b4c0a, 0x560b4c0a, 0x621a540b, 0x621a540b, 0x621a540b },
-    { 0x0000a310, 0x641a600f, 0x641a600f, 0x764f6c1b, 0x764f6c1b, 0x764f6c1b },
-    { 0x0000a314, 0x7a4f6e1b, 0x7a4f6e1b, 0x845b7a5a, 0x845b7a5a, 0x845b7a5a },
-    { 0x0000a318, 0x8c5b7e5a, 0x8c5b7e5a, 0x950f8ccf, 0x950f8ccf, 0x950f8ccf },
-    { 0x0000a31c, 0x9d0f96cf, 0x9d0f96cf, 0xa5cf9b4f, 0xa5cf9b4f, 0xa5cf9b4f },
-    { 0x0000a320, 0xb51fa69f, 0xb51fa69f, 0xbddfaf1f, 0xbddfaf1f, 0xbddfaf1f },
-    { 0x0000a324, 0xcb3fbd07, 0xcb3fbcbf, 0xd1ffc93f, 0xd1ffc93f, 0xd1ffc93f },
-    { 0x0000a328, 0x0000d7bf, 0x0000d7bf, 0x00000000, 0x00000000, 0x00000000 },
-    { 0x0000a32c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
-    { 0x0000a330, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
-    { 0x0000a334, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
-};
-
-static const u32 ar5416Common_9160[][2] = {
-    { 0x0000000c, 0x00000000 },
-    { 0x00000030, 0x00020015 },
-    { 0x00000034, 0x00000005 },
-    { 0x00000040, 0x00000000 },
-    { 0x00000044, 0x00000008 },
-    { 0x00000048, 0x00000008 },
-    { 0x0000004c, 0x00000010 },
-    { 0x00000050, 0x00000000 },
-    { 0x00000054, 0x0000001f },
-    { 0x00000800, 0x00000000 },
-    { 0x00000804, 0x00000000 },
-    { 0x00000808, 0x00000000 },
-    { 0x0000080c, 0x00000000 },
-    { 0x00000810, 0x00000000 },
-    { 0x00000814, 0x00000000 },
-    { 0x00000818, 0x00000000 },
-    { 0x0000081c, 0x00000000 },
-    { 0x00000820, 0x00000000 },
-    { 0x00000824, 0x00000000 },
-    { 0x00001040, 0x002ffc0f },
-    { 0x00001044, 0x002ffc0f },
-    { 0x00001048, 0x002ffc0f },
-    { 0x0000104c, 0x002ffc0f },
-    { 0x00001050, 0x002ffc0f },
-    { 0x00001054, 0x002ffc0f },
-    { 0x00001058, 0x002ffc0f },
-    { 0x0000105c, 0x002ffc0f },
-    { 0x00001060, 0x002ffc0f },
-    { 0x00001064, 0x002ffc0f },
-    { 0x00001230, 0x00000000 },
-    { 0x00001270, 0x00000000 },
-    { 0x00001038, 0x00000000 },
-    { 0x00001078, 0x00000000 },
-    { 0x000010b8, 0x00000000 },
-    { 0x000010f8, 0x00000000 },
-    { 0x00001138, 0x00000000 },
-    { 0x00001178, 0x00000000 },
-    { 0x000011b8, 0x00000000 },
-    { 0x000011f8, 0x00000000 },
-    { 0x00001238, 0x00000000 },
-    { 0x00001278, 0x00000000 },
-    { 0x000012b8, 0x00000000 },
-    { 0x000012f8, 0x00000000 },
-    { 0x00001338, 0x00000000 },
-    { 0x00001378, 0x00000000 },
-    { 0x000013b8, 0x00000000 },
-    { 0x000013f8, 0x00000000 },
-    { 0x00001438, 0x00000000 },
-    { 0x00001478, 0x00000000 },
-    { 0x000014b8, 0x00000000 },
-    { 0x000014f8, 0x00000000 },
-    { 0x00001538, 0x00000000 },
-    { 0x00001578, 0x00000000 },
-    { 0x000015b8, 0x00000000 },
-    { 0x000015f8, 0x00000000 },
-    { 0x00001638, 0x00000000 },
-    { 0x00001678, 0x00000000 },
-    { 0x000016b8, 0x00000000 },
-    { 0x000016f8, 0x00000000 },
-    { 0x00001738, 0x00000000 },
-    { 0x00001778, 0x00000000 },
-    { 0x000017b8, 0x00000000 },
-    { 0x000017f8, 0x00000000 },
-    { 0x0000103c, 0x00000000 },
-    { 0x0000107c, 0x00000000 },
-    { 0x000010bc, 0x00000000 },
-    { 0x000010fc, 0x00000000 },
-    { 0x0000113c, 0x00000000 },
-    { 0x0000117c, 0x00000000 },
-    { 0x000011bc, 0x00000000 },
-    { 0x000011fc, 0x00000000 },
-    { 0x0000123c, 0x00000000 },
-    { 0x0000127c, 0x00000000 },
-    { 0x000012bc, 0x00000000 },
-    { 0x000012fc, 0x00000000 },
-    { 0x0000133c, 0x00000000 },
-    { 0x0000137c, 0x00000000 },
-    { 0x000013bc, 0x00000000 },
-    { 0x000013fc, 0x00000000 },
-    { 0x0000143c, 0x00000000 },
-    { 0x0000147c, 0x00000000 },
-    { 0x00004030, 0x00000002 },
-    { 0x0000403c, 0x00000002 },
-    { 0x00007010, 0x00000020 },
-    { 0x00007038, 0x000004c2 },
-    { 0x00008004, 0x00000000 },
-    { 0x00008008, 0x00000000 },
-    { 0x0000800c, 0x00000000 },
-    { 0x00008018, 0x00000700 },
-    { 0x00008020, 0x00000000 },
-    { 0x00008038, 0x00000000 },
-    { 0x0000803c, 0x00000000 },
-    { 0x00008048, 0x40000000 },
-    { 0x00008054, 0x00000000 },
-    { 0x00008058, 0x00000000 },
-    { 0x0000805c, 0x000fc78f },
-    { 0x00008060, 0x0000000f },
-    { 0x00008064, 0x00000000 },
-    { 0x000080c0, 0x2a82301a },
-    { 0x000080c4, 0x05dc01e0 },
-    { 0x000080c8, 0x1f402710 },
-    { 0x000080cc, 0x01f40000 },
-    { 0x000080d0, 0x00001e00 },
-    { 0x000080d4, 0x00000000 },
-    { 0x000080d8, 0x00400000 },
-    { 0x000080e0, 0xffffffff },
-    { 0x000080e4, 0x0000ffff },
-    { 0x000080e8, 0x003f3f3f },
-    { 0x000080ec, 0x00000000 },
-    { 0x000080f0, 0x00000000 },
-    { 0x000080f4, 0x00000000 },
-    { 0x000080f8, 0x00000000 },
-    { 0x000080fc, 0x00020000 },
-    { 0x00008100, 0x00020000 },
-    { 0x00008104, 0x00000001 },
-    { 0x00008108, 0x00000052 },
-    { 0x0000810c, 0x00000000 },
-    { 0x00008110, 0x00000168 },
-    { 0x00008118, 0x000100aa },
-    { 0x0000811c, 0x00003210 },
-    { 0x00008120, 0x08f04800 },
-    { 0x00008124, 0x00000000 },
-    { 0x00008128, 0x00000000 },
-    { 0x0000812c, 0x00000000 },
-    { 0x00008130, 0x00000000 },
-    { 0x00008134, 0x00000000 },
-    { 0x00008138, 0x00000000 },
-    { 0x0000813c, 0x00000000 },
-    { 0x00008144, 0xffffffff },
-    { 0x00008168, 0x00000000 },
-    { 0x0000816c, 0x00000000 },
-    { 0x00008170, 0x32143320 },
-    { 0x00008174, 0xfaa4fa50 },
-    { 0x00008178, 0x00000100 },
-    { 0x0000817c, 0x00000000 },
-    { 0x000081c4, 0x00000000 },
-    { 0x000081d0, 0x00003210 },
-    { 0x000081ec, 0x00000000 },
-    { 0x000081f0, 0x00000000 },
-    { 0x000081f4, 0x00000000 },
-    { 0x000081f8, 0x00000000 },
-    { 0x000081fc, 0x00000000 },
-    { 0x00008200, 0x00000000 },
-    { 0x00008204, 0x00000000 },
-    { 0x00008208, 0x00000000 },
-    { 0x0000820c, 0x00000000 },
-    { 0x00008210, 0x00000000 },
-    { 0x00008214, 0x00000000 },
-    { 0x00008218, 0x00000000 },
-    { 0x0000821c, 0x00000000 },
-    { 0x00008220, 0x00000000 },
-    { 0x00008224, 0x00000000 },
-    { 0x00008228, 0x00000000 },
-    { 0x0000822c, 0x00000000 },
-    { 0x00008230, 0x00000000 },
-    { 0x00008234, 0x00000000 },
-    { 0x00008238, 0x00000000 },
-    { 0x0000823c, 0x00000000 },
-    { 0x00008240, 0x00100000 },
-    { 0x00008244, 0x0010f400 },
-    { 0x00008248, 0x00000100 },
-    { 0x0000824c, 0x0001e800 },
-    { 0x00008250, 0x00000000 },
-    { 0x00008254, 0x00000000 },
-    { 0x00008258, 0x00000000 },
-    { 0x0000825c, 0x400000ff },
-    { 0x00008260, 0x00080922 },
-    { 0x00008270, 0x00000000 },
-    { 0x00008274, 0x40000000 },
-    { 0x00008278, 0x003e4180 },
-    { 0x0000827c, 0x00000000 },
-    { 0x00008284, 0x0000002c },
-    { 0x00008288, 0x0000002c },
-    { 0x0000828c, 0x00000000 },
-    { 0x00008294, 0x00000000 },
-    { 0x00008298, 0x00000000 },
-    { 0x00008300, 0x00000000 },
-    { 0x00008304, 0x00000000 },
-    { 0x00008308, 0x00000000 },
-    { 0x0000830c, 0x00000000 },
-    { 0x00008310, 0x00000000 },
-    { 0x00008314, 0x00000000 },
-    { 0x00008318, 0x00000000 },
-    { 0x00008328, 0x00000000 },
-    { 0x0000832c, 0x00000007 },
-    { 0x00008330, 0x00000302 },
-    { 0x00008334, 0x00000e00 },
-    { 0x00008338, 0x00ff0000 },
-    { 0x0000833c, 0x00000000 },
-    { 0x00008340, 0x000107ff },
-    { 0x00009808, 0x00000000 },
-    { 0x0000980c, 0xad848e19 },
-    { 0x00009810, 0x7d14e000 },
-    { 0x00009814, 0x9c0a9f6b },
-    { 0x0000981c, 0x00000000 },
-    { 0x0000982c, 0x0000a000 },
-    { 0x00009830, 0x00000000 },
-    { 0x0000983c, 0x00200400 },
-    { 0x00009840, 0x206a01ae },
-    { 0x0000984c, 0x1284233c },
-    { 0x00009854, 0x00000859 },
-    { 0x00009900, 0x00000000 },
-    { 0x00009904, 0x00000000 },
-    { 0x00009908, 0x00000000 },
-    { 0x0000990c, 0x00000000 },
-    { 0x0000991c, 0x10000fff },
-    { 0x00009920, 0x05100000 },
-    { 0x0000a920, 0x05100000 },
-    { 0x0000b920, 0x05100000 },
-    { 0x00009928, 0x00000001 },
-    { 0x0000992c, 0x00000004 },
-    { 0x00009934, 0x1e1f2022 },
-    { 0x00009938, 0x0a0b0c0d },
-    { 0x0000993c, 0x00000000 },
-    { 0x00009948, 0x9280b212 },
-    { 0x0000994c, 0x00020028 },
-    { 0x00009954, 0x5f3ca3de },
-    { 0x00009958, 0x2108ecff },
-    { 0x00009940, 0x00750604 },
-    { 0x0000c95c, 0x004b6a8e },
-    { 0x00009970, 0x190fb515 },
-    { 0x00009974, 0x00000000 },
-    { 0x00009978, 0x00000001 },
-    { 0x0000997c, 0x00000000 },
-    { 0x00009980, 0x00000000 },
-    { 0x00009984, 0x00000000 },
-    { 0x00009988, 0x00000000 },
-    { 0x0000998c, 0x00000000 },
-    { 0x00009990, 0x00000000 },
-    { 0x00009994, 0x00000000 },
-    { 0x00009998, 0x00000000 },
-    { 0x0000999c, 0x00000000 },
-    { 0x000099a0, 0x00000000 },
-    { 0x000099a4, 0x00000001 },
-    { 0x000099a8, 0x201fff00 },
-    { 0x000099ac, 0x006f0000 },
-    { 0x000099b0, 0x03051000 },
-    { 0x000099dc, 0x00000000 },
-    { 0x000099e0, 0x00000200 },
-    { 0x000099e4, 0xaaaaaaaa },
-    { 0x000099e8, 0x3c466478 },
-    { 0x000099ec, 0x0cc80caa },
-    { 0x000099fc, 0x00001042 },
-    { 0x00009b00, 0x00000000 },
-    { 0x00009b04, 0x00000001 },
-    { 0x00009b08, 0x00000002 },
-    { 0x00009b0c, 0x00000003 },
-    { 0x00009b10, 0x00000004 },
-    { 0x00009b14, 0x00000005 },
-    { 0x00009b18, 0x00000008 },
-    { 0x00009b1c, 0x00000009 },
-    { 0x00009b20, 0x0000000a },
-    { 0x00009b24, 0x0000000b },
-    { 0x00009b28, 0x0000000c },
-    { 0x00009b2c, 0x0000000d },
-    { 0x00009b30, 0x00000010 },
-    { 0x00009b34, 0x00000011 },
-    { 0x00009b38, 0x00000012 },
-    { 0x00009b3c, 0x00000013 },
-    { 0x00009b40, 0x00000014 },
-    { 0x00009b44, 0x00000015 },
-    { 0x00009b48, 0x00000018 },
-    { 0x00009b4c, 0x00000019 },
-    { 0x00009b50, 0x0000001a },
-    { 0x00009b54, 0x0000001b },
-    { 0x00009b58, 0x0000001c },
-    { 0x00009b5c, 0x0000001d },
-    { 0x00009b60, 0x00000020 },
-    { 0x00009b64, 0x00000021 },
-    { 0x00009b68, 0x00000022 },
-    { 0x00009b6c, 0x00000023 },
-    { 0x00009b70, 0x00000024 },
-    { 0x00009b74, 0x00000025 },
-    { 0x00009b78, 0x00000028 },
-    { 0x00009b7c, 0x00000029 },
-    { 0x00009b80, 0x0000002a },
-    { 0x00009b84, 0x0000002b },
-    { 0x00009b88, 0x0000002c },
-    { 0x00009b8c, 0x0000002d },
-    { 0x00009b90, 0x00000030 },
-    { 0x00009b94, 0x00000031 },
-    { 0x00009b98, 0x00000032 },
-    { 0x00009b9c, 0x00000033 },
-    { 0x00009ba0, 0x00000034 },
-    { 0x00009ba4, 0x00000035 },
-    { 0x00009ba8, 0x00000035 },
-    { 0x00009bac, 0x00000035 },
-    { 0x00009bb0, 0x00000035 },
-    { 0x00009bb4, 0x00000035 },
-    { 0x00009bb8, 0x00000035 },
-    { 0x00009bbc, 0x00000035 },
-    { 0x00009bc0, 0x00000035 },
-    { 0x00009bc4, 0x00000035 },
-    { 0x00009bc8, 0x00000035 },
-    { 0x00009bcc, 0x00000035 },
-    { 0x00009bd0, 0x00000035 },
-    { 0x00009bd4, 0x00000035 },
-    { 0x00009bd8, 0x00000035 },
-    { 0x00009bdc, 0x00000035 },
-    { 0x00009be0, 0x00000035 },
-    { 0x00009be4, 0x00000035 },
-    { 0x00009be8, 0x00000035 },
-    { 0x00009bec, 0x00000035 },
-    { 0x00009bf0, 0x00000035 },
-    { 0x00009bf4, 0x00000035 },
-    { 0x00009bf8, 0x00000010 },
-    { 0x00009bfc, 0x0000001a },
-    { 0x0000a210, 0x40806333 },
-    { 0x0000a214, 0x00106c10 },
-    { 0x0000a218, 0x009c4060 },
-    { 0x0000a220, 0x018830c6 },
-    { 0x0000a224, 0x00000400 },
-    { 0x0000a228, 0x001a0bb5 },
-    { 0x0000a22c, 0x00000000 },
-    { 0x0000a234, 0x20202020 },
-    { 0x0000a238, 0x20202020 },
-    { 0x0000a23c, 0x13c889af },
-    { 0x0000a240, 0x38490a20 },
-    { 0x0000a244, 0x00007bb6 },
-    { 0x0000a248, 0x0fff3ffc },
-    { 0x0000a24c, 0x00000001 },
-    { 0x0000a250, 0x0000e000 },
-    { 0x0000a254, 0x00000000 },
-    { 0x0000a258, 0x0cc75380 },
-    { 0x0000a25c, 0x0f0f0f01 },
-    { 0x0000a260, 0xdfa91f01 },
-    { 0x0000a268, 0x00000001 },
-    { 0x0000a26c, 0x0ebae9c6 },
-    { 0x0000b26c, 0x0ebae9c6 },
-    { 0x0000c26c, 0x0ebae9c6 },
-    { 0x0000d270, 0x00820820 },
-    { 0x0000a278, 0x1ce739ce },
-    { 0x0000a27c, 0x050701ce },
-    { 0x0000a338, 0x00000000 },
-    { 0x0000a33c, 0x00000000 },
-    { 0x0000a340, 0x00000000 },
-    { 0x0000a344, 0x00000000 },
-    { 0x0000a348, 0x3fffffff },
-    { 0x0000a34c, 0x3fffffff },
-    { 0x0000a350, 0x3fffffff },
-    { 0x0000a354, 0x0003ffff },
-    { 0x0000a358, 0x79bfaa03 },
-    { 0x0000d35c, 0x07ffffef },
-    { 0x0000d360, 0x0fffffe7 },
-    { 0x0000d364, 0x17ffffe5 },
-    { 0x0000d368, 0x1fffffe4 },
-    { 0x0000d36c, 0x37ffffe3 },
-    { 0x0000d370, 0x3fffffe3 },
-    { 0x0000d374, 0x57ffffe3 },
-    { 0x0000d378, 0x5fffffe2 },
-    { 0x0000d37c, 0x7fffffe2 },
-    { 0x0000d380, 0x7f3c7bba },
-    { 0x0000d384, 0xf3307ff0 },
-    { 0x0000a388, 0x0c000000 },
-    { 0x0000a38c, 0x20202020 },
-    { 0x0000a390, 0x20202020 },
-    { 0x0000a394, 0x1ce739ce },
-    { 0x0000a398, 0x000001ce },
-    { 0x0000a39c, 0x00000001 },
-    { 0x0000a3a0, 0x00000000 },
-    { 0x0000a3a4, 0x00000000 },
-    { 0x0000a3a8, 0x00000000 },
-    { 0x0000a3ac, 0x00000000 },
-    { 0x0000a3b0, 0x00000000 },
-    { 0x0000a3b4, 0x00000000 },
-    { 0x0000a3b8, 0x00000000 },
-    { 0x0000a3bc, 0x00000000 },
-    { 0x0000a3c0, 0x00000000 },
-    { 0x0000a3c4, 0x00000000 },
-    { 0x0000a3c8, 0x00000246 },
-    { 0x0000a3cc, 0x20202020 },
-    { 0x0000a3d0, 0x20202020 },
-    { 0x0000a3d4, 0x20202020 },
-    { 0x0000a3dc, 0x1ce739ce },
-    { 0x0000a3e0, 0x000001ce },
-};
-
-static const u32 ar5416Bank0_9160[][2] = {
-    { 0x000098b0, 0x1e5795e5 },
-    { 0x000098e0, 0x02008020 },
-};
-
-static const u32 ar5416BB_RfGain_9160[][3] = {
-    { 0x00009a00, 0x00000000, 0x00000000 },
-    { 0x00009a04, 0x00000040, 0x00000040 },
-    { 0x00009a08, 0x00000080, 0x00000080 },
-    { 0x00009a0c, 0x000001a1, 0x00000141 },
-    { 0x00009a10, 0x000001e1, 0x00000181 },
-    { 0x00009a14, 0x00000021, 0x000001c1 },
-    { 0x00009a18, 0x00000061, 0x00000001 },
-    { 0x00009a1c, 0x00000168, 0x00000041 },
-    { 0x00009a20, 0x000001a8, 0x000001a8 },
-    { 0x00009a24, 0x000001e8, 0x000001e8 },
-    { 0x00009a28, 0x00000028, 0x00000028 },
-    { 0x00009a2c, 0x00000068, 0x00000068 },
-    { 0x00009a30, 0x00000189, 0x000000a8 },
-    { 0x00009a34, 0x000001c9, 0x00000169 },
-    { 0x00009a38, 0x00000009, 0x000001a9 },
-    { 0x00009a3c, 0x00000049, 0x000001e9 },
-    { 0x00009a40, 0x00000089, 0x00000029 },
-    { 0x00009a44, 0x00000170, 0x00000069 },
-    { 0x00009a48, 0x000001b0, 0x00000190 },
-    { 0x00009a4c, 0x000001f0, 0x000001d0 },
-    { 0x00009a50, 0x00000030, 0x00000010 },
-    { 0x00009a54, 0x00000070, 0x00000050 },
-    { 0x00009a58, 0x00000191, 0x00000090 },
-    { 0x00009a5c, 0x000001d1, 0x00000151 },
-    { 0x00009a60, 0x00000011, 0x00000191 },
-    { 0x00009a64, 0x00000051, 0x000001d1 },
-    { 0x00009a68, 0x00000091, 0x00000011 },
-    { 0x00009a6c, 0x000001b8, 0x00000051 },
-    { 0x00009a70, 0x000001f8, 0x00000198 },
-    { 0x00009a74, 0x00000038, 0x000001d8 },
-    { 0x00009a78, 0x00000078, 0x00000018 },
-    { 0x00009a7c, 0x00000199, 0x00000058 },
-    { 0x00009a80, 0x000001d9, 0x00000098 },
-    { 0x00009a84, 0x00000019, 0x00000159 },
-    { 0x00009a88, 0x00000059, 0x00000199 },
-    { 0x00009a8c, 0x00000099, 0x000001d9 },
-    { 0x00009a90, 0x000000d9, 0x00000019 },
-    { 0x00009a94, 0x000000f9, 0x00000059 },
-    { 0x00009a98, 0x000000f9, 0x00000099 },
-    { 0x00009a9c, 0x000000f9, 0x000000d9 },
-    { 0x00009aa0, 0x000000f9, 0x000000f9 },
-    { 0x00009aa4, 0x000000f9, 0x000000f9 },
-    { 0x00009aa8, 0x000000f9, 0x000000f9 },
-    { 0x00009aac, 0x000000f9, 0x000000f9 },
-    { 0x00009ab0, 0x000000f9, 0x000000f9 },
-    { 0x00009ab4, 0x000000f9, 0x000000f9 },
-    { 0x00009ab8, 0x000000f9, 0x000000f9 },
-    { 0x00009abc, 0x000000f9, 0x000000f9 },
-    { 0x00009ac0, 0x000000f9, 0x000000f9 },
-    { 0x00009ac4, 0x000000f9, 0x000000f9 },
-    { 0x00009ac8, 0x000000f9, 0x000000f9 },
-    { 0x00009acc, 0x000000f9, 0x000000f9 },
-    { 0x00009ad0, 0x000000f9, 0x000000f9 },
-    { 0x00009ad4, 0x000000f9, 0x000000f9 },
-    { 0x00009ad8, 0x000000f9, 0x000000f9 },
-    { 0x00009adc, 0x000000f9, 0x000000f9 },
-    { 0x00009ae0, 0x000000f9, 0x000000f9 },
-    { 0x00009ae4, 0x000000f9, 0x000000f9 },
-    { 0x00009ae8, 0x000000f9, 0x000000f9 },
-    { 0x00009aec, 0x000000f9, 0x000000f9 },
-    { 0x00009af0, 0x000000f9, 0x000000f9 },
-    { 0x00009af4, 0x000000f9, 0x000000f9 },
-    { 0x00009af8, 0x000000f9, 0x000000f9 },
-    { 0x00009afc, 0x000000f9, 0x000000f9 },
-};
-
-static const u32 ar5416Bank1_9160[][2] = {
-    { 0x000098b0, 0x02108421 },
-    { 0x000098ec, 0x00000008 },
-};
-
-static const u32 ar5416Bank2_9160[][2] = {
-    { 0x000098b0, 0x0e73ff17 },
-    { 0x000098e0, 0x00000420 },
-};
-
-static const u32 ar5416Bank3_9160[][3] = {
-    { 0x000098f0, 0x01400018, 0x01c00018 },
-};
-
-static const u32 ar5416Bank6_9160[][3] = {
-    { 0x0000989c, 0x00000000, 0x00000000 },
-    { 0x0000989c, 0x00000000, 0x00000000 },
-    { 0x0000989c, 0x00000000, 0x00000000 },
-    { 0x0000989c, 0x00e00000, 0x00e00000 },
-    { 0x0000989c, 0x005e0000, 0x005e0000 },
-    { 0x0000989c, 0x00120000, 0x00120000 },
-    { 0x0000989c, 0x00620000, 0x00620000 },
-    { 0x0000989c, 0x00020000, 0x00020000 },
-    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
-    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
-    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
-    { 0x0000989c, 0x40ff0000, 0x40ff0000 },
-    { 0x0000989c, 0x005f0000, 0x005f0000 },
-    { 0x0000989c, 0x00870000, 0x00870000 },
-    { 0x0000989c, 0x00f90000, 0x00f90000 },
-    { 0x0000989c, 0x007b0000, 0x007b0000 },
-    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
-    { 0x0000989c, 0x00f50000, 0x00f50000 },
-    { 0x0000989c, 0x00dc0000, 0x00dc0000 },
-    { 0x0000989c, 0x00110000, 0x00110000 },
-    { 0x0000989c, 0x006100a8, 0x006100a8 },
-    { 0x0000989c, 0x004210a2, 0x004210a2 },
-    { 0x0000989c, 0x0014008f, 0x0014008f },
-    { 0x0000989c, 0x00c40003, 0x00c40003 },
-    { 0x0000989c, 0x003000f2, 0x003000f2 },
-    { 0x0000989c, 0x00440016, 0x00440016 },
-    { 0x0000989c, 0x00410040, 0x00410040 },
-    { 0x0000989c, 0x0001805e, 0x0001805e },
-    { 0x0000989c, 0x0000c0ab, 0x0000c0ab },
-    { 0x0000989c, 0x000000f1, 0x000000f1 },
-    { 0x0000989c, 0x00002081, 0x00002081 },
-    { 0x0000989c, 0x000000d4, 0x000000d4 },
-    { 0x000098d0, 0x0000000f, 0x0010000f },
-};
-
-static const u32 ar5416Bank6TPC_9160[][3] = {
-    { 0x0000989c, 0x00000000, 0x00000000 },
-    { 0x0000989c, 0x00000000, 0x00000000 },
-    { 0x0000989c, 0x00000000, 0x00000000 },
-    { 0x0000989c, 0x00e00000, 0x00e00000 },
-    { 0x0000989c, 0x005e0000, 0x005e0000 },
-    { 0x0000989c, 0x00120000, 0x00120000 },
-    { 0x0000989c, 0x00620000, 0x00620000 },
-    { 0x0000989c, 0x00020000, 0x00020000 },
-    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
-    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
-    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
-    { 0x0000989c, 0x40ff0000, 0x40ff0000 },
-    { 0x0000989c, 0x005f0000, 0x005f0000 },
-    { 0x0000989c, 0x00870000, 0x00870000 },
-    { 0x0000989c, 0x00f90000, 0x00f90000 },
-    { 0x0000989c, 0x007b0000, 0x007b0000 },
-    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
-    { 0x0000989c, 0x00f50000, 0x00f50000 },
-    { 0x0000989c, 0x00dc0000, 0x00dc0000 },
-    { 0x0000989c, 0x00110000, 0x00110000 },
-    { 0x0000989c, 0x006100a8, 0x006100a8 },
-    { 0x0000989c, 0x00423022, 0x00423022 },
-    { 0x0000989c, 0x2014008f, 0x2014008f },
-    { 0x0000989c, 0x00c40002, 0x00c40002 },
-    { 0x0000989c, 0x003000f2, 0x003000f2 },
-    { 0x0000989c, 0x00440016, 0x00440016 },
-    { 0x0000989c, 0x00410040, 0x00410040 },
-    { 0x0000989c, 0x0001805e, 0x0001805e },
-    { 0x0000989c, 0x0000c0ab, 0x0000c0ab },
-    { 0x0000989c, 0x000000e1, 0x000000e1 },
-    { 0x0000989c, 0x00007080, 0x00007080 },
-    { 0x0000989c, 0x000000d4, 0x000000d4 },
-    { 0x000098d0, 0x0000000f, 0x0010000f },
-};
-
-static const u32 ar5416Bank7_9160[][2] = {
-    { 0x0000989c, 0x00000500 },
-    { 0x0000989c, 0x00000800 },
-    { 0x000098cc, 0x0000000e },
-};
-
-static u32 ar5416Addac_9160[][2] = {
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x000000c0 },
-    {0x0000989c,  0x00000018 },
-    {0x0000989c,  0x00000004 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x000000c0 },
-    {0x0000989c,  0x00000019 },
-    {0x0000989c,  0x00000004 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000004 },
-    {0x0000989c,  0x00000003 },
-    {0x0000989c,  0x00000008 },
-    {0x0000989c,  0x00000000 },
-    {0x000098cc,  0x00000000 },
-};
-
-static u32 ar5416Addac_91601_1[][2] = {
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x000000c0 },
-    {0x0000989c,  0x00000018 },
-    {0x0000989c,  0x00000004 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x000000c0 },
-    {0x0000989c,  0x00000019 },
-    {0x0000989c,  0x00000004 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x000098cc,  0x00000000 },
-};
+#ifndef INITVALS_9002_10_H
+#define INITVALS_9002_10_H
 
-/* XXX 9280 1 */
 static const u32 ar9280Modes_9280[][6] = {
     { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 },
     { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 },
@@ -3441,7 +1468,7 @@ static const u32 ar9280PciePhy_clkreq_always_on_L1_9280[][2] = {
 };
 
 /* AR9285 Revsion 10*/
-static const u_int32_t ar9285Modes_9285[][6] = {
+static const u32 ar9285Modes_9285[][6] = {
     { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 },
     { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 },
     { 0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180 },
@@ -3763,7 +1790,7 @@ static const u_int32_t ar9285Modes_9285[][6] = {
     { 0x0000a358, 0x7999aa02, 0x7999aa02, 0x7999aa0e, 0x7999aa0e, 0x7999aa0e },
 };
 
-static const u_int32_t ar9285Common_9285[][2] = {
+static const u32 ar9285Common_9285[][2] = {
     { 0x0000000c, 0x00000000 },
     { 0x00000030, 0x00020045 },
     { 0x00000034, 0x00000005 },
@@ -4096,7 +2123,7 @@ static const u_int32_t ar9285Common_9285[][2] = {
     { 0x00007870, 0x10142c00 },
 };
 
-static const u_int32_t ar9285PciePhy_clkreq_always_on_L1_9285[][2] = {
+static const u32 ar9285PciePhy_clkreq_always_on_L1_9285[][2] = {
     {0x00004040,  0x9248fd00 },
     {0x00004040,  0x24924924 },
     {0x00004040,  0xa8000019 },
@@ -4109,7 +2136,7 @@ static const u_int32_t ar9285PciePhy_clkreq_always_on_L1_9285[][2] = {
     {0x00004044,  0x00000000 },
 };
 
-static const u_int32_t ar9285PciePhy_clkreq_off_L1_9285[][2] = {
+static const u32 ar9285PciePhy_clkreq_off_L1_9285[][2] = {
     {0x00004040,  0x9248fd00 },
     {0x00004040,  0x24924924 },
     {0x00004040,  0xa8000019 },
@@ -4123,7 +2150,7 @@ static const u_int32_t ar9285PciePhy_clkreq_off_L1_9285[][2] = {
 };
 
 /* AR9285 v1_2 PCI Register Writes.  Created: 04/13/09 */
-static const u_int32_t ar9285Modes_9285_1_2[][6] = {
+static const u32 ar9285Modes_9285_1_2[][6] = {
     /* Address      5G-HT20     5G-HT40     2G-HT40     2G-HT20     Turbo   */
     { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 },
     { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 },
@@ -4429,7 +2456,7 @@ static const u_int32_t ar9285Modes_9285_1_2[][6] = {
     { 0x0000a358, 0x7999aa02, 0x7999aa02, 0x7999aa0e, 0x7999aa0e, 0x7999aa0e },
 };
 
-static const u_int32_t ar9285Common_9285_1_2[][2] = {
+static const u32 ar9285Common_9285_1_2[][2] = {
     { 0x0000000c, 0x00000000 },
     { 0x00000030, 0x00020045 },
     { 0x00000034, 0x00000005 },
@@ -4748,7 +2775,7 @@ static const u_int32_t ar9285Common_9285_1_2[][2] = {
     { 0x00007870, 0x10142c00 },
 };
 
-static const u_int32_t ar9285Modes_high_power_tx_gain_9285_1_2[][6] = {
+static const u32 ar9285Modes_high_power_tx_gain_9285_1_2[][6] = {
     /* Address      5G-HT20     5G-HT40     2G-HT40     2G-HT20     Turbo   */
     { 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
     { 0x0000a304, 0x00000000, 0x00000000, 0x00006200, 0x00006200, 0x00000000 },
@@ -4789,7 +2816,7 @@ static const u_int32_t ar9285Modes_high_power_tx_gain_9285_1_2[][6] = {
     { 0x0000a3e0, 0x000000e7, 0x000000e7, 0x000000e7, 0x000000e7, 0x000000e7 },
 };
 
-static const u_int32_t ar9285Modes_original_tx_gain_9285_1_2[][6] = {
+static const u32 ar9285Modes_original_tx_gain_9285_1_2[][6] = {
     /* Address      5G-HT20     5G-HT40     2G-HT40     2G-HT20     Turbo   */
     { 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
     { 0x0000a304, 0x00000000, 0x00000000, 0x00009200, 0x00009200, 0x00000000 },
@@ -4830,7 +2857,7 @@ static const u_int32_t ar9285Modes_original_tx_gain_9285_1_2[][6] = {
     { 0x0000a3e0, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c },
 };
 
-static const u_int32_t ar9285Modes_XE2_0_normal_power[][6] = {
+static const u32 ar9285Modes_XE2_0_normal_power[][6] = {
     { 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
     { 0x0000a304, 0x00000000, 0x00000000, 0x00009200, 0x00009200, 0x00000000 },
     { 0x0000a308, 0x00000000, 0x00000000, 0x00010208, 0x00010208, 0x00000000 },
@@ -4870,7 +2897,7 @@ static const u_int32_t ar9285Modes_XE2_0_normal_power[][6] = {
     { 0x0000a3e0, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c },
 };
 
-static const u_int32_t ar9285Modes_XE2_0_high_power[][6] = {
+static const u32 ar9285Modes_XE2_0_high_power[][6] = {
     { 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
     { 0x0000a304, 0x00000000, 0x00000000, 0x00006200, 0x00006200, 0x00000000 },
     { 0x0000a308, 0x00000000, 0x00000000, 0x00008201, 0x00008201, 0x00000000 },
@@ -4910,7 +2937,7 @@ static const u_int32_t ar9285Modes_XE2_0_high_power[][6] = {
     { 0x0000a3e0, 0x000000e7, 0x000000e7, 0x000000e7, 0x000000e7, 0x000000e7 },
 };
 
-static const u_int32_t ar9285PciePhy_clkreq_always_on_L1_9285_1_2[][2] = {
+static const u32 ar9285PciePhy_clkreq_always_on_L1_9285_1_2[][2] = {
     {0x00004040,  0x9248fd00 },
     {0x00004040,  0x24924924 },
     {0x00004040,  0xa8000019 },
@@ -4923,7 +2950,7 @@ static const u_int32_t ar9285PciePhy_clkreq_always_on_L1_9285_1_2[][2] = {
     {0x00004044,  0x00000000 },
 };
 
-static const u_int32_t ar9285PciePhy_clkreq_off_L1_9285_1_2[][2] = {
+static const u32 ar9285PciePhy_clkreq_off_L1_9285_1_2[][2] = {
     {0x00004040,  0x9248fd00 },
     {0x00004040,  0x24924924 },
     {0x00004040,  0xa8000019 },
@@ -4937,7 +2964,7 @@ static const u_int32_t ar9285PciePhy_clkreq_off_L1_9285_1_2[][2] = {
 };
 
 /* AR9287 Revision 10 */
-static const u_int32_t ar9287Modes_9287_1_0[][6] = {
+static const u32 ar9287Modes_9287_1_0[][6] = {
     /* Address      5G-HT20     5G-HT40     2G-HT40     2G-HT20     Turbo   */
     { 0x00001030, 0x00000000, 0x00000000, 0x000002c0, 0x00000160, 0x000001e0 },
     { 0x00001070, 0x00000000, 0x00000000, 0x00000318, 0x0000018c, 0x000001e0 },
@@ -4984,7 +3011,7 @@ static const u_int32_t ar9287Modes_9287_1_0[][6] = {
     { 0x0000a3d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
 };
 
-static const u_int32_t ar9287Common_9287_1_0[][2] = {
+static const u32 ar9287Common_9287_1_0[][2] = {
     { 0x0000000c, 0x00000000 },
     { 0x00000030, 0x00020015 },
     { 0x00000034, 0x00000005 },
@@ -5355,7 +3382,7 @@ static const u_int32_t ar9287Common_9287_1_0[][2] = {
     { 0x000078b8, 0x2a850160 },
 };
 
-static const u_int32_t ar9287Modes_tx_gain_9287_1_0[][6] = {
+static const u32 ar9287Modes_tx_gain_9287_1_0[][6] = {
     /* Address      5G-HT20     5G-HT40     2G-HT40     2G-HT20     Turbo   */
     { 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
     { 0x0000a304, 0x00000000, 0x00000000, 0x00004002, 0x00004002, 0x00004002 },
@@ -5405,7 +3432,7 @@ static const u_int32_t ar9287Modes_tx_gain_9287_1_0[][6] = {
 };
 
 
-static const u_int32_t ar9287Modes_rx_gain_9287_1_0[][6] = {
+static const u32 ar9287Modes_rx_gain_9287_1_0[][6] = {
     /* Address      5G-HT20     5G-HT40     2G-HT40     2G-HT20     Turbo   */
     { 0x00009a00, 0x00000000, 0x00000000, 0x0000a120, 0x0000a120, 0x0000a120 },
     { 0x00009a04, 0x00000000, 0x00000000, 0x0000a124, 0x0000a124, 0x0000a124 },
@@ -5667,7 +3694,7 @@ static const u_int32_t ar9287Modes_rx_gain_9287_1_0[][6] = {
     { 0x0000a848, 0x00000000, 0x00000000, 0x00001067, 0x00001067, 0x00001067 },
 };
 
-static const u_int32_t ar9287PciePhy_clkreq_always_on_L1_9287_1_0[][2] = {
+static const u32 ar9287PciePhy_clkreq_always_on_L1_9287_1_0[][2] = {
     {0x00004040,  0x9248fd00 },
     {0x00004040,  0x24924924 },
     {0x00004040,  0xa8000019 },
@@ -5680,7 +3707,7 @@ static const u_int32_t ar9287PciePhy_clkreq_always_on_L1_9287_1_0[][2] = {
     {0x00004044,  0x00000000 },
 };
 
-static const u_int32_t ar9287PciePhy_clkreq_off_L1_9287_1_0[][2] = {
+static const u32 ar9287PciePhy_clkreq_off_L1_9287_1_0[][2] = {
     {0x00004040,  0x9248fd00 },
     {0x00004040,  0x24924924 },
     {0x00004040,  0xa8000019 },
@@ -5695,7 +3722,7 @@ static const u_int32_t ar9287PciePhy_clkreq_off_L1_9287_1_0[][2] = {
 
 /* AR9287 Revision 11 */
 
-static const u_int32_t ar9287Modes_9287_1_1[][6] = {
+static const u32 ar9287Modes_9287_1_1[][6] = {
     /* Address      5G-HT20     5G-HT40     2G-HT40     2G-HT20     Turbo   */
     { 0x00001030, 0x00000000, 0x00000000, 0x000002c0, 0x00000160, 0x000001e0 },
     { 0x00001070, 0x00000000, 0x00000000, 0x00000318, 0x0000018c, 0x000001e0 },
@@ -5742,7 +3769,7 @@ static const u_int32_t ar9287Modes_9287_1_1[][6] = {
     { 0x0000a3d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
 };
 
-static const u_int32_t ar9287Common_9287_1_1[][2] = {
+static const u32 ar9287Common_9287_1_1[][2] = {
     { 0x0000000c, 0x00000000 },
     { 0x00000030, 0x00020015 },
     { 0x00000034, 0x00000005 },
@@ -6112,21 +4139,22 @@ static const u_int32_t ar9287Common_9287_1_1[][2] = {
 
 /*
  * For Japanese regulatory requirements, 2484 MHz requires the following three
- * registers be programmed differently from the channel between 2412 and 2472 MHz.
+ * registers be programmed differently from the channel between 2412 and
+ * 2472 MHz.
  */
-static const u_int32_t ar9287Common_normal_cck_fir_coeff_92871_1[][2] = {
+static const u32 ar9287Common_normal_cck_fir_coeff_92871_1[][2] = {
     { 0x0000a1f4, 0x00fffeff },
     { 0x0000a1f8, 0x00f5f9ff },
     { 0x0000a1fc, 0xb79f6427 },
 };
 
-static const u_int32_t ar9287Common_japan_2484_cck_fir_coeff_92871_1[][2] = {
+static const u32 ar9287Common_japan_2484_cck_fir_coeff_92871_1[][2] = {
     { 0x0000a1f4, 0x00000000 },
     { 0x0000a1f8, 0xefff0301 },
     { 0x0000a1fc, 0xca9228ee },
 };
 
-static const u_int32_t ar9287Modes_tx_gain_9287_1_1[][6] = {
+static const u32 ar9287Modes_tx_gain_9287_1_1[][6] = {
     /* Address      5G-HT20     5G-HT40     2G-HT40     2G-HT20     Turbo   */
     { 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
     { 0x0000a304, 0x00000000, 0x00000000, 0x00004002, 0x00004002, 0x00004002 },
@@ -6175,7 +4203,7 @@ static const u_int32_t ar9287Modes_tx_gain_9287_1_1[][6] = {
     { 0x0000a274, 0x0a180000, 0x0a180000, 0x0a1aa000, 0x0a1aa000, 0x0a1aa000 },
 };
 
-static const u_int32_t ar9287Modes_rx_gain_9287_1_1[][6] = {
+static const u32 ar9287Modes_rx_gain_9287_1_1[][6] = {
     /* Address      5G-HT20     5G-HT40     2G-HT40     2G-HT20     Turbo   */
     { 0x00009a00, 0x00000000, 0x00000000, 0x0000a120, 0x0000a120, 0x0000a120 },
     { 0x00009a04, 0x00000000, 0x00000000, 0x0000a124, 0x0000a124, 0x0000a124 },
@@ -6437,7 +4465,7 @@ static const u_int32_t ar9287Modes_rx_gain_9287_1_1[][6] = {
     { 0x0000a848, 0x00000000, 0x00000000, 0x00001067, 0x00001067, 0x00001067 },
 };
 
-static const u_int32_t ar9287PciePhy_clkreq_always_on_L1_9287_1_1[][2] = {
+static const u32 ar9287PciePhy_clkreq_always_on_L1_9287_1_1[][2] = {
     {0x00004040,  0x9248fd00 },
     {0x00004040,  0x24924924 },
     {0x00004040,  0xa8000019 },
@@ -6450,7 +4478,7 @@ static const u_int32_t ar9287PciePhy_clkreq_always_on_L1_9287_1_1[][2] = {
     {0x00004044,  0x00000000 },
 };
 
-static const u_int32_t ar9287PciePhy_clkreq_off_L1_9287_1_1[][2] = {
+static const u32 ar9287PciePhy_clkreq_off_L1_9287_1_1[][2] = {
     {0x00004040,  0x9248fd00 },
     {0x00004040,  0x24924924 },
     {0x00004040,  0xa8000019 },
@@ -6465,7 +4493,7 @@ static const u_int32_t ar9287PciePhy_clkreq_off_L1_9287_1_1[][2] = {
 
 
 /* AR9271 initialization values automaticaly created: 06/04/09 */
-static const u_int32_t ar9271Modes_9271[][6] = {
+static const u32 ar9271Modes_9271[][6] = {
     { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 },
     { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 },
     { 0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180 },
@@ -6771,7 +4799,7 @@ static const u_int32_t ar9271Modes_9271[][6] = {
     { 0x0000a358, 0x7999aa02, 0x7999aa02, 0x7999aa0e, 0x7999aa0e, 0x7999aa0e },
 };
 
-static const u_int32_t ar9271Common_9271[][2] = {
+static const u32 ar9271Common_9271[][2] = {
     { 0x0000000c, 0x00000000 },
     { 0x00000030, 0x00020045 },
     { 0x00000034, 0x00000005 },
@@ -7099,24 +5127,24 @@ static const u_int32_t ar9271Common_9271[][2] = {
     { 0x0000d384, 0xf3307ff0 },
 };
 
-static const u_int32_t ar9271Common_normal_cck_fir_coeff_9271[][2] = {
+static const u32 ar9271Common_normal_cck_fir_coeff_9271[][2] = {
     { 0x0000a1f4, 0x00fffeff },
     { 0x0000a1f8, 0x00f5f9ff },
     { 0x0000a1fc, 0xb79f6427 },
 };
 
-static const u_int32_t ar9271Common_japan_2484_cck_fir_coeff_9271[][2] = {
+static const u32 ar9271Common_japan_2484_cck_fir_coeff_9271[][2] = {
     { 0x0000a1f4, 0x00000000 },
     { 0x0000a1f8, 0xefff0301 },
     { 0x0000a1fc, 0xca9228ee },
 };
 
-static const u_int32_t ar9271Modes_9271_1_0_only[][6] = {
+static const u32 ar9271Modes_9271_1_0_only[][6] = {
     { 0x00009910, 0x30002311, 0x30002311, 0x30002311, 0x30002311, 0x30002311 },
     { 0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001 },
 };
 
-static const u_int32_t ar9271Modes_9271_ANI_reg[][6] = {
+static const u32 ar9271Modes_9271_ANI_reg[][6] = {
     { 0x00009850, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2 },
     { 0x0000985c, 0x3139605e, 0x3139605e, 0x3137605e, 0x3137605e, 0x3139605e },
     { 0x00009858, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e },
@@ -7127,7 +5155,7 @@ static const u_int32_t ar9271Modes_9271_ANI_reg[][6] = {
     { 0x000099c0, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4 },
 };
 
-static const u_int32_t ar9271Modes_normal_power_tx_gain_9271[][6] = {
+static const u32 ar9271Modes_normal_power_tx_gain_9271[][6] = {
     { 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
     { 0x0000a304, 0x00000000, 0x00000000, 0x00009200, 0x00009200, 0x00000000 },
     { 0x0000a308, 0x00000000, 0x00000000, 0x00010208, 0x00010208, 0x00000000 },
@@ -7163,7 +5191,7 @@ static const u_int32_t ar9271Modes_normal_power_tx_gain_9271[][6] = {
     { 0x0000a3e0, 0x000003bd, 0x000003bd, 0x000003bd, 0x000003bd, 0x000003bd },
 };
 
-static const u_int32_t ar9271Modes_high_power_tx_gain_9271[][6] = {
+static const u32 ar9271Modes_high_power_tx_gain_9271[][6] = {
     { 0x0000a300, 0x00000000, 0x00000000, 0x00010000, 0x00010000, 0x00000000 },
     { 0x0000a304, 0x00000000, 0x00000000, 0x00016200, 0x00016200, 0x00000000 },
     { 0x0000a308, 0x00000000, 0x00000000, 0x00018201, 0x00018201, 0x00000000 },
@@ -7198,3 +5226,5 @@ static const u_int32_t ar9271Modes_high_power_tx_gain_9271[][6] = {
     { 0x0000a3dc, 0x06318c63, 0x06318c63, 0x06318c63, 0x06318c63, 0x06318c63 },
     { 0x0000a3e0, 0x00000063, 0x00000063, 0x00000063, 0x00000063, 0x00000063 },
 };
+
+#endif /* INITVALS_9002_10_H */
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_mac.c b/drivers/net/wireless/ath/ath9k/ar9002_mac.c
new file mode 100644 (file)
index 0000000..2be20d2
--- /dev/null
@@ -0,0 +1,480 @@
+/*
+ * Copyright (c) 2008-2009 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT 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 "hw.h"
+
+#define AR_BufLen           0x00000fff
+
+static void ar9002_hw_rx_enable(struct ath_hw *ah)
+{
+       REG_WRITE(ah, AR_CR, AR_CR_RXE);
+}
+
+static void ar9002_hw_set_desc_link(void *ds, u32 ds_link)
+{
+       ((struct ath_desc*) ds)->ds_link = ds_link;
+}
+
+static void ar9002_hw_get_desc_link(void *ds, u32 **ds_link)
+{
+       *ds_link = &((struct ath_desc *)ds)->ds_link;
+}
+
+static bool ar9002_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked)
+{
+       u32 isr = 0;
+       u32 mask2 = 0;
+       struct ath9k_hw_capabilities *pCap = &ah->caps;
+       u32 sync_cause = 0;
+       bool fatal_int = false;
+       struct ath_common *common = ath9k_hw_common(ah);
+
+       if (!AR_SREV_9100(ah)) {
+               if (REG_READ(ah, AR_INTR_ASYNC_CAUSE) & AR_INTR_MAC_IRQ) {
+                       if ((REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M)
+                           == AR_RTC_STATUS_ON) {
+                               isr = REG_READ(ah, AR_ISR);
+                       }
+               }
+
+               sync_cause = REG_READ(ah, AR_INTR_SYNC_CAUSE) &
+                       AR_INTR_SYNC_DEFAULT;
+
+               *masked = 0;
+
+               if (!isr && !sync_cause)
+                       return false;
+       } else {
+               *masked = 0;
+               isr = REG_READ(ah, AR_ISR);
+       }
+
+       if (isr) {
+               if (isr & AR_ISR_BCNMISC) {
+                       u32 isr2;
+                       isr2 = REG_READ(ah, AR_ISR_S2);
+                       if (isr2 & AR_ISR_S2_TIM)
+                               mask2 |= ATH9K_INT_TIM;
+                       if (isr2 & AR_ISR_S2_DTIM)
+                               mask2 |= ATH9K_INT_DTIM;
+                       if (isr2 & AR_ISR_S2_DTIMSYNC)
+                               mask2 |= ATH9K_INT_DTIMSYNC;
+                       if (isr2 & (AR_ISR_S2_CABEND))
+                               mask2 |= ATH9K_INT_CABEND;
+                       if (isr2 & AR_ISR_S2_GTT)
+                               mask2 |= ATH9K_INT_GTT;
+                       if (isr2 & AR_ISR_S2_CST)
+                               mask2 |= ATH9K_INT_CST;
+                       if (isr2 & AR_ISR_S2_TSFOOR)
+                               mask2 |= ATH9K_INT_TSFOOR;
+               }
+
+               isr = REG_READ(ah, AR_ISR_RAC);
+               if (isr == 0xffffffff) {
+                       *masked = 0;
+                       return false;
+               }
+
+               *masked = isr & ATH9K_INT_COMMON;
+
+               if (ah->config.rx_intr_mitigation) {
+                       if (isr & (AR_ISR_RXMINTR | AR_ISR_RXINTM))
+                               *masked |= ATH9K_INT_RX;
+               }
+
+               if (isr & (AR_ISR_RXOK | AR_ISR_RXERR))
+                       *masked |= ATH9K_INT_RX;
+               if (isr &
+                   (AR_ISR_TXOK | AR_ISR_TXDESC | AR_ISR_TXERR |
+                    AR_ISR_TXEOL)) {
+                       u32 s0_s, s1_s;
+
+                       *masked |= ATH9K_INT_TX;
+
+                       s0_s = REG_READ(ah, AR_ISR_S0_S);
+                       ah->intr_txqs |= MS(s0_s, AR_ISR_S0_QCU_TXOK);
+                       ah->intr_txqs |= MS(s0_s, AR_ISR_S0_QCU_TXDESC);
+
+                       s1_s = REG_READ(ah, AR_ISR_S1_S);
+                       ah->intr_txqs |= MS(s1_s, AR_ISR_S1_QCU_TXERR);
+                       ah->intr_txqs |= MS(s1_s, AR_ISR_S1_QCU_TXEOL);
+               }
+
+               if (isr & AR_ISR_RXORN) {
+                       ath_print(common, ATH_DBG_INTERRUPT,
+                                 "receive FIFO overrun interrupt\n");
+               }
+
+               if (!AR_SREV_9100(ah)) {
+                       if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) {
+                               u32 isr5 = REG_READ(ah, AR_ISR_S5_S);
+                               if (isr5 & AR_ISR_S5_TIM_TIMER)
+                                       *masked |= ATH9K_INT_TIM_TIMER;
+                       }
+               }
+
+               *masked |= mask2;
+       }
+
+       if (AR_SREV_9100(ah))
+               return true;
+
+       if (isr & AR_ISR_GENTMR) {
+               u32 s5_s;
+
+               s5_s = REG_READ(ah, AR_ISR_S5_S);
+               if (isr & AR_ISR_GENTMR) {
+                       ah->intr_gen_timer_trigger =
+                               MS(s5_s, AR_ISR_S5_GENTIMER_TRIG);
+
+                       ah->intr_gen_timer_thresh =
+                               MS(s5_s, AR_ISR_S5_GENTIMER_THRESH);
+
+                       if (ah->intr_gen_timer_trigger)
+                               *masked |= ATH9K_INT_GENTIMER;
+
+               }
+       }
+
+       if (sync_cause) {
+               fatal_int =
+                       (sync_cause &
+                        (AR_INTR_SYNC_HOST1_FATAL | AR_INTR_SYNC_HOST1_PERR))
+                       ? true : false;
+
+               if (fatal_int) {
+                       if (sync_cause & AR_INTR_SYNC_HOST1_FATAL) {
+                               ath_print(common, ATH_DBG_ANY,
+                                         "received PCI FATAL interrupt\n");
+                       }
+                       if (sync_cause & AR_INTR_SYNC_HOST1_PERR) {
+                               ath_print(common, ATH_DBG_ANY,
+                                         "received PCI PERR interrupt\n");
+                       }
+                       *masked |= ATH9K_INT_FATAL;
+               }
+               if (sync_cause & AR_INTR_SYNC_RADM_CPL_TIMEOUT) {
+                       ath_print(common, ATH_DBG_INTERRUPT,
+                                 "AR_INTR_SYNC_RADM_CPL_TIMEOUT\n");
+                       REG_WRITE(ah, AR_RC, AR_RC_HOSTIF);
+                       REG_WRITE(ah, AR_RC, 0);
+                       *masked |= ATH9K_INT_FATAL;
+               }
+               if (sync_cause & AR_INTR_SYNC_LOCAL_TIMEOUT) {
+                       ath_print(common, ATH_DBG_INTERRUPT,
+                                 "AR_INTR_SYNC_LOCAL_TIMEOUT\n");
+               }
+
+               REG_WRITE(ah, AR_INTR_SYNC_CAUSE_CLR, sync_cause);
+               (void) REG_READ(ah, AR_INTR_SYNC_CAUSE_CLR);
+       }
+
+       return true;
+}
+
+static void ar9002_hw_fill_txdesc(struct ath_hw *ah, void *ds, u32 seglen,
+                                 bool is_firstseg, bool is_lastseg,
+                                 const void *ds0, dma_addr_t buf_addr,
+                                 unsigned int qcu)
+{
+       struct ar5416_desc *ads = AR5416DESC(ds);
+
+       ads->ds_data = buf_addr;
+
+       if (is_firstseg) {
+               ads->ds_ctl1 |= seglen | (is_lastseg ? 0 : AR_TxMore);
+       } else if (is_lastseg) {
+               ads->ds_ctl0 = 0;
+               ads->ds_ctl1 = seglen;
+               ads->ds_ctl2 = AR5416DESC_CONST(ds0)->ds_ctl2;
+               ads->ds_ctl3 = AR5416DESC_CONST(ds0)->ds_ctl3;
+       } else {
+               ads->ds_ctl0 = 0;
+               ads->ds_ctl1 = seglen | AR_TxMore;
+               ads->ds_ctl2 = 0;
+               ads->ds_ctl3 = 0;
+       }
+       ads->ds_txstatus0 = ads->ds_txstatus1 = 0;
+       ads->ds_txstatus2 = ads->ds_txstatus3 = 0;
+       ads->ds_txstatus4 = ads->ds_txstatus5 = 0;
+       ads->ds_txstatus6 = ads->ds_txstatus7 = 0;
+       ads->ds_txstatus8 = ads->ds_txstatus9 = 0;
+}
+
+static int ar9002_hw_proc_txdesc(struct ath_hw *ah, void *ds,
+                                struct ath_tx_status *ts)
+{
+       struct ar5416_desc *ads = AR5416DESC(ds);
+
+       if ((ads->ds_txstatus9 & AR_TxDone) == 0)
+               return -EINPROGRESS;
+
+       ts->ts_seqnum = MS(ads->ds_txstatus9, AR_SeqNum);
+       ts->ts_tstamp = ads->AR_SendTimestamp;
+       ts->ts_status = 0;
+       ts->ts_flags = 0;
+
+       if (ads->ds_txstatus1 & AR_FrmXmitOK)
+               ts->ts_status |= ATH9K_TX_ACKED;
+       if (ads->ds_txstatus1 & AR_ExcessiveRetries)
+               ts->ts_status |= ATH9K_TXERR_XRETRY;
+       if (ads->ds_txstatus1 & AR_Filtered)
+               ts->ts_status |= ATH9K_TXERR_FILT;
+       if (ads->ds_txstatus1 & AR_FIFOUnderrun) {
+               ts->ts_status |= ATH9K_TXERR_FIFO;
+               ath9k_hw_updatetxtriglevel(ah, true);
+       }
+       if (ads->ds_txstatus9 & AR_TxOpExceeded)
+               ts->ts_status |= ATH9K_TXERR_XTXOP;
+       if (ads->ds_txstatus1 & AR_TxTimerExpired)
+               ts->ts_status |= ATH9K_TXERR_TIMER_EXPIRED;
+
+       if (ads->ds_txstatus1 & AR_DescCfgErr)
+               ts->ts_flags |= ATH9K_TX_DESC_CFG_ERR;
+       if (ads->ds_txstatus1 & AR_TxDataUnderrun) {
+               ts->ts_flags |= ATH9K_TX_DATA_UNDERRUN;
+               ath9k_hw_updatetxtriglevel(ah, true);
+       }
+       if (ads->ds_txstatus1 & AR_TxDelimUnderrun) {
+               ts->ts_flags |= ATH9K_TX_DELIM_UNDERRUN;
+               ath9k_hw_updatetxtriglevel(ah, true);
+       }
+       if (ads->ds_txstatus0 & AR_TxBaStatus) {
+               ts->ts_flags |= ATH9K_TX_BA;
+               ts->ba_low = ads->AR_BaBitmapLow;
+               ts->ba_high = ads->AR_BaBitmapHigh;
+       }
+
+       ts->ts_rateindex = MS(ads->ds_txstatus9, AR_FinalTxIdx);
+       switch (ts->ts_rateindex) {
+       case 0:
+               ts->ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate0);
+               break;
+       case 1:
+               ts->ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate1);
+               break;
+       case 2:
+               ts->ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate2);
+               break;
+       case 3:
+               ts->ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate3);
+               break;
+       }
+
+       ts->ts_rssi = MS(ads->ds_txstatus5, AR_TxRSSICombined);
+       ts->ts_rssi_ctl0 = MS(ads->ds_txstatus0, AR_TxRSSIAnt00);
+       ts->ts_rssi_ctl1 = MS(ads->ds_txstatus0, AR_TxRSSIAnt01);
+       ts->ts_rssi_ctl2 = MS(ads->ds_txstatus0, AR_TxRSSIAnt02);
+       ts->ts_rssi_ext0 = MS(ads->ds_txstatus5, AR_TxRSSIAnt10);
+       ts->ts_rssi_ext1 = MS(ads->ds_txstatus5, AR_TxRSSIAnt11);
+       ts->ts_rssi_ext2 = MS(ads->ds_txstatus5, AR_TxRSSIAnt12);
+       ts->evm0 = ads->AR_TxEVM0;
+       ts->evm1 = ads->AR_TxEVM1;
+       ts->evm2 = ads->AR_TxEVM2;
+       ts->ts_shortretry = MS(ads->ds_txstatus1, AR_RTSFailCnt);
+       ts->ts_longretry = MS(ads->ds_txstatus1, AR_DataFailCnt);
+       ts->ts_virtcol = MS(ads->ds_txstatus1, AR_VirtRetryCnt);
+       ts->ts_antenna = 0;
+
+       return 0;
+}
+
+static void ar9002_hw_set11n_txdesc(struct ath_hw *ah, void *ds,
+                                   u32 pktLen, enum ath9k_pkt_type type,
+                                   u32 txPower, u32 keyIx,
+                                   enum ath9k_key_type keyType, u32 flags)
+{
+       struct ar5416_desc *ads = AR5416DESC(ds);
+
+       txPower += ah->txpower_indexoffset;
+       if (txPower > 63)
+               txPower = 63;
+
+       ads->ds_ctl0 = (pktLen & AR_FrameLen)
+               | (flags & ATH9K_TXDESC_VMF ? AR_VirtMoreFrag : 0)
+               | SM(txPower, AR_XmitPower)
+               | (flags & ATH9K_TXDESC_VEOL ? AR_VEOL : 0)
+               | (flags & ATH9K_TXDESC_CLRDMASK ? AR_ClrDestMask : 0)
+               | (flags & ATH9K_TXDESC_INTREQ ? AR_TxIntrReq : 0)
+               | (keyIx != ATH9K_TXKEYIX_INVALID ? AR_DestIdxValid : 0);
+
+       ads->ds_ctl1 =
+               (keyIx != ATH9K_TXKEYIX_INVALID ? SM(keyIx, AR_DestIdx) : 0)
+               | SM(type, AR_FrameType)
+               | (flags & ATH9K_TXDESC_NOACK ? AR_NoAck : 0)
+               | (flags & ATH9K_TXDESC_EXT_ONLY ? AR_ExtOnly : 0)
+               | (flags & ATH9K_TXDESC_EXT_AND_CTL ? AR_ExtAndCtl : 0);
+
+       ads->ds_ctl6 = SM(keyType, AR_EncrType);
+
+       if (AR_SREV_9285(ah) || AR_SREV_9271(ah)) {
+               ads->ds_ctl8 = 0;
+               ads->ds_ctl9 = 0;
+               ads->ds_ctl10 = 0;
+               ads->ds_ctl11 = 0;
+       }
+}
+
+static void ar9002_hw_set11n_ratescenario(struct ath_hw *ah, void *ds,
+                                         void *lastds,
+                                         u32 durUpdateEn, u32 rtsctsRate,
+                                         u32 rtsctsDuration,
+                                         struct ath9k_11n_rate_series series[],
+                                         u32 nseries, u32 flags)
+{
+       struct ar5416_desc *ads = AR5416DESC(ds);
+       struct ar5416_desc *last_ads = AR5416DESC(lastds);
+       u32 ds_ctl0;
+
+       if (flags & (ATH9K_TXDESC_RTSENA | ATH9K_TXDESC_CTSENA)) {
+               ds_ctl0 = ads->ds_ctl0;
+
+               if (flags & ATH9K_TXDESC_RTSENA) {
+                       ds_ctl0 &= ~AR_CTSEnable;
+                       ds_ctl0 |= AR_RTSEnable;
+               } else {
+                       ds_ctl0 &= ~AR_RTSEnable;
+                       ds_ctl0 |= AR_CTSEnable;
+               }
+
+               ads->ds_ctl0 = ds_ctl0;
+       } else {
+               ads->ds_ctl0 =
+                       (ads->ds_ctl0 & ~(AR_RTSEnable | AR_CTSEnable));
+       }
+
+       ads->ds_ctl2 = set11nTries(series, 0)
+               | set11nTries(series, 1)
+               | set11nTries(series, 2)
+               | set11nTries(series, 3)
+               | (durUpdateEn ? AR_DurUpdateEna : 0)
+               | SM(0, AR_BurstDur);
+
+       ads->ds_ctl3 = set11nRate(series, 0)
+               | set11nRate(series, 1)
+               | set11nRate(series, 2)
+               | set11nRate(series, 3);
+
+       ads->ds_ctl4 = set11nPktDurRTSCTS(series, 0)
+               | set11nPktDurRTSCTS(series, 1);
+
+       ads->ds_ctl5 = set11nPktDurRTSCTS(series, 2)
+               | set11nPktDurRTSCTS(series, 3);
+
+       ads->ds_ctl7 = set11nRateFlags(series, 0)
+               | set11nRateFlags(series, 1)
+               | set11nRateFlags(series, 2)
+               | set11nRateFlags(series, 3)
+               | SM(rtsctsRate, AR_RTSCTSRate);
+       last_ads->ds_ctl2 = ads->ds_ctl2;
+       last_ads->ds_ctl3 = ads->ds_ctl3;
+}
+
+static void ar9002_hw_set11n_aggr_first(struct ath_hw *ah, void *ds,
+                                       u32 aggrLen)
+{
+       struct ar5416_desc *ads = AR5416DESC(ds);
+
+       ads->ds_ctl1 |= (AR_IsAggr | AR_MoreAggr);
+       ads->ds_ctl6 &= ~AR_AggrLen;
+       ads->ds_ctl6 |= SM(aggrLen, AR_AggrLen);
+}
+
+static void ar9002_hw_set11n_aggr_middle(struct ath_hw *ah, void *ds,
+                                        u32 numDelims)
+{
+       struct ar5416_desc *ads = AR5416DESC(ds);
+       unsigned int ctl6;
+
+       ads->ds_ctl1 |= (AR_IsAggr | AR_MoreAggr);
+
+       ctl6 = ads->ds_ctl6;
+       ctl6 &= ~AR_PadDelim;
+       ctl6 |= SM(numDelims, AR_PadDelim);
+       ads->ds_ctl6 = ctl6;
+}
+
+static void ar9002_hw_set11n_aggr_last(struct ath_hw *ah, void *ds)
+{
+       struct ar5416_desc *ads = AR5416DESC(ds);
+
+       ads->ds_ctl1 |= AR_IsAggr;
+       ads->ds_ctl1 &= ~AR_MoreAggr;
+       ads->ds_ctl6 &= ~AR_PadDelim;
+}
+
+static void ar9002_hw_clr11n_aggr(struct ath_hw *ah, void *ds)
+{
+       struct ar5416_desc *ads = AR5416DESC(ds);
+
+       ads->ds_ctl1 &= (~AR_IsAggr & ~AR_MoreAggr);
+}
+
+static void ar9002_hw_set11n_burstduration(struct ath_hw *ah, void *ds,
+                                          u32 burstDuration)
+{
+       struct ar5416_desc *ads = AR5416DESC(ds);
+
+       ads->ds_ctl2 &= ~AR_BurstDur;
+       ads->ds_ctl2 |= SM(burstDuration, AR_BurstDur);
+}
+
+static void ar9002_hw_set11n_virtualmorefrag(struct ath_hw *ah, void *ds,
+                                           u32 vmf)
+{
+       struct ar5416_desc *ads = AR5416DESC(ds);
+
+       if (vmf)
+               ads->ds_ctl0 |= AR_VirtMoreFrag;
+       else
+               ads->ds_ctl0 &= ~AR_VirtMoreFrag;
+}
+
+void ath9k_hw_setuprxdesc(struct ath_hw *ah, struct ath_desc *ds,
+                         u32 size, u32 flags)
+{
+       struct ar5416_desc *ads = AR5416DESC(ds);
+       struct ath9k_hw_capabilities *pCap = &ah->caps;
+
+       ads->ds_ctl1 = size & AR_BufLen;
+       if (flags & ATH9K_RXDESC_INTREQ)
+               ads->ds_ctl1 |= AR_RxIntrReq;
+
+       ads->ds_rxstatus8 &= ~AR_RxDone;
+       if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP))
+               memset(&(ads->u), 0, sizeof(ads->u));
+}
+EXPORT_SYMBOL(ath9k_hw_setuprxdesc);
+
+void ar9002_hw_attach_mac_ops(struct ath_hw *ah)
+{
+       struct ath_hw_ops *ops = ath9k_hw_ops(ah);
+
+       ops->rx_enable = ar9002_hw_rx_enable;
+       ops->set_desc_link = ar9002_hw_set_desc_link;
+       ops->get_desc_link = ar9002_hw_get_desc_link;
+       ops->get_isr = ar9002_hw_get_isr;
+       ops->fill_txdesc = ar9002_hw_fill_txdesc;
+       ops->proc_txdesc = ar9002_hw_proc_txdesc;
+       ops->set11n_txdesc = ar9002_hw_set11n_txdesc;
+       ops->set11n_ratescenario = ar9002_hw_set11n_ratescenario;
+       ops->set11n_aggr_first = ar9002_hw_set11n_aggr_first;
+       ops->set11n_aggr_middle = ar9002_hw_set11n_aggr_middle;
+       ops->set11n_aggr_last = ar9002_hw_set11n_aggr_last;
+       ops->clr11n_aggr = ar9002_hw_clr11n_aggr;
+       ops->set11n_burstduration = ar9002_hw_set11n_burstduration;
+       ops->set11n_virtualmorefrag = ar9002_hw_set11n_virtualmorefrag;
+}
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_phy.c b/drivers/net/wireless/ath/ath9k/ar9002_phy.c
new file mode 100644 (file)
index 0000000..18cfe1a
--- /dev/null
@@ -0,0 +1,539 @@
+/*
+ * Copyright (c) 2008-2010 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT 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.
+ */
+
+/**
+ * DOC: Programming Atheros 802.11n analog front end radios
+ *
+ * AR5416 MAC based PCI devices and AR518 MAC based PCI-Express
+ * devices have either an external AR2133 analog front end radio for single
+ * band 2.4 GHz communication or an AR5133 analog front end radio for dual
+ * band 2.4 GHz / 5 GHz communication.
+ *
+ * All devices after the AR5416 and AR5418 family starting with the AR9280
+ * have their analog front radios, MAC/BB and host PCIe/USB interface embedded
+ * into a single-chip and require less programming.
+ *
+ * The following single-chips exist with a respective embedded radio:
+ *
+ * AR9280 - 11n dual-band 2x2 MIMO for PCIe
+ * AR9281 - 11n single-band 1x2 MIMO for PCIe
+ * AR9285 - 11n single-band 1x1 for PCIe
+ * AR9287 - 11n single-band 2x2 MIMO for PCIe
+ *
+ * AR9220 - 11n dual-band 2x2 MIMO for PCI
+ * AR9223 - 11n single-band 2x2 MIMO for PCI
+ *
+ * AR9287 - 11n single-band 1x1 MIMO for USB
+ */
+
+#include "hw.h"
+#include "ar9002_phy.h"
+
+/**
+ * ar9002_hw_set_channel - set channel on single-chip device
+ * @ah: atheros hardware structure
+ * @chan:
+ *
+ * This is the function to change channel on single-chip devices, that is
+ * all devices after ar9280.
+ *
+ * This function takes the channel value in MHz and sets
+ * hardware channel value. Assumes writes have been enabled to analog bus.
+ *
+ * Actual Expression,
+ *
+ * For 2GHz channel,
+ * Channel Frequency = (3/4) * freq_ref * (chansel[8:0] + chanfrac[16:0]/2^17)
+ * (freq_ref = 40MHz)
+ *
+ * For 5GHz channel,
+ * Channel Frequency = (3/2) * freq_ref * (chansel[8:0] + chanfrac[16:0]/2^10)
+ * (freq_ref = 40MHz/(24>>amodeRefSel))
+ */
+static int ar9002_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan)
+{
+       u16 bMode, fracMode, aModeRefSel = 0;
+       u32 freq, ndiv, channelSel = 0, channelFrac = 0, reg32 = 0;
+       struct chan_centers centers;
+       u32 refDivA = 24;
+
+       ath9k_hw_get_channel_centers(ah, chan, &centers);
+       freq = centers.synth_center;
+
+       reg32 = REG_READ(ah, AR_PHY_SYNTH_CONTROL);
+       reg32 &= 0xc0000000;
+
+       if (freq < 4800) { /* 2 GHz, fractional mode */
+               u32 txctl;
+               int regWrites = 0;
+
+               bMode = 1;
+               fracMode = 1;
+               aModeRefSel = 0;
+               channelSel = CHANSEL_2G(freq);
+
+               if (AR_SREV_9287_11_OR_LATER(ah)) {
+                       if (freq == 2484) {
+                               /* Enable channel spreading for channel 14 */
+                               REG_WRITE_ARRAY(&ah->iniCckfirJapan2484,
+                                               1, regWrites);
+                       } else {
+                               REG_WRITE_ARRAY(&ah->iniCckfirNormal,
+                                               1, regWrites);
+                       }
+               } else {
+                       txctl = REG_READ(ah, AR_PHY_CCK_TX_CTRL);
+                       if (freq == 2484) {
+                               /* Enable channel spreading for channel 14 */
+                               REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
+                                         txctl | AR_PHY_CCK_TX_CTRL_JAPAN);
+                       } else {
+                               REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
+                                         txctl & ~AR_PHY_CCK_TX_CTRL_JAPAN);
+                       }
+               }
+       } else {
+               bMode = 0;
+               fracMode = 0;
+
+               switch (ah->eep_ops->get_eeprom(ah, EEP_FRAC_N_5G)) {
+               case 0:
+                       if ((freq % 20) == 0)
+                               aModeRefSel = 3;
+                       else if ((freq % 10) == 0)
+                               aModeRefSel = 2;
+                       if (aModeRefSel)
+                               break;
+               case 1:
+               default:
+                       aModeRefSel = 0;
+                       /*
+                        * Enable 2G (fractional) mode for channels
+                        * which are 5MHz spaced.
+                        */
+                       fracMode = 1;
+                       refDivA = 1;
+                       channelSel = CHANSEL_5G(freq);
+
+                       /* RefDivA setting */
+                       REG_RMW_FIELD(ah, AR_AN_SYNTH9,
+                                     AR_AN_SYNTH9_REFDIVA, refDivA);
+
+               }
+
+               if (!fracMode) {
+                       ndiv = (freq * (refDivA >> aModeRefSel)) / 60;
+                       channelSel = ndiv & 0x1ff;
+                       channelFrac = (ndiv & 0xfffffe00) * 2;
+                       channelSel = (channelSel << 17) | channelFrac;
+               }
+       }
+
+       reg32 = reg32 |
+           (bMode << 29) |
+           (fracMode << 28) | (aModeRefSel << 26) | (channelSel);
+
+       REG_WRITE(ah, AR_PHY_SYNTH_CONTROL, reg32);
+
+       ah->curchan = chan;
+       ah->curchan_rad_index = -1;
+
+       return 0;
+}
+
+/**
+ * ar9002_hw_spur_mitigate - convert baseband spur frequency
+ * @ah: atheros hardware structure
+ * @chan:
+ *
+ * For single-chip solutions. Converts to baseband spur frequency given the
+ * input channel frequency and compute register settings below.
+ */
+static void ar9002_hw_spur_mitigate(struct ath_hw *ah,
+                                   struct ath9k_channel *chan)
+{
+       int bb_spur = AR_NO_SPUR;
+       int freq;
+       int bin, cur_bin;
+       int bb_spur_off, spur_subchannel_sd;
+       int spur_freq_sd;
+       int spur_delta_phase;
+       int denominator;
+       int upper, lower, cur_vit_mask;
+       int tmp, newVal;
+       int i;
+       int pilot_mask_reg[4] = { AR_PHY_TIMING7, AR_PHY_TIMING8,
+                         AR_PHY_PILOT_MASK_01_30, AR_PHY_PILOT_MASK_31_60
+       };
+       int chan_mask_reg[4] = { AR_PHY_TIMING9, AR_PHY_TIMING10,
+                        AR_PHY_CHANNEL_MASK_01_30, AR_PHY_CHANNEL_MASK_31_60
+       };
+       int inc[4] = { 0, 100, 0, 0 };
+       struct chan_centers centers;
+
+       int8_t mask_m[123];
+       int8_t mask_p[123];
+       int8_t mask_amt;
+       int tmp_mask;
+       int cur_bb_spur;
+       bool is2GHz = IS_CHAN_2GHZ(chan);
+
+       memset(&mask_m, 0, sizeof(int8_t) * 123);
+       memset(&mask_p, 0, sizeof(int8_t) * 123);
+
+       ath9k_hw_get_channel_centers(ah, chan, &centers);
+       freq = centers.synth_center;
+
+       ah->config.spurmode = SPUR_ENABLE_EEPROM;
+       for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
+               cur_bb_spur = ah->eep_ops->get_spur_channel(ah, i, is2GHz);
+
+               if (is2GHz)
+                       cur_bb_spur = (cur_bb_spur / 10) + AR_BASE_FREQ_2GHZ;
+               else
+                       cur_bb_spur = (cur_bb_spur / 10) + AR_BASE_FREQ_5GHZ;
+
+               if (AR_NO_SPUR == cur_bb_spur)
+                       break;
+               cur_bb_spur = cur_bb_spur - freq;
+
+               if (IS_CHAN_HT40(chan)) {
+                       if ((cur_bb_spur > -AR_SPUR_FEEQ_BOUND_HT40) &&
+                           (cur_bb_spur < AR_SPUR_FEEQ_BOUND_HT40)) {
+                               bb_spur = cur_bb_spur;
+                               break;
+                       }
+               } else if ((cur_bb_spur > -AR_SPUR_FEEQ_BOUND_HT20) &&
+                          (cur_bb_spur < AR_SPUR_FEEQ_BOUND_HT20)) {
+                       bb_spur = cur_bb_spur;
+                       break;
+               }
+       }
+
+       if (AR_NO_SPUR == bb_spur) {
+               REG_CLR_BIT(ah, AR_PHY_FORCE_CLKEN_CCK,
+                           AR_PHY_FORCE_CLKEN_CCK_MRC_MUX);
+               return;
+       } else {
+               REG_CLR_BIT(ah, AR_PHY_FORCE_CLKEN_CCK,
+                           AR_PHY_FORCE_CLKEN_CCK_MRC_MUX);
+       }
+
+       bin = bb_spur * 320;
+
+       tmp = REG_READ(ah, AR_PHY_TIMING_CTRL4(0));
+
+       ENABLE_REGWRITE_BUFFER(ah);
+
+       newVal = tmp | (AR_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI |
+                       AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER |
+                       AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK |
+                       AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK);
+       REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0), newVal);
+
+       newVal = (AR_PHY_SPUR_REG_MASK_RATE_CNTL |
+                 AR_PHY_SPUR_REG_ENABLE_MASK_PPM |
+                 AR_PHY_SPUR_REG_MASK_RATE_SELECT |
+                 AR_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI |
+                 SM(SPUR_RSSI_THRESH, AR_PHY_SPUR_REG_SPUR_RSSI_THRESH));
+       REG_WRITE(ah, AR_PHY_SPUR_REG, newVal);
+
+       if (IS_CHAN_HT40(chan)) {
+               if (bb_spur < 0) {
+                       spur_subchannel_sd = 1;
+                       bb_spur_off = bb_spur + 10;
+               } else {
+                       spur_subchannel_sd = 0;
+                       bb_spur_off = bb_spur - 10;
+               }
+       } else {
+               spur_subchannel_sd = 0;
+               bb_spur_off = bb_spur;
+       }
+
+       if (IS_CHAN_HT40(chan))
+               spur_delta_phase =
+                       ((bb_spur * 262144) /
+                        10) & AR_PHY_TIMING11_SPUR_DELTA_PHASE;
+       else
+               spur_delta_phase =
+                       ((bb_spur * 524288) /
+                        10) & AR_PHY_TIMING11_SPUR_DELTA_PHASE;
+
+       denominator = IS_CHAN_2GHZ(chan) ? 44 : 40;
+       spur_freq_sd = ((bb_spur_off * 2048) / denominator) & 0x3ff;
+
+       newVal = (AR_PHY_TIMING11_USE_SPUR_IN_AGC |
+                 SM(spur_freq_sd, AR_PHY_TIMING11_SPUR_FREQ_SD) |
+                 SM(spur_delta_phase, AR_PHY_TIMING11_SPUR_DELTA_PHASE));
+       REG_WRITE(ah, AR_PHY_TIMING11, newVal);
+
+       newVal = spur_subchannel_sd << AR_PHY_SFCORR_SPUR_SUBCHNL_SD_S;
+       REG_WRITE(ah, AR_PHY_SFCORR_EXT, newVal);
+
+       cur_bin = -6000;
+       upper = bin + 100;
+       lower = bin - 100;
+
+       for (i = 0; i < 4; i++) {
+               int pilot_mask = 0;
+               int chan_mask = 0;
+               int bp = 0;
+               for (bp = 0; bp < 30; bp++) {
+                       if ((cur_bin > lower) && (cur_bin < upper)) {
+                               pilot_mask = pilot_mask | 0x1 << bp;
+                               chan_mask = chan_mask | 0x1 << bp;
+                       }
+                       cur_bin += 100;
+               }
+               cur_bin += inc[i];
+               REG_WRITE(ah, pilot_mask_reg[i], pilot_mask);
+               REG_WRITE(ah, chan_mask_reg[i], chan_mask);
+       }
+
+       cur_vit_mask = 6100;
+       upper = bin + 120;
+       lower = bin - 120;
+
+       for (i = 0; i < 123; i++) {
+               if ((cur_vit_mask > lower) && (cur_vit_mask < upper)) {
+
+                       /* workaround for gcc bug #37014 */
+                       volatile int tmp_v = abs(cur_vit_mask - bin);
+
+                       if (tmp_v < 75)
+                               mask_amt = 1;
+                       else
+                               mask_amt = 0;
+                       if (cur_vit_mask < 0)
+                               mask_m[abs(cur_vit_mask / 100)] = mask_amt;
+                       else
+                               mask_p[cur_vit_mask / 100] = mask_amt;
+               }
+               cur_vit_mask -= 100;
+       }
+
+       tmp_mask = (mask_m[46] << 30) | (mask_m[47] << 28)
+               | (mask_m[48] << 26) | (mask_m[49] << 24)
+               | (mask_m[50] << 22) | (mask_m[51] << 20)
+               | (mask_m[52] << 18) | (mask_m[53] << 16)
+               | (mask_m[54] << 14) | (mask_m[55] << 12)
+               | (mask_m[56] << 10) | (mask_m[57] << 8)
+               | (mask_m[58] << 6) | (mask_m[59] << 4)
+               | (mask_m[60] << 2) | (mask_m[61] << 0);
+       REG_WRITE(ah, AR_PHY_BIN_MASK_1, tmp_mask);
+       REG_WRITE(ah, AR_PHY_VIT_MASK2_M_46_61, tmp_mask);
+
+       tmp_mask = (mask_m[31] << 28)
+               | (mask_m[32] << 26) | (mask_m[33] << 24)
+               | (mask_m[34] << 22) | (mask_m[35] << 20)
+               | (mask_m[36] << 18) | (mask_m[37] << 16)
+               | (mask_m[48] << 14) | (mask_m[39] << 12)
+               | (mask_m[40] << 10) | (mask_m[41] << 8)
+               | (mask_m[42] << 6) | (mask_m[43] << 4)
+               | (mask_m[44] << 2) | (mask_m[45] << 0);
+       REG_WRITE(ah, AR_PHY_BIN_MASK_2, tmp_mask);
+       REG_WRITE(ah, AR_PHY_MASK2_M_31_45, tmp_mask);
+
+       tmp_mask = (mask_m[16] << 30) | (mask_m[16] << 28)
+               | (mask_m[18] << 26) | (mask_m[18] << 24)
+               | (mask_m[20] << 22) | (mask_m[20] << 20)
+               | (mask_m[22] << 18) | (mask_m[22] << 16)
+               | (mask_m[24] << 14) | (mask_m[24] << 12)
+               | (mask_m[25] << 10) | (mask_m[26] << 8)
+               | (mask_m[27] << 6) | (mask_m[28] << 4)
+               | (mask_m[29] << 2) | (mask_m[30] << 0);
+       REG_WRITE(ah, AR_PHY_BIN_MASK_3, tmp_mask);
+       REG_WRITE(ah, AR_PHY_MASK2_M_16_30, tmp_mask);
+
+       tmp_mask = (mask_m[0] << 30) | (mask_m[1] << 28)
+               | (mask_m[2] << 26) | (mask_m[3] << 24)
+               | (mask_m[4] << 22) | (mask_m[5] << 20)
+               | (mask_m[6] << 18) | (mask_m[7] << 16)
+               | (mask_m[8] << 14) | (mask_m[9] << 12)
+               | (mask_m[10] << 10) | (mask_m[11] << 8)
+               | (mask_m[12] << 6) | (mask_m[13] << 4)
+               | (mask_m[14] << 2) | (mask_m[15] << 0);
+       REG_WRITE(ah, AR_PHY_MASK_CTL, tmp_mask);
+       REG_WRITE(ah, AR_PHY_MASK2_M_00_15, tmp_mask);
+
+       tmp_mask = (mask_p[15] << 28)
+               | (mask_p[14] << 26) | (mask_p[13] << 24)
+               | (mask_p[12] << 22) | (mask_p[11] << 20)
+               | (mask_p[10] << 18) | (mask_p[9] << 16)
+               | (mask_p[8] << 14) | (mask_p[7] << 12)
+               | (mask_p[6] << 10) | (mask_p[5] << 8)
+               | (mask_p[4] << 6) | (mask_p[3] << 4)
+               | (mask_p[2] << 2) | (mask_p[1] << 0);
+       REG_WRITE(ah, AR_PHY_BIN_MASK2_1, tmp_mask);
+       REG_WRITE(ah, AR_PHY_MASK2_P_15_01, tmp_mask);
+
+       tmp_mask = (mask_p[30] << 28)
+               | (mask_p[29] << 26) | (mask_p[28] << 24)
+               | (mask_p[27] << 22) | (mask_p[26] << 20)
+               | (mask_p[25] << 18) | (mask_p[24] << 16)
+               | (mask_p[23] << 14) | (mask_p[22] << 12)
+               | (mask_p[21] << 10) | (mask_p[20] << 8)
+               | (mask_p[19] << 6) | (mask_p[18] << 4)
+               | (mask_p[17] << 2) | (mask_p[16] << 0);
+       REG_WRITE(ah, AR_PHY_BIN_MASK2_2, tmp_mask);
+       REG_WRITE(ah, AR_PHY_MASK2_P_30_16, tmp_mask);
+
+       tmp_mask = (mask_p[45] << 28)
+               | (mask_p[44] << 26) | (mask_p[43] << 24)
+               | (mask_p[42] << 22) | (mask_p[41] << 20)
+               | (mask_p[40] << 18) | (mask_p[39] << 16)
+               | (mask_p[38] << 14) | (mask_p[37] << 12)
+               | (mask_p[36] << 10) | (mask_p[35] << 8)
+               | (mask_p[34] << 6) | (mask_p[33] << 4)
+               | (mask_p[32] << 2) | (mask_p[31] << 0);
+       REG_WRITE(ah, AR_PHY_BIN_MASK2_3, tmp_mask);
+       REG_WRITE(ah, AR_PHY_MASK2_P_45_31, tmp_mask);
+
+       tmp_mask = (mask_p[61] << 30) | (mask_p[60] << 28)
+               | (mask_p[59] << 26) | (mask_p[58] << 24)
+               | (mask_p[57] << 22) | (mask_p[56] << 20)
+               | (mask_p[55] << 18) | (mask_p[54] << 16)
+               | (mask_p[53] << 14) | (mask_p[52] << 12)
+               | (mask_p[51] << 10) | (mask_p[50] << 8)
+               | (mask_p[49] << 6) | (mask_p[48] << 4)
+               | (mask_p[47] << 2) | (mask_p[46] << 0);
+       REG_WRITE(ah, AR_PHY_BIN_MASK2_4, tmp_mask);
+       REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask);
+
+       REGWRITE_BUFFER_FLUSH(ah);
+       DISABLE_REGWRITE_BUFFER(ah);
+}
+
+static void ar9002_olc_init(struct ath_hw *ah)
+{
+       u32 i;
+
+       if (!OLC_FOR_AR9280_20_LATER)
+               return;
+
+       if (OLC_FOR_AR9287_10_LATER) {
+               REG_SET_BIT(ah, AR_PHY_TX_PWRCTRL9,
+                               AR_PHY_TX_PWRCTRL9_RES_DC_REMOVAL);
+               ath9k_hw_analog_shift_rmw(ah, AR9287_AN_TXPC0,
+                               AR9287_AN_TXPC0_TXPCMODE,
+                               AR9287_AN_TXPC0_TXPCMODE_S,
+                               AR9287_AN_TXPC0_TXPCMODE_TEMPSENSE);
+               udelay(100);
+       } else {
+               for (i = 0; i < AR9280_TX_GAIN_TABLE_SIZE; i++)
+                       ah->originalGain[i] =
+                               MS(REG_READ(ah, AR_PHY_TX_GAIN_TBL1 + i * 4),
+                                               AR_PHY_TX_GAIN);
+               ah->PDADCdelta = 0;
+       }
+}
+
+static u32 ar9002_hw_compute_pll_control(struct ath_hw *ah,
+                                        struct ath9k_channel *chan)
+{
+       u32 pll;
+
+       pll = SM(0x5, AR_RTC_9160_PLL_REFDIV);
+
+       if (chan && IS_CHAN_HALF_RATE(chan))
+               pll |= SM(0x1, AR_RTC_9160_PLL_CLKSEL);
+       else if (chan && IS_CHAN_QUARTER_RATE(chan))
+               pll |= SM(0x2, AR_RTC_9160_PLL_CLKSEL);
+
+       if (chan && IS_CHAN_5GHZ(chan)) {
+               pll |= SM(0x28, AR_RTC_9160_PLL_DIV);
+
+
+               if (AR_SREV_9280_20(ah)) {
+                       if (((chan->channel % 20) == 0)
+                           || ((chan->channel % 10) == 0))
+                               pll = 0x2850;
+                       else
+                               pll = 0x142c;
+               }
+       } else {
+               pll |= SM(0x2c, AR_RTC_9160_PLL_DIV);
+       }
+
+       return pll;
+}
+
+static void ar9002_hw_do_getnf(struct ath_hw *ah,
+                             int16_t nfarray[NUM_NF_READINGS])
+{
+       struct ath_common *common = ath9k_hw_common(ah);
+       int16_t nf;
+
+       nf = MS(REG_READ(ah, AR_PHY_CCA), AR9280_PHY_MINCCA_PWR);
+
+       if (nf & 0x100)
+               nf = 0 - ((nf ^ 0x1ff) + 1);
+       ath_print(common, ATH_DBG_CALIBRATE,
+                 "NF calibrated [ctl] [chain 0] is %d\n", nf);
+
+       if (AR_SREV_9271(ah) && (nf >= -114))
+               nf = -116;
+
+       nfarray[0] = nf;
+
+       if (!AR_SREV_9285(ah) && !AR_SREV_9271(ah)) {
+               nf = MS(REG_READ(ah, AR_PHY_CH1_CCA),
+                               AR9280_PHY_CH1_MINCCA_PWR);
+
+               if (nf & 0x100)
+                       nf = 0 - ((nf ^ 0x1ff) + 1);
+               ath_print(common, ATH_DBG_CALIBRATE,
+                         "NF calibrated [ctl] [chain 1] is %d\n", nf);
+               nfarray[1] = nf;
+       }
+
+       nf = MS(REG_READ(ah, AR_PHY_EXT_CCA), AR9280_PHY_EXT_MINCCA_PWR);
+       if (nf & 0x100)
+               nf = 0 - ((nf ^ 0x1ff) + 1);
+       ath_print(common, ATH_DBG_CALIBRATE,
+                 "NF calibrated [ext] [chain 0] is %d\n", nf);
+
+       if (AR_SREV_9271(ah) && (nf >= -114))
+               nf = -116;
+
+       nfarray[3] = nf;
+
+       if (!AR_SREV_9285(ah) && !AR_SREV_9271(ah)) {
+               nf = MS(REG_READ(ah, AR_PHY_CH1_EXT_CCA),
+                               AR9280_PHY_CH1_EXT_MINCCA_PWR);
+
+               if (nf & 0x100)
+                       nf = 0 - ((nf ^ 0x1ff) + 1);
+               ath_print(common, ATH_DBG_CALIBRATE,
+                         "NF calibrated [ext] [chain 1] is %d\n", nf);
+               nfarray[4] = nf;
+       }
+}
+
+void ar9002_hw_attach_phy_ops(struct ath_hw *ah)
+{
+       struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
+
+       priv_ops->set_rf_regs = NULL;
+       priv_ops->rf_alloc_ext_banks = NULL;
+       priv_ops->rf_free_ext_banks = NULL;
+       priv_ops->rf_set_freq = ar9002_hw_set_channel;
+       priv_ops->spur_mitigate_freq = ar9002_hw_spur_mitigate;
+       priv_ops->olc_init = ar9002_olc_init;
+       priv_ops->compute_pll_control = ar9002_hw_compute_pll_control;
+       priv_ops->do_getnf = ar9002_hw_do_getnf;
+}
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_phy.h b/drivers/net/wireless/ath/ath9k/ar9002_phy.h
new file mode 100644 (file)
index 0000000..81bf6e5
--- /dev/null
@@ -0,0 +1,572 @@
+/*
+ * Copyright (c) 2008-2010 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT 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.
+ */
+#ifndef AR9002_PHY_H
+#define AR9002_PHY_H
+
+#define AR_PHY_TEST             0x9800
+#define PHY_AGC_CLR             0x10000000
+#define RFSILENT_BB             0x00002000
+
+#define AR_PHY_TURBO                0x9804
+#define AR_PHY_FC_TURBO_MODE        0x00000001
+#define AR_PHY_FC_TURBO_SHORT       0x00000002
+#define AR_PHY_FC_DYN2040_EN        0x00000004
+#define AR_PHY_FC_DYN2040_PRI_ONLY  0x00000008
+#define AR_PHY_FC_DYN2040_PRI_CH    0x00000010
+/* For 25 MHz channel spacing -- not used but supported by hw */
+#define AR_PHY_FC_DYN2040_EXT_CH    0x00000020
+#define AR_PHY_FC_HT_EN             0x00000040
+#define AR_PHY_FC_SHORT_GI_40       0x00000080
+#define AR_PHY_FC_WALSH             0x00000100
+#define AR_PHY_FC_SINGLE_HT_LTF1    0x00000200
+#define AR_PHY_FC_ENABLE_DAC_FIFO   0x00000800
+
+#define AR_PHY_TEST2                   0x9808
+
+#define AR_PHY_TIMING2           0x9810
+#define AR_PHY_TIMING3           0x9814
+#define AR_PHY_TIMING3_DSC_MAN   0xFFFE0000
+#define AR_PHY_TIMING3_DSC_MAN_S 17
+#define AR_PHY_TIMING3_DSC_EXP   0x0001E000
+#define AR_PHY_TIMING3_DSC_EXP_S 13
+
+#define AR_PHY_CHIP_ID_REV_0      0x80
+#define AR_PHY_CHIP_ID_REV_1      0x81
+#define AR_PHY_CHIP_ID_9160_REV_0 0xb0
+
+#define AR_PHY_ACTIVE       0x981C
+#define AR_PHY_ACTIVE_EN    0x00000001
+#define AR_PHY_ACTIVE_DIS   0x00000000
+
+#define AR_PHY_RF_CTL2             0x9824
+#define AR_PHY_TX_END_DATA_START   0x000000FF
+#define AR_PHY_TX_END_DATA_START_S 0
+#define AR_PHY_TX_END_PA_ON        0x0000FF00
+#define AR_PHY_TX_END_PA_ON_S      8
+
+#define AR_PHY_RF_CTL3                  0x9828
+#define AR_PHY_TX_END_TO_A2_RX_ON       0x00FF0000
+#define AR_PHY_TX_END_TO_A2_RX_ON_S     16
+
+#define AR_PHY_ADC_CTL                  0x982C
+#define AR_PHY_ADC_CTL_OFF_INBUFGAIN    0x00000003
+#define AR_PHY_ADC_CTL_OFF_INBUFGAIN_S  0
+#define AR_PHY_ADC_CTL_OFF_PWDDAC       0x00002000
+#define AR_PHY_ADC_CTL_OFF_PWDBANDGAP   0x00004000
+#define AR_PHY_ADC_CTL_OFF_PWDADC       0x00008000
+#define AR_PHY_ADC_CTL_ON_INBUFGAIN     0x00030000
+#define AR_PHY_ADC_CTL_ON_INBUFGAIN_S   16
+
+#define AR_PHY_ADC_SERIAL_CTL       0x9830
+#define AR_PHY_SEL_INTERNAL_ADDAC   0x00000000
+#define AR_PHY_SEL_EXTERNAL_RADIO   0x00000001
+
+#define AR_PHY_RF_CTL4                    0x9834
+#define AR_PHY_RF_CTL4_TX_END_XPAB_OFF    0xFF000000
+#define AR_PHY_RF_CTL4_TX_END_XPAB_OFF_S  24
+#define AR_PHY_RF_CTL4_TX_END_XPAA_OFF    0x00FF0000
+#define AR_PHY_RF_CTL4_TX_END_XPAA_OFF_S  16
+#define AR_PHY_RF_CTL4_FRAME_XPAB_ON      0x0000FF00
+#define AR_PHY_RF_CTL4_FRAME_XPAB_ON_S    8
+#define AR_PHY_RF_CTL4_FRAME_XPAA_ON      0x000000FF
+#define AR_PHY_RF_CTL4_FRAME_XPAA_ON_S    0
+
+#define AR_PHY_TSTDAC_CONST               0x983c
+
+#define AR_PHY_SETTLING          0x9844
+#define AR_PHY_SETTLING_SWITCH   0x00003F80
+#define AR_PHY_SETTLING_SWITCH_S 7
+
+#define AR_PHY_RXGAIN                   0x9848
+#define AR_PHY_RXGAIN_TXRX_ATTEN        0x0003F000
+#define AR_PHY_RXGAIN_TXRX_ATTEN_S      12
+#define AR_PHY_RXGAIN_TXRX_RF_MAX       0x007C0000
+#define AR_PHY_RXGAIN_TXRX_RF_MAX_S     18
+#define AR9280_PHY_RXGAIN_TXRX_ATTEN    0x00003F80
+#define AR9280_PHY_RXGAIN_TXRX_ATTEN_S  7
+#define AR9280_PHY_RXGAIN_TXRX_MARGIN   0x001FC000
+#define AR9280_PHY_RXGAIN_TXRX_MARGIN_S 14
+
+#define AR_PHY_DESIRED_SZ           0x9850
+#define AR_PHY_DESIRED_SZ_ADC       0x000000FF
+#define AR_PHY_DESIRED_SZ_ADC_S     0
+#define AR_PHY_DESIRED_SZ_PGA       0x0000FF00
+#define AR_PHY_DESIRED_SZ_PGA_S     8
+#define AR_PHY_DESIRED_SZ_TOT_DES   0x0FF00000
+#define AR_PHY_DESIRED_SZ_TOT_DES_S 20
+
+#define AR_PHY_FIND_SIG           0x9858
+#define AR_PHY_FIND_SIG_FIRSTEP   0x0003F000
+#define AR_PHY_FIND_SIG_FIRSTEP_S 12
+#define AR_PHY_FIND_SIG_FIRPWR    0x03FC0000
+#define AR_PHY_FIND_SIG_FIRPWR_S  18
+
+#define AR_PHY_AGC_CTL1                  0x985C
+#define AR_PHY_AGC_CTL1_COARSE_LOW       0x00007F80
+#define AR_PHY_AGC_CTL1_COARSE_LOW_S     7
+#define AR_PHY_AGC_CTL1_COARSE_HIGH      0x003F8000
+#define AR_PHY_AGC_CTL1_COARSE_HIGH_S    15
+
+#define AR_PHY_CCA                  0x9864
+#define AR_PHY_MINCCA_PWR           0x0FF80000
+#define AR_PHY_MINCCA_PWR_S         19
+#define AR_PHY_CCA_THRESH62         0x0007F000
+#define AR_PHY_CCA_THRESH62_S       12
+#define AR9280_PHY_MINCCA_PWR       0x1FF00000
+#define AR9280_PHY_MINCCA_PWR_S     20
+#define AR9280_PHY_CCA_THRESH62     0x000FF000
+#define AR9280_PHY_CCA_THRESH62_S   12
+
+#define AR_PHY_SFCORR_LOW                    0x986C
+#define AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW  0x00000001
+#define AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW    0x00003F00
+#define AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW_S  8
+#define AR_PHY_SFCORR_LOW_M1_THRESH_LOW      0x001FC000
+#define AR_PHY_SFCORR_LOW_M1_THRESH_LOW_S    14
+#define AR_PHY_SFCORR_LOW_M2_THRESH_LOW      0x0FE00000
+#define AR_PHY_SFCORR_LOW_M2_THRESH_LOW_S    21
+
+#define AR_PHY_SFCORR                0x9868
+#define AR_PHY_SFCORR_M2COUNT_THR    0x0000001F
+#define AR_PHY_SFCORR_M2COUNT_THR_S  0
+#define AR_PHY_SFCORR_M1_THRESH      0x00FE0000
+#define AR_PHY_SFCORR_M1_THRESH_S    17
+#define AR_PHY_SFCORR_M2_THRESH      0x7F000000
+#define AR_PHY_SFCORR_M2_THRESH_S    24
+
+#define AR_PHY_SLEEP_CTR_CONTROL    0x9870
+#define AR_PHY_SLEEP_CTR_LIMIT      0x9874
+#define AR_PHY_SYNTH_CONTROL        0x9874
+#define AR_PHY_SLEEP_SCAL           0x9878
+
+#define AR_PHY_PLL_CTL          0x987c
+#define AR_PHY_PLL_CTL_40       0xaa
+#define AR_PHY_PLL_CTL_40_5413  0x04
+#define AR_PHY_PLL_CTL_44       0xab
+#define AR_PHY_PLL_CTL_44_2133  0xeb
+#define AR_PHY_PLL_CTL_40_2133  0xea
+
+#define AR_PHY_SPECTRAL_SCAN                   0x9910  /* AR9280 spectral scan configuration register */
+#define        AR_PHY_SPECTRAL_SCAN_ENABLE             0x1
+#define AR_PHY_SPECTRAL_SCAN_ENA               0x00000001  /* Enable spectral scan, reg 68, bit 0 */
+#define AR_PHY_SPECTRAL_SCAN_ENA_S             0  /* Enable spectral scan, reg 68, bit 0 */
+#define AR_PHY_SPECTRAL_SCAN_ACTIVE            0x00000002  /* Activate spectral scan reg 68, bit 1*/
+#define AR_PHY_SPECTRAL_SCAN_ACTIVE_S          1  /* Activate spectral scan reg 68, bit 1*/
+#define AR_PHY_SPECTRAL_SCAN_FFT_PERIOD                0x000000F0  /* Interval for FFT reports, reg 68, bits 4-7*/
+#define AR_PHY_SPECTRAL_SCAN_FFT_PERIOD_S      4
+#define AR_PHY_SPECTRAL_SCAN_PERIOD            0x0000FF00  /* Interval for FFT reports, reg 68, bits 8-15*/
+#define AR_PHY_SPECTRAL_SCAN_PERIOD_S          8
+#define AR_PHY_SPECTRAL_SCAN_COUNT             0x00FF0000  /* Number of reports, reg 68, bits 16-23*/
+#define AR_PHY_SPECTRAL_SCAN_COUNT_S           16
+#define AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT      0x01000000  /* Short repeat, reg 68, bit 24*/
+#define AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT_S    24  /* Short repeat, reg 68, bit 24*/
+
+#define AR_PHY_RX_DELAY           0x9914
+#define AR_PHY_SEARCH_START_DELAY 0x9918
+#define AR_PHY_RX_DELAY_DELAY     0x00003FFF
+
+#define AR_PHY_TIMING_CTRL4(_i)     (0x9920 + ((_i) << 12))
+#define AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF 0x01F
+#define AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF_S   0
+#define AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF 0x7E0
+#define AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF_S   5
+#define AR_PHY_TIMING_CTRL4_IQCORR_ENABLE   0x800
+#define AR_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX 0xF000
+#define AR_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX_S   12
+#define AR_PHY_TIMING_CTRL4_DO_CAL    0x10000
+
+#define AR_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI   0x80000000
+#define        AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER  0x40000000
+#define        AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK    0x20000000
+#define        AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK   0x10000000
+
+#define AR_PHY_TIMING5               0x9924
+#define AR_PHY_TIMING5_CYCPWR_THR1   0x000000FE
+#define AR_PHY_TIMING5_CYCPWR_THR1_S 1
+
+#define AR_PHY_POWER_TX_RATE1               0x9934
+#define AR_PHY_POWER_TX_RATE2               0x9938
+#define AR_PHY_POWER_TX_RATE_MAX            0x993c
+#define AR_PHY_POWER_TX_RATE_MAX_TPC_ENABLE 0x00000040
+
+#define AR_PHY_FRAME_CTL            0x9944
+#define AR_PHY_FRAME_CTL_TX_CLIP    0x00000038
+#define AR_PHY_FRAME_CTL_TX_CLIP_S  3
+
+#define AR_PHY_TXPWRADJ                   0x994C
+#define AR_PHY_TXPWRADJ_CCK_GAIN_DELTA    0x00000FC0
+#define AR_PHY_TXPWRADJ_CCK_GAIN_DELTA_S  6
+#define AR_PHY_TXPWRADJ_CCK_PCDAC_INDEX   0x00FC0000
+#define AR_PHY_TXPWRADJ_CCK_PCDAC_INDEX_S 18
+
+#define AR_PHY_RADAR_EXT      0x9940
+#define AR_PHY_RADAR_EXT_ENA  0x00004000
+
+#define AR_PHY_RADAR_0          0x9954
+#define AR_PHY_RADAR_0_ENA      0x00000001
+#define AR_PHY_RADAR_0_FFT_ENA  0x80000000
+#define AR_PHY_RADAR_0_INBAND   0x0000003e
+#define AR_PHY_RADAR_0_INBAND_S 1
+#define AR_PHY_RADAR_0_PRSSI    0x00000FC0
+#define AR_PHY_RADAR_0_PRSSI_S  6
+#define AR_PHY_RADAR_0_HEIGHT   0x0003F000
+#define AR_PHY_RADAR_0_HEIGHT_S 12
+#define AR_PHY_RADAR_0_RRSSI    0x00FC0000
+#define AR_PHY_RADAR_0_RRSSI_S  18
+#define AR_PHY_RADAR_0_FIRPWR   0x7F000000
+#define AR_PHY_RADAR_0_FIRPWR_S 24
+
+#define AR_PHY_RADAR_1                  0x9958
+#define AR_PHY_RADAR_1_RELPWR_ENA       0x00800000
+#define AR_PHY_RADAR_1_USE_FIR128       0x00400000
+#define AR_PHY_RADAR_1_RELPWR_THRESH    0x003F0000
+#define AR_PHY_RADAR_1_RELPWR_THRESH_S  16
+#define AR_PHY_RADAR_1_BLOCK_CHECK      0x00008000
+#define AR_PHY_RADAR_1_MAX_RRSSI        0x00004000
+#define AR_PHY_RADAR_1_RELSTEP_CHECK    0x00002000
+#define AR_PHY_RADAR_1_RELSTEP_THRESH   0x00001F00
+#define AR_PHY_RADAR_1_RELSTEP_THRESH_S 8
+#define AR_PHY_RADAR_1_MAXLEN           0x000000FF
+#define AR_PHY_RADAR_1_MAXLEN_S         0
+
+#define AR_PHY_SWITCH_CHAIN_0     0x9960
+#define AR_PHY_SWITCH_COM         0x9964
+
+#define AR_PHY_SIGMA_DELTA            0x996C
+#define AR_PHY_SIGMA_DELTA_ADC_SEL    0x00000003
+#define AR_PHY_SIGMA_DELTA_ADC_SEL_S  0
+#define AR_PHY_SIGMA_DELTA_FILT2      0x000000F8
+#define AR_PHY_SIGMA_DELTA_FILT2_S    3
+#define AR_PHY_SIGMA_DELTA_FILT1      0x00001F00
+#define AR_PHY_SIGMA_DELTA_FILT1_S    8
+#define AR_PHY_SIGMA_DELTA_ADC_CLIP   0x01FFE000
+#define AR_PHY_SIGMA_DELTA_ADC_CLIP_S 13
+
+#define AR_PHY_RESTART          0x9970
+#define AR_PHY_RESTART_DIV_GC   0x001C0000
+#define AR_PHY_RESTART_DIV_GC_S 18
+
+#define AR_PHY_RFBUS_REQ        0x997C
+#define AR_PHY_RFBUS_REQ_EN     0x00000001
+
+#define        AR_PHY_TIMING7                  0x9980
+#define        AR_PHY_TIMING8                  0x9984
+#define        AR_PHY_TIMING8_PILOT_MASK_2     0x000FFFFF
+#define        AR_PHY_TIMING8_PILOT_MASK_2_S   0
+
+#define        AR_PHY_BIN_MASK2_1      0x9988
+#define        AR_PHY_BIN_MASK2_2      0x998c
+#define        AR_PHY_BIN_MASK2_3      0x9990
+#define        AR_PHY_BIN_MASK2_4      0x9994
+
+#define        AR_PHY_BIN_MASK_1       0x9900
+#define        AR_PHY_BIN_MASK_2       0x9904
+#define        AR_PHY_BIN_MASK_3       0x9908
+
+#define        AR_PHY_MASK_CTL         0x990c
+
+#define        AR_PHY_BIN_MASK2_4_MASK_4       0x00003FFF
+#define        AR_PHY_BIN_MASK2_4_MASK_4_S     0
+
+#define        AR_PHY_TIMING9                  0x9998
+#define        AR_PHY_TIMING10                 0x999c
+#define        AR_PHY_TIMING10_PILOT_MASK_2    0x000FFFFF
+#define        AR_PHY_TIMING10_PILOT_MASK_2_S  0
+
+#define        AR_PHY_TIMING11                         0x99a0
+#define        AR_PHY_TIMING11_SPUR_DELTA_PHASE        0x000FFFFF
+#define        AR_PHY_TIMING11_SPUR_DELTA_PHASE_S      0
+#define AR_PHY_TIMING11_USE_SPUR_IN_AGC                0x40000000
+#define AR_PHY_TIMING11_USE_SPUR_IN_SELFCOR    0x80000000
+
+#define AR_PHY_RX_CHAINMASK     0x99a4
+#define AR_PHY_NEW_ADC_DC_GAIN_CORR(_i) (0x99b4 + ((_i) << 12))
+#define AR_PHY_NEW_ADC_GAIN_CORR_ENABLE 0x40000000
+#define AR_PHY_NEW_ADC_DC_OFFSET_CORR_ENABLE 0x80000000
+
+#define AR_PHY_MULTICHAIN_GAIN_CTL          0x99ac
+#define AR_PHY_9285_ANT_DIV_CTL_ALL         0x7f000000
+#define AR_PHY_9285_ANT_DIV_CTL             0x01000000
+#define AR_PHY_9285_ANT_DIV_CTL_S           24
+#define AR_PHY_9285_ANT_DIV_ALT_LNACONF     0x06000000
+#define AR_PHY_9285_ANT_DIV_ALT_LNACONF_S   25
+#define AR_PHY_9285_ANT_DIV_MAIN_LNACONF    0x18000000
+#define AR_PHY_9285_ANT_DIV_MAIN_LNACONF_S  27
+#define AR_PHY_9285_ANT_DIV_ALT_GAINTB      0x20000000
+#define AR_PHY_9285_ANT_DIV_ALT_GAINTB_S    29
+#define AR_PHY_9285_ANT_DIV_MAIN_GAINTB     0x40000000
+#define AR_PHY_9285_ANT_DIV_MAIN_GAINTB_S   30
+#define AR_PHY_9285_ANT_DIV_LNA1            2
+#define AR_PHY_9285_ANT_DIV_LNA2            1
+#define AR_PHY_9285_ANT_DIV_LNA1_PLUS_LNA2  3
+#define AR_PHY_9285_ANT_DIV_LNA1_MINUS_LNA2 0
+#define AR_PHY_9285_ANT_DIV_GAINTB_0        0
+#define AR_PHY_9285_ANT_DIV_GAINTB_1        1
+
+#define AR_PHY_EXT_CCA0             0x99b8
+#define AR_PHY_EXT_CCA0_THRESH62    0x000000FF
+#define AR_PHY_EXT_CCA0_THRESH62_S  0
+
+#define AR_PHY_EXT_CCA                  0x99bc
+#define AR_PHY_EXT_CCA_CYCPWR_THR1      0x0000FE00
+#define AR_PHY_EXT_CCA_CYCPWR_THR1_S    9
+#define AR_PHY_EXT_CCA_THRESH62         0x007F0000
+#define AR_PHY_EXT_CCA_THRESH62_S       16
+#define AR_PHY_EXT_MINCCA_PWR           0xFF800000
+#define AR_PHY_EXT_MINCCA_PWR_S         23
+#define AR9280_PHY_EXT_MINCCA_PWR       0x01FF0000
+#define AR9280_PHY_EXT_MINCCA_PWR_S     16
+
+#define AR_PHY_SFCORR_EXT                 0x99c0
+#define AR_PHY_SFCORR_EXT_M1_THRESH       0x0000007F
+#define AR_PHY_SFCORR_EXT_M1_THRESH_S     0
+#define AR_PHY_SFCORR_EXT_M2_THRESH       0x00003F80
+#define AR_PHY_SFCORR_EXT_M2_THRESH_S     7
+#define AR_PHY_SFCORR_EXT_M1_THRESH_LOW   0x001FC000
+#define AR_PHY_SFCORR_EXT_M1_THRESH_LOW_S 14
+#define AR_PHY_SFCORR_EXT_M2_THRESH_LOW   0x0FE00000
+#define AR_PHY_SFCORR_EXT_M2_THRESH_LOW_S 21
+#define AR_PHY_SFCORR_SPUR_SUBCHNL_SD_S   28
+
+#define AR_PHY_HALFGI           0x99D0
+#define AR_PHY_HALFGI_DSC_MAN   0x0007FFF0
+#define AR_PHY_HALFGI_DSC_MAN_S 4
+#define AR_PHY_HALFGI_DSC_EXP   0x0000000F
+#define AR_PHY_HALFGI_DSC_EXP_S 0
+
+#define AR_PHY_CHAN_INFO_MEMORY               0x99DC
+#define AR_PHY_CHAN_INFO_MEMORY_CAPTURE_MASK  0x0001
+
+#define AR_PHY_HEAVY_CLIP_ENABLE         0x99E0
+
+#define AR_PHY_HEAVY_CLIP_FACTOR_RIFS    0x99EC
+#define AR_PHY_RIFS_INIT_DELAY         0x03ff0000
+
+#define AR_PHY_M_SLEEP      0x99f0
+#define AR_PHY_REFCLKDLY    0x99f4
+#define AR_PHY_REFCLKPD     0x99f8
+
+#define AR_PHY_CALMODE      0x99f0
+
+#define AR_PHY_CALMODE_IQ           0x00000000
+#define AR_PHY_CALMODE_ADC_GAIN     0x00000001
+#define AR_PHY_CALMODE_ADC_DC_PER   0x00000002
+#define AR_PHY_CALMODE_ADC_DC_INIT  0x00000003
+
+#define AR_PHY_CAL_MEAS_0(_i)     (0x9c10 + ((_i) << 12))
+#define AR_PHY_CAL_MEAS_1(_i)     (0x9c14 + ((_i) << 12))
+#define AR_PHY_CAL_MEAS_2(_i)     (0x9c18 + ((_i) << 12))
+#define AR_PHY_CAL_MEAS_3(_i)     (0x9c1c + ((_i) << 12))
+
+#define AR_PHY_CURRENT_RSSI 0x9c1c
+#define AR9280_PHY_CURRENT_RSSI 0x9c3c
+
+#define AR_PHY_RFBUS_GRANT       0x9C20
+#define AR_PHY_RFBUS_GRANT_EN    0x00000001
+
+#define AR_PHY_CHAN_INFO_GAIN_DIFF             0x9CF4
+#define AR_PHY_CHAN_INFO_GAIN_DIFF_UPPER_LIMIT 320
+
+#define AR_PHY_CHAN_INFO_GAIN          0x9CFC
+
+#define AR_PHY_MODE         0xA200
+#define AR_PHY_MODE_ASYNCFIFO 0x80
+#define AR_PHY_MODE_AR2133  0x08
+#define AR_PHY_MODE_AR5111  0x00
+#define AR_PHY_MODE_AR5112  0x08
+#define AR_PHY_MODE_DYNAMIC 0x04
+#define AR_PHY_MODE_RF2GHZ  0x02
+#define AR_PHY_MODE_RF5GHZ  0x00
+#define AR_PHY_MODE_CCK     0x01
+#define AR_PHY_MODE_OFDM    0x00
+#define AR_PHY_MODE_DYN_CCK_DISABLE 0x100
+
+#define AR_PHY_CCK_TX_CTRL       0xA204
+#define AR_PHY_CCK_TX_CTRL_JAPAN 0x00000010
+#define AR_PHY_CCK_TX_CTRL_TX_DAC_SCALE_CCK         0x0000000C
+#define AR_PHY_CCK_TX_CTRL_TX_DAC_SCALE_CCK_S       2
+
+#define AR_PHY_CCK_DETECT                           0xA208
+#define AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK          0x0000003F
+#define AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK_S        0
+/* [12:6] settling time for antenna switch */
+#define AR_PHY_CCK_DETECT_ANT_SWITCH_TIME           0x00001FC0
+#define AR_PHY_CCK_DETECT_ANT_SWITCH_TIME_S         6
+#define AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV    0x2000
+#define AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV_S  13
+
+#define AR_PHY_GAIN_2GHZ                0xA20C
+#define AR_PHY_GAIN_2GHZ_RXTX_MARGIN    0x00FC0000
+#define AR_PHY_GAIN_2GHZ_RXTX_MARGIN_S  18
+#define AR_PHY_GAIN_2GHZ_BSW_MARGIN     0x00003C00
+#define AR_PHY_GAIN_2GHZ_BSW_MARGIN_S   10
+#define AR_PHY_GAIN_2GHZ_BSW_ATTEN      0x0000001F
+#define AR_PHY_GAIN_2GHZ_BSW_ATTEN_S    0
+
+#define AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN     0x003E0000
+#define AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN_S   17
+#define AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN     0x0001F000
+#define AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN_S   12
+#define AR_PHY_GAIN_2GHZ_XATTEN2_DB         0x00000FC0
+#define AR_PHY_GAIN_2GHZ_XATTEN2_DB_S       6
+#define AR_PHY_GAIN_2GHZ_XATTEN1_DB         0x0000003F
+#define AR_PHY_GAIN_2GHZ_XATTEN1_DB_S       0
+
+#define AR_PHY_CCK_RXCTRL4  0xA21C
+#define AR_PHY_CCK_RXCTRL4_FREQ_EST_SHORT   0x01F80000
+#define AR_PHY_CCK_RXCTRL4_FREQ_EST_SHORT_S 19
+
+#define AR_PHY_DAG_CTRLCCK  0xA228
+#define AR_PHY_DAG_CTRLCCK_EN_RSSI_THR  0x00000200
+#define AR_PHY_DAG_CTRLCCK_RSSI_THR     0x0001FC00
+#define AR_PHY_DAG_CTRLCCK_RSSI_THR_S   10
+
+#define AR_PHY_FORCE_CLKEN_CCK              0xA22C
+#define AR_PHY_FORCE_CLKEN_CCK_MRC_MUX      0x00000040
+
+#define AR_PHY_POWER_TX_RATE3   0xA234
+#define AR_PHY_POWER_TX_RATE4   0xA238
+
+#define AR_PHY_SCRM_SEQ_XR       0xA23C
+#define AR_PHY_HEADER_DETECT_XR  0xA240
+#define AR_PHY_CHIRP_DETECTED_XR 0xA244
+#define AR_PHY_BLUETOOTH         0xA254
+
+#define AR_PHY_TPCRG1   0xA258
+#define AR_PHY_TPCRG1_NUM_PD_GAIN   0x0000c000
+#define AR_PHY_TPCRG1_NUM_PD_GAIN_S 14
+
+#define AR_PHY_TPCRG1_PD_GAIN_1    0x00030000
+#define AR_PHY_TPCRG1_PD_GAIN_1_S  16
+#define AR_PHY_TPCRG1_PD_GAIN_2    0x000C0000
+#define AR_PHY_TPCRG1_PD_GAIN_2_S  18
+#define AR_PHY_TPCRG1_PD_GAIN_3    0x00300000
+#define AR_PHY_TPCRG1_PD_GAIN_3_S  20
+
+#define AR_PHY_TPCRG1_PD_CAL_ENABLE   0x00400000
+#define AR_PHY_TPCRG1_PD_CAL_ENABLE_S 22
+
+#define AR_PHY_TX_PWRCTRL4       0xa264
+#define AR_PHY_TX_PWRCTRL_PD_AVG_VALID     0x00000001
+#define AR_PHY_TX_PWRCTRL_PD_AVG_VALID_S   0
+#define AR_PHY_TX_PWRCTRL_PD_AVG_OUT       0x000001FE
+#define AR_PHY_TX_PWRCTRL_PD_AVG_OUT_S     1
+
+#define AR_PHY_TX_PWRCTRL6_0     0xa270
+#define AR_PHY_TX_PWRCTRL6_1     0xb270
+#define AR_PHY_TX_PWRCTRL_ERR_EST_MODE     0x03000000
+#define AR_PHY_TX_PWRCTRL_ERR_EST_MODE_S   24
+
+#define AR_PHY_TX_PWRCTRL7       0xa274
+#define AR_PHY_TX_PWRCTRL_INIT_TX_GAIN     0x01F80000
+#define AR_PHY_TX_PWRCTRL_INIT_TX_GAIN_S   19
+
+#define AR_PHY_TX_PWRCTRL9       0xa27C
+#define AR_PHY_TX_DESIRED_SCALE_CCK        0x00007C00
+#define AR_PHY_TX_DESIRED_SCALE_CCK_S      10
+#define AR_PHY_TX_PWRCTRL9_RES_DC_REMOVAL  0x80000000
+#define AR_PHY_TX_PWRCTRL9_RES_DC_REMOVAL_S 31
+
+#define AR_PHY_TX_GAIN_TBL1      0xa300
+#define AR_PHY_TX_GAIN                     0x0007F000
+#define AR_PHY_TX_GAIN_S                   12
+
+#define AR_PHY_CH0_TX_PWRCTRL11  0xa398
+#define AR_PHY_CH1_TX_PWRCTRL11  0xb398
+#define AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP   0x0000FC00
+#define AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP_S 10
+
+#define AR_PHY_VIT_MASK2_M_46_61 0xa3a0
+#define AR_PHY_MASK2_M_31_45     0xa3a4
+#define AR_PHY_MASK2_M_16_30     0xa3a8
+#define AR_PHY_MASK2_M_00_15     0xa3ac
+#define AR_PHY_MASK2_P_15_01     0xa3b8
+#define AR_PHY_MASK2_P_30_16     0xa3bc
+#define AR_PHY_MASK2_P_45_31     0xa3c0
+#define AR_PHY_MASK2_P_61_45     0xa3c4
+#define AR_PHY_SPUR_REG          0x994c
+
+#define AR_PHY_SPUR_REG_MASK_RATE_CNTL       (0xFF << 18)
+#define AR_PHY_SPUR_REG_MASK_RATE_CNTL_S     18
+
+#define AR_PHY_SPUR_REG_ENABLE_MASK_PPM      0x20000
+#define AR_PHY_SPUR_REG_MASK_RATE_SELECT     (0xFF << 9)
+#define AR_PHY_SPUR_REG_MASK_RATE_SELECT_S   9
+#define AR_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI 0x100
+#define AR_PHY_SPUR_REG_SPUR_RSSI_THRESH     0x7F
+#define AR_PHY_SPUR_REG_SPUR_RSSI_THRESH_S   0
+
+#define AR_PHY_PILOT_MASK_01_30   0xa3b0
+#define AR_PHY_PILOT_MASK_31_60   0xa3b4
+
+#define AR_PHY_CHANNEL_MASK_01_30 0x99d4
+#define AR_PHY_CHANNEL_MASK_31_60 0x99d8
+
+#define AR_PHY_ANALOG_SWAP      0xa268
+#define AR_PHY_SWAP_ALT_CHAIN   0x00000040
+
+#define AR_PHY_TPCRG5   0xA26C
+#define AR_PHY_TPCRG5_PD_GAIN_OVERLAP       0x0000000F
+#define AR_PHY_TPCRG5_PD_GAIN_OVERLAP_S     0
+#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1    0x000003F0
+#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1_S  4
+#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2    0x0000FC00
+#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2_S  10
+#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3    0x003F0000
+#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3_S  16
+#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4    0x0FC00000
+#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4_S  22
+
+/* Carrier leak calibration control, do it after AGC calibration */
+#define AR_PHY_CL_CAL_CTL       0xA358
+#define AR_PHY_CL_CAL_ENABLE    0x00000002
+#define AR_PHY_PARALLEL_CAL_ENABLE    0x00000001
+
+#define AR_PHY_POWER_TX_RATE5   0xA38C
+#define AR_PHY_POWER_TX_RATE6   0xA390
+
+#define AR_PHY_CAL_CHAINMASK    0xA39C
+
+#define AR_PHY_POWER_TX_SUB     0xA3C8
+#define AR_PHY_POWER_TX_RATE7   0xA3CC
+#define AR_PHY_POWER_TX_RATE8   0xA3D0
+#define AR_PHY_POWER_TX_RATE9   0xA3D4
+
+#define AR_PHY_XPA_CFG         0xA3D8
+#define AR_PHY_FORCE_XPA_CFG   0x000000001
+#define AR_PHY_FORCE_XPA_CFG_S 0
+
+#define AR_PHY_CH1_CCA          0xa864
+#define AR_PHY_CH1_MINCCA_PWR   0x0FF80000
+#define AR_PHY_CH1_MINCCA_PWR_S 19
+#define AR9280_PHY_CH1_MINCCA_PWR   0x1FF00000
+#define AR9280_PHY_CH1_MINCCA_PWR_S 20
+
+#define AR_PHY_CH2_CCA          0xb864
+#define AR_PHY_CH2_MINCCA_PWR   0x0FF80000
+#define AR_PHY_CH2_MINCCA_PWR_S 19
+
+#define AR_PHY_CH1_EXT_CCA          0xa9bc
+#define AR_PHY_CH1_EXT_MINCCA_PWR   0xFF800000
+#define AR_PHY_CH1_EXT_MINCCA_PWR_S 23
+#define AR9280_PHY_CH1_EXT_MINCCA_PWR   0x01FF0000
+#define AR9280_PHY_CH1_EXT_MINCCA_PWR_S 16
+
+#define AR_PHY_CH2_EXT_CCA          0xb9bc
+#define AR_PHY_CH2_EXT_MINCCA_PWR   0xFF800000
+#define AR_PHY_CH2_EXT_MINCCA_PWR_S 23
+
+#endif
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_calib.c b/drivers/net/wireless/ath/ath9k/ar9003_calib.c
new file mode 100644 (file)
index 0000000..5e20b48
--- /dev/null
@@ -0,0 +1,802 @@
+/*
+ * Copyright (c) 2010 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT 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 "hw.h"
+#include "hw-ops.h"
+#include "ar9003_phy.h"
+
+static void ar9003_hw_setup_calibration(struct ath_hw *ah,
+                                       struct ath9k_cal_list *currCal)
+{
+       struct ath_common *common = ath9k_hw_common(ah);
+
+       /* Select calibration to run */
+       switch (currCal->calData->calType) {
+       case IQ_MISMATCH_CAL:
+               /*
+                * Start calibration with
+                * 2^(INIT_IQCAL_LOG_COUNT_MAX+1) samples
+                */
+               REG_RMW_FIELD(ah, AR_PHY_TIMING4,
+                             AR_PHY_TIMING4_IQCAL_LOG_COUNT_MAX,
+               currCal->calData->calCountMax);
+               REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_IQ);
+
+               ath_print(common, ATH_DBG_CALIBRATE,
+                         "starting IQ Mismatch Calibration\n");
+
+               /* Kick-off cal */
+               REG_SET_BIT(ah, AR_PHY_TIMING4, AR_PHY_TIMING4_DO_CAL);
+               break;
+       case TEMP_COMP_CAL:
+               REG_RMW_FIELD(ah, AR_PHY_65NM_CH0_THERM,
+                             AR_PHY_65NM_CH0_THERM_LOCAL, 1);
+               REG_RMW_FIELD(ah, AR_PHY_65NM_CH0_THERM,
+                             AR_PHY_65NM_CH0_THERM_START, 1);
+
+               ath_print(common, ATH_DBG_CALIBRATE,
+                         "starting Temperature Compensation Calibration\n");
+               break;
+       case ADC_DC_INIT_CAL:
+       case ADC_GAIN_CAL:
+       case ADC_DC_CAL:
+               /* Not yet */
+               break;
+       }
+}
+
+/*
+ * Generic calibration routine.
+ * Recalibrate the lower PHY chips to account for temperature/environment
+ * changes.
+ */
+static bool ar9003_hw_per_calibration(struct ath_hw *ah,
+                                     struct ath9k_channel *ichan,
+                                     u8 rxchainmask,
+                                     struct ath9k_cal_list *currCal)
+{
+       /* Cal is assumed not done until explicitly set below */
+       bool iscaldone = false;
+
+       /* Calibration in progress. */
+       if (currCal->calState == CAL_RUNNING) {
+               /* Check to see if it has finished. */
+               if (!(REG_READ(ah, AR_PHY_TIMING4) & AR_PHY_TIMING4_DO_CAL)) {
+                       /*
+                       * Accumulate cal measures for active chains
+                       */
+                       currCal->calData->calCollect(ah);
+                       ah->cal_samples++;
+
+                       if (ah->cal_samples >=
+                           currCal->calData->calNumSamples) {
+                               unsigned int i, numChains = 0;
+                               for (i = 0; i < AR9300_MAX_CHAINS; i++) {
+                                       if (rxchainmask & (1 << i))
+                                               numChains++;
+                               }
+
+                               /*
+                               * Process accumulated data
+                               */
+                               currCal->calData->calPostProc(ah, numChains);
+
+                               /* Calibration has finished. */
+                               ichan->CalValid |= currCal->calData->calType;
+                               currCal->calState = CAL_DONE;
+                               iscaldone = true;
+                       } else {
+                       /*
+                        * Set-up collection of another sub-sample until we
+                        * get desired number
+                        */
+                       ar9003_hw_setup_calibration(ah, currCal);
+                       }
+               }
+       } else if (!(ichan->CalValid & currCal->calData->calType)) {
+               /* If current cal is marked invalid in channel, kick it off */
+               ath9k_hw_reset_calibration(ah, currCal);
+       }
+
+       return iscaldone;
+}
+
+static bool ar9003_hw_calibrate(struct ath_hw *ah,
+                               struct ath9k_channel *chan,
+                               u8 rxchainmask,
+                               bool longcal)
+{
+       bool iscaldone = true;
+       struct ath9k_cal_list *currCal = ah->cal_list_curr;
+
+       /*
+        * For given calibration:
+        * 1. Call generic cal routine
+        * 2. When this cal is done (isCalDone) if we have more cals waiting
+        *    (eg after reset), mask this to upper layers by not propagating
+        *    isCalDone if it is set to TRUE.
+        *    Instead, change isCalDone to FALSE and setup the waiting cal(s)
+        *    to be run.
+        */
+       if (currCal &&
+           (currCal->calState == CAL_RUNNING ||
+            currCal->calState == CAL_WAITING)) {
+               iscaldone = ar9003_hw_per_calibration(ah, chan,
+                                                     rxchainmask, currCal);
+               if (iscaldone) {
+                       ah->cal_list_curr = currCal = currCal->calNext;
+
+                       if (currCal->calState == CAL_WAITING) {
+                               iscaldone = false;
+                               ath9k_hw_reset_calibration(ah, currCal);
+                       }
+               }
+       }
+
+       /* Do NF cal only at longer intervals */
+       if (longcal) {
+               /*
+                * Load the NF from history buffer of the current channel.
+                * NF is slow time-variant, so it is OK to use a historical
+                * value.
+                */
+               ath9k_hw_loadnf(ah, ah->curchan);
+
+               /* start NF calibration, without updating BB NF register */
+               ath9k_hw_start_nfcal(ah);
+       }
+
+       return iscaldone;
+}
+
+static void ar9003_hw_iqcal_collect(struct ath_hw *ah)
+{
+       int i;
+
+       /* Accumulate IQ cal measures for active chains */
+       for (i = 0; i < AR5416_MAX_CHAINS; i++) {
+               ah->totalPowerMeasI[i] +=
+                       REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
+               ah->totalPowerMeasQ[i] +=
+                       REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
+               ah->totalIqCorrMeas[i] +=
+                       (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
+               ath_print(ath9k_hw_common(ah), ATH_DBG_CALIBRATE,
+                         "%d: Chn %d pmi=0x%08x;pmq=0x%08x;iqcm=0x%08x;\n",
+                         ah->cal_samples, i, ah->totalPowerMeasI[i],
+                         ah->totalPowerMeasQ[i],
+                         ah->totalIqCorrMeas[i]);
+       }
+}
+
+static void ar9003_hw_iqcalibrate(struct ath_hw *ah, u8 numChains)
+{
+       struct ath_common *common = ath9k_hw_common(ah);
+       u32 powerMeasQ, powerMeasI, iqCorrMeas;
+       u32 qCoffDenom, iCoffDenom;
+       int32_t qCoff, iCoff;
+       int iqCorrNeg, i;
+       const u_int32_t offset_array[3] = {
+               AR_PHY_RX_IQCAL_CORR_B0,
+               AR_PHY_RX_IQCAL_CORR_B1,
+               AR_PHY_RX_IQCAL_CORR_B2,
+       };
+
+       for (i = 0; i < numChains; i++) {
+               powerMeasI = ah->totalPowerMeasI[i];
+               powerMeasQ = ah->totalPowerMeasQ[i];
+               iqCorrMeas = ah->totalIqCorrMeas[i];
+
+               ath_print(common, ATH_DBG_CALIBRATE,
+                         "Starting IQ Cal and Correction for Chain %d\n",
+                         i);
+
+               ath_print(common, ATH_DBG_CALIBRATE,
+                         "Orignal: Chn %diq_corr_meas = 0x%08x\n",
+                         i, ah->totalIqCorrMeas[i]);
+
+               iqCorrNeg = 0;
+
+               if (iqCorrMeas > 0x80000000) {
+                       iqCorrMeas = (0xffffffff - iqCorrMeas) + 1;
+                       iqCorrNeg = 1;
+               }
+
+               ath_print(common, ATH_DBG_CALIBRATE,
+                         "Chn %d pwr_meas_i = 0x%08x\n", i, powerMeasI);
+               ath_print(common, ATH_DBG_CALIBRATE,
+                         "Chn %d pwr_meas_q = 0x%08x\n", i, powerMeasQ);
+               ath_print(common, ATH_DBG_CALIBRATE, "iqCorrNeg is 0x%08x\n",
+                         iqCorrNeg);
+
+               iCoffDenom = (powerMeasI / 2 + powerMeasQ / 2) / 256;
+               qCoffDenom = powerMeasQ / 64;
+
+               if ((iCoffDenom != 0) && (qCoffDenom != 0)) {
+                       iCoff = iqCorrMeas / iCoffDenom;
+                       qCoff = powerMeasI / qCoffDenom - 64;
+                       ath_print(common, ATH_DBG_CALIBRATE,
+                                 "Chn %d iCoff = 0x%08x\n", i, iCoff);
+                       ath_print(common, ATH_DBG_CALIBRATE,
+                                 "Chn %d qCoff = 0x%08x\n", i, qCoff);
+
+                       /* Force bounds on iCoff */
+                       if (iCoff >= 63)
+                               iCoff = 63;
+                       else if (iCoff <= -63)
+                               iCoff = -63;
+
+                       /* Negate iCoff if iqCorrNeg == 0 */
+                       if (iqCorrNeg == 0x0)
+                               iCoff = -iCoff;
+
+                       /* Force bounds on qCoff */
+                       if (qCoff >= 63)
+                               qCoff = 63;
+                       else if (qCoff <= -63)
+                               qCoff = -63;
+
+                       iCoff = iCoff & 0x7f;
+                       qCoff = qCoff & 0x7f;
+
+                       ath_print(common, ATH_DBG_CALIBRATE,
+                                 "Chn %d : iCoff = 0x%x  qCoff = 0x%x\n",
+                                 i, iCoff, qCoff);
+                       ath_print(common, ATH_DBG_CALIBRATE,
+                                 "Register offset (0x%04x) "
+                                 "before update = 0x%x\n",
+                                 offset_array[i],
+                                 REG_READ(ah, offset_array[i]));
+
+                       REG_RMW_FIELD(ah, offset_array[i],
+                                     AR_PHY_RX_IQCAL_CORR_IQCORR_Q_I_COFF,
+                                     iCoff);
+                       REG_RMW_FIELD(ah, offset_array[i],
+                                     AR_PHY_RX_IQCAL_CORR_IQCORR_Q_Q_COFF,
+                                     qCoff);
+                       ath_print(common, ATH_DBG_CALIBRATE,
+                                 "Register offset (0x%04x) QI COFF "
+                                 "(bitfields 0x%08x) after update = 0x%x\n",
+                                 offset_array[i],
+                                 AR_PHY_RX_IQCAL_CORR_IQCORR_Q_I_COFF,
+                                 REG_READ(ah, offset_array[i]));
+                       ath_print(common, ATH_DBG_CALIBRATE,
+                                 "Register offset (0x%04x) QQ COFF "
+                                 "(bitfields 0x%08x) after update = 0x%x\n",
+                                 offset_array[i],
+                                 AR_PHY_RX_IQCAL_CORR_IQCORR_Q_Q_COFF,
+                                 REG_READ(ah, offset_array[i]));
+
+                       ath_print(common, ATH_DBG_CALIBRATE,
+                                 "IQ Cal and Correction done for Chain %d\n",
+                                 i);
+               }
+       }
+
+       REG_SET_BIT(ah, AR_PHY_RX_IQCAL_CORR_B0,
+                   AR_PHY_RX_IQCAL_CORR_IQCORR_ENABLE);
+       ath_print(common, ATH_DBG_CALIBRATE,
+                 "IQ Cal and Correction (offset 0x%04x) enabled "
+                 "(bit position 0x%08x). New Value 0x%08x\n",
+                 (unsigned) (AR_PHY_RX_IQCAL_CORR_B0),
+                 AR_PHY_RX_IQCAL_CORR_IQCORR_ENABLE,
+                 REG_READ(ah, AR_PHY_RX_IQCAL_CORR_B0));
+}
+
+static const struct ath9k_percal_data iq_cal_single_sample = {
+       IQ_MISMATCH_CAL,
+       MIN_CAL_SAMPLES,
+       PER_MAX_LOG_COUNT,
+       ar9003_hw_iqcal_collect,
+       ar9003_hw_iqcalibrate
+};
+
+static void ar9003_hw_init_cal_settings(struct ath_hw *ah)
+{
+       ah->iq_caldata.calData = &iq_cal_single_sample;
+       ah->supp_cals = IQ_MISMATCH_CAL;
+}
+
+static bool ar9003_hw_iscal_supported(struct ath_hw *ah,
+                                     enum ath9k_cal_types calType)
+{
+       switch (calType & ah->supp_cals) {
+       case IQ_MISMATCH_CAL:
+               /*
+                * XXX: Run IQ Mismatch for non-CCK only
+                * Note that CHANNEL_B is never set though.
+                */
+               return true;
+       case ADC_GAIN_CAL:
+       case ADC_DC_CAL:
+               return false;
+       case TEMP_COMP_CAL:
+               return true;
+       }
+
+       return false;
+}
+
+/*
+ * solve 4x4 linear equation used in loopback iq cal.
+ */
+static bool ar9003_hw_solve_iq_cal(struct ath_hw *ah,
+                                  s32 sin_2phi_1,
+                                  s32 cos_2phi_1,
+                                  s32 sin_2phi_2,
+                                  s32 cos_2phi_2,
+                                  s32 mag_a0_d0,
+                                  s32 phs_a0_d0,
+                                  s32 mag_a1_d0,
+                                  s32 phs_a1_d0,
+                                  s32 solved_eq[])
+{
+       s32 f1 = cos_2phi_1 - cos_2phi_2,
+           f3 = sin_2phi_1 - sin_2phi_2,
+           f2;
+       s32 mag_tx, phs_tx, mag_rx, phs_rx;
+       const s32 result_shift = 1 << 15;
+       struct ath_common *common = ath9k_hw_common(ah);
+
+       f2 = (f1 * f1 + f3 * f3) / result_shift;
+
+       if (!f2) {
+               ath_print(common, ATH_DBG_CALIBRATE, "Divide by 0\n");
+               return false;
+       }
+
+       /* mag mismatch, tx */
+       mag_tx = f1 * (mag_a0_d0  - mag_a1_d0) + f3 * (phs_a0_d0 - phs_a1_d0);
+       /* phs mismatch, tx */
+       phs_tx = f3 * (-mag_a0_d0 + mag_a1_d0) + f1 * (phs_a0_d0 - phs_a1_d0);
+
+       mag_tx = (mag_tx / f2);
+       phs_tx = (phs_tx / f2);
+
+       /* mag mismatch, rx */
+       mag_rx = mag_a0_d0 - (cos_2phi_1 * mag_tx + sin_2phi_1 * phs_tx) /
+                result_shift;
+       /* phs mismatch, rx */
+       phs_rx = phs_a0_d0 + (sin_2phi_1 * mag_tx - cos_2phi_1 * phs_tx) /
+                result_shift;
+
+       solved_eq[0] = mag_tx;
+       solved_eq[1] = phs_tx;
+       solved_eq[2] = mag_rx;
+       solved_eq[3] = phs_rx;
+
+       return true;
+}
+
+static s32 ar9003_hw_find_mag_approx(struct ath_hw *ah, s32 in_re, s32 in_im)
+{
+       s32 abs_i = abs(in_re),
+           abs_q = abs(in_im),
+           max_abs, min_abs;
+
+       if (abs_i > abs_q) {
+               max_abs = abs_i;
+               min_abs = abs_q;
+       } else {
+               max_abs = abs_q;
+               min_abs = abs_i;
+       }
+
+       return max_abs - (max_abs / 32) + (min_abs / 8) + (min_abs / 4);
+}
+
+#define DELPT 32
+
+static bool ar9003_hw_calc_iq_corr(struct ath_hw *ah,
+                                  s32 chain_idx,
+                                  const s32 iq_res[],
+                                  s32 iqc_coeff[])
+{
+       s32 i2_m_q2_a0_d0, i2_p_q2_a0_d0, iq_corr_a0_d0,
+           i2_m_q2_a0_d1, i2_p_q2_a0_d1, iq_corr_a0_d1,
+           i2_m_q2_a1_d0, i2_p_q2_a1_d0, iq_corr_a1_d0,
+           i2_m_q2_a1_d1, i2_p_q2_a1_d1, iq_corr_a1_d1;
+       s32 mag_a0_d0, mag_a1_d0, mag_a0_d1, mag_a1_d1,
+           phs_a0_d0, phs_a1_d0, phs_a0_d1, phs_a1_d1,
+           sin_2phi_1, cos_2phi_1,
+           sin_2phi_2, cos_2phi_2;
+       s32 mag_tx, phs_tx, mag_rx, phs_rx;
+       s32 solved_eq[4], mag_corr_tx, phs_corr_tx, mag_corr_rx, phs_corr_rx,
+           q_q_coff, q_i_coff;
+       const s32 res_scale = 1 << 15;
+       const s32 delpt_shift = 1 << 8;
+       s32 mag1, mag2;
+       struct ath_common *common = ath9k_hw_common(ah);
+
+       i2_m_q2_a0_d0 = iq_res[0] & 0xfff;
+       i2_p_q2_a0_d0 = (iq_res[0] >> 12) & 0xfff;
+       iq_corr_a0_d0 = ((iq_res[0] >> 24) & 0xff) + ((iq_res[1] & 0xf) << 8);
+
+       if (i2_m_q2_a0_d0 > 0x800)
+               i2_m_q2_a0_d0 = -((0xfff - i2_m_q2_a0_d0) + 1);
+
+       if (i2_p_q2_a0_d0 > 0x800)
+               i2_p_q2_a0_d0 = -((0xfff - i2_p_q2_a0_d0) + 1);
+
+       if (iq_corr_a0_d0 > 0x800)
+               iq_corr_a0_d0 = -((0xfff - iq_corr_a0_d0) + 1);
+
+       i2_m_q2_a0_d1 = (iq_res[1] >> 4) & 0xfff;
+       i2_p_q2_a0_d1 = (iq_res[2] & 0xfff);
+       iq_corr_a0_d1 = (iq_res[2] >> 12) & 0xfff;
+
+       if (i2_m_q2_a0_d1 > 0x800)
+               i2_m_q2_a0_d1 = -((0xfff - i2_m_q2_a0_d1) + 1);
+
+       if (i2_p_q2_a0_d1 > 0x800)
+               i2_p_q2_a0_d1 = -((0xfff - i2_p_q2_a0_d1) + 1);
+
+       if (iq_corr_a0_d1 > 0x800)
+               iq_corr_a0_d1 = -((0xfff - iq_corr_a0_d1) + 1);
+
+       i2_m_q2_a1_d0 = ((iq_res[2] >> 24) & 0xff) + ((iq_res[3] & 0xf) << 8);
+       i2_p_q2_a1_d0 = (iq_res[3] >> 4) & 0xfff;
+       iq_corr_a1_d0 = iq_res[4] & 0xfff;
+
+       if (i2_m_q2_a1_d0 > 0x800)
+               i2_m_q2_a1_d0 = -((0xfff - i2_m_q2_a1_d0) + 1);
+
+       if (i2_p_q2_a1_d0 > 0x800)
+               i2_p_q2_a1_d0 = -((0xfff - i2_p_q2_a1_d0) + 1);
+
+       if (iq_corr_a1_d0 > 0x800)
+               iq_corr_a1_d0 = -((0xfff - iq_corr_a1_d0) + 1);
+
+       i2_m_q2_a1_d1 = (iq_res[4] >> 12) & 0xfff;
+       i2_p_q2_a1_d1 = ((iq_res[4] >> 24) & 0xff) + ((iq_res[5] & 0xf) << 8);
+       iq_corr_a1_d1 = (iq_res[5] >> 4) & 0xfff;
+
+       if (i2_m_q2_a1_d1 > 0x800)
+               i2_m_q2_a1_d1 = -((0xfff - i2_m_q2_a1_d1) + 1);
+
+       if (i2_p_q2_a1_d1 > 0x800)
+               i2_p_q2_a1_d1 = -((0xfff - i2_p_q2_a1_d1) + 1);
+
+       if (iq_corr_a1_d1 > 0x800)
+               iq_corr_a1_d1 = -((0xfff - iq_corr_a1_d1) + 1);
+
+       if ((i2_p_q2_a0_d0 == 0) || (i2_p_q2_a0_d1 == 0) ||
+           (i2_p_q2_a1_d0 == 0) || (i2_p_q2_a1_d1 == 0)) {
+               ath_print(common, ATH_DBG_CALIBRATE,
+                         "Divide by 0:\na0_d0=%d\n"
+                         "a0_d1=%d\na2_d0=%d\na1_d1=%d\n",
+                         i2_p_q2_a0_d0, i2_p_q2_a0_d1,
+                         i2_p_q2_a1_d0, i2_p_q2_a1_d1);
+               return false;
+       }
+
+       mag_a0_d0 = (i2_m_q2_a0_d0 * res_scale) / i2_p_q2_a0_d0;
+       phs_a0_d0 = (iq_corr_a0_d0 * res_scale) / i2_p_q2_a0_d0;
+
+       mag_a0_d1 = (i2_m_q2_a0_d1 * res_scale) / i2_p_q2_a0_d1;
+       phs_a0_d1 = (iq_corr_a0_d1 * res_scale) / i2_p_q2_a0_d1;
+
+       mag_a1_d0 = (i2_m_q2_a1_d0 * res_scale) / i2_p_q2_a1_d0;
+       phs_a1_d0 = (iq_corr_a1_d0 * res_scale) / i2_p_q2_a1_d0;
+
+       mag_a1_d1 = (i2_m_q2_a1_d1 * res_scale) / i2_p_q2_a1_d1;
+       phs_a1_d1 = (iq_corr_a1_d1 * res_scale) / i2_p_q2_a1_d1;
+
+       /* w/o analog phase shift */
+       sin_2phi_1 = (((mag_a0_d0 - mag_a0_d1) * delpt_shift) / DELPT);
+       /* w/o analog phase shift */
+       cos_2phi_1 = (((phs_a0_d1 - phs_a0_d0) * delpt_shift) / DELPT);
+       /* w/  analog phase shift */
+       sin_2phi_2 = (((mag_a1_d0 - mag_a1_d1) * delpt_shift) / DELPT);
+       /* w/  analog phase shift */
+       cos_2phi_2 = (((phs_a1_d1 - phs_a1_d0) * delpt_shift) / DELPT);
+
+       /*
+        * force sin^2 + cos^2 = 1;
+        * find magnitude by approximation
+        */
+       mag1 = ar9003_hw_find_mag_approx(ah, cos_2phi_1, sin_2phi_1);
+       mag2 = ar9003_hw_find_mag_approx(ah, cos_2phi_2, sin_2phi_2);
+
+       if ((mag1 == 0) || (mag2 == 0)) {
+               ath_print(common, ATH_DBG_CALIBRATE,
+                         "Divide by 0: mag1=%d, mag2=%d\n",
+                         mag1, mag2);
+               return false;
+       }
+
+       /* normalization sin and cos by mag */
+       sin_2phi_1 = (sin_2phi_1 * res_scale / mag1);
+       cos_2phi_1 = (cos_2phi_1 * res_scale / mag1);
+       sin_2phi_2 = (sin_2phi_2 * res_scale / mag2);
+       cos_2phi_2 = (cos_2phi_2 * res_scale / mag2);
+
+       /* calculate IQ mismatch */
+       if (!ar9003_hw_solve_iq_cal(ah,
+                            sin_2phi_1, cos_2phi_1,
+                            sin_2phi_2, cos_2phi_2,
+                            mag_a0_d0, phs_a0_d0,
+                            mag_a1_d0,
+                            phs_a1_d0, solved_eq)) {
+               ath_print(common, ATH_DBG_CALIBRATE,
+                         "Call to ar9003_hw_solve_iq_cal() failed.\n");
+               return false;
+       }
+
+       mag_tx = solved_eq[0];
+       phs_tx = solved_eq[1];
+       mag_rx = solved_eq[2];
+       phs_rx = solved_eq[3];
+
+       ath_print(common, ATH_DBG_CALIBRATE,
+                 "chain %d: mag mismatch=%d phase mismatch=%d\n",
+                 chain_idx, mag_tx/res_scale, phs_tx/res_scale);
+
+       if (res_scale == mag_tx) {
+               ath_print(common, ATH_DBG_CALIBRATE,
+                         "Divide by 0: mag_tx=%d, res_scale=%d\n",
+                         mag_tx, res_scale);
+               return false;
+       }
+
+       /* calculate and quantize Tx IQ correction factor */
+       mag_corr_tx = (mag_tx * res_scale) / (res_scale - mag_tx);
+       phs_corr_tx = -phs_tx;
+
+       q_q_coff = (mag_corr_tx * 128 / res_scale);
+       q_i_coff = (phs_corr_tx * 256 / res_scale);
+
+       ath_print(common, ATH_DBG_CALIBRATE,
+                 "tx chain %d: mag corr=%d  phase corr=%d\n",
+                 chain_idx, q_q_coff, q_i_coff);
+
+       if (q_i_coff < -63)
+               q_i_coff = -63;
+       if (q_i_coff > 63)
+               q_i_coff = 63;
+       if (q_q_coff < -63)
+               q_q_coff = -63;
+       if (q_q_coff > 63)
+               q_q_coff = 63;
+
+       iqc_coeff[0] = (q_q_coff * 128) + q_i_coff;
+
+       ath_print(common, ATH_DBG_CALIBRATE,
+                 "tx chain %d: iq corr coeff=%x\n",
+                 chain_idx, iqc_coeff[0]);
+
+       if (-mag_rx == res_scale) {
+               ath_print(common, ATH_DBG_CALIBRATE,
+                         "Divide by 0: mag_rx=%d, res_scale=%d\n",
+                         mag_rx, res_scale);
+               return false;
+       }
+
+       /* calculate and quantize Rx IQ correction factors */
+       mag_corr_rx = (-mag_rx * res_scale) / (res_scale + mag_rx);
+       phs_corr_rx = -phs_rx;
+
+       q_q_coff = (mag_corr_rx * 128 / res_scale);
+       q_i_coff = (phs_corr_rx * 256 / res_scale);
+
+       ath_print(common, ATH_DBG_CALIBRATE,
+                 "rx chain %d: mag corr=%d  phase corr=%d\n",
+                 chain_idx, q_q_coff, q_i_coff);
+
+       if (q_i_coff < -63)
+               q_i_coff = -63;
+       if (q_i_coff > 63)
+               q_i_coff = 63;
+       if (q_q_coff < -63)
+               q_q_coff = -63;
+       if (q_q_coff > 63)
+               q_q_coff = 63;
+
+       iqc_coeff[1] = (q_q_coff * 128) + q_i_coff;
+
+       ath_print(common, ATH_DBG_CALIBRATE,
+                 "rx chain %d: iq corr coeff=%x\n",
+                 chain_idx, iqc_coeff[1]);
+
+       return true;
+}
+
+static void ar9003_hw_tx_iq_cal(struct ath_hw *ah)
+{
+       struct ath_common *common = ath9k_hw_common(ah);
+       const u32 txiqcal_status[AR9300_MAX_CHAINS] = {
+               AR_PHY_TX_IQCAL_STATUS_B0,
+               AR_PHY_TX_IQCAL_STATUS_B1,
+               AR_PHY_TX_IQCAL_STATUS_B2,
+       };
+       const u32 tx_corr_coeff[AR9300_MAX_CHAINS] = {
+               AR_PHY_TX_IQCAL_CORR_COEFF_01_B0,
+               AR_PHY_TX_IQCAL_CORR_COEFF_01_B1,
+               AR_PHY_TX_IQCAL_CORR_COEFF_01_B2,
+       };
+       const u32 rx_corr[AR9300_MAX_CHAINS] = {
+               AR_PHY_RX_IQCAL_CORR_B0,
+               AR_PHY_RX_IQCAL_CORR_B1,
+               AR_PHY_RX_IQCAL_CORR_B2,
+       };
+       const u_int32_t chan_info_tab[] = {
+               AR_PHY_CHAN_INFO_TAB_0,
+               AR_PHY_CHAN_INFO_TAB_1,
+               AR_PHY_CHAN_INFO_TAB_2,
+       };
+       s32 iq_res[6];
+       s32 iqc_coeff[2];
+       s32 i, j;
+       u32 num_chains = 0;
+
+       for (i = 0; i < AR9300_MAX_CHAINS; i++) {
+               if (ah->txchainmask & (1 << i))
+                       num_chains++;
+       }
+
+       REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_1,
+                     AR_PHY_TX_IQCAQL_CONTROL_1_IQCORR_I_Q_COFF_DELPT,
+                     DELPT);
+       REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_START,
+                     AR_PHY_TX_IQCAL_START_DO_CAL,
+                     AR_PHY_TX_IQCAL_START_DO_CAL);
+
+       if (!ath9k_hw_wait(ah, AR_PHY_TX_IQCAL_START,
+                          AR_PHY_TX_IQCAL_START_DO_CAL,
+                          0, AH_WAIT_TIMEOUT)) {
+               ath_print(common, ATH_DBG_CALIBRATE,
+                         "Tx IQ Cal not complete.\n");
+               goto TX_IQ_CAL_FAILED;
+       }
+
+       for (i = 0; i < num_chains; i++) {
+               ath_print(common, ATH_DBG_CALIBRATE,
+                         "Doing Tx IQ Cal for chain %d.\n", i);
+
+               if (REG_READ(ah, txiqcal_status[i]) &
+                            AR_PHY_TX_IQCAL_STATUS_FAILED) {
+                       ath_print(common, ATH_DBG_CALIBRATE,
+                                 "Tx IQ Cal failed for chain %d.\n", i);
+                       goto TX_IQ_CAL_FAILED;
+               }
+
+               for (j = 0; j < 3; j++) {
+                       u_int8_t idx = 2 * j,
+                       offset = 4 * j;
+
+                       REG_RMW_FIELD(ah, AR_PHY_CHAN_INFO_MEMORY,
+                                     AR_PHY_CHAN_INFO_TAB_S2_READ, 0);
+
+                       /* 32 bits */
+                       iq_res[idx] = REG_READ(ah, chan_info_tab[i] + offset);
+
+                       REG_RMW_FIELD(ah, AR_PHY_CHAN_INFO_MEMORY,
+                                     AR_PHY_CHAN_INFO_TAB_S2_READ, 1);
+
+                       /* 16 bits */
+                       iq_res[idx+1] = 0xffff & REG_READ(ah,
+                                                         chan_info_tab[i] +
+                                                         offset);
+
+                       ath_print(common, ATH_DBG_CALIBRATE,
+                                 "IQ RES[%d]=0x%x IQ_RES[%d]=0x%x\n",
+                                 idx, iq_res[idx], idx+1, iq_res[idx+1]);
+               }
+
+               if (!ar9003_hw_calc_iq_corr(ah, i, iq_res, iqc_coeff)) {
+                       ath_print(common, ATH_DBG_CALIBRATE,
+                                 "Failed in calculation of IQ correction.\n");
+                       goto TX_IQ_CAL_FAILED;
+               }
+
+               ath_print(common, ATH_DBG_CALIBRATE,
+                         "IQ_COEFF[0] = 0x%x IQ_COEFF[1] = 0x%x\n",
+                         iqc_coeff[0], iqc_coeff[1]);
+
+               REG_RMW_FIELD(ah, tx_corr_coeff[i],
+                             AR_PHY_TX_IQCAL_CORR_COEFF_01_COEFF_TABLE,
+                             iqc_coeff[0]);
+               REG_RMW_FIELD(ah, rx_corr[i],
+                             AR_PHY_RX_IQCAL_CORR_LOOPBACK_IQCORR_Q_Q_COFF,
+                             iqc_coeff[1] >> 7);
+               REG_RMW_FIELD(ah, rx_corr[i],
+                             AR_PHY_RX_IQCAL_CORR_LOOPBACK_IQCORR_Q_I_COFF,
+                             iqc_coeff[1]);
+       }
+
+       REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_3,
+                     AR_PHY_TX_IQCAL_CONTROL_3_IQCORR_EN, 0x1);
+       REG_RMW_FIELD(ah, AR_PHY_RX_IQCAL_CORR_B0,
+                     AR_PHY_RX_IQCAL_CORR_B0_LOOPBACK_IQCORR_EN, 0x1);
+
+       return;
+
+TX_IQ_CAL_FAILED:
+       ath_print(common, ATH_DBG_CALIBRATE, "Tx IQ Cal failed\n");
+       return;
+}
+
+static bool ar9003_hw_init_cal(struct ath_hw *ah,
+                              struct ath9k_channel *chan)
+{
+       struct ath_common *common = ath9k_hw_common(ah);
+
+       /*
+        * 0x7 = 0b111 , AR9003 needs to be configured for 3-chain mode before
+        * running AGC/TxIQ cals
+        */
+       ar9003_hw_set_chain_masks(ah, 0x7, 0x7);
+
+       /* Calibrate the AGC */
+       REG_WRITE(ah, AR_PHY_AGC_CONTROL,
+                 REG_READ(ah, AR_PHY_AGC_CONTROL) |
+                 AR_PHY_AGC_CONTROL_CAL);
+
+       /* Poll for offset calibration complete */
+       if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL,
+                          0, AH_WAIT_TIMEOUT)) {
+               ath_print(common, ATH_DBG_CALIBRATE,
+                         "offset calibration failed to "
+                         "complete in 1ms; noisy environment?\n");
+               return false;
+       }
+
+       /* Do Tx IQ Calibration */
+       ar9003_hw_tx_iq_cal(ah);
+
+       /* Revert chainmasks to their original values before NF cal */
+       ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask);
+
+       /* Initialize list pointers */
+       ah->cal_list = ah->cal_list_last = ah->cal_list_curr = NULL;
+
+       if (ar9003_hw_iscal_supported(ah, IQ_MISMATCH_CAL)) {
+               INIT_CAL(&ah->iq_caldata);
+               INSERT_CAL(ah, &ah->iq_caldata);
+               ath_print(common, ATH_DBG_CALIBRATE,
+                         "enabling IQ Calibration.\n");
+       }
+
+       if (ar9003_hw_iscal_supported(ah, TEMP_COMP_CAL)) {
+               INIT_CAL(&ah->tempCompCalData);
+               INSERT_CAL(ah, &ah->tempCompCalData);
+               ath_print(common, ATH_DBG_CALIBRATE,
+                         "enabling Temperature Compensation Calibration.\n");
+       }
+
+       /* Initialize current pointer to first element in list */
+       ah->cal_list_curr = ah->cal_list;
+
+       if (ah->cal_list_curr)
+               ath9k_hw_reset_calibration(ah, ah->cal_list_curr);
+
+       chan->CalValid = 0;
+
+       return true;
+}
+
+void ar9003_hw_attach_calib_ops(struct ath_hw *ah)
+{
+       struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
+       struct ath_hw_ops *ops = ath9k_hw_ops(ah);
+
+       priv_ops->init_cal_settings = ar9003_hw_init_cal_settings;
+       priv_ops->init_cal = ar9003_hw_init_cal;
+       priv_ops->setup_calibration = ar9003_hw_setup_calibration;
+       priv_ops->iscal_supported = ar9003_hw_iscal_supported;
+
+       ops->calibrate = ar9003_hw_calibrate;
+}
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
new file mode 100644 (file)
index 0000000..5d92be4
--- /dev/null
@@ -0,0 +1,1856 @@
+/*
+ * Copyright (c) 2010 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT 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 "hw.h"
+#include "ar9003_phy.h"
+#include "ar9003_eeprom.h"
+
+#define COMP_HDR_LEN 4
+#define COMP_CKSUM_LEN 2
+
+#define AR_CH0_TOP (0x00016288)
+#define AR_CH0_TOP_XPABIASLVL (0x3)
+#define AR_CH0_TOP_XPABIASLVL_S (8)
+
+#define AR_CH0_THERM (0x00016290)
+#define AR_CH0_THERM_SPARE (0x3f)
+#define AR_CH0_THERM_SPARE_S (0)
+
+#define AR_SWITCH_TABLE_COM_ALL (0xffff)
+#define AR_SWITCH_TABLE_COM_ALL_S (0)
+
+#define AR_SWITCH_TABLE_COM2_ALL (0xffffff)
+#define AR_SWITCH_TABLE_COM2_ALL_S (0)
+
+#define AR_SWITCH_TABLE_ALL (0xfff)
+#define AR_SWITCH_TABLE_ALL_S (0)
+
+static const struct ar9300_eeprom ar9300_default = {
+       .eepromVersion = 2,
+       .templateVersion = 2,
+       .macAddr = {1, 2, 3, 4, 5, 6},
+       .custData = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+                    0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+       .baseEepHeader = {
+               .regDmn = {0, 0x1f},
+               .txrxMask =  0x77, /* 4 bits tx and 4 bits rx */
+               .opCapFlags = {
+                       .opFlags = AR9300_OPFLAGS_11G | AR9300_OPFLAGS_11A,
+                       .eepMisc = 0,
+               },
+               .rfSilent = 0,
+               .blueToothOptions = 0,
+               .deviceCap = 0,
+               .deviceType = 5, /* takes lower byte in eeprom location */
+               .pwrTableOffset = AR9300_PWR_TABLE_OFFSET,
+               .params_for_tuning_caps = {0, 0},
+               .featureEnable = 0x0c,
+                /*
+                 * bit0 - enable tx temp comp - disabled
+                 * bit1 - enable tx volt comp - disabled
+                 * bit2 - enable fastClock - enabled
+                 * bit3 - enable doubling - enabled
+                 * bit4 - enable internal regulator - disabled
+                 */
+               .miscConfiguration = 0, /* bit0 - turn down drivestrength */
+               .eepromWriteEnableGpio = 3,
+               .wlanDisableGpio = 0,
+               .wlanLedGpio = 8,
+               .rxBandSelectGpio = 0xff,
+               .txrxgain = 0,
+               .swreg = 0,
+        },
+       .modalHeader2G = {
+       /* ar9300_modal_eep_header  2g */
+               /* 4 idle,t1,t2,b(4 bits per setting) */
+               .antCtrlCommon = 0x110,
+               /* 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12 */
+               .antCtrlCommon2 = 0x22222,
+
+               /*
+                * antCtrlChain[AR9300_MAX_CHAINS]; 6 idle, t, r,
+                * rx1, rx12, b (2 bits each)
+                */
+               .antCtrlChain = {0x150, 0x150, 0x150},
+
+               /*
+                * xatten1DB[AR9300_MAX_CHAINS];  3 xatten1_db
+                * for ar9280 (0xa20c/b20c 5:0)
+                */
+               .xatten1DB = {0, 0, 0},
+
+               /*
+                * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
+                * for ar9280 (0xa20c/b20c 16:12
+                */
+               .xatten1Margin = {0, 0, 0},
+               .tempSlope = 36,
+               .voltSlope = 0,
+
+               /*
+                * spurChans[OSPREY_EEPROM_MODAL_SPURS]; spur
+                * channels in usual fbin coding format
+                */
+               .spurChans = {0, 0, 0, 0, 0},
+
+               /*
+                * noiseFloorThreshCh[AR9300_MAX_CHAINS]; 3 Check
+                * if the register is per chain
+                */
+               .noiseFloorThreshCh = {-1, 0, 0},
+               .ob = {1, 1, 1},/* 3 chain */
+               .db_stage2 = {1, 1, 1}, /* 3 chain  */
+               .db_stage3 = {0, 0, 0},
+               .db_stage4 = {0, 0, 0},
+               .xpaBiasLvl = 0,
+               .txFrameToDataStart = 0x0e,
+               .txFrameToPaOn = 0x0e,
+               .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
+               .antennaGain = 0,
+               .switchSettling = 0x2c,
+               .adcDesiredSize = -30,
+               .txEndToXpaOff = 0,
+               .txEndToRxOn = 0x2,
+               .txFrameToXpaOn = 0xe,
+               .thresh62 = 28,
+               .futureModal = { /* [32] */
+                       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+                       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+               },
+        },
+       .calFreqPier2G = {
+               FREQ2FBIN(2412, 1),
+               FREQ2FBIN(2437, 1),
+               FREQ2FBIN(2472, 1),
+        },
+       /* ar9300_cal_data_per_freq_op_loop 2g */
+       .calPierData2G = {
+               { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
+               { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
+               { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
+        },
+       .calTarget_freqbin_Cck = {
+               FREQ2FBIN(2412, 1),
+               FREQ2FBIN(2484, 1),
+        },
+       .calTarget_freqbin_2G = {
+               FREQ2FBIN(2412, 1),
+               FREQ2FBIN(2437, 1),
+               FREQ2FBIN(2472, 1)
+        },
+       .calTarget_freqbin_2GHT20 = {
+               FREQ2FBIN(2412, 1),
+               FREQ2FBIN(2437, 1),
+               FREQ2FBIN(2472, 1)
+        },
+       .calTarget_freqbin_2GHT40 = {
+               FREQ2FBIN(2412, 1),
+               FREQ2FBIN(2437, 1),
+               FREQ2FBIN(2472, 1)
+        },
+       .calTargetPowerCck = {
+                /* 1L-5L,5S,11L,11S */
+                { {36, 36, 36, 36} },
+                { {36, 36, 36, 36} },
+       },
+       .calTargetPower2G = {
+                /* 6-24,36,48,54 */
+                { {32, 32, 28, 24} },
+                { {32, 32, 28, 24} },
+                { {32, 32, 28, 24} },
+       },
+       .calTargetPower2GHT20 = {
+               { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
+               { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
+               { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
+       },
+       .calTargetPower2GHT40 = {
+               { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
+               { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
+               { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
+       },
+       .ctlIndex_2G =  {
+               0x11, 0x12, 0x15, 0x17, 0x41, 0x42,
+               0x45, 0x47, 0x31, 0x32, 0x35, 0x37,
+       },
+       .ctl_freqbin_2G = {
+               {
+                       FREQ2FBIN(2412, 1),
+                       FREQ2FBIN(2417, 1),
+                       FREQ2FBIN(2457, 1),
+                       FREQ2FBIN(2462, 1)
+               },
+               {
+                       FREQ2FBIN(2412, 1),
+                       FREQ2FBIN(2417, 1),
+                       FREQ2FBIN(2462, 1),
+                       0xFF,
+               },
+
+               {
+                       FREQ2FBIN(2412, 1),
+                       FREQ2FBIN(2417, 1),
+                       FREQ2FBIN(2462, 1),
+                       0xFF,
+               },
+               {
+                       FREQ2FBIN(2422, 1),
+                       FREQ2FBIN(2427, 1),
+                       FREQ2FBIN(2447, 1),
+                       FREQ2FBIN(2452, 1)
+               },
+
+               {
+                       /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
+                       /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
+                       /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
+                       /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(2484, 1),
+               },
+
+               {
+                       /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
+                       /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
+                       /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
+                       0,
+               },
+
+               {
+                       /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
+                       /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
+                       FREQ2FBIN(2472, 1),
+                       0,
+               },
+
+               {
+                       /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
+                       /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
+                       /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
+                       /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
+               },
+
+               {
+                       /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
+                       /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
+                       /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
+               },
+
+               {
+                       /* Data[9].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
+                       /* Data[9].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
+                       /* Data[9].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
+                       0
+               },
+
+               {
+                       /* Data[10].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
+                       /* Data[10].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
+                       /* Data[10].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
+                       0
+               },
+
+               {
+                       /* Data[11].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
+                       /* Data[11].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
+                       /* Data[11].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
+                       /* Data[11].ctlEdges[3].bChannel */
+                       FREQ2FBIN(2462, 1),
+               }
+        },
+       .ctlPowerData_2G = {
+                { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } },
+                { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } },
+                { { {60, 1}, {60, 0}, {60, 0}, {60, 1} } },
+
+                { { {60, 1}, {60, 0}, {0, 0}, {0, 0} } },
+                { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } },
+                { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } },
+
+                { { {60, 0}, {60, 1}, {60, 1}, {60, 0} } },
+                { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } },
+                { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } },
+
+                { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } },
+                { { {60, 0}, {60, 1}, {60, 1}, {60, 1} } },
+        },
+       .modalHeader5G = {
+               /* 4 idle,t1,t2,b (4 bits per setting) */
+               .antCtrlCommon = 0x110,
+               /* 4 ra1l1, ra2l1, ra1l2,ra2l2,ra12 */
+               .antCtrlCommon2 = 0x22222,
+                /* antCtrlChain 6 idle, t,r,rx1,rx12,b (2 bits each) */
+               .antCtrlChain = {
+                       0x000, 0x000, 0x000,
+               },
+                /* xatten1DB 3 xatten1_db for AR9280 (0xa20c/b20c 5:0) */
+               .xatten1DB = {0, 0, 0},
+
+               /*
+                * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
+                * for merlin (0xa20c/b20c 16:12
+                */
+               .xatten1Margin = {0, 0, 0},
+               .tempSlope = 68,
+               .voltSlope = 0,
+               /* spurChans spur channels in usual fbin coding format */
+               .spurChans = {0, 0, 0, 0, 0},
+               /* noiseFloorThreshCh Check if the register is per chain */
+               .noiseFloorThreshCh = {-1, 0, 0},
+               .ob = {3, 3, 3}, /* 3 chain */
+               .db_stage2 = {3, 3, 3}, /* 3 chain */
+               .db_stage3 = {3, 3, 3}, /* doesn't exist for 2G */
+               .db_stage4 = {3, 3, 3},  /* don't exist for 2G */
+               .xpaBiasLvl = 0,
+               .txFrameToDataStart = 0x0e,
+               .txFrameToPaOn = 0x0e,
+               .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
+               .antennaGain = 0,
+               .switchSettling = 0x2d,
+               .adcDesiredSize = -30,
+               .txEndToXpaOff = 0,
+               .txEndToRxOn = 0x2,
+               .txFrameToXpaOn = 0xe,
+               .thresh62 = 28,
+               .futureModal = {
+                       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+                       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+               },
+        },
+       .calFreqPier5G = {
+               FREQ2FBIN(5180, 0),
+               FREQ2FBIN(5220, 0),
+               FREQ2FBIN(5320, 0),
+               FREQ2FBIN(5400, 0),
+               FREQ2FBIN(5500, 0),
+               FREQ2FBIN(5600, 0),
+               FREQ2FBIN(5725, 0),
+               FREQ2FBIN(5825, 0)
+       },
+       .calPierData5G = {
+                       {
+                               {0, 0, 0, 0, 0},
+                               {0, 0, 0, 0, 0},
+                               {0, 0, 0, 0, 0},
+                               {0, 0, 0, 0, 0},
+                               {0, 0, 0, 0, 0},
+                               {0, 0, 0, 0, 0},
+                               {0, 0, 0, 0, 0},
+                               {0, 0, 0, 0, 0},
+                       },
+                       {
+                               {0, 0, 0, 0, 0},
+                               {0, 0, 0, 0, 0},
+                               {0, 0, 0, 0, 0},
+                               {0, 0, 0, 0, 0},
+                               {0, 0, 0, 0, 0},
+                               {0, 0, 0, 0, 0},
+                               {0, 0, 0, 0, 0},
+                               {0, 0, 0, 0, 0},
+                       },
+                       {
+                               {0, 0, 0, 0, 0},
+                               {0, 0, 0, 0, 0},
+                               {0, 0, 0, 0, 0},
+                               {0, 0, 0, 0, 0},
+                               {0, 0, 0, 0, 0},
+                               {0, 0, 0, 0, 0},
+                               {0, 0, 0, 0, 0},
+                               {0, 0, 0, 0, 0},
+                       },
+
+       },
+       .calTarget_freqbin_5G = {
+               FREQ2FBIN(5180, 0),
+               FREQ2FBIN(5220, 0),
+               FREQ2FBIN(5320, 0),
+               FREQ2FBIN(5400, 0),
+               FREQ2FBIN(5500, 0),
+               FREQ2FBIN(5600, 0),
+               FREQ2FBIN(5725, 0),
+               FREQ2FBIN(5825, 0)
+       },
+       .calTarget_freqbin_5GHT20 = {
+               FREQ2FBIN(5180, 0),
+               FREQ2FBIN(5240, 0),
+               FREQ2FBIN(5320, 0),
+               FREQ2FBIN(5500, 0),
+               FREQ2FBIN(5700, 0),
+               FREQ2FBIN(5745, 0),
+               FREQ2FBIN(5725, 0),
+               FREQ2FBIN(5825, 0)
+       },
+       .calTarget_freqbin_5GHT40 = {
+               FREQ2FBIN(5180, 0),
+               FREQ2FBIN(5240, 0),
+               FREQ2FBIN(5320, 0),
+               FREQ2FBIN(5500, 0),
+               FREQ2FBIN(5700, 0),
+               FREQ2FBIN(5745, 0),
+               FREQ2FBIN(5725, 0),
+               FREQ2FBIN(5825, 0)
+        },
+       .calTargetPower5G = {
+               /* 6-24,36,48,54 */
+               { {20, 20, 20, 10} },
+               { {20, 20, 20, 10} },
+               { {20, 20, 20, 10} },
+               { {20, 20, 20, 10} },
+               { {20, 20, 20, 10} },
+               { {20, 20, 20, 10} },
+               { {20, 20, 20, 10} },
+               { {20, 20, 20, 10} },
+        },
+       .calTargetPower5GHT20 = {
+               /*
+                * 0_8_16,1-3_9-11_17-19,
+                * 4,5,6,7,12,13,14,15,20,21,22,23
+                */
+               { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
+               { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
+               { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
+               { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
+               { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
+               { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
+               { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
+               { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
+        },
+       .calTargetPower5GHT40 =  {
+               /*
+                * 0_8_16,1-3_9-11_17-19,
+                * 4,5,6,7,12,13,14,15,20,21,22,23
+                */
+               { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
+               { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
+               { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
+               { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
+               { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
+               { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
+               { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
+               { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
+        },
+       .ctlIndex_5G =  {
+               0x10, 0x16, 0x18, 0x40, 0x46,
+               0x48, 0x30, 0x36, 0x38
+       },
+       .ctl_freqbin_5G =  {
+               {
+                       /* Data[0].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
+                       /* Data[0].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
+                       /* Data[0].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
+                       /* Data[0].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
+                       /* Data[0].ctlEdges[4].bChannel */ FREQ2FBIN(5600, 0),
+                       /* Data[0].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
+                       /* Data[0].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
+                       /* Data[0].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
+               },
+               {
+                       /* Data[1].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
+                       /* Data[1].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
+                       /* Data[1].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
+                       /* Data[1].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
+                       /* Data[1].ctlEdges[4].bChannel */ FREQ2FBIN(5520, 0),
+                       /* Data[1].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
+                       /* Data[1].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
+                       /* Data[1].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
+               },
+
+               {
+                       /* Data[2].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
+                       /* Data[2].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
+                       /* Data[2].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
+                       /* Data[2].ctlEdges[3].bChannel */ FREQ2FBIN(5310, 0),
+                       /* Data[2].ctlEdges[4].bChannel */ FREQ2FBIN(5510, 0),
+                       /* Data[2].ctlEdges[5].bChannel */ FREQ2FBIN(5550, 0),
+                       /* Data[2].ctlEdges[6].bChannel */ FREQ2FBIN(5670, 0),
+                       /* Data[2].ctlEdges[7].bChannel */ FREQ2FBIN(5755, 0)
+               },
+
+               {
+                       /* Data[3].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
+                       /* Data[3].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
+                       /* Data[3].ctlEdges[2].bChannel */ FREQ2FBIN(5260, 0),
+                       /* Data[3].ctlEdges[3].bChannel */ FREQ2FBIN(5320, 0),
+                       /* Data[3].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
+                       /* Data[3].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
+                       /* Data[3].ctlEdges[6].bChannel */ 0xFF,
+                       /* Data[3].ctlEdges[7].bChannel */ 0xFF,
+               },
+
+               {
+                       /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
+                       /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
+                       /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(5500, 0),
+                       /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(5700, 0),
+                       /* Data[4].ctlEdges[4].bChannel */ 0xFF,
+                       /* Data[4].ctlEdges[5].bChannel */ 0xFF,
+                       /* Data[4].ctlEdges[6].bChannel */ 0xFF,
+                       /* Data[4].ctlEdges[7].bChannel */ 0xFF,
+               },
+
+               {
+                       /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
+                       /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(5270, 0),
+                       /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(5310, 0),
+                       /* Data[5].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
+                       /* Data[5].ctlEdges[4].bChannel */ FREQ2FBIN(5590, 0),
+                       /* Data[5].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
+                       /* Data[5].ctlEdges[6].bChannel */ 0xFF,
+                       /* Data[5].ctlEdges[7].bChannel */ 0xFF
+               },
+
+               {
+                       /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
+                       /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
+                       /* Data[6].ctlEdges[2].bChannel */ FREQ2FBIN(5220, 0),
+                       /* Data[6].ctlEdges[3].bChannel */ FREQ2FBIN(5260, 0),
+                       /* Data[6].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
+                       /* Data[6].ctlEdges[5].bChannel */ FREQ2FBIN(5600, 0),
+                       /* Data[6].ctlEdges[6].bChannel */ FREQ2FBIN(5700, 0),
+                       /* Data[6].ctlEdges[7].bChannel */ FREQ2FBIN(5745, 0)
+               },
+
+               {
+                       /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
+                       /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
+                       /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(5320, 0),
+                       /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
+                       /* Data[7].ctlEdges[4].bChannel */ FREQ2FBIN(5560, 0),
+                       /* Data[7].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
+                       /* Data[7].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
+                       /* Data[7].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
+               },
+
+               {
+                       /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
+                       /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
+                       /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
+                       /* Data[8].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
+                       /* Data[8].ctlEdges[4].bChannel */ FREQ2FBIN(5550, 0),
+                       /* Data[8].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
+                       /* Data[8].ctlEdges[6].bChannel */ FREQ2FBIN(5755, 0),
+                       /* Data[8].ctlEdges[7].bChannel */ FREQ2FBIN(5795, 0)
+               }
+        },
+       .ctlPowerData_5G = {
+               {
+                       {
+                               {60, 1}, {60, 1}, {60, 1}, {60, 1},
+                               {60, 1}, {60, 1}, {60, 1}, {60, 0},
+                       }
+               },
+               {
+                       {
+                               {60, 1}, {60, 1}, {60, 1}, {60, 1},
+                               {60, 1}, {60, 1}, {60, 1}, {60, 0},
+                       }
+               },
+               {
+                       {
+                               {60, 0}, {60, 1}, {60, 0}, {60, 1},
+                               {60, 1}, {60, 1}, {60, 1}, {60, 1},
+                       }
+               },
+               {
+                       {
+                               {60, 0}, {60, 1}, {60, 1}, {60, 0},
+                               {60, 1}, {60, 0}, {60, 0}, {60, 0},
+                       }
+               },
+               {
+                       {
+                               {60, 1}, {60, 1}, {60, 1}, {60, 0},
+                               {60, 0}, {60, 0}, {60, 0}, {60, 0},
+                       }
+               },
+               {
+                       {
+                               {60, 1}, {60, 1}, {60, 1}, {60, 1},
+                               {60, 1}, {60, 0}, {60, 0}, {60, 0},
+                       }
+               },
+               {
+                       {
+                               {60, 1}, {60, 1}, {60, 1}, {60, 1},
+                               {60, 1}, {60, 1}, {60, 1}, {60, 1},
+                       }
+               },
+               {
+                       {
+                               {60, 1}, {60, 1}, {60, 0}, {60, 1},
+                               {60, 1}, {60, 1}, {60, 1}, {60, 0},
+                       }
+               },
+               {
+                       {
+                               {60, 1}, {60, 0}, {60, 1}, {60, 1},
+                               {60, 1}, {60, 1}, {60, 0}, {60, 1},
+                       }
+               },
+        }
+};
+
+static int ath9k_hw_ar9300_check_eeprom(struct ath_hw *ah)
+{
+       return 0;
+}
+
+static u32 ath9k_hw_ar9300_get_eeprom(struct ath_hw *ah,
+                                     enum eeprom_param param)
+{
+       struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
+       struct ar9300_base_eep_hdr *pBase = &eep->baseEepHeader;
+
+       switch (param) {
+       case EEP_MAC_LSW:
+               return eep->macAddr[0] << 8 | eep->macAddr[1];
+       case EEP_MAC_MID:
+               return eep->macAddr[2] << 8 | eep->macAddr[3];
+       case EEP_MAC_MSW:
+               return eep->macAddr[4] << 8 | eep->macAddr[5];
+       case EEP_REG_0:
+               return pBase->regDmn[0];
+       case EEP_REG_1:
+               return pBase->regDmn[1];
+       case EEP_OP_CAP:
+               return pBase->deviceCap;
+       case EEP_OP_MODE:
+               return pBase->opCapFlags.opFlags;
+       case EEP_RF_SILENT:
+               return pBase->rfSilent;
+       case EEP_TX_MASK:
+               return (pBase->txrxMask >> 4) & 0xf;
+       case EEP_RX_MASK:
+               return pBase->txrxMask & 0xf;
+       case EEP_DRIVE_STRENGTH:
+#define AR9300_EEP_BASE_DRIV_STRENGTH  0x1
+               return pBase->miscConfiguration & AR9300_EEP_BASE_DRIV_STRENGTH;
+       case EEP_INTERNAL_REGULATOR:
+               /* Bit 4 is internal regulator flag */
+               return (pBase->featureEnable & 0x10) >> 4;
+       case EEP_SWREG:
+               return pBase->swreg;
+       default:
+               return 0;
+       }
+}
+
+#ifdef __BIG_ENDIAN
+static void ar9300_swap_eeprom(struct ar9300_eeprom *eep)
+{
+       u32 dword;
+       u16 word;
+       int i;
+
+       word = swab16(eep->baseEepHeader.regDmn[0]);
+       eep->baseEepHeader.regDmn[0] = word;
+
+       word = swab16(eep->baseEepHeader.regDmn[1]);
+       eep->baseEepHeader.regDmn[1] = word;
+
+       dword = swab32(eep->modalHeader2G.antCtrlCommon);
+       eep->modalHeader2G.antCtrlCommon = dword;
+
+       dword = swab32(eep->modalHeader2G.antCtrlCommon2);
+       eep->modalHeader2G.antCtrlCommon2 = dword;
+
+       dword = swab32(eep->modalHeader5G.antCtrlCommon);
+       eep->modalHeader5G.antCtrlCommon = dword;
+
+       dword = swab32(eep->modalHeader5G.antCtrlCommon2);
+       eep->modalHeader5G.antCtrlCommon2 = dword;
+
+       for (i = 0; i < AR9300_MAX_CHAINS; i++) {
+               word = swab16(eep->modalHeader2G.antCtrlChain[i]);
+               eep->modalHeader2G.antCtrlChain[i] = word;
+
+               word = swab16(eep->modalHeader5G.antCtrlChain[i]);
+               eep->modalHeader5G.antCtrlChain[i] = word;
+       }
+}
+#endif
+
+static bool ar9300_hw_read_eeprom(struct ath_hw *ah,
+                                 long address, u8 *buffer, int many)
+{
+       int i;
+       u8 value[2];
+       unsigned long eepAddr;
+       unsigned long byteAddr;
+       u16 *svalue;
+       struct ath_common *common = ath9k_hw_common(ah);
+
+       if ((address < 0) || ((address + many) > AR9300_EEPROM_SIZE - 1)) {
+               ath_print(common, ATH_DBG_EEPROM,
+                         "eeprom address not in range\n");
+               return false;
+       }
+
+       for (i = 0; i < many; i++) {
+               eepAddr = (u16) (address + i) / 2;
+               byteAddr = (u16) (address + i) % 2;
+               svalue = (u16 *) value;
+               if (!ath9k_hw_nvram_read(common, eepAddr, svalue)) {
+                       ath_print(common, ATH_DBG_EEPROM,
+                                 "unable to read eeprom region\n");
+                       return false;
+               }
+               *svalue = le16_to_cpu(*svalue);
+               buffer[i] = value[byteAddr];
+       }
+
+       return true;
+}
+
+static bool ar9300_read_eeprom(struct ath_hw *ah,
+                              int address, u8 *buffer, int many)
+{
+       int it;
+
+       for (it = 0; it < many; it++)
+               if (!ar9300_hw_read_eeprom(ah,
+                                          (address - it),
+                                          (buffer + it), 1))
+                       return false;
+       return true;
+}
+
+static void ar9300_comp_hdr_unpack(u8 *best, int *code, int *reference,
+                                  int *length, int *major, int *minor)
+{
+       unsigned long value[4];
+
+       value[0] = best[0];
+       value[1] = best[1];
+       value[2] = best[2];
+       value[3] = best[3];
+       *code = ((value[0] >> 5) & 0x0007);
+       *reference = (value[0] & 0x001f) | ((value[1] >> 2) & 0x0020);
+       *length = ((value[1] << 4) & 0x07f0) | ((value[2] >> 4) & 0x000f);
+       *major = (value[2] & 0x000f);
+       *minor = (value[3] & 0x00ff);
+}
+
+static u16 ar9300_comp_cksum(u8 *data, int dsize)
+{
+       int it, checksum = 0;
+
+       for (it = 0; it < dsize; it++) {
+               checksum += data[it];
+               checksum &= 0xffff;
+       }
+
+       return checksum;
+}
+
+static bool ar9300_uncompress_block(struct ath_hw *ah,
+                                   u8 *mptr,
+                                   int mdataSize,
+                                   u8 *block,
+                                   int size)
+{
+       int it;
+       int spot;
+       int offset;
+       int length;
+       struct ath_common *common = ath9k_hw_common(ah);
+
+       spot = 0;
+
+       for (it = 0; it < size; it += (length+2)) {
+               offset = block[it];
+               offset &= 0xff;
+               spot += offset;
+               length = block[it+1];
+               length &= 0xff;
+
+               if (length > 0 && spot >= 0 && spot+length < mdataSize) {
+                       ath_print(common, ATH_DBG_EEPROM,
+                                 "Restore at %d: spot=%d "
+                                 "offset=%d length=%d\n",
+                                  it, spot, offset, length);
+                       memcpy(&mptr[spot], &block[it+2], length);
+                       spot += length;
+               } else if (length > 0) {
+                       ath_print(common, ATH_DBG_EEPROM,
+                                 "Bad restore at %d: spot=%d "
+                                 "offset=%d length=%d\n",
+                                 it, spot, offset, length);
+                       return false;
+               }
+       }
+       return true;
+}
+
+static int ar9300_compress_decision(struct ath_hw *ah,
+                                   int it,
+                                   int code,
+                                   int reference,
+                                   u8 *mptr,
+                                   u8 *word, int length, int mdata_size)
+{
+       struct ath_common *common = ath9k_hw_common(ah);
+       u8 *dptr;
+
+       switch (code) {
+       case _CompressNone:
+               if (length != mdata_size) {
+                       ath_print(common, ATH_DBG_EEPROM,
+                                 "EEPROM structure size mismatch"
+                                 "memory=%d eeprom=%d\n", mdata_size, length);
+                       return -1;
+               }
+               memcpy(mptr, (u8 *) (word + COMP_HDR_LEN), length);
+               ath_print(common, ATH_DBG_EEPROM, "restored eeprom %d:"
+                         " uncompressed, length %d\n", it, length);
+               break;
+       case _CompressBlock:
+               if (reference == 0) {
+                       dptr = mptr;
+               } else {
+                       if (reference != 2) {
+                               ath_print(common, ATH_DBG_EEPROM,
+                                         "cant find reference eeprom"
+                                         "struct %d\n", reference);
+                               return -1;
+                       }
+                       memcpy(mptr, &ar9300_default, mdata_size);
+               }
+               ath_print(common, ATH_DBG_EEPROM,
+                         "restore eeprom %d: block, reference %d,"
+                         " length %d\n", it, reference, length);
+               ar9300_uncompress_block(ah, mptr, mdata_size,
+                                       (u8 *) (word + COMP_HDR_LEN), length);
+               break;
+       default:
+               ath_print(common, ATH_DBG_EEPROM, "unknown compression"
+                         " code %d\n", code);
+               return -1;
+       }
+       return 0;
+}
+
+/*
+ * Read the configuration data from the eeprom.
+ * The data can be put in any specified memory buffer.
+ *
+ * Returns -1 on error.
+ * Returns address of next memory location on success.
+ */
+static int ar9300_eeprom_restore_internal(struct ath_hw *ah,
+                                         u8 *mptr, int mdata_size)
+{
+#define MDEFAULT 15
+#define MSTATE 100
+       int cptr;
+       u8 *word;
+       int code;
+       int reference, length, major, minor;
+       int osize;
+       int it;
+       u16 checksum, mchecksum;
+       struct ath_common *common = ath9k_hw_common(ah);
+
+       word = kzalloc(2048, GFP_KERNEL);
+       if (!word)
+               return -1;
+
+       memcpy(mptr, &ar9300_default, mdata_size);
+
+       cptr = AR9300_BASE_ADDR;
+       for (it = 0; it < MSTATE; it++) {
+               if (!ar9300_read_eeprom(ah, cptr, word, COMP_HDR_LEN))
+                       goto fail;
+
+               if ((word[0] == 0 && word[1] == 0 && word[2] == 0 &&
+                    word[3] == 0) || (word[0] == 0xff && word[1] == 0xff
+                                      && word[2] == 0xff && word[3] == 0xff))
+                       break;
+
+               ar9300_comp_hdr_unpack(word, &code, &reference,
+                                      &length, &major, &minor);
+               ath_print(common, ATH_DBG_EEPROM,
+                         "Found block at %x: code=%d ref=%d"
+                         "length=%d major=%d minor=%d\n", cptr, code,
+                         reference, length, major, minor);
+               if (length >= 1024) {
+                       ath_print(common, ATH_DBG_EEPROM,
+                                 "Skipping bad header\n");
+                       cptr -= COMP_HDR_LEN;
+                       continue;
+               }
+
+               osize = length;
+               ar9300_read_eeprom(ah, cptr, word,
+                                  COMP_HDR_LEN + osize + COMP_CKSUM_LEN);
+               checksum = ar9300_comp_cksum(&word[COMP_HDR_LEN], length);
+               mchecksum = word[COMP_HDR_LEN + osize] |
+                   (word[COMP_HDR_LEN + osize + 1] << 8);
+               ath_print(common, ATH_DBG_EEPROM,
+                         "checksum %x %x\n", checksum, mchecksum);
+               if (checksum == mchecksum) {
+                       ar9300_compress_decision(ah, it, code, reference, mptr,
+                                                word, length, mdata_size);
+               } else {
+                       ath_print(common, ATH_DBG_EEPROM,
+                                 "skipping block with bad checksum\n");
+               }
+               cptr -= (COMP_HDR_LEN + osize + COMP_CKSUM_LEN);
+       }
+
+       kfree(word);
+       return cptr;
+
+fail:
+       kfree(word);
+       return -1;
+}
+
+/*
+ * Restore the configuration structure by reading the eeprom.
+ * This function destroys any existing in-memory structure
+ * content.
+ */
+static bool ath9k_hw_ar9300_fill_eeprom(struct ath_hw *ah)
+{
+       u8 *mptr = NULL;
+       int mdata_size;
+
+       mptr = (u8 *) &ah->eeprom.ar9300_eep;
+       mdata_size = sizeof(struct ar9300_eeprom);
+
+       if (mptr && mdata_size > 0) {
+               /* At this point, mptr points to the eeprom data structure
+                * in it's "default" state. If this is big endian, swap the
+                * data structures back to "little endian"
+                */
+               /* First swap, default to Little Endian */
+#ifdef __BIG_ENDIAN
+               ar9300_swap_eeprom((struct ar9300_eeprom *)mptr);
+#endif
+               if (ar9300_eeprom_restore_internal(ah, mptr, mdata_size) >= 0)
+                       return true;
+
+               /* Second Swap, back to Big Endian */
+#ifdef __BIG_ENDIAN
+               ar9300_swap_eeprom((struct ar9300_eeprom *)mptr);
+#endif
+       }
+       return false;
+}
+
+/* XXX: review hardware docs */
+static int ath9k_hw_ar9300_get_eeprom_ver(struct ath_hw *ah)
+{
+       return ah->eeprom.ar9300_eep.eepromVersion;
+}
+
+/* XXX: could be read from the eepromVersion, not sure yet */
+static int ath9k_hw_ar9300_get_eeprom_rev(struct ath_hw *ah)
+{
+       return 0;
+}
+
+static u8 ath9k_hw_ar9300_get_num_ant_config(struct ath_hw *ah,
+                                            enum ieee80211_band freq_band)
+{
+       return 1;
+}
+
+static u16 ath9k_hw_ar9300_get_eeprom_antenna_cfg(struct ath_hw *ah,
+                                                 struct ath9k_channel *chan)
+{
+       return -EINVAL;
+}
+
+static s32 ar9003_hw_xpa_bias_level_get(struct ath_hw *ah, bool is2ghz)
+{
+       struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
+
+       if (is2ghz)
+               return eep->modalHeader2G.xpaBiasLvl;
+       else
+               return eep->modalHeader5G.xpaBiasLvl;
+}
+
+static void ar9003_hw_xpa_bias_level_apply(struct ath_hw *ah, bool is2ghz)
+{
+       int bias = ar9003_hw_xpa_bias_level_get(ah, is2ghz);
+       REG_RMW_FIELD(ah, AR_CH0_TOP, AR_CH0_TOP_XPABIASLVL, (bias & 0x3));
+       REG_RMW_FIELD(ah, AR_CH0_THERM, AR_CH0_THERM_SPARE,
+                     ((bias >> 2) & 0x3));
+}
+
+static u32 ar9003_hw_ant_ctrl_common_get(struct ath_hw *ah, bool is2ghz)
+{
+       struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
+
+       if (is2ghz)
+               return eep->modalHeader2G.antCtrlCommon;
+       else
+               return eep->modalHeader5G.antCtrlCommon;
+}
+
+static u32 ar9003_hw_ant_ctrl_common_2_get(struct ath_hw *ah, bool is2ghz)
+{
+       struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
+
+       if (is2ghz)
+               return eep->modalHeader2G.antCtrlCommon2;
+       else
+               return eep->modalHeader5G.antCtrlCommon2;
+}
+
+static u16 ar9003_hw_ant_ctrl_chain_get(struct ath_hw *ah,
+                                       int chain,
+                                       bool is2ghz)
+{
+       struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
+
+       if (chain >= 0 && chain < AR9300_MAX_CHAINS) {
+               if (is2ghz)
+                       return eep->modalHeader2G.antCtrlChain[chain];
+               else
+                       return eep->modalHeader5G.antCtrlChain[chain];
+       }
+
+       return 0;
+}
+
+static void ar9003_hw_ant_ctrl_apply(struct ath_hw *ah, bool is2ghz)
+{
+       u32 value = ar9003_hw_ant_ctrl_common_get(ah, is2ghz);
+       REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM, AR_SWITCH_TABLE_COM_ALL, value);
+
+       value = ar9003_hw_ant_ctrl_common_2_get(ah, is2ghz);
+       REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM_2, AR_SWITCH_TABLE_COM2_ALL, value);
+
+       value = ar9003_hw_ant_ctrl_chain_get(ah, 0, is2ghz);
+       REG_RMW_FIELD(ah, AR_PHY_SWITCH_CHAIN_0, AR_SWITCH_TABLE_ALL, value);
+
+       value = ar9003_hw_ant_ctrl_chain_get(ah, 1, is2ghz);
+       REG_RMW_FIELD(ah, AR_PHY_SWITCH_CHAIN_1, AR_SWITCH_TABLE_ALL, value);
+
+       value = ar9003_hw_ant_ctrl_chain_get(ah, 2, is2ghz);
+       REG_RMW_FIELD(ah, AR_PHY_SWITCH_CHAIN_2, AR_SWITCH_TABLE_ALL, value);
+}
+
+static void ar9003_hw_drive_strength_apply(struct ath_hw *ah)
+{
+       int drive_strength;
+       unsigned long reg;
+
+       drive_strength = ath9k_hw_ar9300_get_eeprom(ah, EEP_DRIVE_STRENGTH);
+
+       if (!drive_strength)
+               return;
+
+       reg = REG_READ(ah, AR_PHY_65NM_CH0_BIAS1);
+       reg &= ~0x00ffffc0;
+       reg |= 0x5 << 21;
+       reg |= 0x5 << 18;
+       reg |= 0x5 << 15;
+       reg |= 0x5 << 12;
+       reg |= 0x5 << 9;
+       reg |= 0x5 << 6;
+       REG_WRITE(ah, AR_PHY_65NM_CH0_BIAS1, reg);
+
+       reg = REG_READ(ah, AR_PHY_65NM_CH0_BIAS2);
+       reg &= ~0xffffffe0;
+       reg |= 0x5 << 29;
+       reg |= 0x5 << 26;
+       reg |= 0x5 << 23;
+       reg |= 0x5 << 20;
+       reg |= 0x5 << 17;
+       reg |= 0x5 << 14;
+       reg |= 0x5 << 11;
+       reg |= 0x5 << 8;
+       reg |= 0x5 << 5;
+       REG_WRITE(ah, AR_PHY_65NM_CH0_BIAS2, reg);
+
+       reg = REG_READ(ah, AR_PHY_65NM_CH0_BIAS4);
+       reg &= ~0xff800000;
+       reg |= 0x5 << 29;
+       reg |= 0x5 << 26;
+       reg |= 0x5 << 23;
+       REG_WRITE(ah, AR_PHY_65NM_CH0_BIAS4, reg);
+}
+
+static void ar9003_hw_internal_regulator_apply(struct ath_hw *ah)
+{
+       int internal_regulator =
+               ath9k_hw_ar9300_get_eeprom(ah, EEP_INTERNAL_REGULATOR);
+
+       if (internal_regulator) {
+               /* Internal regulator is ON. Write swreg register. */
+               int swreg = ath9k_hw_ar9300_get_eeprom(ah, EEP_SWREG);
+               REG_WRITE(ah, AR_RTC_REG_CONTROL1,
+               REG_READ(ah, AR_RTC_REG_CONTROL1) &
+                        (~AR_RTC_REG_CONTROL1_SWREG_PROGRAM));
+               REG_WRITE(ah, AR_RTC_REG_CONTROL0, swreg);
+               /* Set REG_CONTROL1.SWREG_PROGRAM */
+               REG_WRITE(ah, AR_RTC_REG_CONTROL1,
+                         REG_READ(ah,
+                                  AR_RTC_REG_CONTROL1) |
+                                  AR_RTC_REG_CONTROL1_SWREG_PROGRAM);
+       } else {
+               REG_WRITE(ah, AR_RTC_SLEEP_CLK,
+                         (REG_READ(ah,
+                                   AR_RTC_SLEEP_CLK) |
+                                   AR_RTC_FORCE_SWREG_PRD));
+       }
+}
+
+static void ath9k_hw_ar9300_set_board_values(struct ath_hw *ah,
+                                            struct ath9k_channel *chan)
+{
+       ar9003_hw_xpa_bias_level_apply(ah, IS_CHAN_2GHZ(chan));
+       ar9003_hw_ant_ctrl_apply(ah, IS_CHAN_2GHZ(chan));
+       ar9003_hw_drive_strength_apply(ah);
+       ar9003_hw_internal_regulator_apply(ah);
+}
+
+static void ath9k_hw_ar9300_set_addac(struct ath_hw *ah,
+                                     struct ath9k_channel *chan)
+{
+}
+
+/*
+ * Returns the interpolated y value corresponding to the specified x value
+ * from the np ordered pairs of data (px,py).
+ * The pairs do not have to be in any order.
+ * If the specified x value is less than any of the px,
+ * the returned y value is equal to the py for the lowest px.
+ * If the specified x value is greater than any of the px,
+ * the returned y value is equal to the py for the highest px.
+ */
+static int ar9003_hw_power_interpolate(int32_t x,
+                                      int32_t *px, int32_t *py, u_int16_t np)
+{
+       int ip = 0;
+       int lx = 0, ly = 0, lhave = 0;
+       int hx = 0, hy = 0, hhave = 0;
+       int dx = 0;
+       int y = 0;
+
+       lhave = 0;
+       hhave = 0;
+
+       /* identify best lower and higher x calibration measurement */
+       for (ip = 0; ip < np; ip++) {
+               dx = x - px[ip];
+
+               /* this measurement is higher than our desired x */
+               if (dx <= 0) {
+                       if (!hhave || dx > (x - hx)) {
+                               /* new best higher x measurement */
+                               hx = px[ip];
+                               hy = py[ip];
+                               hhave = 1;
+                       }
+               }
+               /* this measurement is lower than our desired x */
+               if (dx >= 0) {
+                       if (!lhave || dx < (x - lx)) {
+                               /* new best lower x measurement */
+                               lx = px[ip];
+                               ly = py[ip];
+                               lhave = 1;
+                       }
+               }
+       }
+
+       /* the low x is good */
+       if (lhave) {
+               /* so is the high x */
+               if (hhave) {
+                       /* they're the same, so just pick one */
+                       if (hx == lx)
+                               y = ly;
+                       else    /* interpolate  */
+                               y = ly + (((x - lx) * (hy - ly)) / (hx - lx));
+               } else          /* only low is good, use it */
+                       y = ly;
+       } else if (hhave)       /* only high is good, use it */
+               y = hy;
+       else /* nothing is good,this should never happen unless np=0, ???? */
+               y = -(1 << 30);
+       return y;
+}
+
+static u8 ar9003_hw_eeprom_get_tgt_pwr(struct ath_hw *ah,
+                                      u16 rateIndex, u16 freq, bool is2GHz)
+{
+       u16 numPiers, i;
+       s32 targetPowerArray[AR9300_NUM_5G_20_TARGET_POWERS];
+       s32 freqArray[AR9300_NUM_5G_20_TARGET_POWERS];
+       struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
+       struct cal_tgt_pow_legacy *pEepromTargetPwr;
+       u8 *pFreqBin;
+
+       if (is2GHz) {
+               numPiers = AR9300_NUM_5G_20_TARGET_POWERS;
+               pEepromTargetPwr = eep->calTargetPower2G;
+               pFreqBin = eep->calTarget_freqbin_2G;
+       } else {
+               numPiers = AR9300_NUM_5G_20_TARGET_POWERS;
+               pEepromTargetPwr = eep->calTargetPower5G;
+               pFreqBin = eep->calTarget_freqbin_5G;
+       }
+
+       /*
+        * create array of channels and targetpower from
+        * targetpower piers stored on eeprom
+        */
+       for (i = 0; i < numPiers; i++) {
+               freqArray[i] = FBIN2FREQ(pFreqBin[i], is2GHz);
+               targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex];
+       }
+
+       /* interpolate to get target power for given frequency */
+       return (u8) ar9003_hw_power_interpolate((s32) freq,
+                                                freqArray,
+                                                targetPowerArray, numPiers);
+}
+
+static u8 ar9003_hw_eeprom_get_ht20_tgt_pwr(struct ath_hw *ah,
+                                           u16 rateIndex,
+                                           u16 freq, bool is2GHz)
+{
+       u16 numPiers, i;
+       s32 targetPowerArray[AR9300_NUM_5G_20_TARGET_POWERS];
+       s32 freqArray[AR9300_NUM_5G_20_TARGET_POWERS];
+       struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
+       struct cal_tgt_pow_ht *pEepromTargetPwr;
+       u8 *pFreqBin;
+
+       if (is2GHz) {
+               numPiers = AR9300_NUM_5G_20_TARGET_POWERS;
+               pEepromTargetPwr = eep->calTargetPower2GHT20;
+               pFreqBin = eep->calTarget_freqbin_2GHT20;
+       } else {
+               numPiers = AR9300_NUM_5G_20_TARGET_POWERS;
+               pEepromTargetPwr = eep->calTargetPower5GHT20;
+               pFreqBin = eep->calTarget_freqbin_5GHT20;
+       }
+
+       /*
+        * create array of channels and targetpower
+        * from targetpower piers stored on eeprom
+        */
+       for (i = 0; i < numPiers; i++) {
+               freqArray[i] = FBIN2FREQ(pFreqBin[i], is2GHz);
+               targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex];
+       }
+
+       /* interpolate to get target power for given frequency */
+       return (u8) ar9003_hw_power_interpolate((s32) freq,
+                                                freqArray,
+                                                targetPowerArray, numPiers);
+}
+
+static u8 ar9003_hw_eeprom_get_ht40_tgt_pwr(struct ath_hw *ah,
+                                           u16 rateIndex,
+                                           u16 freq, bool is2GHz)
+{
+       u16 numPiers, i;
+       s32 targetPowerArray[AR9300_NUM_5G_40_TARGET_POWERS];
+       s32 freqArray[AR9300_NUM_5G_40_TARGET_POWERS];
+       struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
+       struct cal_tgt_pow_ht *pEepromTargetPwr;
+       u8 *pFreqBin;
+
+       if (is2GHz) {
+               numPiers = AR9300_NUM_2G_40_TARGET_POWERS;
+               pEepromTargetPwr = eep->calTargetPower2GHT40;
+               pFreqBin = eep->calTarget_freqbin_2GHT40;
+       } else {
+               numPiers = AR9300_NUM_5G_40_TARGET_POWERS;
+               pEepromTargetPwr = eep->calTargetPower5GHT40;
+               pFreqBin = eep->calTarget_freqbin_5GHT40;
+       }
+
+       /*
+        * create array of channels and targetpower from
+        * targetpower piers stored on eeprom
+        */
+       for (i = 0; i < numPiers; i++) {
+               freqArray[i] = FBIN2FREQ(pFreqBin[i], is2GHz);
+               targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex];
+       }
+
+       /* interpolate to get target power for given frequency */
+       return (u8) ar9003_hw_power_interpolate((s32) freq,
+                                                freqArray,
+                                                targetPowerArray, numPiers);
+}
+
+static u8 ar9003_hw_eeprom_get_cck_tgt_pwr(struct ath_hw *ah,
+                                          u16 rateIndex, u16 freq)
+{
+       u16 numPiers = AR9300_NUM_2G_CCK_TARGET_POWERS, i;
+       s32 targetPowerArray[AR9300_NUM_2G_CCK_TARGET_POWERS];
+       s32 freqArray[AR9300_NUM_2G_CCK_TARGET_POWERS];
+       struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
+       struct cal_tgt_pow_legacy *pEepromTargetPwr = eep->calTargetPowerCck;
+       u8 *pFreqBin = eep->calTarget_freqbin_Cck;
+
+       /*
+        * create array of channels and targetpower from
+        * targetpower piers stored on eeprom
+        */
+       for (i = 0; i < numPiers; i++) {
+               freqArray[i] = FBIN2FREQ(pFreqBin[i], 1);
+               targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex];
+       }
+
+       /* interpolate to get target power for given frequency */
+       return (u8) ar9003_hw_power_interpolate((s32) freq,
+                                                freqArray,
+                                                targetPowerArray, numPiers);
+}
+
+/* Set tx power registers to array of values passed in */
+static int ar9003_hw_tx_power_regwrite(struct ath_hw *ah, u8 * pPwrArray)
+{
+#define POW_SM(_r, _s)     (((_r) & 0x3f) << (_s))
+       /* make sure forced gain is not set */
+       REG_WRITE(ah, 0xa458, 0);
+
+       /* Write the OFDM power per rate set */
+
+       /* 6 (LSB), 9, 12, 18 (MSB) */
+       REG_WRITE(ah, 0xa3c0,
+                 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 24) |
+                 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 16) |
+                 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 8) |
+                 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 0));
+
+       /* 24 (LSB), 36, 48, 54 (MSB) */
+       REG_WRITE(ah, 0xa3c4,
+                 POW_SM(pPwrArray[ALL_TARGET_LEGACY_54], 24) |
+                 POW_SM(pPwrArray[ALL_TARGET_LEGACY_48], 16) |
+                 POW_SM(pPwrArray[ALL_TARGET_LEGACY_36], 8) |
+                 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 0));
+
+       /* Write the CCK power per rate set */
+
+       /* 1L (LSB), reserved, 2L, 2S (MSB) */
+       REG_WRITE(ah, 0xa3c8,
+                 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 24) |
+                 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 16) |
+                 /* POW_SM(txPowerTimes2,  8) | this is reserved for AR9003 */
+                 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 0));
+
+       /* 5.5L (LSB), 5.5S, 11L, 11S (MSB) */
+       REG_WRITE(ah, 0xa3cc,
+                 POW_SM(pPwrArray[ALL_TARGET_LEGACY_11S], 24) |
+                 POW_SM(pPwrArray[ALL_TARGET_LEGACY_11L], 16) |
+                 POW_SM(pPwrArray[ALL_TARGET_LEGACY_5S], 8) |
+                 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 0)
+           );
+
+       /* Write the HT20 power per rate set */
+
+       /* 0/8/16 (LSB), 1-3/9-11/17-19, 4, 5 (MSB) */
+       REG_WRITE(ah, 0xa3d0,
+                 POW_SM(pPwrArray[ALL_TARGET_HT20_5], 24) |
+                 POW_SM(pPwrArray[ALL_TARGET_HT20_4], 16) |
+                 POW_SM(pPwrArray[ALL_TARGET_HT20_1_3_9_11_17_19], 8) |
+                 POW_SM(pPwrArray[ALL_TARGET_HT20_0_8_16], 0)
+           );
+
+       /* 6 (LSB), 7, 12, 13 (MSB) */
+       REG_WRITE(ah, 0xa3d4,
+                 POW_SM(pPwrArray[ALL_TARGET_HT20_13], 24) |
+                 POW_SM(pPwrArray[ALL_TARGET_HT20_12], 16) |
+                 POW_SM(pPwrArray[ALL_TARGET_HT20_7], 8) |
+                 POW_SM(pPwrArray[ALL_TARGET_HT20_6], 0)
+           );
+
+       /* 14 (LSB), 15, 20, 21 */
+       REG_WRITE(ah, 0xa3e4,
+                 POW_SM(pPwrArray[ALL_TARGET_HT20_21], 24) |
+                 POW_SM(pPwrArray[ALL_TARGET_HT20_20], 16) |
+                 POW_SM(pPwrArray[ALL_TARGET_HT20_15], 8) |
+                 POW_SM(pPwrArray[ALL_TARGET_HT20_14], 0)
+           );
+
+       /* Mixed HT20 and HT40 rates */
+
+       /* HT20 22 (LSB), HT20 23, HT40 22, HT40 23 (MSB) */
+       REG_WRITE(ah, 0xa3e8,
+                 POW_SM(pPwrArray[ALL_TARGET_HT40_23], 24) |
+                 POW_SM(pPwrArray[ALL_TARGET_HT40_22], 16) |
+                 POW_SM(pPwrArray[ALL_TARGET_HT20_23], 8) |
+                 POW_SM(pPwrArray[ALL_TARGET_HT20_22], 0)
+           );
+
+       /*
+        * Write the HT40 power per rate set
+        * correct PAR difference between HT40 and HT20/LEGACY
+        * 0/8/16 (LSB), 1-3/9-11/17-19, 4, 5 (MSB)
+        */
+       REG_WRITE(ah, 0xa3d8,
+                 POW_SM(pPwrArray[ALL_TARGET_HT40_5], 24) |
+                 POW_SM(pPwrArray[ALL_TARGET_HT40_4], 16) |
+                 POW_SM(pPwrArray[ALL_TARGET_HT40_1_3_9_11_17_19], 8) |
+                 POW_SM(pPwrArray[ALL_TARGET_HT40_0_8_16], 0)
+           );
+
+       /* 6 (LSB), 7, 12, 13 (MSB) */
+       REG_WRITE(ah, 0xa3dc,
+                 POW_SM(pPwrArray[ALL_TARGET_HT40_13], 24) |
+                 POW_SM(pPwrArray[ALL_TARGET_HT40_12], 16) |
+                 POW_SM(pPwrArray[ALL_TARGET_HT40_7], 8) |
+                 POW_SM(pPwrArray[ALL_TARGET_HT40_6], 0)
+           );
+
+       /* 14 (LSB), 15, 20, 21 */
+       REG_WRITE(ah, 0xa3ec,
+                 POW_SM(pPwrArray[ALL_TARGET_HT40_21], 24) |
+                 POW_SM(pPwrArray[ALL_TARGET_HT40_20], 16) |
+                 POW_SM(pPwrArray[ALL_TARGET_HT40_15], 8) |
+                 POW_SM(pPwrArray[ALL_TARGET_HT40_14], 0)
+           );
+
+       return 0;
+#undef POW_SM
+}
+
+static void ar9003_hw_set_target_power_eeprom(struct ath_hw *ah, u16 freq)
+{
+       u8 targetPowerValT2[ar9300RateSize];
+       /* XXX: hard code for now, need to get from eeprom struct */
+       u8 ht40PowerIncForPdadc = 0;
+       bool is2GHz = false;
+       unsigned int i = 0;
+       struct ath_common *common = ath9k_hw_common(ah);
+
+       if (freq < 4000)
+               is2GHz = true;
+
+       targetPowerValT2[ALL_TARGET_LEGACY_6_24] =
+           ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_6_24, freq,
+                                        is2GHz);
+       targetPowerValT2[ALL_TARGET_LEGACY_36] =
+           ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_36, freq,
+                                        is2GHz);
+       targetPowerValT2[ALL_TARGET_LEGACY_48] =
+           ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_48, freq,
+                                        is2GHz);
+       targetPowerValT2[ALL_TARGET_LEGACY_54] =
+           ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_54, freq,
+                                        is2GHz);
+       targetPowerValT2[ALL_TARGET_LEGACY_1L_5L] =
+           ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_1L_5L,
+                                            freq);
+       targetPowerValT2[ALL_TARGET_LEGACY_5S] =
+           ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_5S, freq);
+       targetPowerValT2[ALL_TARGET_LEGACY_11L] =
+           ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_11L, freq);
+       targetPowerValT2[ALL_TARGET_LEGACY_11S] =
+           ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_11S, freq);
+       targetPowerValT2[ALL_TARGET_HT20_0_8_16] =
+           ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_0_8_16, freq,
+                                             is2GHz);
+       targetPowerValT2[ALL_TARGET_HT20_1_3_9_11_17_19] =
+           ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_1_3_9_11_17_19,
+                                             freq, is2GHz);
+       targetPowerValT2[ALL_TARGET_HT20_4] =
+           ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_4, freq,
+                                             is2GHz);
+       targetPowerValT2[ALL_TARGET_HT20_5] =
+           ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_5, freq,
+                                             is2GHz);
+       targetPowerValT2[ALL_TARGET_HT20_6] =
+           ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_6, freq,
+                                             is2GHz);
+       targetPowerValT2[ALL_TARGET_HT20_7] =
+           ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_7, freq,
+                                             is2GHz);
+       targetPowerValT2[ALL_TARGET_HT20_12] =
+           ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_12, freq,
+                                             is2GHz);
+       targetPowerValT2[ALL_TARGET_HT20_13] =
+           ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_13, freq,
+                                             is2GHz);
+       targetPowerValT2[ALL_TARGET_HT20_14] =
+           ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_14, freq,
+                                             is2GHz);
+       targetPowerValT2[ALL_TARGET_HT20_15] =
+           ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_15, freq,
+                                             is2GHz);
+       targetPowerValT2[ALL_TARGET_HT20_20] =
+           ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_20, freq,
+                                             is2GHz);
+       targetPowerValT2[ALL_TARGET_HT20_21] =
+           ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_21, freq,
+                                             is2GHz);
+       targetPowerValT2[ALL_TARGET_HT20_22] =
+           ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_22, freq,
+                                             is2GHz);
+       targetPowerValT2[ALL_TARGET_HT20_23] =
+           ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_23, freq,
+                                             is2GHz);
+       targetPowerValT2[ALL_TARGET_HT40_0_8_16] =
+           ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_0_8_16, freq,
+                                             is2GHz) + ht40PowerIncForPdadc;
+       targetPowerValT2[ALL_TARGET_HT40_1_3_9_11_17_19] =
+           ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_1_3_9_11_17_19,
+                                             freq,
+                                             is2GHz) + ht40PowerIncForPdadc;
+       targetPowerValT2[ALL_TARGET_HT40_4] =
+           ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_4, freq,
+                                             is2GHz) + ht40PowerIncForPdadc;
+       targetPowerValT2[ALL_TARGET_HT40_5] =
+           ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_5, freq,
+                                             is2GHz) + ht40PowerIncForPdadc;
+       targetPowerValT2[ALL_TARGET_HT40_6] =
+           ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_6, freq,
+                                             is2GHz) + ht40PowerIncForPdadc;
+       targetPowerValT2[ALL_TARGET_HT40_7] =
+           ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_7, freq,
+                                             is2GHz) + ht40PowerIncForPdadc;
+       targetPowerValT2[ALL_TARGET_HT40_12] =
+           ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_12, freq,
+                                             is2GHz) + ht40PowerIncForPdadc;
+       targetPowerValT2[ALL_TARGET_HT40_13] =
+           ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_13, freq,
+                                             is2GHz) + ht40PowerIncForPdadc;
+       targetPowerValT2[ALL_TARGET_HT40_14] =
+           ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_14, freq,
+                                             is2GHz) + ht40PowerIncForPdadc;
+       targetPowerValT2[ALL_TARGET_HT40_15] =
+           ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_15, freq,
+                                             is2GHz) + ht40PowerIncForPdadc;
+       targetPowerValT2[ALL_TARGET_HT40_20] =
+           ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_20, freq,
+                                             is2GHz) + ht40PowerIncForPdadc;
+       targetPowerValT2[ALL_TARGET_HT40_21] =
+           ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_21, freq,
+                                             is2GHz) + ht40PowerIncForPdadc;
+       targetPowerValT2[ALL_TARGET_HT40_22] =
+           ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_22, freq,
+                                             is2GHz) + ht40PowerIncForPdadc;
+       targetPowerValT2[ALL_TARGET_HT40_23] =
+           ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_23, freq,
+                                             is2GHz) + ht40PowerIncForPdadc;
+
+       while (i < ar9300RateSize) {
+               ath_print(common, ATH_DBG_EEPROM,
+                         "TPC[%02d] 0x%08x ", i, targetPowerValT2[i]);
+               i++;
+
+               ath_print(common, ATH_DBG_EEPROM,
+                         "TPC[%02d] 0x%08x ", i, targetPowerValT2[i]);
+               i++;
+
+               ath_print(common, ATH_DBG_EEPROM,
+                         "TPC[%02d] 0x%08x ", i, targetPowerValT2[i]);
+               i++;
+
+               ath_print(common, ATH_DBG_EEPROM,
+                         "TPC[%02d] 0x%08x\n", i, targetPowerValT2[i]);
+               i++;
+       }
+
+       /* Write target power array to registers */
+       ar9003_hw_tx_power_regwrite(ah, targetPowerValT2);
+}
+
+static int ar9003_hw_cal_pier_get(struct ath_hw *ah,
+                                 int mode,
+                                 int ipier,
+                                 int ichain,
+                                 int *pfrequency,
+                                 int *pcorrection,
+                                 int *ptemperature, int *pvoltage)
+{
+       u8 *pCalPier;
+       struct ar9300_cal_data_per_freq_op_loop *pCalPierStruct;
+       int is2GHz;
+       struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
+       struct ath_common *common = ath9k_hw_common(ah);
+
+       if (ichain >= AR9300_MAX_CHAINS) {
+               ath_print(common, ATH_DBG_EEPROM,
+                         "Invalid chain index, must be less than %d\n",
+                         AR9300_MAX_CHAINS);
+               return -1;
+       }
+
+       if (mode) {             /* 5GHz */
+               if (ipier >= AR9300_NUM_5G_CAL_PIERS) {
+                       ath_print(common, ATH_DBG_EEPROM,
+                                 "Invalid 5GHz cal pier index, must "
+                                 "be less than %d\n",
+                                 AR9300_NUM_5G_CAL_PIERS);
+                       return -1;
+               }
+               pCalPier = &(eep->calFreqPier5G[ipier]);
+               pCalPierStruct = &(eep->calPierData5G[ichain][ipier]);
+               is2GHz = 0;
+       } else {
+               if (ipier >= AR9300_NUM_2G_CAL_PIERS) {
+                       ath_print(common, ATH_DBG_EEPROM,
+                                 "Invalid 2GHz cal pier index, must "
+                                 "be less than %d\n", AR9300_NUM_2G_CAL_PIERS);
+                       return -1;
+               }
+
+               pCalPier = &(eep->calFreqPier2G[ipier]);
+               pCalPierStruct = &(eep->calPierData2G[ichain][ipier]);
+               is2GHz = 1;
+       }
+
+       *pfrequency = FBIN2FREQ(*pCalPier, is2GHz);
+       *pcorrection = pCalPierStruct->refPower;
+       *ptemperature = pCalPierStruct->tempMeas;
+       *pvoltage = pCalPierStruct->voltMeas;
+
+       return 0;
+}
+
+static int ar9003_hw_power_control_override(struct ath_hw *ah,
+                                           int frequency,
+                                           int *correction,
+                                           int *voltage, int *temperature)
+{
+       int tempSlope = 0;
+       struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
+
+       REG_RMW(ah, AR_PHY_TPC_11_B0,
+               (correction[0] << AR_PHY_TPC_OLPC_GAIN_DELTA_S),
+               AR_PHY_TPC_OLPC_GAIN_DELTA);
+       REG_RMW(ah, AR_PHY_TPC_11_B1,
+               (correction[1] << AR_PHY_TPC_OLPC_GAIN_DELTA_S),
+               AR_PHY_TPC_OLPC_GAIN_DELTA);
+       REG_RMW(ah, AR_PHY_TPC_11_B2,
+               (correction[2] << AR_PHY_TPC_OLPC_GAIN_DELTA_S),
+               AR_PHY_TPC_OLPC_GAIN_DELTA);
+
+       /* enable open loop power control on chip */
+       REG_RMW(ah, AR_PHY_TPC_6_B0,
+               (3 << AR_PHY_TPC_6_ERROR_EST_MODE_S),
+               AR_PHY_TPC_6_ERROR_EST_MODE);
+       REG_RMW(ah, AR_PHY_TPC_6_B1,
+               (3 << AR_PHY_TPC_6_ERROR_EST_MODE_S),
+               AR_PHY_TPC_6_ERROR_EST_MODE);
+       REG_RMW(ah, AR_PHY_TPC_6_B2,
+               (3 << AR_PHY_TPC_6_ERROR_EST_MODE_S),
+               AR_PHY_TPC_6_ERROR_EST_MODE);
+
+       /*
+        * enable temperature compensation
+        * Need to use register names
+        */
+       if (frequency < 4000)
+               tempSlope = eep->modalHeader2G.tempSlope;
+       else
+               tempSlope = eep->modalHeader5G.tempSlope;
+
+       REG_RMW_FIELD(ah, AR_PHY_TPC_19, AR_PHY_TPC_19_ALPHA_THERM, tempSlope);
+       REG_RMW_FIELD(ah, AR_PHY_TPC_18, AR_PHY_TPC_18_THERM_CAL_VALUE,
+                     temperature[0]);
+
+       return 0;
+}
+
+/* Apply the recorded correction values. */
+static int ar9003_hw_calibration_apply(struct ath_hw *ah, int frequency)
+{
+       int ichain, ipier, npier;
+       int mode;
+       int lfrequency[AR9300_MAX_CHAINS],
+           lcorrection[AR9300_MAX_CHAINS],
+           ltemperature[AR9300_MAX_CHAINS], lvoltage[AR9300_MAX_CHAINS];
+       int hfrequency[AR9300_MAX_CHAINS],
+           hcorrection[AR9300_MAX_CHAINS],
+           htemperature[AR9300_MAX_CHAINS], hvoltage[AR9300_MAX_CHAINS];
+       int fdiff;
+       int correction[AR9300_MAX_CHAINS],
+           voltage[AR9300_MAX_CHAINS], temperature[AR9300_MAX_CHAINS];
+       int pfrequency, pcorrection, ptemperature, pvoltage;
+       struct ath_common *common = ath9k_hw_common(ah);
+
+       mode = (frequency >= 4000);
+       if (mode)
+               npier = AR9300_NUM_5G_CAL_PIERS;
+       else
+               npier = AR9300_NUM_2G_CAL_PIERS;
+
+       for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) {
+               lfrequency[ichain] = 0;
+               hfrequency[ichain] = 100000;
+       }
+       /* identify best lower and higher frequency calibration measurement */
+       for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) {
+               for (ipier = 0; ipier < npier; ipier++) {
+                       if (!ar9003_hw_cal_pier_get(ah, mode, ipier, ichain,
+                                                   &pfrequency, &pcorrection,
+                                                   &ptemperature, &pvoltage)) {
+                               fdiff = frequency - pfrequency;
+
+                               /*
+                                * this measurement is higher than
+                                * our desired frequency
+                                */
+                               if (fdiff <= 0) {
+                                       if (hfrequency[ichain] <= 0 ||
+                                           hfrequency[ichain] >= 100000 ||
+                                           fdiff >
+                                           (frequency - hfrequency[ichain])) {
+                                               /*
+                                                * new best higher
+                                                * frequency measurement
+                                                */
+                                               hfrequency[ichain] = pfrequency;
+                                               hcorrection[ichain] =
+                                                   pcorrection;
+                                               htemperature[ichain] =
+                                                   ptemperature;
+                                               hvoltage[ichain] = pvoltage;
+                                       }
+                               }
+                               if (fdiff >= 0) {
+                                       if (lfrequency[ichain] <= 0
+                                           || fdiff <
+                                           (frequency - lfrequency[ichain])) {
+                                               /*
+                                                * new best lower
+                                                * frequency measurement
+                                                */
+                                               lfrequency[ichain] = pfrequency;
+                                               lcorrection[ichain] =
+                                                   pcorrection;
+                                               ltemperature[ichain] =
+                                                   ptemperature;
+                                               lvoltage[ichain] = pvoltage;
+                                       }
+                               }
+                       }
+               }
+       }
+
+       /* interpolate  */
+       for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) {
+               ath_print(common, ATH_DBG_EEPROM,
+                         "ch=%d f=%d low=%d %d h=%d %d\n",
+                         ichain, frequency, lfrequency[ichain],
+                         lcorrection[ichain], hfrequency[ichain],
+                         hcorrection[ichain]);
+               /* they're the same, so just pick one */
+               if (hfrequency[ichain] == lfrequency[ichain]) {
+                       correction[ichain] = lcorrection[ichain];
+                       voltage[ichain] = lvoltage[ichain];
+                       temperature[ichain] = ltemperature[ichain];
+               }
+               /* the low frequency is good */
+               else if (frequency - lfrequency[ichain] < 1000) {
+                       /* so is the high frequency, interpolate */
+                       if (hfrequency[ichain] - frequency < 1000) {
+
+                               correction[ichain] = lcorrection[ichain] +
+                                   (((frequency - lfrequency[ichain]) *
+                                     (hcorrection[ichain] -
+                                      lcorrection[ichain])) /
+                                    (hfrequency[ichain] - lfrequency[ichain]));
+
+                               temperature[ichain] = ltemperature[ichain] +
+                                   (((frequency - lfrequency[ichain]) *
+                                     (htemperature[ichain] -
+                                      ltemperature[ichain])) /
+                                    (hfrequency[ichain] - lfrequency[ichain]));
+
+                               voltage[ichain] =
+                                   lvoltage[ichain] +
+                                   (((frequency -
+                                      lfrequency[ichain]) * (hvoltage[ichain] -
+                                                             lvoltage[ichain]))
+                                    / (hfrequency[ichain] -
+                                       lfrequency[ichain]));
+                       }
+                       /* only low is good, use it */
+                       else {
+                               correction[ichain] = lcorrection[ichain];
+                               temperature[ichain] = ltemperature[ichain];
+                               voltage[ichain] = lvoltage[ichain];
+                       }
+               }
+               /* only high is good, use it */
+               else if (hfrequency[ichain] - frequency < 1000) {
+                       correction[ichain] = hcorrection[ichain];
+                       temperature[ichain] = htemperature[ichain];
+                       voltage[ichain] = hvoltage[ichain];
+               } else {        /* nothing is good, presume 0???? */
+                       correction[ichain] = 0;
+                       temperature[ichain] = 0;
+                       voltage[ichain] = 0;
+               }
+       }
+
+       ar9003_hw_power_control_override(ah, frequency, correction, voltage,
+                                        temperature);
+
+       ath_print(common, ATH_DBG_EEPROM,
+                 "for frequency=%d, calibration correction = %d %d %d\n",
+                 frequency, correction[0], correction[1], correction[2]);
+
+       return 0;
+}
+
+static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah,
+                                       struct ath9k_channel *chan, u16 cfgCtl,
+                                       u8 twiceAntennaReduction,
+                                       u8 twiceMaxRegulatoryPower,
+                                       u8 powerLimit)
+{
+       ar9003_hw_set_target_power_eeprom(ah, chan->channel);
+       ar9003_hw_calibration_apply(ah, chan->channel);
+}
+
+static u16 ath9k_hw_ar9300_get_spur_channel(struct ath_hw *ah,
+                                           u16 i, bool is2GHz)
+{
+       return AR_NO_SPUR;
+}
+
+s32 ar9003_hw_get_tx_gain_idx(struct ath_hw *ah)
+{
+       struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
+
+       return (eep->baseEepHeader.txrxgain >> 4) & 0xf; /* bits 7:4 */
+}
+
+s32 ar9003_hw_get_rx_gain_idx(struct ath_hw *ah)
+{
+       struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
+
+       return (eep->baseEepHeader.txrxgain) & 0xf; /* bits 3:0 */
+}
+
+const struct eeprom_ops eep_ar9300_ops = {
+       .check_eeprom = ath9k_hw_ar9300_check_eeprom,
+       .get_eeprom = ath9k_hw_ar9300_get_eeprom,
+       .fill_eeprom = ath9k_hw_ar9300_fill_eeprom,
+       .get_eeprom_ver = ath9k_hw_ar9300_get_eeprom_ver,
+       .get_eeprom_rev = ath9k_hw_ar9300_get_eeprom_rev,
+       .get_num_ant_config = ath9k_hw_ar9300_get_num_ant_config,
+       .get_eeprom_antenna_cfg = ath9k_hw_ar9300_get_eeprom_antenna_cfg,
+       .set_board_values = ath9k_hw_ar9300_set_board_values,
+       .set_addac = ath9k_hw_ar9300_set_addac,
+       .set_txpower = ath9k_hw_ar9300_set_txpower,
+       .get_spur_channel = ath9k_hw_ar9300_get_spur_channel
+};
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h
new file mode 100644 (file)
index 0000000..5fe335e
--- /dev/null
@@ -0,0 +1,323 @@
+#ifndef AR9003_EEPROM_H
+#define AR9003_EEPROM_H
+
+#include <linux/types.h>
+
+#define AR9300_EEP_VER               0xD000
+#define AR9300_EEP_VER_MINOR_MASK    0xFFF
+#define AR9300_EEP_MINOR_VER_1       0x1
+#define AR9300_EEP_MINOR_VER         AR9300_EEP_MINOR_VER_1
+
+/* 16-bit offset location start of calibration struct */
+#define AR9300_EEP_START_LOC         256
+#define AR9300_NUM_5G_CAL_PIERS      8
+#define AR9300_NUM_2G_CAL_PIERS      3
+#define AR9300_NUM_5G_20_TARGET_POWERS  8
+#define AR9300_NUM_5G_40_TARGET_POWERS  8
+#define AR9300_NUM_2G_CCK_TARGET_POWERS 2
+#define AR9300_NUM_2G_20_TARGET_POWERS  3
+#define AR9300_NUM_2G_40_TARGET_POWERS  3
+/* #define AR9300_NUM_CTLS              21 */
+#define AR9300_NUM_CTLS_5G           9
+#define AR9300_NUM_CTLS_2G           12
+#define AR9300_CTL_MODE_M            0xF
+#define AR9300_NUM_BAND_EDGES_5G     8
+#define AR9300_NUM_BAND_EDGES_2G     4
+#define AR9300_NUM_PD_GAINS          4
+#define AR9300_PD_GAINS_IN_MASK      4
+#define AR9300_PD_GAIN_ICEPTS        5
+#define AR9300_EEPROM_MODAL_SPURS    5
+#define AR9300_MAX_RATE_POWER        63
+#define AR9300_NUM_PDADC_VALUES      128
+#define AR9300_NUM_RATES             16
+#define AR9300_BCHAN_UNUSED          0xFF
+#define AR9300_MAX_PWR_RANGE_IN_HALF_DB 64
+#define AR9300_OPFLAGS_11A           0x01
+#define AR9300_OPFLAGS_11G           0x02
+#define AR9300_OPFLAGS_5G_HT40       0x04
+#define AR9300_OPFLAGS_2G_HT40       0x08
+#define AR9300_OPFLAGS_5G_HT20       0x10
+#define AR9300_OPFLAGS_2G_HT20       0x20
+#define AR9300_EEPMISC_BIG_ENDIAN    0x01
+#define AR9300_EEPMISC_WOW           0x02
+#define AR9300_CUSTOMER_DATA_SIZE    20
+
+#define FREQ2FBIN(x, y) ((y) ? ((x) - 2300) : (((x) - 4800) / 5))
+#define FBIN2FREQ(x, y) ((y) ? (2300 + x) : (4800 + 5 * x))
+#define AR9300_MAX_CHAINS            3
+#define AR9300_ANT_16S               25
+#define AR9300_FUTURE_MODAL_SZ       6
+
+#define AR9300_NUM_ANT_CHAIN_FIELDS     7
+#define AR9300_NUM_ANT_COMMON_FIELDS    4
+#define AR9300_SIZE_ANT_CHAIN_FIELD     3
+#define AR9300_SIZE_ANT_COMMON_FIELD    4
+#define AR9300_ANT_CHAIN_MASK           0x7
+#define AR9300_ANT_COMMON_MASK          0xf
+#define AR9300_CHAIN_0_IDX              0
+#define AR9300_CHAIN_1_IDX              1
+#define AR9300_CHAIN_2_IDX              2
+
+#define AR928X_NUM_ANT_CHAIN_FIELDS     6
+#define AR928X_SIZE_ANT_CHAIN_FIELD     2
+#define AR928X_ANT_CHAIN_MASK           0x3
+
+/* Delta from which to start power to pdadc table */
+/* This offset is used in both open loop and closed loop power control
+ * schemes. In open loop power control, it is not really needed, but for
+ * the "sake of consistency" it was kept. For certain AP designs, this
+ * value is overwritten by the value in the flag "pwrTableOffset" just
+ * before writing the pdadc vs pwr into the chip registers.
+ */
+#define AR9300_PWR_TABLE_OFFSET  0
+
+/* enable flags for voltage and temp compensation */
+#define ENABLE_TEMP_COMPENSATION 0x01
+#define ENABLE_VOLT_COMPENSATION 0x02
+/* byte addressable */
+#define AR9300_EEPROM_SIZE (16*1024)
+#define FIXED_CCA_THRESHOLD 15
+
+#define AR9300_BASE_ADDR 0x3ff
+
+enum targetPowerHTRates {
+       HT_TARGET_RATE_0_8_16,
+       HT_TARGET_RATE_1_3_9_11_17_19,
+       HT_TARGET_RATE_4,
+       HT_TARGET_RATE_5,
+       HT_TARGET_RATE_6,
+       HT_TARGET_RATE_7,
+       HT_TARGET_RATE_12,
+       HT_TARGET_RATE_13,
+       HT_TARGET_RATE_14,
+       HT_TARGET_RATE_15,
+       HT_TARGET_RATE_20,
+       HT_TARGET_RATE_21,
+       HT_TARGET_RATE_22,
+       HT_TARGET_RATE_23
+};
+
+enum targetPowerLegacyRates {
+       LEGACY_TARGET_RATE_6_24,
+       LEGACY_TARGET_RATE_36,
+       LEGACY_TARGET_RATE_48,
+       LEGACY_TARGET_RATE_54
+};
+
+enum targetPowerCckRates {
+       LEGACY_TARGET_RATE_1L_5L,
+       LEGACY_TARGET_RATE_5S,
+       LEGACY_TARGET_RATE_11L,
+       LEGACY_TARGET_RATE_11S
+};
+
+enum ar9300_Rates {
+       ALL_TARGET_LEGACY_6_24,
+       ALL_TARGET_LEGACY_36,
+       ALL_TARGET_LEGACY_48,
+       ALL_TARGET_LEGACY_54,
+       ALL_TARGET_LEGACY_1L_5L,
+       ALL_TARGET_LEGACY_5S,
+       ALL_TARGET_LEGACY_11L,
+       ALL_TARGET_LEGACY_11S,
+       ALL_TARGET_HT20_0_8_16,
+       ALL_TARGET_HT20_1_3_9_11_17_19,
+       ALL_TARGET_HT20_4,
+       ALL_TARGET_HT20_5,
+       ALL_TARGET_HT20_6,
+       ALL_TARGET_HT20_7,
+       ALL_TARGET_HT20_12,
+       ALL_TARGET_HT20_13,
+       ALL_TARGET_HT20_14,
+       ALL_TARGET_HT20_15,
+       ALL_TARGET_HT20_20,
+       ALL_TARGET_HT20_21,
+       ALL_TARGET_HT20_22,
+       ALL_TARGET_HT20_23,
+       ALL_TARGET_HT40_0_8_16,
+       ALL_TARGET_HT40_1_3_9_11_17_19,
+       ALL_TARGET_HT40_4,
+       ALL_TARGET_HT40_5,
+       ALL_TARGET_HT40_6,
+       ALL_TARGET_HT40_7,
+       ALL_TARGET_HT40_12,
+       ALL_TARGET_HT40_13,
+       ALL_TARGET_HT40_14,
+       ALL_TARGET_HT40_15,
+       ALL_TARGET_HT40_20,
+       ALL_TARGET_HT40_21,
+       ALL_TARGET_HT40_22,
+       ALL_TARGET_HT40_23,
+       ar9300RateSize,
+};
+
+
+struct eepFlags {
+       u8 opFlags;
+       u8 eepMisc;
+} __packed;
+
+enum CompressAlgorithm {
+       _CompressNone = 0,
+       _CompressLzma,
+       _CompressPairs,
+       _CompressBlock,
+       _Compress4,
+       _Compress5,
+       _Compress6,
+       _Compress7,
+};
+
+struct ar9300_base_eep_hdr {
+       u16 regDmn[2];
+       /* 4 bits tx and 4 bits rx */
+       u8 txrxMask;
+       struct eepFlags opCapFlags;
+       u8 rfSilent;
+       u8 blueToothOptions;
+       u8 deviceCap;
+       /* takes lower byte in eeprom location */
+       u8 deviceType;
+       /* offset in dB to be added to beginning
+        * of pdadc table in calibration
+        */
+       int8_t pwrTableOffset;
+       u8 params_for_tuning_caps[2];
+       /*
+        * bit0 - enable tx temp comp
+        * bit1 - enable tx volt comp
+        * bit2 - enable fastClock - default to 1
+        * bit3 - enable doubling - default to 1
+        * bit4 - enable internal regulator - default to 1
+        */
+       u8 featureEnable;
+       /* misc flags: bit0 - turn down drivestrength */
+       u8 miscConfiguration;
+       u8 eepromWriteEnableGpio;
+       u8 wlanDisableGpio;
+       u8 wlanLedGpio;
+       u8 rxBandSelectGpio;
+       u8 txrxgain;
+       /* SW controlled internal regulator fields */
+       u32 swreg;
+} __packed;
+
+struct ar9300_modal_eep_header {
+       /* 4 idle, t1, t2, b (4 bits per setting) */
+       u32 antCtrlCommon;
+       /* 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12 */
+       u32 antCtrlCommon2;
+       /* 6 idle, t, r, rx1, rx12, b (2 bits each) */
+       u16 antCtrlChain[AR9300_MAX_CHAINS];
+       /* 3 xatten1_db for AR9280 (0xa20c/b20c 5:0) */
+       u8 xatten1DB[AR9300_MAX_CHAINS];
+       /* 3  xatten1_margin for merlin (0xa20c/b20c 16:12 */
+       u8 xatten1Margin[AR9300_MAX_CHAINS];
+       int8_t tempSlope;
+       int8_t voltSlope;
+       /* spur channels in usual fbin coding format */
+       u8 spurChans[AR9300_EEPROM_MODAL_SPURS];
+       /* 3  Check if the register is per chain */
+       int8_t noiseFloorThreshCh[AR9300_MAX_CHAINS];
+       u8 ob[AR9300_MAX_CHAINS];
+       u8 db_stage2[AR9300_MAX_CHAINS];
+       u8 db_stage3[AR9300_MAX_CHAINS];
+       u8 db_stage4[AR9300_MAX_CHAINS];
+       u8 xpaBiasLvl;
+       u8 txFrameToDataStart;
+       u8 txFrameToPaOn;
+       u8 txClip;
+       int8_t antennaGain;
+       u8 switchSettling;
+       int8_t adcDesiredSize;
+       u8 txEndToXpaOff;
+       u8 txEndToRxOn;
+       u8 txFrameToXpaOn;
+       u8 thresh62;
+       u8 futureModal[32];
+} __packed;
+
+struct ar9300_cal_data_per_freq_op_loop {
+       int8_t refPower;
+       /* pdadc voltage at power measurement */
+       u8 voltMeas;
+       /* pcdac used for power measurement   */
+       u8 tempMeas;
+       /* range is -60 to -127 create a mapping equation 1db resolution */
+       int8_t rxNoisefloorCal;
+       /*range is same as noisefloor */
+       int8_t rxNoisefloorPower;
+       /* temp measured when noisefloor cal was performed */
+       u8 rxTempMeas;
+} __packed;
+
+struct cal_tgt_pow_legacy {
+       u8 tPow2x[4];
+} __packed;
+
+struct cal_tgt_pow_ht {
+       u8 tPow2x[14];
+} __packed;
+
+struct cal_ctl_edge_pwr {
+       u8 tPower:6,
+          flag:2;
+} __packed;
+
+struct cal_ctl_data_2g {
+       struct cal_ctl_edge_pwr ctlEdges[AR9300_NUM_BAND_EDGES_5G];
+} __packed;
+
+struct cal_ctl_data_5g {
+       struct cal_ctl_edge_pwr ctlEdges[AR9300_NUM_BAND_EDGES_5G];
+} __packed;
+
+struct ar9300_eeprom {
+       u8 eepromVersion;
+       u8 templateVersion;
+       u8 macAddr[6];
+       u8 custData[AR9300_CUSTOMER_DATA_SIZE];
+
+       struct ar9300_base_eep_hdr baseEepHeader;
+
+       struct ar9300_modal_eep_header modalHeader2G;
+       u8 calFreqPier2G[AR9300_NUM_2G_CAL_PIERS];
+       struct ar9300_cal_data_per_freq_op_loop
+        calPierData2G[AR9300_MAX_CHAINS][AR9300_NUM_2G_CAL_PIERS];
+       u8 calTarget_freqbin_Cck[AR9300_NUM_2G_CCK_TARGET_POWERS];
+       u8 calTarget_freqbin_2G[AR9300_NUM_2G_20_TARGET_POWERS];
+       u8 calTarget_freqbin_2GHT20[AR9300_NUM_2G_20_TARGET_POWERS];
+       u8 calTarget_freqbin_2GHT40[AR9300_NUM_2G_40_TARGET_POWERS];
+       struct cal_tgt_pow_legacy
+        calTargetPowerCck[AR9300_NUM_2G_CCK_TARGET_POWERS];
+       struct cal_tgt_pow_legacy
+        calTargetPower2G[AR9300_NUM_2G_20_TARGET_POWERS];
+       struct cal_tgt_pow_ht
+        calTargetPower2GHT20[AR9300_NUM_2G_20_TARGET_POWERS];
+       struct cal_tgt_pow_ht
+        calTargetPower2GHT40[AR9300_NUM_2G_40_TARGET_POWERS];
+       u8 ctlIndex_2G[AR9300_NUM_CTLS_2G];
+       u8 ctl_freqbin_2G[AR9300_NUM_CTLS_2G][AR9300_NUM_BAND_EDGES_2G];
+       struct cal_ctl_data_2g ctlPowerData_2G[AR9300_NUM_CTLS_2G];
+       struct ar9300_modal_eep_header modalHeader5G;
+       u8 calFreqPier5G[AR9300_NUM_5G_CAL_PIERS];
+       struct ar9300_cal_data_per_freq_op_loop
+        calPierData5G[AR9300_MAX_CHAINS][AR9300_NUM_5G_CAL_PIERS];
+       u8 calTarget_freqbin_5G[AR9300_NUM_5G_20_TARGET_POWERS];
+       u8 calTarget_freqbin_5GHT20[AR9300_NUM_5G_20_TARGET_POWERS];
+       u8 calTarget_freqbin_5GHT40[AR9300_NUM_5G_40_TARGET_POWERS];
+       struct cal_tgt_pow_legacy
+        calTargetPower5G[AR9300_NUM_5G_20_TARGET_POWERS];
+       struct cal_tgt_pow_ht
+        calTargetPower5GHT20[AR9300_NUM_5G_20_TARGET_POWERS];
+       struct cal_tgt_pow_ht
+        calTargetPower5GHT40[AR9300_NUM_5G_40_TARGET_POWERS];
+       u8 ctlIndex_5G[AR9300_NUM_CTLS_5G];
+       u8 ctl_freqbin_5G[AR9300_NUM_CTLS_5G][AR9300_NUM_BAND_EDGES_5G];
+       struct cal_ctl_data_5g ctlPowerData_5G[AR9300_NUM_CTLS_5G];
+} __packed;
+
+s32 ar9003_hw_get_tx_gain_idx(struct ath_hw *ah);
+s32 ar9003_hw_get_rx_gain_idx(struct ath_hw *ah);
+
+#endif
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_hw.c b/drivers/net/wireless/ath/ath9k/ar9003_hw.c
new file mode 100644 (file)
index 0000000..b15309c
--- /dev/null
@@ -0,0 +1,205 @@
+/*
+ * Copyright (c) 2008-2010 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT 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 "hw.h"
+#include "ar9003_mac.h"
+#include "ar9003_initvals.h"
+
+/* General hardware code for the AR9003 hadware family */
+
+static bool ar9003_hw_macversion_supported(u32 macversion)
+{
+       switch (macversion) {
+       case AR_SREV_VERSION_9300:
+               return true;
+       default:
+               break;
+       }
+       return false;
+}
+
+/* AR9003 2.0 - new INI format (pre, core, post arrays per subsystem) */
+/*
+ * XXX: move TX/RX gain INI to its own init_mode_gain_regs after
+ * ensuring it does not affect hardware bring up
+ */
+static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
+{
+       /* mac */
+       INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0);
+       INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE],
+                      ar9300_2p0_mac_core,
+                      ARRAY_SIZE(ar9300_2p0_mac_core), 2);
+       INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST],
+                      ar9300_2p0_mac_postamble,
+                      ARRAY_SIZE(ar9300_2p0_mac_postamble), 5);
+
+       /* bb */
+       INIT_INI_ARRAY(&ah->iniBB[ATH_INI_PRE], NULL, 0, 0);
+       INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE],
+                      ar9300_2p0_baseband_core,
+                      ARRAY_SIZE(ar9300_2p0_baseband_core), 2);
+       INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST],
+                      ar9300_2p0_baseband_postamble,
+                      ARRAY_SIZE(ar9300_2p0_baseband_postamble), 5);
+
+       /* radio */
+       INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_PRE], NULL, 0, 0);
+       INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE],
+                      ar9300_2p0_radio_core,
+                      ARRAY_SIZE(ar9300_2p0_radio_core), 2);
+       INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST],
+                      ar9300_2p0_radio_postamble,
+                      ARRAY_SIZE(ar9300_2p0_radio_postamble), 5);
+
+       /* soc */
+       INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE],
+                      ar9300_2p0_soc_preamble,
+                      ARRAY_SIZE(ar9300_2p0_soc_preamble), 2);
+       INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_CORE], NULL, 0, 0);
+       INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST],
+                      ar9300_2p0_soc_postamble,
+                      ARRAY_SIZE(ar9300_2p0_soc_postamble), 5);
+
+       /* rx/tx gain */
+       INIT_INI_ARRAY(&ah->iniModesRxGain,
+                      ar9300Common_rx_gain_table_2p0,
+                      ARRAY_SIZE(ar9300Common_rx_gain_table_2p0), 2);
+       INIT_INI_ARRAY(&ah->iniModesTxGain,
+                      ar9300Modes_lowest_ob_db_tx_gain_table_2p0,
+                      ARRAY_SIZE(ar9300Modes_lowest_ob_db_tx_gain_table_2p0),
+                      5);
+
+       /* Load PCIE SERDES settings from INI */
+
+       /* Awake Setting */
+
+       INIT_INI_ARRAY(&ah->iniPcieSerdes,
+                      ar9300PciePhy_pll_on_clkreq_disable_L1_2p0,
+                      ARRAY_SIZE(ar9300PciePhy_pll_on_clkreq_disable_L1_2p0),
+                      2);
+
+       /* Sleep Setting */
+
+       INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower,
+                      ar9300PciePhy_clkreq_enable_L1_2p0,
+                      ARRAY_SIZE(ar9300PciePhy_clkreq_enable_L1_2p0),
+                      2);
+
+       /* Fast clock modal settings */
+       INIT_INI_ARRAY(&ah->iniModesAdditional,
+                      ar9300Modes_fast_clock_2p0,
+                      ARRAY_SIZE(ar9300Modes_fast_clock_2p0),
+                      3);
+}
+
+static void ar9003_tx_gain_table_apply(struct ath_hw *ah)
+{
+       switch (ar9003_hw_get_tx_gain_idx(ah)) {
+       case 0:
+       default:
+               INIT_INI_ARRAY(&ah->iniModesTxGain,
+                              ar9300Modes_lowest_ob_db_tx_gain_table_2p0,
+                              ARRAY_SIZE(ar9300Modes_lowest_ob_db_tx_gain_table_2p0),
+                              5);
+               break;
+       case 1:
+               INIT_INI_ARRAY(&ah->iniModesTxGain,
+                              ar9300Modes_high_ob_db_tx_gain_table_2p0,
+                              ARRAY_SIZE(ar9300Modes_high_ob_db_tx_gain_table_2p0),
+                              5);
+               break;
+       case 2:
+               INIT_INI_ARRAY(&ah->iniModesTxGain,
+                              ar9300Modes_low_ob_db_tx_gain_table_2p0,
+                              ARRAY_SIZE(ar9300Modes_low_ob_db_tx_gain_table_2p0),
+                              5);
+               break;
+       }
+}
+
+static void ar9003_rx_gain_table_apply(struct ath_hw *ah)
+{
+       switch (ar9003_hw_get_rx_gain_idx(ah)) {
+       case 0:
+       default:
+               INIT_INI_ARRAY(&ah->iniModesRxGain, ar9300Common_rx_gain_table_2p0,
+                              ARRAY_SIZE(ar9300Common_rx_gain_table_2p0),
+                              2);
+               break;
+       case 1:
+               INIT_INI_ARRAY(&ah->iniModesRxGain,
+                              ar9300Common_wo_xlna_rx_gain_table_2p0,
+                              ARRAY_SIZE(ar9300Common_wo_xlna_rx_gain_table_2p0),
+                              2);
+               break;
+       }
+}
+
+/* set gain table pointers according to values read from the eeprom */
+static void ar9003_hw_init_mode_gain_regs(struct ath_hw *ah)
+{
+       ar9003_tx_gain_table_apply(ah);
+       ar9003_rx_gain_table_apply(ah);
+}
+
+/*
+ * Helper for ASPM support.
+ *
+ * Disable PLL when in L0s as well as receiver clock when in L1.
+ * This power saving option must be enabled through the SerDes.
+ *
+ * Programming the SerDes must go through the same 288 bit serial shift
+ * register as the other analog registers.  Hence the 9 writes.
+ */
+static void ar9003_hw_configpcipowersave(struct ath_hw *ah,
+                                        int restore,
+                                        int power_off)
+{
+       if (ah->is_pciexpress != true)
+               return;
+
+       /* Do not touch SerDes registers */
+       if (ah->config.pcie_powersave_enable == 2)
+               return;
+
+       /* Nothing to do on restore for 11N */
+       if (!restore) {
+               /* set bit 19 to allow forcing of pcie core into L1 state */
+               REG_SET_BIT(ah, AR_PCIE_PM_CTRL, AR_PCIE_PM_CTRL_ENA);
+
+               /* Several PCIe massages to ensure proper behaviour */
+               if (ah->config.pcie_waen)
+                       REG_WRITE(ah, AR_WA, ah->config.pcie_waen);
+       }
+}
+
+/* Sets up the AR9003 hardware familiy callbacks */
+void ar9003_hw_attach_ops(struct ath_hw *ah)
+{
+       struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
+       struct ath_hw_ops *ops = ath9k_hw_ops(ah);
+
+       priv_ops->init_mode_regs = ar9003_hw_init_mode_regs;
+       priv_ops->init_mode_gain_regs = ar9003_hw_init_mode_gain_regs;
+       priv_ops->macversion_supported = ar9003_hw_macversion_supported;
+
+       ops->config_pci_powersave = ar9003_hw_configpcipowersave;
+
+       ar9003_hw_attach_phy_ops(ah);
+       ar9003_hw_attach_calib_ops(ah);
+       ar9003_hw_attach_mac_ops(ah);
+}
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_initvals.h b/drivers/net/wireless/ath/ath9k/ar9003_initvals.h
new file mode 100644 (file)
index 0000000..e0391b1
--- /dev/null
@@ -0,0 +1,1793 @@
+/*
+ * Copyright (c) 2010 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT 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.
+ */
+
+#ifndef INITVALS_9003_H
+#define INITVALS_9003_H
+
+/* AR9003 2.0 */
+
+static const u32 ar9300_2p0_radio_postamble[][5] = {
+       /* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
+       {0x0001609c, 0x0dd08f29, 0x0dd08f29, 0x0b283f31, 0x0b283f31},
+       {0x000160ac, 0xa4653c00, 0xa4653c00, 0x24652800, 0x24652800},
+       {0x000160b0, 0x03284f3e, 0x03284f3e, 0x05d08f20, 0x05d08f20},
+       {0x0001610c, 0x08000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0001650c, 0x08000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0001690c, 0x08000000, 0x00000000, 0x00000000, 0x00000000},
+};
+
+static const u32 ar9300Modes_lowest_ob_db_tx_gain_table_2p0[][5] = {
+       /* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
+       {0x0000a410, 0x000050da, 0x000050da, 0x000050da, 0x000050da},
+       {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002},
+       {0x0000a508, 0x0a000020, 0x0a000020, 0x08000004, 0x08000004},
+       {0x0000a50c, 0x10000023, 0x10000023, 0x0b000200, 0x0b000200},
+       {0x0000a510, 0x16000220, 0x16000220, 0x0f000202, 0x0f000202},
+       {0x0000a514, 0x1c000223, 0x1c000223, 0x12000400, 0x12000400},
+       {0x0000a518, 0x21020220, 0x21020220, 0x16000402, 0x16000402},
+       {0x0000a51c, 0x27020223, 0x27020223, 0x19000404, 0x19000404},
+       {0x0000a520, 0x2b022220, 0x2b022220, 0x1c000603, 0x1c000603},
+       {0x0000a524, 0x2f022222, 0x2f022222, 0x21000a02, 0x21000a02},
+       {0x0000a528, 0x34022225, 0x34022225, 0x25000a04, 0x25000a04},
+       {0x0000a52c, 0x3a02222a, 0x3a02222a, 0x28000a20, 0x28000a20},
+       {0x0000a530, 0x3e02222c, 0x3e02222c, 0x2c000e20, 0x2c000e20},
+       {0x0000a534, 0x4202242a, 0x4202242a, 0x30000e22, 0x30000e22},
+       {0x0000a538, 0x4702244a, 0x4702244a, 0x34000e24, 0x34000e24},
+       {0x0000a53c, 0x4b02244c, 0x4b02244c, 0x38001640, 0x38001640},
+       {0x0000a540, 0x4e02246c, 0x4e02246c, 0x3c001660, 0x3c001660},
+       {0x0000a544, 0x5302266c, 0x5302266c, 0x3f001861, 0x3f001861},
+       {0x0000a548, 0x5702286c, 0x5702286c, 0x43001a81, 0x43001a81},
+       {0x0000a54c, 0x5c04286b, 0x5c04286b, 0x47001a83, 0x47001a83},
+       {0x0000a550, 0x61042a6c, 0x61042a6c, 0x4a001c84, 0x4a001c84},
+       {0x0000a554, 0x66062a6c, 0x66062a6c, 0x4e001ce3, 0x4e001ce3},
+       {0x0000a558, 0x6b062e6c, 0x6b062e6c, 0x52001ce5, 0x52001ce5},
+       {0x0000a55c, 0x7006308c, 0x7006308c, 0x56001ce9, 0x56001ce9},
+       {0x0000a560, 0x730a308a, 0x730a308a, 0x5a001ceb, 0x5a001ceb},
+       {0x0000a564, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
+       {0x0000a568, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
+       {0x0000a56c, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
+       {0x0000a570, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
+       {0x0000a574, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
+       {0x0000a578, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
+       {0x0000a57c, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
+       {0x0000a580, 0x00800000, 0x00800000, 0x00800000, 0x00800000},
+       {0x0000a584, 0x06800003, 0x06800003, 0x04800002, 0x04800002},
+       {0x0000a588, 0x0a800020, 0x0a800020, 0x08800004, 0x08800004},
+       {0x0000a58c, 0x10800023, 0x10800023, 0x0b800200, 0x0b800200},
+       {0x0000a590, 0x16800220, 0x16800220, 0x0f800202, 0x0f800202},
+       {0x0000a594, 0x1c800223, 0x1c800223, 0x12800400, 0x12800400},
+       {0x0000a598, 0x21820220, 0x21820220, 0x16800402, 0x16800402},
+       {0x0000a59c, 0x27820223, 0x27820223, 0x19800404, 0x19800404},
+       {0x0000a5a0, 0x2b822220, 0x2b822220, 0x1c800603, 0x1c800603},
+       {0x0000a5a4, 0x2f822222, 0x2f822222, 0x21800a02, 0x21800a02},
+       {0x0000a5a8, 0x34822225, 0x34822225, 0x25800a04, 0x25800a04},
+       {0x0000a5ac, 0x3a82222a, 0x3a82222a, 0x28800a20, 0x28800a20},
+       {0x0000a5b0, 0x3e82222c, 0x3e82222c, 0x2c800e20, 0x2c800e20},
+       {0x0000a5b4, 0x4282242a, 0x4282242a, 0x30800e22, 0x30800e22},
+       {0x0000a5b8, 0x4782244a, 0x4782244a, 0x34800e24, 0x34800e24},
+       {0x0000a5bc, 0x4b82244c, 0x4b82244c, 0x38801640, 0x38801640},
+       {0x0000a5c0, 0x4e82246c, 0x4e82246c, 0x3c801660, 0x3c801660},
+       {0x0000a5c4, 0x5382266c, 0x5382266c, 0x3f801861, 0x3f801861},
+       {0x0000a5c8, 0x5782286c, 0x5782286c, 0x43801a81, 0x43801a81},
+       {0x0000a5cc, 0x5c84286b, 0x5c84286b, 0x47801a83, 0x47801a83},
+       {0x0000a5d0, 0x61842a6c, 0x61842a6c, 0x4a801c84, 0x4a801c84},
+       {0x0000a5d4, 0x66862a6c, 0x66862a6c, 0x4e801ce3, 0x4e801ce3},
+       {0x0000a5d8, 0x6b862e6c, 0x6b862e6c, 0x52801ce5, 0x52801ce5},
+       {0x0000a5dc, 0x7086308c, 0x7086308c, 0x56801ce9, 0x56801ce9},
+       {0x0000a5e0, 0x738a308a, 0x738a308a, 0x5a801ceb, 0x5a801ceb},
+       {0x0000a5e4, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
+       {0x0000a5e8, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
+       {0x0000a5ec, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
+       {0x0000a5f0, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
+       {0x0000a5f4, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
+       {0x0000a5f8, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
+       {0x0000a5fc, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
+       {0x00016044, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
+       {0x00016048, 0x60001a61, 0x60001a61, 0x60001a61, 0x60001a61},
+       {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
+       {0x00016444, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
+       {0x00016448, 0x60001a61, 0x60001a61, 0x60001a61, 0x60001a61},
+       {0x00016468, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
+       {0x00016844, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
+       {0x00016848, 0x60001a61, 0x60001a61, 0x60001a61, 0x60001a61},
+       {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
+};
+
+static const u32 ar9300Modes_fast_clock_2p0[][3] = {
+       /* Addr      5G_HT20     5G_HT40   */
+       {0x00001030, 0x00000268, 0x000004d0},
+       {0x00001070, 0x0000018c, 0x00000318},
+       {0x000010b0, 0x00000fd0, 0x00001fa0},
+       {0x00008014, 0x044c044c, 0x08980898},
+       {0x0000801c, 0x148ec02b, 0x148ec057},
+       {0x00008318, 0x000044c0, 0x00008980},
+       {0x00009e00, 0x03721821, 0x03721821},
+       {0x0000a230, 0x0000000b, 0x00000016},
+       {0x0000a254, 0x00000898, 0x00001130},
+};
+
+static const u32 ar9300_2p0_radio_core[][2] = {
+       /* Addr      allmodes  */
+       {0x00016000, 0x36db6db6},
+       {0x00016004, 0x6db6db40},
+       {0x00016008, 0x73f00000},
+       {0x0001600c, 0x00000000},
+       {0x00016040, 0x7f80fff8},
+       {0x0001604c, 0x76d005b5},
+       {0x00016050, 0x556cf031},
+       {0x00016054, 0x43449440},
+       {0x00016058, 0x0c51c92c},
+       {0x0001605c, 0x3db7fffc},
+       {0x00016060, 0xfffffffc},
+       {0x00016064, 0x000f0278},
+       {0x0001606c, 0x6db60000},
+       {0x00016080, 0x00000000},
+       {0x00016084, 0x0e48048c},
+       {0x00016088, 0x54214514},
+       {0x0001608c, 0x119f481e},
+       {0x00016090, 0x24926490},
+       {0x00016098, 0xd2888888},
+       {0x000160a0, 0x0a108ffe},
+       {0x000160a4, 0x812fc370},
+       {0x000160a8, 0x423c8000},
+       {0x000160b4, 0x92480080},
+       {0x000160c0, 0x00adb6d0},
+       {0x000160c4, 0x6db6db60},
+       {0x000160c8, 0x6db6db6c},
+       {0x000160cc, 0x01e6c000},
+       {0x00016100, 0x3fffbe01},
+       {0x00016104, 0xfff80000},
+       {0x00016108, 0x00080010},
+       {0x00016140, 0x10804008},
+       {0x00016144, 0x02084080},
+       {0x00016148, 0x00000000},
+       {0x00016280, 0x058a0001},
+       {0x00016284, 0x3d840208},
+       {0x00016288, 0x01a20408},
+       {0x0001628c, 0x00038c07},
+       {0x00016290, 0x40000004},
+       {0x00016294, 0x458aa14f},
+       {0x00016380, 0x00000000},
+       {0x00016384, 0x00000000},
+       {0x00016388, 0x00800700},
+       {0x0001638c, 0x00800700},
+       {0x00016390, 0x00800700},
+       {0x00016394, 0x00000000},
+       {0x00016398, 0x00000000},
+       {0x0001639c, 0x00000000},
+       {0x000163a0, 0x00000001},
+       {0x000163a4, 0x00000001},
+       {0x000163a8, 0x00000000},
+       {0x000163ac, 0x00000000},
+       {0x000163b0, 0x00000000},
+       {0x000163b4, 0x00000000},
+       {0x000163b8, 0x00000000},
+       {0x000163bc, 0x00000000},
+       {0x000163c0, 0x000000a0},
+       {0x000163c4, 0x000c0000},
+       {0x000163c8, 0x14021402},
+       {0x000163cc, 0x00001402},
+       {0x000163d0, 0x00000000},
+       {0x000163d4, 0x00000000},
+       {0x00016400, 0x36db6db6},
+       {0x00016404, 0x6db6db40},
+       {0x00016408, 0x73f00000},
+       {0x0001640c, 0x00000000},
+       {0x00016440, 0x7f80fff8},
+       {0x0001644c, 0x76d005b5},
+       {0x00016450, 0x556cf031},
+       {0x00016454, 0x43449440},
+       {0x00016458, 0x0c51c92c},
+       {0x0001645c, 0x3db7fffc},
+       {0x00016460, 0xfffffffc},
+       {0x00016464, 0x000f0278},
+       {0x0001646c, 0x6db60000},
+       {0x00016500, 0x3fffbe01},
+       {0x00016504, 0xfff80000},
+       {0x00016508, 0x00080010},
+       {0x00016540, 0x10804008},
+       {0x00016544, 0x02084080},
+       {0x00016548, 0x00000000},
+       {0x00016780, 0x00000000},
+       {0x00016784, 0x00000000},
+       {0x00016788, 0x00800700},
+       {0x0001678c, 0x00800700},
+       {0x00016790, 0x00800700},
+       {0x00016794, 0x00000000},
+       {0x00016798, 0x00000000},
+       {0x0001679c, 0x00000000},
+       {0x000167a0, 0x00000001},
+       {0x000167a4, 0x00000001},
+       {0x000167a8, 0x00000000},
+       {0x000167ac, 0x00000000},
+       {0x000167b0, 0x00000000},
+       {0x000167b4, 0x00000000},
+       {0x000167b8, 0x00000000},
+       {0x000167bc, 0x00000000},
+       {0x000167c0, 0x000000a0},
+       {0x000167c4, 0x000c0000},
+       {0x000167c8, 0x14021402},
+       {0x000167cc, 0x00001402},
+       {0x000167d0, 0x00000000},
+       {0x000167d4, 0x00000000},
+       {0x00016800, 0x36db6db6},
+       {0x00016804, 0x6db6db40},
+       {0x00016808, 0x73f00000},
+       {0x0001680c, 0x00000000},
+       {0x00016840, 0x7f80fff8},
+       {0x0001684c, 0x76d005b5},
+       {0x00016850, 0x556cf031},
+       {0x00016854, 0x43449440},
+       {0x00016858, 0x0c51c92c},
+       {0x0001685c, 0x3db7fffc},
+       {0x00016860, 0xfffffffc},
+       {0x00016864, 0x000f0278},
+       {0x0001686c, 0x6db60000},
+       {0x00016900, 0x3fffbe01},
+       {0x00016904, 0xfff80000},
+       {0x00016908, 0x00080010},
+       {0x00016940, 0x10804008},
+       {0x00016944, 0x02084080},
+       {0x00016948, 0x00000000},
+       {0x00016b80, 0x00000000},
+       {0x00016b84, 0x00000000},
+       {0x00016b88, 0x00800700},
+       {0x00016b8c, 0x00800700},
+       {0x00016b90, 0x00800700},
+       {0x00016b94, 0x00000000},
+       {0x00016b98, 0x00000000},
+       {0x00016b9c, 0x00000000},
+       {0x00016ba0, 0x00000001},
+       {0x00016ba4, 0x00000001},
+       {0x00016ba8, 0x00000000},
+       {0x00016bac, 0x00000000},
+       {0x00016bb0, 0x00000000},
+       {0x00016bb4, 0x00000000},
+       {0x00016bb8, 0x00000000},
+       {0x00016bbc, 0x00000000},
+       {0x00016bc0, 0x000000a0},
+       {0x00016bc4, 0x000c0000},
+       {0x00016bc8, 0x14021402},
+       {0x00016bcc, 0x00001402},
+       {0x00016bd0, 0x00000000},
+       {0x00016bd4, 0x00000000},
+};
+
+static const u32 ar9300Common_rx_gain_table_merlin_2p0[][2] = {
+       /* Addr      allmodes  */
+       {0x0000a000, 0x02000101},
+       {0x0000a004, 0x02000102},
+       {0x0000a008, 0x02000103},
+       {0x0000a00c, 0x02000104},
+       {0x0000a010, 0x02000200},
+       {0x0000a014, 0x02000201},
+       {0x0000a018, 0x02000202},
+       {0x0000a01c, 0x02000203},
+       {0x0000a020, 0x02000204},
+       {0x0000a024, 0x02000205},
+       {0x0000a028, 0x02000208},
+       {0x0000a02c, 0x02000302},
+       {0x0000a030, 0x02000303},
+       {0x0000a034, 0x02000304},
+       {0x0000a038, 0x02000400},
+       {0x0000a03c, 0x02010300},
+       {0x0000a040, 0x02010301},
+       {0x0000a044, 0x02010302},
+       {0x0000a048, 0x02000500},
+       {0x0000a04c, 0x02010400},
+       {0x0000a050, 0x02020300},
+       {0x0000a054, 0x02020301},
+       {0x0000a058, 0x02020302},
+       {0x0000a05c, 0x02020303},
+       {0x0000a060, 0x02020400},
+       {0x0000a064, 0x02030300},
+       {0x0000a068, 0x02030301},
+       {0x0000a06c, 0x02030302},
+       {0x0000a070, 0x02030303},
+       {0x0000a074, 0x02030400},
+       {0x0000a078, 0x02040300},
+       {0x0000a07c, 0x02040301},
+       {0x0000a080, 0x02040302},
+       {0x0000a084, 0x02040303},
+       {0x0000a088, 0x02030500},
+       {0x0000a08c, 0x02040400},
+       {0x0000a090, 0x02050203},
+       {0x0000a094, 0x02050204},
+       {0x0000a098, 0x02050205},
+       {0x0000a09c, 0x02040500},
+       {0x0000a0a0, 0x02050301},
+       {0x0000a0a4, 0x02050302},
+       {0x0000a0a8, 0x02050303},
+       {0x0000a0ac, 0x02050400},
+       {0x0000a0b0, 0x02050401},
+       {0x0000a0b4, 0x02050402},
+       {0x0000a0b8, 0x02050403},
+       {0x0000a0bc, 0x02050500},
+       {0x0000a0c0, 0x02050501},
+       {0x0000a0c4, 0x02050502},
+       {0x0000a0c8, 0x02050503},
+       {0x0000a0cc, 0x02050504},
+       {0x0000a0d0, 0x02050600},
+       {0x0000a0d4, 0x02050601},
+       {0x0000a0d8, 0x02050602},
+       {0x0000a0dc, 0x02050603},
+       {0x0000a0e0, 0x02050604},
+       {0x0000a0e4, 0x02050700},
+       {0x0000a0e8, 0x02050701},
+       {0x0000a0ec, 0x02050702},
+       {0x0000a0f0, 0x02050703},
+       {0x0000a0f4, 0x02050704},
+       {0x0000a0f8, 0x02050705},
+       {0x0000a0fc, 0x02050708},
+       {0x0000a100, 0x02050709},
+       {0x0000a104, 0x0205070a},
+       {0x0000a108, 0x0205070b},
+       {0x0000a10c, 0x0205070c},
+       {0x0000a110, 0x0205070d},
+       {0x0000a114, 0x02050710},
+       {0x0000a118, 0x02050711},
+       {0x0000a11c, 0x02050712},
+       {0x0000a120, 0x02050713},
+       {0x0000a124, 0x02050714},
+       {0x0000a128, 0x02050715},
+       {0x0000a12c, 0x02050730},
+       {0x0000a130, 0x02050731},
+       {0x0000a134, 0x02050732},
+       {0x0000a138, 0x02050733},
+       {0x0000a13c, 0x02050734},
+       {0x0000a140, 0x02050735},
+       {0x0000a144, 0x02050750},
+       {0x0000a148, 0x02050751},
+       {0x0000a14c, 0x02050752},
+       {0x0000a150, 0x02050753},
+       {0x0000a154, 0x02050754},
+       {0x0000a158, 0x02050755},
+       {0x0000a15c, 0x02050770},
+       {0x0000a160, 0x02050771},
+       {0x0000a164, 0x02050772},
+       {0x0000a168, 0x02050773},
+       {0x0000a16c, 0x02050774},
+       {0x0000a170, 0x02050775},
+       {0x0000a174, 0x00000776},
+       {0x0000a178, 0x00000776},
+       {0x0000a17c, 0x00000776},
+       {0x0000a180, 0x00000776},
+       {0x0000a184, 0x00000776},
+       {0x0000a188, 0x00000776},
+       {0x0000a18c, 0x00000776},
+       {0x0000a190, 0x00000776},
+       {0x0000a194, 0x00000776},
+       {0x0000a198, 0x00000776},
+       {0x0000a19c, 0x00000776},
+       {0x0000a1a0, 0x00000776},
+       {0x0000a1a4, 0x00000776},
+       {0x0000a1a8, 0x00000776},
+       {0x0000a1ac, 0x00000776},
+       {0x0000a1b0, 0x00000776},
+       {0x0000a1b4, 0x00000776},
+       {0x0000a1b8, 0x00000776},
+       {0x0000a1bc, 0x00000776},
+       {0x0000a1c0, 0x00000776},
+       {0x0000a1c4, 0x00000776},
+       {0x0000a1c8, 0x00000776},
+       {0x0000a1cc, 0x00000776},
+       {0x0000a1d0, 0x00000776},
+       {0x0000a1d4, 0x00000776},
+       {0x0000a1d8, 0x00000776},
+       {0x0000a1dc, 0x00000776},
+       {0x0000a1e0, 0x00000776},
+       {0x0000a1e4, 0x00000776},
+       {0x0000a1e8, 0x00000776},
+       {0x0000a1ec, 0x00000776},
+       {0x0000a1f0, 0x00000776},
+       {0x0000a1f4, 0x00000776},
+       {0x0000a1f8, 0x00000776},
+       {0x0000a1fc, 0x00000776},
+       {0x0000b000, 0x02000101},
+       {0x0000b004, 0x02000102},
+       {0x0000b008, 0x02000103},
+       {0x0000b00c, 0x02000104},
+       {0x0000b010, 0x02000200},
+       {0x0000b014, 0x02000201},
+       {0x0000b018, 0x02000202},
+       {0x0000b01c, 0x02000203},
+       {0x0000b020, 0x02000204},
+       {0x0000b024, 0x02000205},
+       {0x0000b028, 0x02000208},
+       {0x0000b02c, 0x02000302},
+       {0x0000b030, 0x02000303},
+       {0x0000b034, 0x02000304},
+       {0x0000b038, 0x02000400},
+       {0x0000b03c, 0x02010300},
+       {0x0000b040, 0x02010301},
+       {0x0000b044, 0x02010302},
+       {0x0000b048, 0x02000500},
+       {0x0000b04c, 0x02010400},
+       {0x0000b050, 0x02020300},
+       {0x0000b054, 0x02020301},
+       {0x0000b058, 0x02020302},
+       {0x0000b05c, 0x02020303},
+       {0x0000b060, 0x02020400},
+       {0x0000b064, 0x02030300},
+       {0x0000b068, 0x02030301},
+       {0x0000b06c, 0x02030302},
+       {0x0000b070, 0x02030303},
+       {0x0000b074, 0x02030400},
+       {0x0000b078, 0x02040300},
+       {0x0000b07c, 0x02040301},
+       {0x0000b080, 0x02040302},
+       {0x0000b084, 0x02040303},
+       {0x0000b088, 0x02030500},
+       {0x0000b08c, 0x02040400},
+       {0x0000b090, 0x02050203},
+       {0x0000b094, 0x02050204},
+       {0x0000b098, 0x02050205},
+       {0x0000b09c, 0x02040500},
+       {0x0000b0a0, 0x02050301},
+       {0x0000b0a4, 0x02050302},
+       {0x0000b0a8, 0x02050303},
+       {0x0000b0ac, 0x02050400},
+       {0x0000b0b0, 0x02050401},
+       {0x0000b0b4, 0x02050402},
+       {0x0000b0b8, 0x02050403},
+       {0x0000b0bc, 0x02050500},
+       {0x0000b0c0, 0x02050501},
+       {0x0000b0c4, 0x02050502},
+       {0x0000b0c8, 0x02050503},
+       {0x0000b0cc, 0x02050504},
+       {0x0000b0d0, 0x02050600},
+       {0x0000b0d4, 0x02050601},
+       {0x0000b0d8, 0x02050602},
+       {0x0000b0dc, 0x02050603},
+       {0x0000b0e0, 0x02050604},
+       {0x0000b0e4, 0x02050700},
+       {0x0000b0e8, 0x02050701},
+       {0x0000b0ec, 0x02050702},
+       {0x0000b0f0, 0x02050703},
+       {0x0000b0f4, 0x02050704},
+       {0x0000b0f8, 0x02050705},
+       {0x0000b0fc, 0x02050708},
+       {0x0000b100, 0x02050709},
+       {0x0000b104, 0x0205070a},
+       {0x0000b108, 0x0205070b},
+       {0x0000b10c, 0x0205070c},
+       {0x0000b110, 0x0205070d},
+       {0x0000b114, 0x02050710},
+       {0x0000b118, 0x02050711},
+       {0x0000b11c, 0x02050712},
+       {0x0000b120, 0x02050713},
+       {0x0000b124, 0x02050714},
+       {0x0000b128, 0x02050715},
+       {0x0000b12c, 0x02050730},
+       {0x0000b130, 0x02050731},
+       {0x0000b134, 0x02050732},
+       {0x0000b138, 0x02050733},
+       {0x0000b13c, 0x02050734},
+       {0x0000b140, 0x02050735},
+       {0x0000b144, 0x02050750},
+       {0x0000b148, 0x02050751},
+       {0x0000b14c, 0x02050752},
+       {0x0000b150, 0x02050753},
+       {0x0000b154, 0x02050754},
+       {0x0000b158, 0x02050755},
+       {0x0000b15c, 0x02050770},
+       {0x0000b160, 0x02050771},
+       {0x0000b164, 0x02050772},
+       {0x0000b168, 0x02050773},
+       {0x0000b16c, 0x02050774},
+       {0x0000b170, 0x02050775},
+       {0x0000b174, 0x00000776},
+       {0x0000b178, 0x00000776},
+       {0x0000b17c, 0x00000776},
+       {0x0000b180, 0x00000776},
+       {0x0000b184, 0x00000776},
+       {0x0000b188, 0x00000776},
+       {0x0000b18c, 0x00000776},
+       {0x0000b190, 0x00000776},
+       {0x0000b194, 0x00000776},
+       {0x0000b198, 0x00000776},
+       {0x0000b19c, 0x00000776},
+       {0x0000b1a0, 0x00000776},
+       {0x0000b1a4, 0x00000776},
+       {0x0000b1a8, 0x00000776},
+       {0x0000b1ac, 0x00000776},
+       {0x0000b1b0, 0x00000776},
+       {0x0000b1b4, 0x00000776},
+       {0x0000b1b8, 0x00000776},
+       {0x0000b1bc, 0x00000776},
+       {0x0000b1c0, 0x00000776},
+       {0x0000b1c4, 0x00000776},
+       {0x0000b1c8, 0x00000776},
+       {0x0000b1cc, 0x00000776},
+       {0x0000b1d0, 0x00000776},
+       {0x0000b1d4, 0x00000776},
+       {0x0000b1d8, 0x00000776},
+       {0x0000b1dc, 0x00000776},
+       {0x0000b1e0, 0x00000776},
+       {0x0000b1e4, 0x00000776},
+       {0x0000b1e8, 0x00000776},
+       {0x0000b1ec, 0x00000776},
+       {0x0000b1f0, 0x00000776},
+       {0x0000b1f4, 0x00000776},
+       {0x0000b1f8, 0x00000776},
+       {0x0000b1fc, 0x00000776},
+};
+
+static const u32 ar9300_2p0_mac_postamble[][5] = {
+       /* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
+       {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160},
+       {0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c},
+       {0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38},
+       {0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00},
+       {0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b},
+       {0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810},
+       {0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a},
+       {0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440},
+};
+
+static const u32 ar9300_2p0_soc_postamble[][5] = {
+       /* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
+       {0x00007010, 0x00000023, 0x00000023, 0x00000022, 0x00000022},
+};
+
+static const u32 ar9200_merlin_2p0_radio_core[][2] = {
+       /* Addr      common    */
+       {0x00007800, 0x00040000},
+       {0x00007804, 0xdb005012},
+       {0x00007808, 0x04924914},
+       {0x0000780c, 0x21084210},
+       {0x00007810, 0x6d801300},
+       {0x00007814, 0x0019beff},
+       {0x00007818, 0x07e41000},
+       {0x0000781c, 0x00392000},
+       {0x00007820, 0x92592480},
+       {0x00007824, 0x00040000},
+       {0x00007828, 0xdb005012},
+       {0x0000782c, 0x04924914},
+       {0x00007830, 0x21084210},
+       {0x00007834, 0x6d801300},
+       {0x00007838, 0x0019beff},
+       {0x0000783c, 0x07e40000},
+       {0x00007840, 0x00392000},
+       {0x00007844, 0x92592480},
+       {0x00007848, 0x00100000},
+       {0x0000784c, 0x773f0567},
+       {0x00007850, 0x54214514},
+       {0x00007854, 0x12035828},
+       {0x00007858, 0x92592692},
+       {0x0000785c, 0x00000000},
+       {0x00007860, 0x56400000},
+       {0x00007864, 0x0a8e370e},
+       {0x00007868, 0xc0102850},
+       {0x0000786c, 0x812d4000},
+       {0x00007870, 0x807ec400},
+       {0x00007874, 0x001b6db0},
+       {0x00007878, 0x00376b63},
+       {0x0000787c, 0x06db6db6},
+       {0x00007880, 0x006d8000},
+       {0x00007884, 0xffeffffe},
+       {0x00007888, 0xffeffffe},
+       {0x0000788c, 0x00010000},
+       {0x00007890, 0x02060aeb},
+       {0x00007894, 0x5a108000},
+};
+
+static const u32 ar9300_2p0_baseband_postamble[][5] = {
+       /* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
+       {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8005, 0xd00a8005},
+       {0x00009820, 0x206a022e, 0x206a022e, 0x206a012e, 0x206a012e},
+       {0x00009824, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0},
+       {0x00009828, 0x06903081, 0x06903081, 0x06903881, 0x06903881},
+       {0x0000982c, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4},
+       {0x00009830, 0x0000059c, 0x0000059c, 0x0000059c, 0x0000059c},
+       {0x00009c00, 0x00000044, 0x000000c4, 0x000000c4, 0x00000044},
+       {0x00009e00, 0x0372161e, 0x0372161e, 0x037216a0, 0x037216a0},
+       {0x00009e04, 0x00802020, 0x00802020, 0x00802020, 0x00802020},
+       {0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000e2, 0x6c4000e2},
+       {0x00009e10, 0x7ec88d2e, 0x7ec88d2e, 0x7ec84d2e, 0x7ec84d2e},
+       {0x00009e14, 0x31395d5e, 0x3139605e, 0x3139605e, 0x31395d5e},
+       {0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c},
+       {0x00009e20, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce},
+       {0x00009e2c, 0x0000001c, 0x0000001c, 0x00000021, 0x00000021},
+       {0x00009e44, 0x02321e27, 0x02321e27, 0x02282324, 0x02282324},
+       {0x00009e48, 0x5030201a, 0x5030201a, 0x50302010, 0x50302010},
+       {0x00009fc8, 0x0003f000, 0x0003f000, 0x0001a000, 0x0001a000},
+       {0x0000a204, 0x000037c0, 0x000037c4, 0x000037c4, 0x000037c0},
+       {0x0000a208, 0x00000104, 0x00000104, 0x00000004, 0x00000004},
+       {0x0000a230, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b},
+       {0x0000a238, 0xffb81018, 0xffb81018, 0xffb81018, 0xffb81018},
+       {0x0000a250, 0x00000000, 0x00000000, 0x00000210, 0x00000108},
+       {0x0000a254, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898},
+       {0x0000a258, 0x02020002, 0x02020002, 0x02020002, 0x02020002},
+       {0x0000a25c, 0x01000e0e, 0x01000e0e, 0x01000e0e, 0x01000e0e},
+       {0x0000a260, 0x0a021501, 0x0a021501, 0x3a021501, 0x3a021501},
+       {0x0000a264, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e},
+       {0x0000a280, 0x00000007, 0x00000007, 0x0000000b, 0x0000000b},
+       {0x0000a284, 0x00000000, 0x00000000, 0x00000150, 0x00000150},
+       {0x0000a288, 0x00000110, 0x00000110, 0x00000110, 0x00000110},
+       {0x0000a28c, 0x00022222, 0x00022222, 0x00022222, 0x00022222},
+       {0x0000a2c4, 0x00158d18, 0x00158d18, 0x00158d18, 0x00158d18},
+       {0x0000a2d0, 0x00071981, 0x00071981, 0x00071981, 0x00071982},
+       {0x0000a2d8, 0xf999a83a, 0xf999a83a, 0xf999a83a, 0xf999a83a},
+       {0x0000a358, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000a830, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c},
+       {0x0000ae04, 0x00800000, 0x00800000, 0x00800000, 0x00800000},
+       {0x0000ae18, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000ae1c, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c},
+       {0x0000ae20, 0x000001b5, 0x000001b5, 0x000001ce, 0x000001ce},
+       {0x0000b284, 0x00000000, 0x00000000, 0x00000150, 0x00000150},
+       {0x0000b830, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c},
+       {0x0000be04, 0x00800000, 0x00800000, 0x00800000, 0x00800000},
+       {0x0000be18, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000be1c, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c},
+       {0x0000be20, 0x000001b5, 0x000001b5, 0x000001ce, 0x000001ce},
+       {0x0000c284, 0x00000000, 0x00000000, 0x00000150, 0x00000150},
+};
+
+static const u32 ar9300_2p0_baseband_core[][2] = {
+       /* Addr      allmodes  */
+       {0x00009800, 0xafe68e30},
+       {0x00009804, 0xfd14e000},
+       {0x00009808, 0x9c0a9f6b},
+       {0x0000980c, 0x04900000},
+       {0x00009814, 0x9280c00a},
+       {0x00009818, 0x00000000},
+       {0x0000981c, 0x00020028},
+       {0x00009834, 0x5f3ca3de},
+       {0x00009838, 0x0108ecff},
+       {0x0000983c, 0x14750600},
+       {0x00009880, 0x201fff00},
+       {0x00009884, 0x00001042},
+       {0x000098a4, 0x00200400},
+       {0x000098b0, 0x52440bbe},
+       {0x000098d0, 0x004b6a8e},
+       {0x000098d4, 0x00000820},
+       {0x000098dc, 0x00000000},
+       {0x000098f0, 0x00000000},
+       {0x000098f4, 0x00000000},
+       {0x00009c04, 0xff55ff55},
+       {0x00009c08, 0x0320ff55},
+       {0x00009c0c, 0x00000000},
+       {0x00009c10, 0x00000000},
+       {0x00009c14, 0x00046384},
+       {0x00009c18, 0x05b6b440},
+       {0x00009c1c, 0x00b6b440},
+       {0x00009d00, 0xc080a333},
+       {0x00009d04, 0x40206c10},
+       {0x00009d08, 0x009c4060},
+       {0x00009d0c, 0x9883800a},
+       {0x00009d10, 0x01834061},
+       {0x00009d14, 0x00c0040b},
+       {0x00009d18, 0x00000000},
+       {0x00009e08, 0x0038233c},
+       {0x00009e24, 0x990bb515},
+       {0x00009e28, 0x0c6f0000},
+       {0x00009e30, 0x06336f77},
+       {0x00009e34, 0x6af6532f},
+       {0x00009e38, 0x0cc80c00},
+       {0x00009e3c, 0xcf946222},
+       {0x00009e40, 0x0d261820},
+       {0x00009e4c, 0x00001004},
+       {0x00009e50, 0x00ff03f1},
+       {0x00009e54, 0x00000000},
+       {0x00009fc0, 0x803e4788},
+       {0x00009fc4, 0x0001efb5},
+       {0x00009fcc, 0x40000014},
+       {0x00009fd0, 0x01193b93},
+       {0x0000a20c, 0x00000000},
+       {0x0000a220, 0x00000000},
+       {0x0000a224, 0x00000000},
+       {0x0000a228, 0x10002310},
+       {0x0000a22c, 0x01036a1e},
+       {0x0000a234, 0x10000fff},
+       {0x0000a23c, 0x00000000},
+       {0x0000a244, 0x0c000000},
+       {0x0000a2a0, 0x00000001},
+       {0x0000a2c0, 0x00000001},
+       {0x0000a2c8, 0x00000000},
+       {0x0000a2cc, 0x18c43433},
+       {0x0000a2d4, 0x00000000},
+       {0x0000a2dc, 0x00000000},
+       {0x0000a2e0, 0x00000000},
+       {0x0000a2e4, 0x00000000},
+       {0x0000a2e8, 0x00000000},
+       {0x0000a2ec, 0x00000000},
+       {0x0000a2f0, 0x00000000},
+       {0x0000a2f4, 0x00000000},
+       {0x0000a2f8, 0x00000000},
+       {0x0000a344, 0x00000000},
+       {0x0000a34c, 0x00000000},
+       {0x0000a350, 0x0000a000},
+       {0x0000a364, 0x00000000},
+       {0x0000a370, 0x00000000},
+       {0x0000a390, 0x00000001},
+       {0x0000a394, 0x00000444},
+       {0x0000a398, 0x001f0e0f},
+       {0x0000a39c, 0x0075393f},
+       {0x0000a3a0, 0xb79f6427},
+       {0x0000a3a4, 0x00000000},
+       {0x0000a3a8, 0xaaaaaaaa},
+       {0x0000a3ac, 0x3c466478},
+       {0x0000a3c0, 0x20202020},
+       {0x0000a3c4, 0x22222220},
+       {0x0000a3c8, 0x20200020},
+       {0x0000a3cc, 0x20202020},
+       {0x0000a3d0, 0x20202020},
+       {0x0000a3d4, 0x20202020},
+       {0x0000a3d8, 0x20202020},
+       {0x0000a3dc, 0x20202020},
+       {0x0000a3e0, 0x20202020},
+       {0x0000a3e4, 0x20202020},
+       {0x0000a3e8, 0x20202020},
+       {0x0000a3ec, 0x20202020},
+       {0x0000a3f0, 0x00000000},
+       {0x0000a3f4, 0x00000246},
+       {0x0000a3f8, 0x0cdbd380},
+       {0x0000a3fc, 0x000f0f01},
+       {0x0000a400, 0x8fa91f01},
+       {0x0000a404, 0x00000000},
+       {0x0000a408, 0x0e79e5c6},
+       {0x0000a40c, 0x00820820},
+       {0x0000a414, 0x1ce739ce},
+       {0x0000a418, 0x7d001dce},
+       {0x0000a41c, 0x1ce739ce},
+       {0x0000a420, 0x000001ce},
+       {0x0000a424, 0x1ce739ce},
+       {0x0000a428, 0x000001ce},
+       {0x0000a42c, 0x1ce739ce},
+       {0x0000a430, 0x1ce739ce},
+       {0x0000a434, 0x00000000},
+       {0x0000a438, 0x00001801},
+       {0x0000a43c, 0x00000000},
+       {0x0000a440, 0x00000000},
+       {0x0000a444, 0x00000000},
+       {0x0000a448, 0x07000080},
+       {0x0000a44c, 0x00000001},
+       {0x0000a450, 0x00010000},
+       {0x0000a458, 0x00000000},
+       {0x0000a600, 0x00000000},
+       {0x0000a604, 0x00000000},
+       {0x0000a608, 0x00000000},
+       {0x0000a60c, 0x00000000},
+       {0x0000a610, 0x00000000},
+       {0x0000a614, 0x00000000},
+       {0x0000a618, 0x00000000},
+       {0x0000a61c, 0x00000000},
+       {0x0000a620, 0x00000000},
+       {0x0000a624, 0x00000000},
+       {0x0000a628, 0x00000000},
+       {0x0000a62c, 0x00000000},
+       {0x0000a630, 0x00000000},
+       {0x0000a634, 0x00000000},
+       {0x0000a638, 0x00000000},
+       {0x0000a63c, 0x00000000},
+       {0x0000a640, 0x00000000},
+       {0x0000a644, 0x3ffd9d74},
+       {0x0000a648, 0x0048060a},
+       {0x0000a64c, 0x00000637},
+       {0x0000a670, 0x03020100},
+       {0x0000a674, 0x09080504},
+       {0x0000a678, 0x0d0c0b0a},
+       {0x0000a67c, 0x13121110},
+       {0x0000a680, 0x31301514},
+       {0x0000a684, 0x35343332},
+       {0x0000a688, 0x00000036},
+       {0x0000a690, 0x00000838},
+       {0x0000a7c0, 0x00000000},
+       {0x0000a7c4, 0xfffffffc},
+       {0x0000a7c8, 0x00000000},
+       {0x0000a7cc, 0x00000000},
+       {0x0000a7d0, 0x00000000},
+       {0x0000a7d4, 0x00000004},
+       {0x0000a7dc, 0x00000001},
+       {0x0000a8d0, 0x004b6a8e},
+       {0x0000a8d4, 0x00000820},
+       {0x0000a8dc, 0x00000000},
+       {0x0000a8f0, 0x00000000},
+       {0x0000a8f4, 0x00000000},
+       {0x0000b2d0, 0x00000080},
+       {0x0000b2d4, 0x00000000},
+       {0x0000b2dc, 0x00000000},
+       {0x0000b2e0, 0x00000000},
+       {0x0000b2e4, 0x00000000},
+       {0x0000b2e8, 0x00000000},
+       {0x0000b2ec, 0x00000000},
+       {0x0000b2f0, 0x00000000},
+       {0x0000b2f4, 0x00000000},
+       {0x0000b2f8, 0x00000000},
+       {0x0000b408, 0x0e79e5c0},
+       {0x0000b40c, 0x00820820},
+       {0x0000b420, 0x00000000},
+       {0x0000b8d0, 0x004b6a8e},
+       {0x0000b8d4, 0x00000820},
+       {0x0000b8dc, 0x00000000},
+       {0x0000b8f0, 0x00000000},
+       {0x0000b8f4, 0x00000000},
+       {0x0000c2d0, 0x00000080},
+       {0x0000c2d4, 0x00000000},
+       {0x0000c2dc, 0x00000000},
+       {0x0000c2e0, 0x00000000},
+       {0x0000c2e4, 0x00000000},
+       {0x0000c2e8, 0x00000000},
+       {0x0000c2ec, 0x00000000},
+       {0x0000c2f0, 0x00000000},
+       {0x0000c2f4, 0x00000000},
+       {0x0000c2f8, 0x00000000},
+       {0x0000c408, 0x0e79e5c0},
+       {0x0000c40c, 0x00820820},
+       {0x0000c420, 0x00000000},
+};
+
+static const u32 ar9300Modes_high_power_tx_gain_table_2p0[][5] = {
+       /* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
+       {0x0000a410, 0x000050d9, 0x000050d9, 0x000050da, 0x000050da},
+       {0x0000a500, 0x00020220, 0x00020220, 0x00000000, 0x00000000},
+       {0x0000a504, 0x06020223, 0x06020223, 0x04000002, 0x04000002},
+       {0x0000a508, 0x0b022220, 0x0b022220, 0x08000004, 0x08000004},
+       {0x0000a50c, 0x10022223, 0x10022223, 0x0b000200, 0x0b000200},
+       {0x0000a510, 0x17022620, 0x17022620, 0x0f000202, 0x0f000202},
+       {0x0000a514, 0x1b022622, 0x1b022622, 0x11000400, 0x11000400},
+       {0x0000a518, 0x1f022822, 0x1f022822, 0x15000402, 0x15000402},
+       {0x0000a51c, 0x24022842, 0x24022842, 0x19000404, 0x19000404},
+       {0x0000a520, 0x28042840, 0x28042840, 0x1b000603, 0x1b000603},
+       {0x0000a524, 0x2c042842, 0x2c042842, 0x1f000a02, 0x1f000a02},
+       {0x0000a528, 0x30042844, 0x30042844, 0x23000a04, 0x23000a04},
+       {0x0000a52c, 0x34042846, 0x34042846, 0x26000a20, 0x26000a20},
+       {0x0000a530, 0x39042869, 0x39042869, 0x2a000e20, 0x2a000e20},
+       {0x0000a534, 0x3d062869, 0x3d062869, 0x2e000e22, 0x2e000e22},
+       {0x0000a538, 0x44062c69, 0x44062c69, 0x31000e24, 0x31000e24},
+       {0x0000a53c, 0x48063069, 0x48063069, 0x34001640, 0x34001640},
+       {0x0000a540, 0x4c0a3065, 0x4c0a3065, 0x38001660, 0x38001660},
+       {0x0000a544, 0x500a3069, 0x500a3069, 0x3b001861, 0x3b001861},
+       {0x0000a548, 0x530a3469, 0x530a3469, 0x3e001a81, 0x3e001a81},
+       {0x0000a54c, 0x590a7464, 0x590a7464, 0x42001a83, 0x42001a83},
+       {0x0000a550, 0x5e0a7865, 0x5e0a7865, 0x44001c84, 0x44001c84},
+       {0x0000a554, 0x630a7e66, 0x630a7e66, 0x48001ce3, 0x48001ce3},
+       {0x0000a558, 0x680a7e89, 0x680a7e89, 0x4c001ce5, 0x4c001ce5},
+       {0x0000a55c, 0x6e0a7e8c, 0x6e0a7e8c, 0x50001ce9, 0x50001ce9},
+       {0x0000a560, 0x730e7e8c, 0x730e7e8c, 0x54001ceb, 0x54001ceb},
+       {0x0000a564, 0x730e7e8c, 0x730e7e8c, 0x56001eec, 0x56001eec},
+       {0x0000a568, 0x730e7e8c, 0x730e7e8c, 0x56001eec, 0x56001eec},
+       {0x0000a56c, 0x730e7e8c, 0x730e7e8c, 0x56001eec, 0x56001eec},
+       {0x0000a570, 0x730e7e8c, 0x730e7e8c, 0x56001eec, 0x56001eec},
+       {0x0000a574, 0x730e7e8c, 0x730e7e8c, 0x56001eec, 0x56001eec},
+       {0x0000a578, 0x730e7e8c, 0x730e7e8c, 0x56001eec, 0x56001eec},
+       {0x0000a57c, 0x730e7e8c, 0x730e7e8c, 0x56001eec, 0x56001eec},
+       {0x0000a580, 0x00820220, 0x00820220, 0x00800000, 0x00800000},
+       {0x0000a584, 0x06820223, 0x06820223, 0x04800002, 0x04800002},
+       {0x0000a588, 0x0b822220, 0x0b822220, 0x08800004, 0x08800004},
+       {0x0000a58c, 0x10822223, 0x10822223, 0x0b800200, 0x0b800200},
+       {0x0000a590, 0x17822620, 0x17822620, 0x0f800202, 0x0f800202},
+       {0x0000a594, 0x1b822622, 0x1b822622, 0x11800400, 0x11800400},
+       {0x0000a598, 0x1f822822, 0x1f822822, 0x15800402, 0x15800402},
+       {0x0000a59c, 0x24822842, 0x24822842, 0x19800404, 0x19800404},
+       {0x0000a5a0, 0x28842840, 0x28842840, 0x1b800603, 0x1b800603},
+       {0x0000a5a4, 0x2c842842, 0x2c842842, 0x1f800a02, 0x1f800a02},
+       {0x0000a5a8, 0x30842844, 0x30842844, 0x23800a04, 0x23800a04},
+       {0x0000a5ac, 0x34842846, 0x34842846, 0x26800a20, 0x26800a20},
+       {0x0000a5b0, 0x39842869, 0x39842869, 0x2a800e20, 0x2a800e20},
+       {0x0000a5b4, 0x3d862869, 0x3d862869, 0x2e800e22, 0x2e800e22},
+       {0x0000a5b8, 0x44862c69, 0x44862c69, 0x31800e24, 0x31800e24},
+       {0x0000a5bc, 0x48863069, 0x48863069, 0x34801640, 0x34801640},
+       {0x0000a5c0, 0x4c8a3065, 0x4c8a3065, 0x38801660, 0x38801660},
+       {0x0000a5c4, 0x508a3069, 0x508a3069, 0x3b801861, 0x3b801861},
+       {0x0000a5c8, 0x538a3469, 0x538a3469, 0x3e801a81, 0x3e801a81},
+       {0x0000a5cc, 0x598a7464, 0x598a7464, 0x42801a83, 0x42801a83},
+       {0x0000a5d0, 0x5e8a7865, 0x5e8a7865, 0x44801c84, 0x44801c84},
+       {0x0000a5d4, 0x638a7e66, 0x638a7e66, 0x48801ce3, 0x48801ce3},
+       {0x0000a5d8, 0x688a7e89, 0x688a7e89, 0x4c801ce5, 0x4c801ce5},
+       {0x0000a5dc, 0x6e8a7e8c, 0x6e8a7e8c, 0x50801ce9, 0x50801ce9},
+       {0x0000a5e0, 0x738e7e8c, 0x738e7e8c, 0x54801ceb, 0x54801ceb},
+       {0x0000a5e4, 0x738e7e8c, 0x738e7e8c, 0x56801eec, 0x56801eec},
+       {0x0000a5e8, 0x738e7e8c, 0x738e7e8c, 0x56801eec, 0x56801eec},
+       {0x0000a5ec, 0x738e7e8c, 0x738e7e8c, 0x56801eec, 0x56801eec},
+       {0x0000a5f0, 0x738e7e8c, 0x738e7e8c, 0x56801eec, 0x56801eec},
+       {0x0000a5f4, 0x738e7e8c, 0x738e7e8c, 0x56801eec, 0x56801eec},
+       {0x0000a5f8, 0x738e7e8c, 0x738e7e8c, 0x56801eec, 0x56801eec},
+       {0x0000a5fc, 0x738e7e8c, 0x738e7e8c, 0x56801eec, 0x56801eec},
+       {0x00016044, 0x056db2e6, 0x056db2e6, 0x056db2e6, 0x056db2e6},
+       {0x00016048, 0xad241a61, 0xad241a61, 0xad241a61, 0xad241a61},
+       {0x00016068, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c},
+       {0x00016444, 0x056db2e6, 0x056db2e6, 0x056db2e6, 0x056db2e6},
+       {0x00016448, 0xad241a61, 0xad241a61, 0xad241a61, 0xad241a61},
+       {0x00016468, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c},
+       {0x00016844, 0x056db2e6, 0x056db2e6, 0x056db2e6, 0x056db2e6},
+       {0x00016848, 0xad241a61, 0xad241a61, 0xad241a61, 0xad241a61},
+       {0x00016868, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c},
+};
+
+static const u32 ar9300Modes_high_ob_db_tx_gain_table_2p0[][5] = {
+       /* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
+       {0x0000a410, 0x000050d9, 0x000050d9, 0x000050da, 0x000050da},
+       {0x0000a500, 0x00020220, 0x00020220, 0x00000000, 0x00000000},
+       {0x0000a504, 0x06020223, 0x06020223, 0x04000002, 0x04000002},
+       {0x0000a508, 0x0b022220, 0x0b022220, 0x08000004, 0x08000004},
+       {0x0000a50c, 0x10022223, 0x10022223, 0x0b000200, 0x0b000200},
+       {0x0000a510, 0x17022620, 0x17022620, 0x0f000202, 0x0f000202},
+       {0x0000a514, 0x1b022622, 0x1b022622, 0x11000400, 0x11000400},
+       {0x0000a518, 0x1f022822, 0x1f022822, 0x15000402, 0x15000402},
+       {0x0000a51c, 0x24022842, 0x24022842, 0x19000404, 0x19000404},
+       {0x0000a520, 0x28042840, 0x28042840, 0x1b000603, 0x1b000603},
+       {0x0000a524, 0x2c042842, 0x2c042842, 0x1f000a02, 0x1f000a02},
+       {0x0000a528, 0x30042844, 0x30042844, 0x23000a04, 0x23000a04},
+       {0x0000a52c, 0x34042846, 0x34042846, 0x26000a20, 0x26000a20},
+       {0x0000a530, 0x39042869, 0x39042869, 0x2a000e20, 0x2a000e20},
+       {0x0000a534, 0x3d062869, 0x3d062869, 0x2e000e22, 0x2e000e22},
+       {0x0000a538, 0x44062c69, 0x44062c69, 0x31000e24, 0x31000e24},
+       {0x0000a53c, 0x48063069, 0x48063069, 0x34001640, 0x34001640},
+       {0x0000a540, 0x4c0a3065, 0x4c0a3065, 0x38001660, 0x38001660},
+       {0x0000a544, 0x500a3069, 0x500a3069, 0x3b001861, 0x3b001861},
+       {0x0000a548, 0x530a3469, 0x530a3469, 0x3e001a81, 0x3e001a81},
+       {0x0000a54c, 0x590a7464, 0x590a7464, 0x42001a83, 0x42001a83},
+       {0x0000a550, 0x5e0a7865, 0x5e0a7865, 0x44001c84, 0x44001c84},
+       {0x0000a554, 0x630a7e66, 0x630a7e66, 0x48001ce3, 0x48001ce3},
+       {0x0000a558, 0x680a7e89, 0x680a7e89, 0x4c001ce5, 0x4c001ce5},
+       {0x0000a55c, 0x6e0a7e8c, 0x6e0a7e8c, 0x50001ce9, 0x50001ce9},
+       {0x0000a560, 0x730e7e8c, 0x730e7e8c, 0x54001ceb, 0x54001ceb},
+       {0x0000a564, 0x730e7e8c, 0x730e7e8c, 0x56001eec, 0x56001eec},
+       {0x0000a568, 0x730e7e8c, 0x730e7e8c, 0x56001eec, 0x56001eec},
+       {0x0000a56c, 0x730e7e8c, 0x730e7e8c, 0x56001eec, 0x56001eec},
+       {0x0000a570, 0x730e7e8c, 0x730e7e8c, 0x56001eec, 0x56001eec},
+       {0x0000a574, 0x730e7e8c, 0x730e7e8c, 0x56001eec, 0x56001eec},
+       {0x0000a578, 0x730e7e8c, 0x730e7e8c, 0x56001eec, 0x56001eec},
+       {0x0000a57c, 0x730e7e8c, 0x730e7e8c, 0x56001eec, 0x56001eec},
+       {0x0000a580, 0x00820220, 0x00820220, 0x00800000, 0x00800000},
+       {0x0000a584, 0x06820223, 0x06820223, 0x04800002, 0x04800002},
+       {0x0000a588, 0x0b822220, 0x0b822220, 0x08800004, 0x08800004},
+       {0x0000a58c, 0x10822223, 0x10822223, 0x0b800200, 0x0b800200},
+       {0x0000a590, 0x17822620, 0x17822620, 0x0f800202, 0x0f800202},
+       {0x0000a594, 0x1b822622, 0x1b822622, 0x11800400, 0x11800400},
+       {0x0000a598, 0x1f822822, 0x1f822822, 0x15800402, 0x15800402},
+       {0x0000a59c, 0x24822842, 0x24822842, 0x19800404, 0x19800404},
+       {0x0000a5a0, 0x28842840, 0x28842840, 0x1b800603, 0x1b800603},
+       {0x0000a5a4, 0x2c842842, 0x2c842842, 0x1f800a02, 0x1f800a02},
+       {0x0000a5a8, 0x30842844, 0x30842844, 0x23800a04, 0x23800a04},
+       {0x0000a5ac, 0x34842846, 0x34842846, 0x26800a20, 0x26800a20},
+       {0x0000a5b0, 0x39842869, 0x39842869, 0x2a800e20, 0x2a800e20},
+       {0x0000a5b4, 0x3d862869, 0x3d862869, 0x2e800e22, 0x2e800e22},
+       {0x0000a5b8, 0x44862c69, 0x44862c69, 0x31800e24, 0x31800e24},
+       {0x0000a5bc, 0x48863069, 0x48863069, 0x34801640, 0x34801640},
+       {0x0000a5c0, 0x4c8a3065, 0x4c8a3065, 0x38801660, 0x38801660},
+       {0x0000a5c4, 0x508a3069, 0x508a3069, 0x3b801861, 0x3b801861},
+       {0x0000a5c8, 0x538a3469, 0x538a3469, 0x3e801a81, 0x3e801a81},
+       {0x0000a5cc, 0x598a7464, 0x598a7464, 0x42801a83, 0x42801a83},
+       {0x0000a5d0, 0x5e8a7865, 0x5e8a7865, 0x44801c84, 0x44801c84},
+       {0x0000a5d4, 0x638a7e66, 0x638a7e66, 0x48801ce3, 0x48801ce3},
+       {0x0000a5d8, 0x688a7e89, 0x688a7e89, 0x4c801ce5, 0x4c801ce5},
+       {0x0000a5dc, 0x6e8a7e8c, 0x6e8a7e8c, 0x50801ce9, 0x50801ce9},
+       {0x0000a5e0, 0x738e7e8c, 0x738e7e8c, 0x54801ceb, 0x54801ceb},
+       {0x0000a5e4, 0x738e7e8c, 0x738e7e8c, 0x56801eec, 0x56801eec},
+       {0x0000a5e8, 0x738e7e8c, 0x738e7e8c, 0x56801eec, 0x56801eec},
+       {0x0000a5ec, 0x738e7e8c, 0x738e7e8c, 0x56801eec, 0x56801eec},
+       {0x0000a5f0, 0x738e7e8c, 0x738e7e8c, 0x56801eec, 0x56801eec},
+       {0x0000a5f4, 0x738e7e8c, 0x738e7e8c, 0x56801eec, 0x56801eec},
+       {0x0000a5f8, 0x738e7e8c, 0x738e7e8c, 0x56801eec, 0x56801eec},
+       {0x0000a5fc, 0x738e7e8c, 0x738e7e8c, 0x56801eec, 0x56801eec},
+       {0x00016044, 0x056db2e4, 0x056db2e4, 0x056db2e4, 0x056db2e4},
+       {0x00016048, 0x8c001a61, 0x8c001a61, 0x8c001a61, 0x8c001a61},
+       {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
+       {0x00016444, 0x056db2e4, 0x056db2e4, 0x056db2e4, 0x056db2e4},
+       {0x00016448, 0x8c001a61, 0x8c001a61, 0x8c001a61, 0x8c001a61},
+       {0x00016468, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
+       {0x00016844, 0x056db2e4, 0x056db2e4, 0x056db2e4, 0x056db2e4},
+       {0x00016848, 0x8c001a61, 0x8c001a61, 0x8c001a61, 0x8c001a61},
+       {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
+};
+
+static const u32 ar9300Common_rx_gain_table_2p0[][2] = {
+       /* Addr      allmodes  */
+       {0x0000a000, 0x00010000},
+       {0x0000a004, 0x00030002},
+       {0x0000a008, 0x00050004},
+       {0x0000a00c, 0x00810080},
+       {0x0000a010, 0x01800082},
+       {0x0000a014, 0x01820181},
+       {0x0000a018, 0x01840183},
+       {0x0000a01c, 0x01880185},
+       {0x0000a020, 0x018a0189},
+       {0x0000a024, 0x02850284},
+       {0x0000a028, 0x02890288},
+       {0x0000a02c, 0x028b028a},
+       {0x0000a030, 0x028d028c},
+       {0x0000a034, 0x02910290},
+       {0x0000a038, 0x02930292},
+       {0x0000a03c, 0x03910390},
+       {0x0000a040, 0x03930392},
+       {0x0000a044, 0x03950394},
+       {0x0000a048, 0x00000396},
+       {0x0000a04c, 0x00000000},
+       {0x0000a050, 0x00000000},
+       {0x0000a054, 0x00000000},
+       {0x0000a058, 0x00000000},
+       {0x0000a05c, 0x00000000},
+       {0x0000a060, 0x00000000},
+       {0x0000a064, 0x00000000},
+       {0x0000a068, 0x00000000},
+       {0x0000a06c, 0x00000000},
+       {0x0000a070, 0x00000000},
+       {0x0000a074, 0x00000000},
+       {0x0000a078, 0x00000000},
+       {0x0000a07c, 0x00000000},
+       {0x0000a080, 0x28282828},
+       {0x0000a084, 0x21212128},
+       {0x0000a088, 0x21212121},
+       {0x0000a08c, 0x1c1c1c21},
+       {0x0000a090, 0x1c1c1c1c},
+       {0x0000a094, 0x17171c1c},
+       {0x0000a098, 0x02020212},
+       {0x0000a09c, 0x02020202},
+       {0x0000a0a0, 0x00000000},
+       {0x0000a0a4, 0x00000000},
+       {0x0000a0a8, 0x00000000},
+       {0x0000a0ac, 0x00000000},
+       {0x0000a0b0, 0x00000000},
+       {0x0000a0b4, 0x00000000},
+       {0x0000a0b8, 0x00000000},
+       {0x0000a0bc, 0x00000000},
+       {0x0000a0c0, 0x001f0000},
+       {0x0000a0c4, 0x011f0100},
+       {0x0000a0c8, 0x011d011e},
+       {0x0000a0cc, 0x011b011c},
+       {0x0000a0d0, 0x02030204},
+       {0x0000a0d4, 0x02010202},
+       {0x0000a0d8, 0x021f0200},
+       {0x0000a0dc, 0x021d021e},
+       {0x0000a0e0, 0x03010302},
+       {0x0000a0e4, 0x031f0300},
+       {0x0000a0e8, 0x0402031e},
+       {0x0000a0ec, 0x04000401},
+       {0x0000a0f0, 0x041e041f},
+       {0x0000a0f4, 0x05010502},
+       {0x0000a0f8, 0x051f0500},
+       {0x0000a0fc, 0x0602051e},
+       {0x0000a100, 0x06000601},
+       {0x0000a104, 0x061e061f},
+       {0x0000a108, 0x0703061d},
+       {0x0000a10c, 0x07010702},
+       {0x0000a110, 0x00000700},
+       {0x0000a114, 0x00000000},
+       {0x0000a118, 0x00000000},
+       {0x0000a11c, 0x00000000},
+       {0x0000a120, 0x00000000},
+       {0x0000a124, 0x00000000},
+       {0x0000a128, 0x00000000},
+       {0x0000a12c, 0x00000000},
+       {0x0000a130, 0x00000000},
+       {0x0000a134, 0x00000000},
+       {0x0000a138, 0x00000000},
+       {0x0000a13c, 0x00000000},
+       {0x0000a140, 0x001f0000},
+       {0x0000a144, 0x011f0100},
+       {0x0000a148, 0x011d011e},
+       {0x0000a14c, 0x011b011c},
+       {0x0000a150, 0x02030204},
+       {0x0000a154, 0x02010202},
+       {0x0000a158, 0x021f0200},
+       {0x0000a15c, 0x021d021e},
+       {0x0000a160, 0x03010302},
+       {0x0000a164, 0x031f0300},
+       {0x0000a168, 0x0402031e},
+       {0x0000a16c, 0x04000401},
+       {0x0000a170, 0x041e041f},
+       {0x0000a174, 0x05010502},
+       {0x0000a178, 0x051f0500},
+       {0x0000a17c, 0x0602051e},
+       {0x0000a180, 0x06000601},
+       {0x0000a184, 0x061e061f},
+       {0x0000a188, 0x0703061d},
+       {0x0000a18c, 0x07010702},
+       {0x0000a190, 0x00000700},
+       {0x0000a194, 0x00000000},
+       {0x0000a198, 0x00000000},
+       {0x0000a19c, 0x00000000},
+       {0x0000a1a0, 0x00000000},
+       {0x0000a1a4, 0x00000000},
+       {0x0000a1a8, 0x00000000},
+       {0x0000a1ac, 0x00000000},
+       {0x0000a1b0, 0x00000000},
+       {0x0000a1b4, 0x00000000},
+       {0x0000a1b8, 0x00000000},
+       {0x0000a1bc, 0x00000000},
+       {0x0000a1c0, 0x00000000},
+       {0x0000a1c4, 0x00000000},
+       {0x0000a1c8, 0x00000000},
+       {0x0000a1cc, 0x00000000},
+       {0x0000a1d0, 0x00000000},
+       {0x0000a1d4, 0x00000000},
+       {0x0000a1d8, 0x00000000},
+       {0x0000a1dc, 0x00000000},
+       {0x0000a1e0, 0x00000000},
+       {0x0000a1e4, 0x00000000},
+       {0x0000a1e8, 0x00000000},
+       {0x0000a1ec, 0x00000000},
+       {0x0000a1f0, 0x00000396},
+       {0x0000a1f4, 0x00000396},
+       {0x0000a1f8, 0x00000396},
+       {0x0000a1fc, 0x00000196},
+       {0x0000b000, 0x00010000},
+       {0x0000b004, 0x00030002},
+       {0x0000b008, 0x00050004},
+       {0x0000b00c, 0x00810080},
+       {0x0000b010, 0x00830082},
+       {0x0000b014, 0x01810180},
+       {0x0000b018, 0x01830182},
+       {0x0000b01c, 0x01850184},
+       {0x0000b020, 0x02810280},
+       {0x0000b024, 0x02830282},
+       {0x0000b028, 0x02850284},
+       {0x0000b02c, 0x02890288},
+       {0x0000b030, 0x028b028a},
+       {0x0000b034, 0x0388028c},
+       {0x0000b038, 0x038a0389},
+       {0x0000b03c, 0x038c038b},
+       {0x0000b040, 0x0390038d},
+       {0x0000b044, 0x03920391},
+       {0x0000b048, 0x03940393},
+       {0x0000b04c, 0x03960395},
+       {0x0000b050, 0x00000000},
+       {0x0000b054, 0x00000000},
+       {0x0000b058, 0x00000000},
+       {0x0000b05c, 0x00000000},
+       {0x0000b060, 0x00000000},
+       {0x0000b064, 0x00000000},
+       {0x0000b068, 0x00000000},
+       {0x0000b06c, 0x00000000},
+       {0x0000b070, 0x00000000},
+       {0x0000b074, 0x00000000},
+       {0x0000b078, 0x00000000},
+       {0x0000b07c, 0x00000000},
+       {0x0000b080, 0x32323232},
+       {0x0000b084, 0x2f2f3232},
+       {0x0000b088, 0x23282a2d},
+       {0x0000b08c, 0x1c1e2123},
+       {0x0000b090, 0x14171919},
+       {0x0000b094, 0x0e0e1214},
+       {0x0000b098, 0x03050707},
+       {0x0000b09c, 0x00030303},
+       {0x0000b0a0, 0x00000000},
+       {0x0000b0a4, 0x00000000},
+       {0x0000b0a8, 0x00000000},
+       {0x0000b0ac, 0x00000000},
+       {0x0000b0b0, 0x00000000},
+       {0x0000b0b4, 0x00000000},
+       {0x0000b0b8, 0x00000000},
+       {0x0000b0bc, 0x00000000},
+       {0x0000b0c0, 0x003f0020},
+       {0x0000b0c4, 0x00400041},
+       {0x0000b0c8, 0x0140005f},
+       {0x0000b0cc, 0x0160015f},
+       {0x0000b0d0, 0x017e017f},
+       {0x0000b0d4, 0x02410242},
+       {0x0000b0d8, 0x025f0240},
+       {0x0000b0dc, 0x027f0260},
+       {0x0000b0e0, 0x0341027e},
+       {0x0000b0e4, 0x035f0340},
+       {0x0000b0e8, 0x037f0360},
+       {0x0000b0ec, 0x04400441},
+       {0x0000b0f0, 0x0460045f},
+       {0x0000b0f4, 0x0541047f},
+       {0x0000b0f8, 0x055f0540},
+       {0x0000b0fc, 0x057f0560},
+       {0x0000b100, 0x06400641},
+       {0x0000b104, 0x0660065f},
+       {0x0000b108, 0x067e067f},
+       {0x0000b10c, 0x07410742},
+       {0x0000b110, 0x075f0740},
+       {0x0000b114, 0x077f0760},
+       {0x0000b118, 0x07800781},
+       {0x0000b11c, 0x07a0079f},
+       {0x0000b120, 0x07c107bf},
+       {0x0000b124, 0x000007c0},
+       {0x0000b128, 0x00000000},
+       {0x0000b12c, 0x00000000},
+       {0x0000b130, 0x00000000},
+       {0x0000b134, 0x00000000},
+       {0x0000b138, 0x00000000},
+       {0x0000b13c, 0x00000000},
+       {0x0000b140, 0x003f0020},
+       {0x0000b144, 0x00400041},
+       {0x0000b148, 0x0140005f},
+       {0x0000b14c, 0x0160015f},
+       {0x0000b150, 0x017e017f},
+       {0x0000b154, 0x02410242},
+       {0x0000b158, 0x025f0240},
+       {0x0000b15c, 0x027f0260},
+       {0x0000b160, 0x0341027e},
+       {0x0000b164, 0x035f0340},
+       {0x0000b168, 0x037f0360},
+       {0x0000b16c, 0x04400441},
+       {0x0000b170, 0x0460045f},
+       {0x0000b174, 0x0541047f},
+       {0x0000b178, 0x055f0540},
+       {0x0000b17c, 0x057f0560},
+       {0x0000b180, 0x06400641},
+       {0x0000b184, 0x0660065f},
+       {0x0000b188, 0x067e067f},
+       {0x0000b18c, 0x07410742},
+       {0x0000b190, 0x075f0740},
+       {0x0000b194, 0x077f0760},
+       {0x0000b198, 0x07800781},
+       {0x0000b19c, 0x07a0079f},
+       {0x0000b1a0, 0x07c107bf},
+       {0x0000b1a4, 0x000007c0},
+       {0x0000b1a8, 0x00000000},
+       {0x0000b1ac, 0x00000000},
+       {0x0000b1b0, 0x00000000},
+       {0x0000b1b4, 0x00000000},
+       {0x0000b1b8, 0x00000000},
+       {0x0000b1bc, 0x00000000},
+       {0x0000b1c0, 0x00000000},
+       {0x0000b1c4, 0x00000000},
+       {0x0000b1c8, 0x00000000},
+       {0x0000b1cc, 0x00000000},
+       {0x0000b1d0, 0x00000000},
+       {0x0000b1d4, 0x00000000},
+       {0x0000b1d8, 0x00000000},
+       {0x0000b1dc, 0x00000000},
+       {0x0000b1e0, 0x00000000},
+       {0x0000b1e4, 0x00000000},
+       {0x0000b1e8, 0x00000000},
+       {0x0000b1ec, 0x00000000},
+       {0x0000b1f0, 0x00000396},
+       {0x0000b1f4, 0x00000396},
+       {0x0000b1f8, 0x00000396},
+       {0x0000b1fc, 0x00000196},
+};
+
+static const u32 ar9300Modes_low_ob_db_tx_gain_table_2p0[][5] = {
+       /* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
+       {0x0000a410, 0x000050da, 0x000050da, 0x000050da, 0x000050da},
+       {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002},
+       {0x0000a508, 0x0a000020, 0x0a000020, 0x08000004, 0x08000004},
+       {0x0000a50c, 0x10000023, 0x10000023, 0x0b000200, 0x0b000200},
+       {0x0000a510, 0x16000220, 0x16000220, 0x0f000202, 0x0f000202},
+       {0x0000a514, 0x1c000223, 0x1c000223, 0x12000400, 0x12000400},
+       {0x0000a518, 0x21020220, 0x21020220, 0x16000402, 0x16000402},
+       {0x0000a51c, 0x27020223, 0x27020223, 0x19000404, 0x19000404},
+       {0x0000a520, 0x2b022220, 0x2b022220, 0x1c000603, 0x1c000603},
+       {0x0000a524, 0x2f022222, 0x2f022222, 0x21000a02, 0x21000a02},
+       {0x0000a528, 0x34022225, 0x34022225, 0x25000a04, 0x25000a04},
+       {0x0000a52c, 0x3a02222a, 0x3a02222a, 0x28000a20, 0x28000a20},
+       {0x0000a530, 0x3e02222c, 0x3e02222c, 0x2c000e20, 0x2c000e20},
+       {0x0000a534, 0x4202242a, 0x4202242a, 0x30000e22, 0x30000e22},
+       {0x0000a538, 0x4702244a, 0x4702244a, 0x34000e24, 0x34000e24},
+       {0x0000a53c, 0x4b02244c, 0x4b02244c, 0x38001640, 0x38001640},
+       {0x0000a540, 0x4e02246c, 0x4e02246c, 0x3c001660, 0x3c001660},
+       {0x0000a544, 0x5302266c, 0x5302266c, 0x3f001861, 0x3f001861},
+       {0x0000a548, 0x5702286c, 0x5702286c, 0x43001a81, 0x43001a81},
+       {0x0000a54c, 0x5c04286b, 0x5c04286b, 0x47001a83, 0x47001a83},
+       {0x0000a550, 0x61042a6c, 0x61042a6c, 0x4a001c84, 0x4a001c84},
+       {0x0000a554, 0x66062a6c, 0x66062a6c, 0x4e001ce3, 0x4e001ce3},
+       {0x0000a558, 0x6b062e6c, 0x6b062e6c, 0x52001ce5, 0x52001ce5},
+       {0x0000a55c, 0x7006308c, 0x7006308c, 0x56001ce9, 0x56001ce9},
+       {0x0000a560, 0x730a308a, 0x730a308a, 0x5a001ceb, 0x5a001ceb},
+       {0x0000a564, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
+       {0x0000a568, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
+       {0x0000a56c, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
+       {0x0000a570, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
+       {0x0000a574, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
+       {0x0000a578, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
+       {0x0000a57c, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
+       {0x0000a580, 0x00800000, 0x00800000, 0x00800000, 0x00800000},
+       {0x0000a584, 0x06800003, 0x06800003, 0x04800002, 0x04800002},
+       {0x0000a588, 0x0a800020, 0x0a800020, 0x08800004, 0x08800004},
+       {0x0000a58c, 0x10800023, 0x10800023, 0x0b800200, 0x0b800200},
+       {0x0000a590, 0x16800220, 0x16800220, 0x0f800202, 0x0f800202},
+       {0x0000a594, 0x1c800223, 0x1c800223, 0x12800400, 0x12800400},
+       {0x0000a598, 0x21820220, 0x21820220, 0x16800402, 0x16800402},
+       {0x0000a59c, 0x27820223, 0x27820223, 0x19800404, 0x19800404},
+       {0x0000a5a0, 0x2b822220, 0x2b822220, 0x1c800603, 0x1c800603},
+       {0x0000a5a4, 0x2f822222, 0x2f822222, 0x21800a02, 0x21800a02},
+       {0x0000a5a8, 0x34822225, 0x34822225, 0x25800a04, 0x25800a04},
+       {0x0000a5ac, 0x3a82222a, 0x3a82222a, 0x28800a20, 0x28800a20},
+       {0x0000a5b0, 0x3e82222c, 0x3e82222c, 0x2c800e20, 0x2c800e20},
+       {0x0000a5b4, 0x4282242a, 0x4282242a, 0x30800e22, 0x30800e22},
+       {0x0000a5b8, 0x4782244a, 0x4782244a, 0x34800e24, 0x34800e24},
+       {0x0000a5bc, 0x4b82244c, 0x4b82244c, 0x38801640, 0x38801640},
+       {0x0000a5c0, 0x4e82246c, 0x4e82246c, 0x3c801660, 0x3c801660},
+       {0x0000a5c4, 0x5382266c, 0x5382266c, 0x3f801861, 0x3f801861},
+       {0x0000a5c8, 0x5782286c, 0x5782286c, 0x43801a81, 0x43801a81},
+       {0x0000a5cc, 0x5c84286b, 0x5c84286b, 0x47801a83, 0x47801a83},
+       {0x0000a5d0, 0x61842a6c, 0x61842a6c, 0x4a801c84, 0x4a801c84},
+       {0x0000a5d4, 0x66862a6c, 0x66862a6c, 0x4e801ce3, 0x4e801ce3},
+       {0x0000a5d8, 0x6b862e6c, 0x6b862e6c, 0x52801ce5, 0x52801ce5},
+       {0x0000a5dc, 0x7086308c, 0x7086308c, 0x56801ce9, 0x56801ce9},
+       {0x0000a5e0, 0x738a308a, 0x738a308a, 0x5a801ceb, 0x5a801ceb},
+       {0x0000a5e4, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
+       {0x0000a5e8, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
+       {0x0000a5ec, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
+       {0x0000a5f0, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
+       {0x0000a5f4, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
+       {0x0000a5f8, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
+       {0x0000a5fc, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
+       {0x00016044, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
+       {0x00016048, 0x64001a61, 0x64001a61, 0x64001a61, 0x64001a61},
+       {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
+       {0x00016444, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
+       {0x00016448, 0x64001a61, 0x64001a61, 0x64001a61, 0x64001a61},
+       {0x00016468, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
+       {0x00016844, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
+       {0x00016848, 0x64001a61, 0x64001a61, 0x64001a61, 0x64001a61},
+       {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
+};
+
+static const u32 ar9300_2p0_mac_core[][2] = {
+       /* Addr      allmodes  */
+       {0x00000008, 0x00000000},
+       {0x00000030, 0x00020085},
+       {0x00000034, 0x00000005},
+       {0x00000040, 0x00000000},
+       {0x00000044, 0x00000000},
+       {0x00000048, 0x00000008},
+       {0x0000004c, 0x00000010},
+       {0x00000050, 0x00000000},
+       {0x00001040, 0x002ffc0f},
+       {0x00001044, 0x002ffc0f},
+       {0x00001048, 0x002ffc0f},
+       {0x0000104c, 0x002ffc0f},
+       {0x00001050, 0x002ffc0f},
+       {0x00001054, 0x002ffc0f},
+       {0x00001058, 0x002ffc0f},
+       {0x0000105c, 0x002ffc0f},
+       {0x00001060, 0x002ffc0f},
+       {0x00001064, 0x002ffc0f},
+       {0x000010f0, 0x00000100},
+       {0x00001270, 0x00000000},
+       {0x000012b0, 0x00000000},
+       {0x000012f0, 0x00000000},
+       {0x0000143c, 0x00000000},
+       {0x0000147c, 0x00000000},
+       {0x00008000, 0x00000000},
+       {0x00008004, 0x00000000},
+       {0x00008008, 0x00000000},
+       {0x0000800c, 0x00000000},
+       {0x00008018, 0x00000000},
+       {0x00008020, 0x00000000},
+       {0x00008038, 0x00000000},
+       {0x0000803c, 0x00000000},
+       {0x00008040, 0x00000000},
+       {0x00008044, 0x00000000},
+       {0x00008048, 0x00000000},
+       {0x0000804c, 0xffffffff},
+       {0x00008054, 0x00000000},
+       {0x00008058, 0x00000000},
+       {0x0000805c, 0x000fc78f},
+       {0x00008060, 0x0000000f},
+       {0x00008064, 0x00000000},
+       {0x00008070, 0x00000310},
+       {0x00008074, 0x00000020},
+       {0x00008078, 0x00000000},
+       {0x0000809c, 0x0000000f},
+       {0x000080a0, 0x00000000},
+       {0x000080a4, 0x02ff0000},
+       {0x000080a8, 0x0e070605},
+       {0x000080ac, 0x0000000d},
+       {0x000080b0, 0x00000000},
+       {0x000080b4, 0x00000000},
+       {0x000080b8, 0x00000000},
+       {0x000080bc, 0x00000000},
+       {0x000080c0, 0x2a800000},
+       {0x000080c4, 0x06900168},
+       {0x000080c8, 0x13881c20},
+       {0x000080cc, 0x01f40000},
+       {0x000080d0, 0x00252500},
+       {0x000080d4, 0x00a00000},
+       {0x000080d8, 0x00400000},
+       {0x000080dc, 0x00000000},
+       {0x000080e0, 0xffffffff},
+       {0x000080e4, 0x0000ffff},
+       {0x000080e8, 0x3f3f3f3f},
+       {0x000080ec, 0x00000000},
+       {0x000080f0, 0x00000000},
+       {0x000080f4, 0x00000000},
+       {0x000080fc, 0x00020000},
+       {0x00008100, 0x00000000},
+       {0x00008108, 0x00000052},
+       {0x0000810c, 0x00000000},
+       {0x00008110, 0x00000000},
+       {0x00008114, 0x000007ff},
+       {0x00008118, 0x000000aa},
+       {0x0000811c, 0x00003210},
+       {0x00008124, 0x00000000},
+       {0x00008128, 0x00000000},
+       {0x0000812c, 0x00000000},
+       {0x00008130, 0x00000000},
+       {0x00008134, 0x00000000},
+       {0x00008138, 0x00000000},
+       {0x0000813c, 0x0000ffff},
+       {0x00008144, 0xffffffff},
+       {0x00008168, 0x00000000},
+       {0x0000816c, 0x00000000},
+       {0x00008170, 0x18486200},
+       {0x00008174, 0x33332210},
+       {0x00008178, 0x00000000},
+       {0x0000817c, 0x00020000},
+       {0x000081c0, 0x00000000},
+       {0x000081c4, 0x33332210},
+       {0x000081c8, 0x00000000},
+       {0x000081cc, 0x00000000},
+       {0x000081d4, 0x00000000},
+       {0x000081ec, 0x00000000},
+       {0x000081f0, 0x00000000},
+       {0x000081f4, 0x00000000},
+       {0x000081f8, 0x00000000},
+       {0x000081fc, 0x00000000},
+       {0x00008240, 0x00100000},
+       {0x00008244, 0x0010f424},
+       {0x00008248, 0x00000800},
+       {0x0000824c, 0x0001e848},
+       {0x00008250, 0x00000000},
+       {0x00008254, 0x00000000},
+       {0x00008258, 0x00000000},
+       {0x0000825c, 0x40000000},
+       {0x00008260, 0x00080922},
+       {0x00008264, 0x98a00010},
+       {0x00008268, 0xffffffff},
+       {0x0000826c, 0x0000ffff},
+       {0x00008270, 0x00000000},
+       {0x00008274, 0x40000000},
+       {0x00008278, 0x003e4180},
+       {0x0000827c, 0x00000004},
+       {0x00008284, 0x0000002c},
+       {0x00008288, 0x0000002c},
+       {0x0000828c, 0x000000ff},
+       {0x00008294, 0x00000000},
+       {0x00008298, 0x00000000},
+       {0x0000829c, 0x00000000},
+       {0x00008300, 0x00000140},
+       {0x00008314, 0x00000000},
+       {0x0000831c, 0x0000010d},
+       {0x00008328, 0x00000000},
+       {0x0000832c, 0x00000007},
+       {0x00008330, 0x00000302},
+       {0x00008334, 0x00000700},
+       {0x00008338, 0x00ff0000},
+       {0x0000833c, 0x02400000},
+       {0x00008340, 0x000107ff},
+       {0x00008344, 0xaa48105b},
+       {0x00008348, 0x008f0000},
+       {0x0000835c, 0x00000000},
+       {0x00008360, 0xffffffff},
+       {0x00008364, 0xffffffff},
+       {0x00008368, 0x00000000},
+       {0x00008370, 0x00000000},
+       {0x00008374, 0x000000ff},
+       {0x00008378, 0x00000000},
+       {0x0000837c, 0x00000000},
+       {0x00008380, 0xffffffff},
+       {0x00008384, 0xffffffff},
+       {0x00008390, 0xffffffff},
+       {0x00008394, 0xffffffff},
+       {0x00008398, 0x00000000},
+       {0x0000839c, 0x00000000},
+       {0x000083a0, 0x00000000},
+       {0x000083a4, 0x0000fa14},
+       {0x000083a8, 0x000f0c00},
+       {0x000083ac, 0x33332210},
+       {0x000083b0, 0x33332210},
+       {0x000083b4, 0x33332210},
+       {0x000083b8, 0x33332210},
+       {0x000083bc, 0x00000000},
+       {0x000083c0, 0x00000000},
+       {0x000083c4, 0x00000000},
+       {0x000083c8, 0x00000000},
+       {0x000083cc, 0x00000200},
+       {0x000083d0, 0x000301ff},
+};
+
+static const u32 ar9300Common_wo_xlna_rx_gain_table_2p0[][2] = {
+       /* Addr      allmodes  */
+       {0x0000a000, 0x00010000},
+       {0x0000a004, 0x00030002},
+       {0x0000a008, 0x00050004},
+       {0x0000a00c, 0x00810080},
+       {0x0000a010, 0x01800082},
+       {0x0000a014, 0x01820181},
+       {0x0000a018, 0x01840183},
+       {0x0000a01c, 0x01880185},
+       {0x0000a020, 0x018a0189},
+       {0x0000a024, 0x02850284},
+       {0x0000a028, 0x02890288},
+       {0x0000a02c, 0x03850384},
+       {0x0000a030, 0x03890388},
+       {0x0000a034, 0x038b038a},
+       {0x0000a038, 0x038d038c},
+       {0x0000a03c, 0x03910390},
+       {0x0000a040, 0x03930392},
+       {0x0000a044, 0x03950394},
+       {0x0000a048, 0x00000396},
+       {0x0000a04c, 0x00000000},
+       {0x0000a050, 0x00000000},
+       {0x0000a054, 0x00000000},
+       {0x0000a058, 0x00000000},
+       {0x0000a05c, 0x00000000},
+       {0x0000a060, 0x00000000},
+       {0x0000a064, 0x00000000},
+       {0x0000a068, 0x00000000},
+       {0x0000a06c, 0x00000000},
+       {0x0000a070, 0x00000000},
+       {0x0000a074, 0x00000000},
+       {0x0000a078, 0x00000000},
+       {0x0000a07c, 0x00000000},
+       {0x0000a080, 0x28282828},
+       {0x0000a084, 0x28282828},
+       {0x0000a088, 0x28282828},
+       {0x0000a08c, 0x28282828},
+       {0x0000a090, 0x28282828},
+       {0x0000a094, 0x21212128},
+       {0x0000a098, 0x171c1c1c},
+       {0x0000a09c, 0x02020212},
+       {0x0000a0a0, 0x00000202},
+       {0x0000a0a4, 0x00000000},
+       {0x0000a0a8, 0x00000000},
+       {0x0000a0ac, 0x00000000},
+       {0x0000a0b0, 0x00000000},
+       {0x0000a0b4, 0x00000000},
+       {0x0000a0b8, 0x00000000},
+       {0x0000a0bc, 0x00000000},
+       {0x0000a0c0, 0x001f0000},
+       {0x0000a0c4, 0x011f0100},
+       {0x0000a0c8, 0x011d011e},
+       {0x0000a0cc, 0x011b011c},
+       {0x0000a0d0, 0x02030204},
+       {0x0000a0d4, 0x02010202},
+       {0x0000a0d8, 0x021f0200},
+       {0x0000a0dc, 0x021d021e},
+       {0x0000a0e0, 0x03010302},
+       {0x0000a0e4, 0x031f0300},
+       {0x0000a0e8, 0x0402031e},
+       {0x0000a0ec, 0x04000401},
+       {0x0000a0f0, 0x041e041f},
+       {0x0000a0f4, 0x05010502},
+       {0x0000a0f8, 0x051f0500},
+       {0x0000a0fc, 0x0602051e},
+       {0x0000a100, 0x06000601},
+       {0x0000a104, 0x061e061f},
+       {0x0000a108, 0x0703061d},
+       {0x0000a10c, 0x07010702},
+       {0x0000a110, 0x00000700},
+       {0x0000a114, 0x00000000},
+       {0x0000a118, 0x00000000},
+       {0x0000a11c, 0x00000000},
+       {0x0000a120, 0x00000000},
+       {0x0000a124, 0x00000000},
+       {0x0000a128, 0x00000000},
+       {0x0000a12c, 0x00000000},
+       {0x0000a130, 0x00000000},
+       {0x0000a134, 0x00000000},
+       {0x0000a138, 0x00000000},
+       {0x0000a13c, 0x00000000},
+       {0x0000a140, 0x001f0000},
+       {0x0000a144, 0x011f0100},
+       {0x0000a148, 0x011d011e},
+       {0x0000a14c, 0x011b011c},
+       {0x0000a150, 0x02030204},
+       {0x0000a154, 0x02010202},
+       {0x0000a158, 0x021f0200},
+       {0x0000a15c, 0x021d021e},
+       {0x0000a160, 0x03010302},
+       {0x0000a164, 0x031f0300},
+       {0x0000a168, 0x0402031e},
+       {0x0000a16c, 0x04000401},
+       {0x0000a170, 0x041e041f},
+       {0x0000a174, 0x05010502},
+       {0x0000a178, 0x051f0500},
+       {0x0000a17c, 0x0602051e},
+       {0x0000a180, 0x06000601},
+       {0x0000a184, 0x061e061f},
+       {0x0000a188, 0x0703061d},
+       {0x0000a18c, 0x07010702},
+       {0x0000a190, 0x00000700},
+       {0x0000a194, 0x00000000},
+       {0x0000a198, 0x00000000},
+       {0x0000a19c, 0x00000000},
+       {0x0000a1a0, 0x00000000},
+       {0x0000a1a4, 0x00000000},
+       {0x0000a1a8, 0x00000000},
+       {0x0000a1ac, 0x00000000},
+       {0x0000a1b0, 0x00000000},
+       {0x0000a1b4, 0x00000000},
+       {0x0000a1b8, 0x00000000},
+       {0x0000a1bc, 0x00000000},
+       {0x0000a1c0, 0x00000000},
+       {0x0000a1c4, 0x00000000},
+       {0x0000a1c8, 0x00000000},
+       {0x0000a1cc, 0x00000000},
+       {0x0000a1d0, 0x00000000},
+       {0x0000a1d4, 0x00000000},
+       {0x0000a1d8, 0x00000000},
+       {0x0000a1dc, 0x00000000},
+       {0x0000a1e0, 0x00000000},
+       {0x0000a1e4, 0x00000000},
+       {0x0000a1e8, 0x00000000},
+       {0x0000a1ec, 0x00000000},
+       {0x0000a1f0, 0x00000396},
+       {0x0000a1f4, 0x00000396},
+       {0x0000a1f8, 0x00000396},
+       {0x0000a1fc, 0x00000296},
+       {0x0000b000, 0x00010000},
+       {0x0000b004, 0x00030002},
+       {0x0000b008, 0x00050004},
+       {0x0000b00c, 0x00810080},
+       {0x0000b010, 0x00830082},
+       {0x0000b014, 0x01810180},
+       {0x0000b018, 0x01830182},
+       {0x0000b01c, 0x01850184},
+       {0x0000b020, 0x02810280},
+       {0x0000b024, 0x02830282},
+       {0x0000b028, 0x02850284},
+       {0x0000b02c, 0x02890288},
+       {0x0000b030, 0x028b028a},
+       {0x0000b034, 0x0388028c},
+       {0x0000b038, 0x038a0389},
+       {0x0000b03c, 0x038c038b},
+       {0x0000b040, 0x0390038d},
+       {0x0000b044, 0x03920391},
+       {0x0000b048, 0x03940393},
+       {0x0000b04c, 0x03960395},
+       {0x0000b050, 0x00000000},
+       {0x0000b054, 0x00000000},
+       {0x0000b058, 0x00000000},
+       {0x0000b05c, 0x00000000},
+       {0x0000b060, 0x00000000},
+       {0x0000b064, 0x00000000},
+       {0x0000b068, 0x00000000},
+       {0x0000b06c, 0x00000000},
+       {0x0000b070, 0x00000000},
+       {0x0000b074, 0x00000000},
+       {0x0000b078, 0x00000000},
+       {0x0000b07c, 0x00000000},
+       {0x0000b080, 0x32323232},
+       {0x0000b084, 0x2f2f3232},
+       {0x0000b088, 0x23282a2d},
+       {0x0000b08c, 0x1c1e2123},
+       {0x0000b090, 0x14171919},
+       {0x0000b094, 0x0e0e1214},
+       {0x0000b098, 0x03050707},
+       {0x0000b09c, 0x00030303},
+       {0x0000b0a0, 0x00000000},
+       {0x0000b0a4, 0x00000000},
+       {0x0000b0a8, 0x00000000},
+       {0x0000b0ac, 0x00000000},
+       {0x0000b0b0, 0x00000000},
+       {0x0000b0b4, 0x00000000},
+       {0x0000b0b8, 0x00000000},
+       {0x0000b0bc, 0x00000000},
+       {0x0000b0c0, 0x003f0020},
+       {0x0000b0c4, 0x00400041},
+       {0x0000b0c8, 0x0140005f},
+       {0x0000b0cc, 0x0160015f},
+       {0x0000b0d0, 0x017e017f},
+       {0x0000b0d4, 0x02410242},
+       {0x0000b0d8, 0x025f0240},
+       {0x0000b0dc, 0x027f0260},
+       {0x0000b0e0, 0x0341027e},
+       {0x0000b0e4, 0x035f0340},
+       {0x0000b0e8, 0x037f0360},
+       {0x0000b0ec, 0x04400441},
+       {0x0000b0f0, 0x0460045f},
+       {0x0000b0f4, 0x0541047f},
+       {0x0000b0f8, 0x055f0540},
+       {0x0000b0fc, 0x057f0560},
+       {0x0000b100, 0x06400641},
+       {0x0000b104, 0x0660065f},
+       {0x0000b108, 0x067e067f},
+       {0x0000b10c, 0x07410742},
+       {0x0000b110, 0x075f0740},
+       {0x0000b114, 0x077f0760},
+       {0x0000b118, 0x07800781},
+       {0x0000b11c, 0x07a0079f},
+       {0x0000b120, 0x07c107bf},
+       {0x0000b124, 0x000007c0},
+       {0x0000b128, 0x00000000},
+       {0x0000b12c, 0x00000000},
+       {0x0000b130, 0x00000000},
+       {0x0000b134, 0x00000000},
+       {0x0000b138, 0x00000000},
+       {0x0000b13c, 0x00000000},
+       {0x0000b140, 0x003f0020},
+       {0x0000b144, 0x00400041},
+       {0x0000b148, 0x0140005f},
+       {0x0000b14c, 0x0160015f},
+       {0x0000b150, 0x017e017f},
+       {0x0000b154, 0x02410242},
+       {0x0000b158, 0x025f0240},
+       {0x0000b15c, 0x027f0260},
+       {0x0000b160, 0x0341027e},
+       {0x0000b164, 0x035f0340},
+       {0x0000b168, 0x037f0360},
+       {0x0000b16c, 0x04400441},
+       {0x0000b170, 0x0460045f},
+       {0x0000b174, 0x0541047f},
+       {0x0000b178, 0x055f0540},
+       {0x0000b17c, 0x057f0560},
+       {0x0000b180, 0x06400641},
+       {0x0000b184, 0x0660065f},
+       {0x0000b188, 0x067e067f},
+       {0x0000b18c, 0x07410742},
+       {0x0000b190, 0x075f0740},
+       {0x0000b194, 0x077f0760},
+       {0x0000b198, 0x07800781},
+       {0x0000b19c, 0x07a0079f},
+       {0x0000b1a0, 0x07c107bf},
+       {0x0000b1a4, 0x000007c0},
+       {0x0000b1a8, 0x00000000},
+       {0x0000b1ac, 0x00000000},
+       {0x0000b1b0, 0x00000000},
+       {0x0000b1b4, 0x00000000},
+       {0x0000b1b8, 0x00000000},
+       {0x0000b1bc, 0x00000000},
+       {0x0000b1c0, 0x00000000},
+       {0x0000b1c4, 0x00000000},
+       {0x0000b1c8, 0x00000000},
+       {0x0000b1cc, 0x00000000},
+       {0x0000b1d0, 0x00000000},
+       {0x0000b1d4, 0x00000000},
+       {0x0000b1d8, 0x00000000},
+       {0x0000b1dc, 0x00000000},
+       {0x0000b1e0, 0x00000000},
+       {0x0000b1e4, 0x00000000},
+       {0x0000b1e8, 0x00000000},
+       {0x0000b1ec, 0x00000000},
+       {0x0000b1f0, 0x00000396},
+       {0x0000b1f4, 0x00000396},
+       {0x0000b1f8, 0x00000396},
+       {0x0000b1fc, 0x00000196},
+};
+
+static const u32 ar9300_2p0_soc_preamble[][2] = {
+       /* Addr      allmodes  */
+       {0x000040a4, 0x00a0c1c9},
+       {0x00007008, 0x00000000},
+       {0x00007020, 0x00000000},
+       {0x00007034, 0x00000002},
+       {0x00007038, 0x000004c2},
+};
+
+/*
+ * PCIE-PHY programming array, to be used prior to entering
+ * full sleep (holding RTC in reset, PLL is ON in L1 mode)
+ */
+static const u32 ar9300PciePhy_pll_on_clkreq_disable_L1_2p0[][2] = {
+       {0x00004040, 0x08212e5e},
+       {0x00004040, 0x0008003b},
+       {0x00004044, 0x00000000},
+};
+
+/*
+ * PCIE-PHY programming array, to be used when not in
+ * full sleep (holding RTC in reset)
+ */
+static const u32 ar9300PciePhy_clkreq_enable_L1_2p0[][2] = {
+       {0x00004040, 0x08253e5e},
+       {0x00004040, 0x0008003b},
+       {0x00004044, 0x00000000},
+};
+
+/*
+ * PCIE-PHY programming array, to be used prior to entering
+ * full sleep (holding RTC in reset)
+ */
+static const u32 ar9300PciePhy_clkreq_disable_L1_2p0[][2] = {
+       {0x00004040, 0x08213e5e},
+       {0x00004040, 0x0008003b},
+       {0x00004044, 0x00000000},
+};
+
+#endif /* INITVALS_9003_H */
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.c b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
new file mode 100644 (file)
index 0000000..7d111fb
--- /dev/null
@@ -0,0 +1,611 @@
+/*
+ * Copyright (c) 2010 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT 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 "hw.h"
+#include "ar9003_mac.h"
+
+static void ar9003_hw_rx_enable(struct ath_hw *hw)
+{
+       REG_WRITE(hw, AR_CR, 0);
+}
+
+static u16 ar9003_calc_ptr_chksum(struct ar9003_txc *ads)
+{
+       int checksum;
+
+       checksum = ads->info + ads->link
+               + ads->data0 + ads->ctl3
+               + ads->data1 + ads->ctl5
+               + ads->data2 + ads->ctl7
+               + ads->data3 + ads->ctl9;
+
+       return ((checksum & 0xffff) + (checksum >> 16)) & AR_TxPtrChkSum;
+}
+
+static void ar9003_hw_set_desc_link(void *ds, u32 ds_link)
+{
+       struct ar9003_txc *ads = ds;
+
+       ads->link = ds_link;
+       ads->ctl10 &= ~AR_TxPtrChkSum;
+       ads->ctl10 |= ar9003_calc_ptr_chksum(ads);
+}
+
+static void ar9003_hw_get_desc_link(void *ds, u32 **ds_link)
+{
+       struct ar9003_txc *ads = ds;
+
+       *ds_link = &ads->link;
+}
+
+static bool ar9003_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked)
+{
+       u32 isr = 0;
+       u32 mask2 = 0;
+       struct ath9k_hw_capabilities *pCap = &ah->caps;
+       u32 sync_cause = 0;
+       struct ath_common *common = ath9k_hw_common(ah);
+
+       if (REG_READ(ah, AR_INTR_ASYNC_CAUSE) & AR_INTR_MAC_IRQ) {
+               if ((REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M)
+                               == AR_RTC_STATUS_ON)
+                       isr = REG_READ(ah, AR_ISR);
+       }
+
+       sync_cause = REG_READ(ah, AR_INTR_SYNC_CAUSE) & AR_INTR_SYNC_DEFAULT;
+
+       *masked = 0;
+
+       if (!isr && !sync_cause)
+               return false;
+
+       if (isr) {
+               if (isr & AR_ISR_BCNMISC) {
+                       u32 isr2;
+                       isr2 = REG_READ(ah, AR_ISR_S2);
+
+                       mask2 |= ((isr2 & AR_ISR_S2_TIM) >>
+                                 MAP_ISR_S2_TIM);
+                       mask2 |= ((isr2 & AR_ISR_S2_DTIM) >>
+                                 MAP_ISR_S2_DTIM);
+                       mask2 |= ((isr2 & AR_ISR_S2_DTIMSYNC) >>
+                                 MAP_ISR_S2_DTIMSYNC);
+                       mask2 |= ((isr2 & AR_ISR_S2_CABEND) >>
+                                 MAP_ISR_S2_CABEND);
+                       mask2 |= ((isr2 & AR_ISR_S2_GTT) <<
+                                 MAP_ISR_S2_GTT);
+                       mask2 |= ((isr2 & AR_ISR_S2_CST) <<
+                                 MAP_ISR_S2_CST);
+                       mask2 |= ((isr2 & AR_ISR_S2_TSFOOR) >>
+                                 MAP_ISR_S2_TSFOOR);
+
+                       if (!(pCap->hw_caps & ATH9K_HW_CAP_RAC_SUPPORTED)) {
+                               REG_WRITE(ah, AR_ISR_S2, isr2);
+                               isr &= ~AR_ISR_BCNMISC;
+                       }
+               }
+
+               if ((pCap->hw_caps & ATH9K_HW_CAP_RAC_SUPPORTED))
+                       isr = REG_READ(ah, AR_ISR_RAC);
+
+               if (isr == 0xffffffff) {
+                       *masked = 0;
+                       return false;
+               }
+
+               *masked = isr & ATH9K_INT_COMMON;
+
+               if (ah->config.rx_intr_mitigation)
+                       if (isr & (AR_ISR_RXMINTR | AR_ISR_RXINTM))
+                               *masked |= ATH9K_INT_RXLP;
+
+               if (ah->config.tx_intr_mitigation)
+                       if (isr & (AR_ISR_TXMINTR | AR_ISR_TXINTM))
+                               *masked |= ATH9K_INT_TX;
+
+               if (isr & (AR_ISR_LP_RXOK | AR_ISR_RXERR))
+                       *masked |= ATH9K_INT_RXLP;
+
+               if (isr & AR_ISR_HP_RXOK)
+                       *masked |= ATH9K_INT_RXHP;
+
+               if (isr & (AR_ISR_TXOK | AR_ISR_TXERR | AR_ISR_TXEOL)) {
+                       *masked |= ATH9K_INT_TX;
+
+                       if (!(pCap->hw_caps & ATH9K_HW_CAP_RAC_SUPPORTED)) {
+                               u32 s0, s1;
+                               s0 = REG_READ(ah, AR_ISR_S0);
+                               REG_WRITE(ah, AR_ISR_S0, s0);
+                               s1 = REG_READ(ah, AR_ISR_S1);
+                               REG_WRITE(ah, AR_ISR_S1, s1);
+
+                               isr &= ~(AR_ISR_TXOK | AR_ISR_TXERR |
+                                        AR_ISR_TXEOL);
+                       }
+               }
+
+               if (isr & AR_ISR_GENTMR) {
+                       u32 s5;
+
+                       if (pCap->hw_caps & ATH9K_HW_CAP_RAC_SUPPORTED)
+                               s5 = REG_READ(ah, AR_ISR_S5_S);
+                       else
+                               s5 = REG_READ(ah, AR_ISR_S5);
+
+                       ah->intr_gen_timer_trigger =
+                               MS(s5, AR_ISR_S5_GENTIMER_TRIG);
+
+                       ah->intr_gen_timer_thresh =
+                               MS(s5, AR_ISR_S5_GENTIMER_THRESH);
+
+                       if (ah->intr_gen_timer_trigger)
+                               *masked |= ATH9K_INT_GENTIMER;
+
+                       if (!(pCap->hw_caps & ATH9K_HW_CAP_RAC_SUPPORTED)) {
+                               REG_WRITE(ah, AR_ISR_S5, s5);
+                               isr &= ~AR_ISR_GENTMR;
+                       }
+
+               }
+
+               *masked |= mask2;
+
+               if (!(pCap->hw_caps & ATH9K_HW_CAP_RAC_SUPPORTED)) {
+                       REG_WRITE(ah, AR_ISR, isr);
+
+                       (void) REG_READ(ah, AR_ISR);
+               }
+       }
+
+       if (sync_cause) {
+               if (sync_cause & AR_INTR_SYNC_RADM_CPL_TIMEOUT) {
+                       REG_WRITE(ah, AR_RC, AR_RC_HOSTIF);
+                       REG_WRITE(ah, AR_RC, 0);
+                       *masked |= ATH9K_INT_FATAL;
+               }
+
+               if (sync_cause & AR_INTR_SYNC_LOCAL_TIMEOUT)
+                       ath_print(common, ATH_DBG_INTERRUPT,
+                                 "AR_INTR_SYNC_LOCAL_TIMEOUT\n");
+
+                       REG_WRITE(ah, AR_INTR_SYNC_CAUSE_CLR, sync_cause);
+               (void) REG_READ(ah, AR_INTR_SYNC_CAUSE_CLR);
+
+       }
+       return true;
+}
+
+static void ar9003_hw_fill_txdesc(struct ath_hw *ah, void *ds, u32 seglen,
+                                 bool is_firstseg, bool is_lastseg,
+                                 const void *ds0, dma_addr_t buf_addr,
+                                 unsigned int qcu)
+{
+       struct ar9003_txc *ads = (struct ar9003_txc *) ds;
+       unsigned int descid = 0;
+
+       ads->info = (ATHEROS_VENDOR_ID << AR_DescId_S) |
+                                    (1 << AR_TxRxDesc_S) |
+                                    (1 << AR_CtrlStat_S) |
+                                    (qcu << AR_TxQcuNum_S) | 0x17;
+
+       ads->data0 = buf_addr;
+       ads->data1 = 0;
+       ads->data2 = 0;
+       ads->data3 = 0;
+
+       ads->ctl3 = (seglen << AR_BufLen_S);
+       ads->ctl3 &= AR_BufLen;
+
+       /* Fill in pointer checksum and descriptor id */
+       ads->ctl10 = ar9003_calc_ptr_chksum(ads);
+       ads->ctl10 |= (descid << AR_TxDescId_S);
+
+       if (is_firstseg) {
+               ads->ctl12 |= (is_lastseg ? 0 : AR_TxMore);
+       } else if (is_lastseg) {
+               ads->ctl11 = 0;
+               ads->ctl12 = 0;
+               ads->ctl13 = AR9003TXC_CONST(ds0)->ctl13;
+               ads->ctl14 = AR9003TXC_CONST(ds0)->ctl14;
+       } else {
+               /* XXX Intermediate descriptor in a multi-descriptor frame.*/
+               ads->ctl11 = 0;
+               ads->ctl12 = AR_TxMore;
+               ads->ctl13 = 0;
+               ads->ctl14 = 0;
+       }
+}
+
+static int ar9003_hw_proc_txdesc(struct ath_hw *ah, void *ds,
+                                struct ath_tx_status *ts)
+{
+       struct ar9003_txs *ads;
+
+       ads = &ah->ts_ring[ah->ts_tail];
+
+       if ((ads->status8 & AR_TxDone) == 0)
+               return -EINPROGRESS;
+
+       ah->ts_tail = (ah->ts_tail + 1) % ah->ts_size;
+
+       if ((MS(ads->ds_info, AR_DescId) != ATHEROS_VENDOR_ID) ||
+           (MS(ads->ds_info, AR_TxRxDesc) != 1)) {
+               ath_print(ath9k_hw_common(ah), ATH_DBG_XMIT,
+                         "Tx Descriptor error %x\n", ads->ds_info);
+               memset(ads, 0, sizeof(*ads));
+               return -EIO;
+       }
+
+       ts->qid = MS(ads->ds_info, AR_TxQcuNum);
+       ts->desc_id = MS(ads->status1, AR_TxDescId);
+       ts->ts_seqnum = MS(ads->status8, AR_SeqNum);
+       ts->ts_tstamp = ads->status4;
+       ts->ts_status = 0;
+       ts->ts_flags  = 0;
+
+       if (ads->status3 & AR_ExcessiveRetries)
+               ts->ts_status |= ATH9K_TXERR_XRETRY;
+       if (ads->status3 & AR_Filtered)
+               ts->ts_status |= ATH9K_TXERR_FILT;
+       if (ads->status3 & AR_FIFOUnderrun) {
+               ts->ts_status |= ATH9K_TXERR_FIFO;
+               ath9k_hw_updatetxtriglevel(ah, true);
+       }
+       if (ads->status8 & AR_TxOpExceeded)
+               ts->ts_status |= ATH9K_TXERR_XTXOP;
+       if (ads->status3 & AR_TxTimerExpired)
+               ts->ts_status |= ATH9K_TXERR_TIMER_EXPIRED;
+
+       if (ads->status3 & AR_DescCfgErr)
+               ts->ts_flags |= ATH9K_TX_DESC_CFG_ERR;
+       if (ads->status3 & AR_TxDataUnderrun) {
+               ts->ts_flags |= ATH9K_TX_DATA_UNDERRUN;
+               ath9k_hw_updatetxtriglevel(ah, true);
+       }
+       if (ads->status3 & AR_TxDelimUnderrun) {
+               ts->ts_flags |= ATH9K_TX_DELIM_UNDERRUN;
+               ath9k_hw_updatetxtriglevel(ah, true);
+       }
+       if (ads->status2 & AR_TxBaStatus) {
+               ts->ts_flags |= ATH9K_TX_BA;
+               ts->ba_low = ads->status5;
+               ts->ba_high = ads->status6;
+       }
+
+       ts->ts_rateindex = MS(ads->status8, AR_FinalTxIdx);
+
+       ts->ts_rssi = MS(ads->status7, AR_TxRSSICombined);
+       ts->ts_rssi_ctl0 = MS(ads->status2, AR_TxRSSIAnt00);
+       ts->ts_rssi_ctl1 = MS(ads->status2, AR_TxRSSIAnt01);
+       ts->ts_rssi_ctl2 = MS(ads->status2, AR_TxRSSIAnt02);
+       ts->ts_rssi_ext0 = MS(ads->status7, AR_TxRSSIAnt10);
+       ts->ts_rssi_ext1 = MS(ads->status7, AR_TxRSSIAnt11);
+       ts->ts_rssi_ext2 = MS(ads->status7, AR_TxRSSIAnt12);
+       ts->ts_shortretry = MS(ads->status3, AR_RTSFailCnt);
+       ts->ts_longretry = MS(ads->status3, AR_DataFailCnt);
+       ts->ts_virtcol = MS(ads->status3, AR_VirtRetryCnt);
+       ts->ts_antenna = 0;
+
+       ts->tid = MS(ads->status8, AR_TxTid);
+
+       memset(ads, 0, sizeof(*ads));
+
+       return 0;
+}
+
+static void ar9003_hw_set11n_txdesc(struct ath_hw *ah, void *ds,
+               u32 pktlen, enum ath9k_pkt_type type, u32 txpower,
+               u32 keyIx, enum ath9k_key_type keyType, u32 flags)
+{
+       struct ar9003_txc *ads = (struct ar9003_txc *) ds;
+
+       txpower += ah->txpower_indexoffset;
+       if (txpower > 63)
+               txpower = 63;
+
+       ads->ctl11 = (pktlen & AR_FrameLen)
+               | (flags & ATH9K_TXDESC_VMF ? AR_VirtMoreFrag : 0)
+               | SM(txpower, AR_XmitPower)
+               | (flags & ATH9K_TXDESC_VEOL ? AR_VEOL : 0)
+               | (flags & ATH9K_TXDESC_CLRDMASK ? AR_ClrDestMask : 0)
+               | (keyIx != ATH9K_TXKEYIX_INVALID ? AR_DestIdxValid : 0)
+               | (flags & ATH9K_TXDESC_LOWRXCHAIN ? AR_LowRxChain : 0);
+
+       ads->ctl12 =
+               (keyIx != ATH9K_TXKEYIX_INVALID ? SM(keyIx, AR_DestIdx) : 0)
+               | SM(type, AR_FrameType)
+               | (flags & ATH9K_TXDESC_NOACK ? AR_NoAck : 0)
+               | (flags & ATH9K_TXDESC_EXT_ONLY ? AR_ExtOnly : 0)
+               | (flags & ATH9K_TXDESC_EXT_AND_CTL ? AR_ExtAndCtl : 0);
+
+       ads->ctl17 = SM(keyType, AR_EncrType) |
+                    (flags & ATH9K_TXDESC_LDPC ? AR_LDPC : 0);
+       ads->ctl18 = 0;
+       ads->ctl19 = AR_Not_Sounding;
+
+       ads->ctl20 = 0;
+       ads->ctl21 = 0;
+       ads->ctl22 = 0;
+}
+
+static void ar9003_hw_set11n_ratescenario(struct ath_hw *ah, void *ds,
+                                         void *lastds,
+                                         u32 durUpdateEn, u32 rtsctsRate,
+                                         u32 rtsctsDuration,
+                                         struct ath9k_11n_rate_series series[],
+                                         u32 nseries, u32 flags)
+{
+       struct ar9003_txc *ads = (struct ar9003_txc *) ds;
+       struct ar9003_txc *last_ads = (struct ar9003_txc *) lastds;
+       u_int32_t ctl11;
+
+       if (flags & (ATH9K_TXDESC_RTSENA | ATH9K_TXDESC_CTSENA)) {
+               ctl11 = ads->ctl11;
+
+               if (flags & ATH9K_TXDESC_RTSENA) {
+                       ctl11 &= ~AR_CTSEnable;
+                       ctl11 |= AR_RTSEnable;
+               } else {
+                       ctl11 &= ~AR_RTSEnable;
+                       ctl11 |= AR_CTSEnable;
+               }
+
+               ads->ctl11 = ctl11;
+       } else {
+               ads->ctl11 = (ads->ctl11 & ~(AR_RTSEnable | AR_CTSEnable));
+       }
+
+       ads->ctl13 = set11nTries(series, 0)
+               |  set11nTries(series, 1)
+               |  set11nTries(series, 2)
+               |  set11nTries(series, 3)
+               |  (durUpdateEn ? AR_DurUpdateEna : 0)
+               |  SM(0, AR_BurstDur);
+
+       ads->ctl14 = set11nRate(series, 0)
+               |  set11nRate(series, 1)
+               |  set11nRate(series, 2)
+               |  set11nRate(series, 3);
+
+       ads->ctl15 = set11nPktDurRTSCTS(series, 0)
+               |  set11nPktDurRTSCTS(series, 1);
+
+       ads->ctl16 = set11nPktDurRTSCTS(series, 2)
+               |  set11nPktDurRTSCTS(series, 3);
+
+       ads->ctl18 = set11nRateFlags(series, 0)
+               |  set11nRateFlags(series, 1)
+               |  set11nRateFlags(series, 2)
+               |  set11nRateFlags(series, 3)
+               | SM(rtsctsRate, AR_RTSCTSRate);
+       ads->ctl19 = AR_Not_Sounding;
+
+       last_ads->ctl13 = ads->ctl13;
+       last_ads->ctl14 = ads->ctl14;
+}
+
+static void ar9003_hw_set11n_aggr_first(struct ath_hw *ah, void *ds,
+                                       u32 aggrLen)
+{
+       struct ar9003_txc *ads = (struct ar9003_txc *) ds;
+
+       ads->ctl12 |= (AR_IsAggr | AR_MoreAggr);
+
+       ads->ctl17 &= ~AR_AggrLen;
+       ads->ctl17 |= SM(aggrLen, AR_AggrLen);
+}
+
+static void ar9003_hw_set11n_aggr_middle(struct ath_hw *ah, void *ds,
+                                        u32 numDelims)
+{
+       struct ar9003_txc *ads = (struct ar9003_txc *) ds;
+       unsigned int ctl17;
+
+       ads->ctl12 |= (AR_IsAggr | AR_MoreAggr);
+
+       /*
+        * We use a stack variable to manipulate ctl6 to reduce uncached
+        * read modify, modfiy, write.
+        */
+       ctl17 = ads->ctl17;
+       ctl17 &= ~AR_PadDelim;
+       ctl17 |= SM(numDelims, AR_PadDelim);
+       ads->ctl17 = ctl17;
+}
+
+static void ar9003_hw_set11n_aggr_last(struct ath_hw *ah, void *ds)
+{
+       struct ar9003_txc *ads = (struct ar9003_txc *) ds;
+
+       ads->ctl12 |= AR_IsAggr;
+       ads->ctl12 &= ~AR_MoreAggr;
+       ads->ctl17 &= ~AR_PadDelim;
+}
+
+static void ar9003_hw_clr11n_aggr(struct ath_hw *ah, void *ds)
+{
+       struct ar9003_txc *ads = (struct ar9003_txc *) ds;
+
+       ads->ctl12 &= (~AR_IsAggr & ~AR_MoreAggr);
+}
+
+static void ar9003_hw_set11n_burstduration(struct ath_hw *ah, void *ds,
+                                          u32 burstDuration)
+{
+       struct ar9003_txc *ads = (struct ar9003_txc *) ds;
+
+       ads->ctl13 &= ~AR_BurstDur;
+       ads->ctl13 |= SM(burstDuration, AR_BurstDur);
+
+}
+
+static void ar9003_hw_set11n_virtualmorefrag(struct ath_hw *ah, void *ds,
+                                            u32 vmf)
+{
+       struct ar9003_txc *ads = (struct ar9003_txc *) ds;
+
+       if (vmf)
+               ads->ctl11 |=  AR_VirtMoreFrag;
+       else
+               ads->ctl11 &= ~AR_VirtMoreFrag;
+}
+
+void ar9003_hw_attach_mac_ops(struct ath_hw *hw)
+{
+       struct ath_hw_ops *ops = ath9k_hw_ops(hw);
+
+       ops->rx_enable = ar9003_hw_rx_enable;
+       ops->set_desc_link = ar9003_hw_set_desc_link;
+       ops->get_desc_link = ar9003_hw_get_desc_link;
+       ops->get_isr = ar9003_hw_get_isr;
+       ops->fill_txdesc = ar9003_hw_fill_txdesc;
+       ops->proc_txdesc = ar9003_hw_proc_txdesc;
+       ops->set11n_txdesc = ar9003_hw_set11n_txdesc;
+       ops->set11n_ratescenario = ar9003_hw_set11n_ratescenario;
+       ops->set11n_aggr_first = ar9003_hw_set11n_aggr_first;
+       ops->set11n_aggr_middle = ar9003_hw_set11n_aggr_middle;
+       ops->set11n_aggr_last = ar9003_hw_set11n_aggr_last;
+       ops->clr11n_aggr = ar9003_hw_clr11n_aggr;
+       ops->set11n_burstduration = ar9003_hw_set11n_burstduration;
+       ops->set11n_virtualmorefrag = ar9003_hw_set11n_virtualmorefrag;
+}
+
+void ath9k_hw_set_rx_bufsize(struct ath_hw *ah, u16 buf_size)
+{
+       REG_WRITE(ah, AR_DATABUF_SIZE, buf_size & AR_DATABUF_SIZE_MASK);
+}
+EXPORT_SYMBOL(ath9k_hw_set_rx_bufsize);
+
+void ath9k_hw_addrxbuf_edma(struct ath_hw *ah, u32 rxdp,
+                           enum ath9k_rx_qtype qtype)
+{
+       if (qtype == ATH9K_RX_QUEUE_HP)
+               REG_WRITE(ah, AR_HP_RXDP, rxdp);
+       else
+               REG_WRITE(ah, AR_LP_RXDP, rxdp);
+}
+EXPORT_SYMBOL(ath9k_hw_addrxbuf_edma);
+
+int ath9k_hw_process_rxdesc_edma(struct ath_hw *ah, struct ath_rx_status *rxs,
+                                void *buf_addr)
+{
+       struct ar9003_rxs *rxsp = (struct ar9003_rxs *) buf_addr;
+       unsigned int phyerr;
+
+       /* TODO: byte swap on big endian for ar9300_10 */
+
+       if ((rxsp->status11 & AR_RxDone) == 0)
+               return -EINPROGRESS;
+
+       if (MS(rxsp->ds_info, AR_DescId) != 0x168c)
+               return -EINVAL;
+
+       if ((rxsp->ds_info & (AR_TxRxDesc | AR_CtrlStat)) != 0)
+               return -EINPROGRESS;
+
+       if (!rxs)
+               return 0;
+
+       rxs->rs_status = 0;
+       rxs->rs_flags =  0;
+
+       rxs->rs_datalen = rxsp->status2 & AR_DataLen;
+       rxs->rs_tstamp =  rxsp->status3;
+
+       /* XXX: Keycache */
+       rxs->rs_rssi = MS(rxsp->status5, AR_RxRSSICombined);
+       rxs->rs_rssi_ctl0 = MS(rxsp->status1, AR_RxRSSIAnt00);
+       rxs->rs_rssi_ctl1 = MS(rxsp->status1, AR_RxRSSIAnt01);
+       rxs->rs_rssi_ctl2 = MS(rxsp->status1, AR_RxRSSIAnt02);
+       rxs->rs_rssi_ext0 = MS(rxsp->status5, AR_RxRSSIAnt10);
+       rxs->rs_rssi_ext1 = MS(rxsp->status5, AR_RxRSSIAnt11);
+       rxs->rs_rssi_ext2 = MS(rxsp->status5, AR_RxRSSIAnt12);
+
+       if (rxsp->status11 & AR_RxKeyIdxValid)
+               rxs->rs_keyix = MS(rxsp->status11, AR_KeyIdx);
+       else
+               rxs->rs_keyix = ATH9K_RXKEYIX_INVALID;
+
+       rxs->rs_rate = MS(rxsp->status1, AR_RxRate);
+       rxs->rs_more = (rxsp->status2 & AR_RxMore) ? 1 : 0;
+
+       rxs->rs_isaggr = (rxsp->status11 & AR_RxAggr) ? 1 : 0;
+       rxs->rs_moreaggr = (rxsp->status11 & AR_RxMoreAggr) ? 1 : 0;
+       rxs->rs_antenna = (MS(rxsp->status4, AR_RxAntenna) & 0x7);
+       rxs->rs_flags  = (rxsp->status4 & AR_GI) ? ATH9K_RX_GI : 0;
+       rxs->rs_flags  |= (rxsp->status4 & AR_2040) ? ATH9K_RX_2040 : 0;
+
+       rxs->evm0 = rxsp->status6;
+       rxs->evm1 = rxsp->status7;
+       rxs->evm2 = rxsp->status8;
+       rxs->evm3 = rxsp->status9;
+       rxs->evm4 = (rxsp->status10 & 0xffff);
+
+       if (rxsp->status11 & AR_PreDelimCRCErr)
+               rxs->rs_flags |= ATH9K_RX_DELIM_CRC_PRE;
+
+       if (rxsp->status11 & AR_PostDelimCRCErr)
+               rxs->rs_flags |= ATH9K_RX_DELIM_CRC_POST;
+
+       if (rxsp->status11 & AR_DecryptBusyErr)
+               rxs->rs_flags |= ATH9K_RX_DECRYPT_BUSY;
+
+       if ((rxsp->status11 & AR_RxFrameOK) == 0) {
+               if (rxsp->status11 & AR_CRCErr) {
+                       rxs->rs_status |= ATH9K_RXERR_CRC;
+               } else if (rxsp->status11 & AR_PHYErr) {
+                       rxs->rs_status |= ATH9K_RXERR_PHY;
+                       phyerr = MS(rxsp->status11, AR_PHYErrCode);
+                       rxs->rs_phyerr = phyerr;
+               } else if (rxsp->status11 & AR_DecryptCRCErr) {
+                       rxs->rs_status |= ATH9K_RXERR_DECRYPT;
+               } else if (rxsp->status11 & AR_MichaelErr) {
+                       rxs->rs_status |= ATH9K_RXERR_MIC;
+               }
+       }
+
+       return 0;
+}
+EXPORT_SYMBOL(ath9k_hw_process_rxdesc_edma);
+
+void ath9k_hw_reset_txstatus_ring(struct ath_hw *ah)
+{
+       ah->ts_tail = 0;
+
+       memset((void *) ah->ts_ring, 0,
+               ah->ts_size * sizeof(struct ar9003_txs));
+
+       ath_print(ath9k_hw_common(ah), ATH_DBG_XMIT,
+                 "TS Start 0x%x End 0x%x Virt %p, Size %d\n",
+                  ah->ts_paddr_start, ah->ts_paddr_end,
+                  ah->ts_ring, ah->ts_size);
+
+       REG_WRITE(ah, AR_Q_STATUS_RING_START, ah->ts_paddr_start);
+       REG_WRITE(ah, AR_Q_STATUS_RING_END, ah->ts_paddr_end);
+}
+
+void ath9k_hw_setup_statusring(struct ath_hw *ah, void *ts_start,
+                              u32 ts_paddr_start,
+                              u8 size)
+{
+
+       ah->ts_paddr_start = ts_paddr_start;
+       ah->ts_paddr_end = ts_paddr_start + (size * sizeof(struct ar9003_txs));
+       ah->ts_size = size;
+       ah->ts_ring = (struct ar9003_txs *) ts_start;
+
+       ath9k_hw_reset_txstatus_ring(ah);
+}
+EXPORT_SYMBOL(ath9k_hw_setup_statusring);
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.h b/drivers/net/wireless/ath/ath9k/ar9003_mac.h
new file mode 100644 (file)
index 0000000..f17558b
--- /dev/null
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2010 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT 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.
+ */
+
+#ifndef AR9003_MAC_H
+#define AR9003_MAC_H
+
+#define AR_DescId      0xffff0000
+#define AR_DescId_S    16
+#define AR_CtrlStat    0x00004000
+#define AR_CtrlStat_S  14
+#define AR_TxRxDesc    0x00008000
+#define AR_TxRxDesc_S  15
+#define AR_TxQcuNum    0x00000f00
+#define AR_TxQcuNum_S  8
+
+#define AR_BufLen      0x0fff0000
+#define AR_BufLen_S    16
+
+#define AR_TxDescId    0xffff0000
+#define AR_TxDescId_S  16
+#define AR_TxPtrChkSum 0x0000ffff
+
+#define AR_TxTid       0xf0000000
+#define AR_TxTid_S     28
+
+#define AR_LowRxChain  0x00004000
+
+#define AR_Not_Sounding        0x20000000
+
+#define MAP_ISR_S2_CST          6
+#define MAP_ISR_S2_GTT          6
+#define MAP_ISR_S2_TIM          3
+#define MAP_ISR_S2_CABEND       0
+#define MAP_ISR_S2_DTIMSYNC     7
+#define MAP_ISR_S2_DTIM         7
+#define MAP_ISR_S2_TSFOOR       4
+
+#define AR9003TXC_CONST(_ds) ((const struct ar9003_txc *) _ds)
+
+struct ar9003_rxs {
+       u32 ds_info;
+       u32 status1;
+       u32 status2;
+       u32 status3;
+       u32 status4;
+       u32 status5;
+       u32 status6;
+       u32 status7;
+       u32 status8;
+       u32 status9;
+       u32 status10;
+       u32 status11;
+} __packed;
+
+/* Transmit Control Descriptor */
+struct ar9003_txc {
+       u32 info;   /* descriptor information */
+       u32 link;   /* link pointer */
+       u32 data0;  /* data pointer to 1st buffer */
+       u32 ctl3;   /* DMA control 3  */
+       u32 data1;  /* data pointer to 2nd buffer */
+       u32 ctl5;   /* DMA control 5  */
+       u32 data2;  /* data pointer to 3rd buffer */
+       u32 ctl7;   /* DMA control 7  */
+       u32 data3;  /* data pointer to 4th buffer */
+       u32 ctl9;   /* DMA control 9  */
+       u32 ctl10;  /* DMA control 10 */
+       u32 ctl11;  /* DMA control 11 */
+       u32 ctl12;  /* DMA control 12 */
+       u32 ctl13;  /* DMA control 13 */
+       u32 ctl14;  /* DMA control 14 */
+       u32 ctl15;  /* DMA control 15 */
+       u32 ctl16;  /* DMA control 16 */
+       u32 ctl17;  /* DMA control 17 */
+       u32 ctl18;  /* DMA control 18 */
+       u32 ctl19;  /* DMA control 19 */
+       u32 ctl20;  /* DMA control 20 */
+       u32 ctl21;  /* DMA control 21 */
+       u32 ctl22;  /* DMA control 22 */
+       u32 pad[9]; /* pad to cache line (128 bytes/32 dwords) */
+} __packed;
+
+struct ar9003_txs {
+       u32 ds_info;
+       u32 status1;
+       u32 status2;
+       u32 status3;
+       u32 status4;
+       u32 status5;
+       u32 status6;
+       u32 status7;
+       u32 status8;
+} __packed;
+
+void ar9003_hw_attach_mac_ops(struct ath_hw *hw);
+void ath9k_hw_set_rx_bufsize(struct ath_hw *ah, u16 buf_size);
+void ath9k_hw_addrxbuf_edma(struct ath_hw *ah, u32 rxdp,
+                           enum ath9k_rx_qtype qtype);
+
+int ath9k_hw_process_rxdesc_edma(struct ath_hw *ah,
+                                struct ath_rx_status *rxs,
+                                void *buf_addr);
+void ath9k_hw_reset_txstatus_ring(struct ath_hw *ah);
+void ath9k_hw_setup_statusring(struct ath_hw *ah, void *ts_start,
+                              u32 ts_paddr_start,
+                              u8 size);
+#endif
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
new file mode 100644 (file)
index 0000000..137543b
--- /dev/null
@@ -0,0 +1,1142 @@
+/*
+ * Copyright (c) 2010 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT 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 "hw.h"
+#include "ar9003_phy.h"
+
+/**
+ * ar9003_hw_set_channel - set channel on single-chip device
+ * @ah: atheros hardware structure
+ * @chan:
+ *
+ * This is the function to change channel on single-chip devices, that is
+ * all devices after ar9280.
+ *
+ * This function takes the channel value in MHz and sets
+ * hardware channel value. Assumes writes have been enabled to analog bus.
+ *
+ * Actual Expression,
+ *
+ * For 2GHz channel,
+ * Channel Frequency = (3/4) * freq_ref * (chansel[8:0] + chanfrac[16:0]/2^17)
+ * (freq_ref = 40MHz)
+ *
+ * For 5GHz channel,
+ * Channel Frequency = (3/2) * freq_ref * (chansel[8:0] + chanfrac[16:0]/2^10)
+ * (freq_ref = 40MHz/(24>>amodeRefSel))
+ *
+ * For 5GHz channels which are 5MHz spaced,
+ * Channel Frequency = (3/2) * freq_ref * (chansel[8:0] + chanfrac[16:0]/2^17)
+ * (freq_ref = 40MHz)
+ */
+static int ar9003_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan)
+{
+       u16 bMode, fracMode = 0, aModeRefSel = 0;
+       u32 freq, channelSel = 0, reg32 = 0;
+       struct chan_centers centers;
+       int loadSynthChannel;
+
+       ath9k_hw_get_channel_centers(ah, chan, &centers);
+       freq = centers.synth_center;
+
+       if (freq < 4800) {     /* 2 GHz, fractional mode */
+               channelSel = CHANSEL_2G(freq);
+               /* Set to 2G mode */
+               bMode = 1;
+       } else {
+               channelSel = CHANSEL_5G(freq);
+               /* Doubler is ON, so, divide channelSel by 2. */
+               channelSel >>= 1;
+               /* Set to 5G mode */
+               bMode = 0;
+       }
+
+       /* Enable fractional mode for all channels */
+       fracMode = 1;
+       aModeRefSel = 0;
+       loadSynthChannel = 0;
+
+       reg32 = (bMode << 29);
+       REG_WRITE(ah, AR_PHY_SYNTH_CONTROL, reg32);
+
+       /* Enable Long shift Select for Synthesizer */
+       REG_RMW_FIELD(ah, AR_PHY_65NM_CH0_SYNTH4,
+                     AR_PHY_SYNTH4_LONG_SHIFT_SELECT, 1);
+
+       /* Program Synth. setting */
+       reg32 = (channelSel << 2) | (fracMode << 30) |
+               (aModeRefSel << 28) | (loadSynthChannel << 31);
+       REG_WRITE(ah, AR_PHY_65NM_CH0_SYNTH7, reg32);
+
+       /* Toggle Load Synth channel bit */
+       loadSynthChannel = 1;
+       reg32 = (channelSel << 2) | (fracMode << 30) |
+               (aModeRefSel << 28) | (loadSynthChannel << 31);
+       REG_WRITE(ah, AR_PHY_65NM_CH0_SYNTH7, reg32);
+
+       ah->curchan = chan;
+       ah->curchan_rad_index = -1;
+
+       return 0;
+}
+
+/**
+ * ar9003_hw_spur_mitigate - convert baseband spur frequency
+ * @ah: atheros hardware structure
+ * @chan:
+ *
+ * For single-chip solutions. Converts to baseband spur frequency given the
+ * input channel frequency and compute register settings below.
+ *
+ * Spur mitigation for MRC CCK
+ */
+static void ar9003_hw_spur_mitigate_mrc_cck(struct ath_hw *ah,
+                                           struct ath9k_channel *chan)
+{
+       u32 spur_freq[4] = { 2420, 2440, 2464, 2480 };
+       int cur_bb_spur, negative = 0, cck_spur_freq;
+       int i;
+
+       /*
+        * Need to verify range +/- 10 MHz in control channel, otherwise spur
+        * is out-of-band and can be ignored.
+        */
+
+       for (i = 0; i < 4; i++) {
+               negative = 0;
+               cur_bb_spur = spur_freq[i] - chan->channel;
+
+               if (cur_bb_spur < 0) {
+                       negative = 1;
+                       cur_bb_spur = -cur_bb_spur;
+               }
+               if (cur_bb_spur < 10) {
+                       cck_spur_freq = (int)((cur_bb_spur << 19) / 11);
+
+                       if (negative == 1)
+                               cck_spur_freq = -cck_spur_freq;
+
+                       cck_spur_freq = cck_spur_freq & 0xfffff;
+
+                       REG_RMW_FIELD(ah, AR_PHY_AGC_CONTROL,
+                                     AR_PHY_AGC_CONTROL_YCOK_MAX, 0x7);
+                       REG_RMW_FIELD(ah, AR_PHY_CCK_SPUR_MIT,
+                                     AR_PHY_CCK_SPUR_MIT_SPUR_RSSI_THR, 0x7f);
+                       REG_RMW_FIELD(ah, AR_PHY_CCK_SPUR_MIT,
+                                     AR_PHY_CCK_SPUR_MIT_SPUR_FILTER_TYPE,
+                                     0x2);
+                       REG_RMW_FIELD(ah, AR_PHY_CCK_SPUR_MIT,
+                                     AR_PHY_CCK_SPUR_MIT_USE_CCK_SPUR_MIT,
+                                     0x1);
+                       REG_RMW_FIELD(ah, AR_PHY_CCK_SPUR_MIT,
+                                     AR_PHY_CCK_SPUR_MIT_CCK_SPUR_FREQ,
+                                     cck_spur_freq);
+
+                       return;
+               }
+       }
+
+       REG_RMW_FIELD(ah, AR_PHY_AGC_CONTROL,
+                     AR_PHY_AGC_CONTROL_YCOK_MAX, 0x5);
+       REG_RMW_FIELD(ah, AR_PHY_CCK_SPUR_MIT,
+                     AR_PHY_CCK_SPUR_MIT_USE_CCK_SPUR_MIT, 0x0);
+       REG_RMW_FIELD(ah, AR_PHY_CCK_SPUR_MIT,
+                     AR_PHY_CCK_SPUR_MIT_CCK_SPUR_FREQ, 0x0);
+}
+
+/* Clean all spur register fields */
+static void ar9003_hw_spur_ofdm_clear(struct ath_hw *ah)
+{
+       REG_RMW_FIELD(ah, AR_PHY_TIMING4,
+                     AR_PHY_TIMING4_ENABLE_SPUR_FILTER, 0);
+       REG_RMW_FIELD(ah, AR_PHY_TIMING11,
+                     AR_PHY_TIMING11_SPUR_FREQ_SD, 0);
+       REG_RMW_FIELD(ah, AR_PHY_TIMING11,
+                     AR_PHY_TIMING11_SPUR_DELTA_PHASE, 0);
+       REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
+                     AR_PHY_SFCORR_EXT_SPUR_SUBCHANNEL_SD, 0);
+       REG_RMW_FIELD(ah, AR_PHY_TIMING11,
+                     AR_PHY_TIMING11_USE_SPUR_FILTER_IN_AGC, 0);
+       REG_RMW_FIELD(ah, AR_PHY_TIMING11,
+                     AR_PHY_TIMING11_USE_SPUR_FILTER_IN_SELFCOR, 0);
+       REG_RMW_FIELD(ah, AR_PHY_TIMING4,
+                     AR_PHY_TIMING4_ENABLE_SPUR_RSSI, 0);
+       REG_RMW_FIELD(ah, AR_PHY_SPUR_REG,
+                     AR_PHY_SPUR_REG_EN_VIT_SPUR_RSSI, 0);
+       REG_RMW_FIELD(ah, AR_PHY_SPUR_REG,
+                     AR_PHY_SPUR_REG_ENABLE_NF_RSSI_SPUR_MIT, 0);
+
+       REG_RMW_FIELD(ah, AR_PHY_SPUR_REG,
+                     AR_PHY_SPUR_REG_ENABLE_MASK_PPM, 0);
+       REG_RMW_FIELD(ah, AR_PHY_TIMING4,
+                     AR_PHY_TIMING4_ENABLE_PILOT_MASK, 0);
+       REG_RMW_FIELD(ah, AR_PHY_TIMING4,
+                     AR_PHY_TIMING4_ENABLE_CHAN_MASK, 0);
+       REG_RMW_FIELD(ah, AR_PHY_PILOT_SPUR_MASK,
+                     AR_PHY_PILOT_SPUR_MASK_CF_PILOT_MASK_IDX_A, 0);
+       REG_RMW_FIELD(ah, AR_PHY_SPUR_MASK_A,
+                     AR_PHY_SPUR_MASK_A_CF_PUNC_MASK_IDX_A, 0);
+       REG_RMW_FIELD(ah, AR_PHY_CHAN_SPUR_MASK,
+                     AR_PHY_CHAN_SPUR_MASK_CF_CHAN_MASK_IDX_A, 0);
+       REG_RMW_FIELD(ah, AR_PHY_PILOT_SPUR_MASK,
+                     AR_PHY_PILOT_SPUR_MASK_CF_PILOT_MASK_A, 0);
+       REG_RMW_FIELD(ah, AR_PHY_CHAN_SPUR_MASK,
+                     AR_PHY_CHAN_SPUR_MASK_CF_CHAN_MASK_A, 0);
+       REG_RMW_FIELD(ah, AR_PHY_SPUR_MASK_A,
+                     AR_PHY_SPUR_MASK_A_CF_PUNC_MASK_A, 0);
+       REG_RMW_FIELD(ah, AR_PHY_SPUR_REG,
+                     AR_PHY_SPUR_REG_MASK_RATE_CNTL, 0);
+}
+
+static void ar9003_hw_spur_ofdm(struct ath_hw *ah,
+                               int freq_offset,
+                               int spur_freq_sd,
+                               int spur_delta_phase,
+                               int spur_subchannel_sd)
+{
+       int mask_index = 0;
+
+       /* OFDM Spur mitigation */
+       REG_RMW_FIELD(ah, AR_PHY_TIMING4,
+                AR_PHY_TIMING4_ENABLE_SPUR_FILTER, 0x1);
+       REG_RMW_FIELD(ah, AR_PHY_TIMING11,
+                     AR_PHY_TIMING11_SPUR_FREQ_SD, spur_freq_sd);
+       REG_RMW_FIELD(ah, AR_PHY_TIMING11,
+                     AR_PHY_TIMING11_SPUR_DELTA_PHASE, spur_delta_phase);
+       REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
+                     AR_PHY_SFCORR_EXT_SPUR_SUBCHANNEL_SD, spur_subchannel_sd);
+       REG_RMW_FIELD(ah, AR_PHY_TIMING11,
+                     AR_PHY_TIMING11_USE_SPUR_FILTER_IN_AGC, 0x1);
+       REG_RMW_FIELD(ah, AR_PHY_TIMING11,
+                     AR_PHY_TIMING11_USE_SPUR_FILTER_IN_SELFCOR, 0x1);
+       REG_RMW_FIELD(ah, AR_PHY_TIMING4,
+                     AR_PHY_TIMING4_ENABLE_SPUR_RSSI, 0x1);
+       REG_RMW_FIELD(ah, AR_PHY_SPUR_REG,
+                     AR_PHY_SPUR_REG_SPUR_RSSI_THRESH, 34);
+       REG_RMW_FIELD(ah, AR_PHY_SPUR_REG,
+                     AR_PHY_SPUR_REG_EN_VIT_SPUR_RSSI, 1);
+
+       if (REG_READ_FIELD(ah, AR_PHY_MODE,
+                          AR_PHY_MODE_DYNAMIC) == 0x1)
+               REG_RMW_FIELD(ah, AR_PHY_SPUR_REG,
+                             AR_PHY_SPUR_REG_ENABLE_NF_RSSI_SPUR_MIT, 1);
+
+       mask_index = (freq_offset << 4) / 5;
+       if (mask_index < 0)
+               mask_index = mask_index - 1;
+
+       mask_index = mask_index & 0x7f;
+
+       REG_RMW_FIELD(ah, AR_PHY_SPUR_REG,
+                     AR_PHY_SPUR_REG_ENABLE_MASK_PPM, 0x1);
+       REG_RMW_FIELD(ah, AR_PHY_TIMING4,
+                     AR_PHY_TIMING4_ENABLE_PILOT_MASK, 0x1);
+       REG_RMW_FIELD(ah, AR_PHY_TIMING4,
+                     AR_PHY_TIMING4_ENABLE_CHAN_MASK, 0x1);
+       REG_RMW_FIELD(ah, AR_PHY_PILOT_SPUR_MASK,
+                     AR_PHY_PILOT_SPUR_MASK_CF_PILOT_MASK_IDX_A, mask_index);
+       REG_RMW_FIELD(ah, AR_PHY_SPUR_MASK_A,
+                     AR_PHY_SPUR_MASK_A_CF_PUNC_MASK_IDX_A, mask_index);
+       REG_RMW_FIELD(ah, AR_PHY_CHAN_SPUR_MASK,
+                     AR_PHY_CHAN_SPUR_MASK_CF_CHAN_MASK_IDX_A, mask_index);
+       REG_RMW_FIELD(ah, AR_PHY_PILOT_SPUR_MASK,
+                     AR_PHY_PILOT_SPUR_MASK_CF_PILOT_MASK_A, 0xc);
+       REG_RMW_FIELD(ah, AR_PHY_CHAN_SPUR_MASK,
+                     AR_PHY_CHAN_SPUR_MASK_CF_CHAN_MASK_A, 0xc);
+       REG_RMW_FIELD(ah, AR_PHY_SPUR_MASK_A,
+                     AR_PHY_SPUR_MASK_A_CF_PUNC_MASK_A, 0xa0);
+       REG_RMW_FIELD(ah, AR_PHY_SPUR_REG,
+                     AR_PHY_SPUR_REG_MASK_RATE_CNTL, 0xff);
+}
+
+static void ar9003_hw_spur_ofdm_work(struct ath_hw *ah,
+                                    struct ath9k_channel *chan,
+                                    int freq_offset)
+{
+       int spur_freq_sd = 0;
+       int spur_subchannel_sd = 0;
+       int spur_delta_phase = 0;
+
+       if (IS_CHAN_HT40(chan)) {
+               if (freq_offset < 0) {
+                       if (REG_READ_FIELD(ah, AR_PHY_GEN_CTRL,
+                                          AR_PHY_GC_DYN2040_PRI_CH) == 0x0)
+                               spur_subchannel_sd = 1;
+                       else
+                               spur_subchannel_sd = 0;
+
+                       spur_freq_sd = ((freq_offset + 10) << 9) / 11;
+
+               } else {
+                       if (REG_READ_FIELD(ah, AR_PHY_GEN_CTRL,
+                           AR_PHY_GC_DYN2040_PRI_CH) == 0x0)
+                               spur_subchannel_sd = 0;
+                       else
+                               spur_subchannel_sd = 1;
+
+                       spur_freq_sd = ((freq_offset - 10) << 9) / 11;
+
+               }
+
+               spur_delta_phase = (freq_offset << 17) / 5;
+
+       } else {
+               spur_subchannel_sd = 0;
+               spur_freq_sd = (freq_offset << 9) /11;
+               spur_delta_phase = (freq_offset << 18) / 5;
+       }
+
+       spur_freq_sd = spur_freq_sd & 0x3ff;
+       spur_delta_phase = spur_delta_phase & 0xfffff;
+
+       ar9003_hw_spur_ofdm(ah,
+                           freq_offset,
+                           spur_freq_sd,
+                           spur_delta_phase,
+                           spur_subchannel_sd);
+}
+
+/* Spur mitigation for OFDM */
+static void ar9003_hw_spur_mitigate_ofdm(struct ath_hw *ah,
+                                        struct ath9k_channel *chan)
+{
+       int synth_freq;
+       int range = 10;
+       int freq_offset = 0;
+       int mode;
+       u8* spurChansPtr;
+       unsigned int i;
+       struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
+
+       if (IS_CHAN_5GHZ(chan)) {
+               spurChansPtr = &(eep->modalHeader5G.spurChans[0]);
+               mode = 0;
+       }
+       else {
+               spurChansPtr = &(eep->modalHeader2G.spurChans[0]);
+               mode = 1;
+       }
+
+       if (spurChansPtr[0] == 0)
+               return; /* No spur in the mode */
+
+       if (IS_CHAN_HT40(chan)) {
+               range = 19;
+               if (REG_READ_FIELD(ah, AR_PHY_GEN_CTRL,
+                                  AR_PHY_GC_DYN2040_PRI_CH) == 0x0)
+                       synth_freq = chan->channel - 10;
+               else
+                       synth_freq = chan->channel + 10;
+       } else {
+               range = 10;
+               synth_freq = chan->channel;
+       }
+
+       ar9003_hw_spur_ofdm_clear(ah);
+
+       for (i = 0; spurChansPtr[i] && i < 5; i++) {
+               freq_offset = FBIN2FREQ(spurChansPtr[i], mode) - synth_freq;
+               if (abs(freq_offset) < range) {
+                       ar9003_hw_spur_ofdm_work(ah, chan, freq_offset);
+                       break;
+               }
+       }
+}
+
+static void ar9003_hw_spur_mitigate(struct ath_hw *ah,
+                                   struct ath9k_channel *chan)
+{
+       ar9003_hw_spur_mitigate_mrc_cck(ah, chan);
+       ar9003_hw_spur_mitigate_ofdm(ah, chan);
+}
+
+static u32 ar9003_hw_compute_pll_control(struct ath_hw *ah,
+                                        struct ath9k_channel *chan)
+{
+       u32 pll;
+
+       pll = SM(0x5, AR_RTC_9300_PLL_REFDIV);
+
+       if (chan && IS_CHAN_HALF_RATE(chan))
+               pll |= SM(0x1, AR_RTC_9300_PLL_CLKSEL);
+       else if (chan && IS_CHAN_QUARTER_RATE(chan))
+               pll |= SM(0x2, AR_RTC_9300_PLL_CLKSEL);
+
+       if (chan && IS_CHAN_5GHZ(chan)) {
+               pll |= SM(0x28, AR_RTC_9300_PLL_DIV);
+
+               /*
+                * When doing fast clock, set PLL to 0x142c
+                */
+               if (IS_CHAN_A_5MHZ_SPACED(chan))
+                       pll = 0x142c;
+       } else
+               pll |= SM(0x2c, AR_RTC_9300_PLL_DIV);
+
+       return pll;
+}
+
+static void ar9003_hw_set_channel_regs(struct ath_hw *ah,
+                                      struct ath9k_channel *chan)
+{
+       u32 phymode;
+       u32 enableDacFifo = 0;
+
+       enableDacFifo =
+               (REG_READ(ah, AR_PHY_GEN_CTRL) & AR_PHY_GC_ENABLE_DAC_FIFO);
+
+       /* Enable 11n HT, 20 MHz */
+       phymode = AR_PHY_GC_HT_EN | AR_PHY_GC_SINGLE_HT_LTF1 | AR_PHY_GC_WALSH |
+                 AR_PHY_GC_SHORT_GI_40 | enableDacFifo;
+
+       /* Configure baseband for dynamic 20/40 operation */
+       if (IS_CHAN_HT40(chan)) {
+               phymode |= AR_PHY_GC_DYN2040_EN;
+               /* Configure control (primary) channel at +-10MHz */
+               if ((chan->chanmode == CHANNEL_A_HT40PLUS) ||
+                   (chan->chanmode == CHANNEL_G_HT40PLUS))
+                       phymode |= AR_PHY_GC_DYN2040_PRI_CH;
+
+       }
+
+       /* make sure we preserve INI settings */
+       phymode |= REG_READ(ah, AR_PHY_GEN_CTRL);
+       /* turn off Green Field detection for STA for now */
+       phymode &= ~AR_PHY_GC_GF_DETECT_EN;
+
+       REG_WRITE(ah, AR_PHY_GEN_CTRL, phymode);
+
+       /* Configure MAC for 20/40 operation */
+       ath9k_hw_set11nmac2040(ah);
+
+       /* global transmit timeout (25 TUs default)*/
+       REG_WRITE(ah, AR_GTXTO, 25 << AR_GTXTO_TIMEOUT_LIMIT_S);
+       /* carrier sense timeout */
+       REG_WRITE(ah, AR_CST, 0xF << AR_CST_TIMEOUT_LIMIT_S);
+}
+
+static void ar9003_hw_init_bb(struct ath_hw *ah,
+                             struct ath9k_channel *chan)
+{
+       u32 synthDelay;
+
+       /*
+        * Wait for the frequency synth to settle (synth goes on
+        * via AR_PHY_ACTIVE_EN).  Read the phy active delay register.
+        * Value is in 100ns increments.
+        */
+       synthDelay = REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY;
+       if (IS_CHAN_B(chan))
+               synthDelay = (4 * synthDelay) / 22;
+       else
+               synthDelay /= 10;
+
+       /* Activate the PHY (includes baseband activate + synthesizer on) */
+       REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
+
+       /*
+        * There is an issue if the AP starts the calibration before
+        * the base band timeout completes.  This could result in the
+        * rx_clear false triggering.  As a workaround we add delay an
+        * extra BASE_ACTIVATE_DELAY usecs to ensure this condition
+        * does not happen.
+        */
+       udelay(synthDelay + BASE_ACTIVATE_DELAY);
+}
+
+void ar9003_hw_set_chain_masks(struct ath_hw *ah, u8 rx, u8 tx)
+{
+       switch (rx) {
+       case 0x5:
+               REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP,
+                           AR_PHY_SWAP_ALT_CHAIN);
+       case 0x3:
+       case 0x1:
+       case 0x2:
+       case 0x7:
+               REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx);
+               REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx);
+               break;
+       default:
+               break;
+       }
+
+       REG_WRITE(ah, AR_SELFGEN_MASK, tx);
+       if (tx == 0x5) {
+               REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP,
+                           AR_PHY_SWAP_ALT_CHAIN);
+       }
+}
+
+/*
+ * Override INI values with chip specific configuration.
+ */
+static void ar9003_hw_override_ini(struct ath_hw *ah)
+{
+       u32 val;
+
+       /*
+        * Set the RX_ABORT and RX_DIS and clear it only after
+        * RXE is set for MAC. This prevents frames with
+        * corrupted descriptor status.
+        */
+       REG_SET_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
+
+       /*
+        * For AR9280 and above, there is a new feature that allows
+        * Multicast search based on both MAC Address and Key ID. By default,
+        * this feature is enabled. But since the driver is not using this
+        * feature, we switch it off; otherwise multicast search based on
+        * MAC addr only will fail.
+        */
+       val = REG_READ(ah, AR_PCU_MISC_MODE2) & (~AR_ADHOC_MCAST_KEYID_ENABLE);
+       REG_WRITE(ah, AR_PCU_MISC_MODE2,
+                 val | AR_AGG_WEP_ENABLE_FIX | AR_AGG_WEP_ENABLE);
+}
+
+static void ar9003_hw_prog_ini(struct ath_hw *ah,
+                              struct ar5416IniArray *iniArr,
+                              int column)
+{
+       unsigned int i, regWrites = 0;
+
+       /* New INI format: Array may be undefined (pre, core, post arrays) */
+       if (!iniArr->ia_array)
+               return;
+
+       /*
+        * New INI format: Pre, core, and post arrays for a given subsystem
+        * may be modal (> 2 columns) or non-modal (2 columns). Determine if
+        * the array is non-modal and force the column to 1.
+        */
+       if (column >= iniArr->ia_columns)
+               column = 1;
+
+       for (i = 0; i < iniArr->ia_rows; i++) {
+               u32 reg = INI_RA(iniArr, i, 0);
+               u32 val = INI_RA(iniArr, i, column);
+
+               REG_WRITE(ah, reg, val);
+
+               /*
+                * Determine if this is a shift register value, and insert the
+                * configured delay if so.
+                */
+               if (reg >= 0x16000 && reg < 0x17000
+                   && ah->config.analog_shiftreg)
+                       udelay(100);
+
+               DO_DELAY(regWrites);
+       }
+}
+
+static int ar9003_hw_process_ini(struct ath_hw *ah,
+                                struct ath9k_channel *chan)
+{
+       struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
+       unsigned int regWrites = 0, i;
+       struct ieee80211_channel *channel = chan->chan;
+       u32 modesIndex, freqIndex;
+
+       switch (chan->chanmode) {
+       case CHANNEL_A:
+       case CHANNEL_A_HT20:
+               modesIndex = 1;
+               freqIndex = 1;
+               break;
+       case CHANNEL_A_HT40PLUS:
+       case CHANNEL_A_HT40MINUS:
+               modesIndex = 2;
+               freqIndex = 1;
+               break;
+       case CHANNEL_G:
+       case CHANNEL_G_HT20:
+       case CHANNEL_B:
+               modesIndex = 4;
+               freqIndex = 2;
+               break;
+       case CHANNEL_G_HT40PLUS:
+       case CHANNEL_G_HT40MINUS:
+               modesIndex = 3;
+               freqIndex = 2;
+               break;
+
+       default:
+               return -EINVAL;
+       }
+
+       for (i = 0; i < ATH_INI_NUM_SPLIT; i++) {
+               ar9003_hw_prog_ini(ah, &ah->iniSOC[i], modesIndex);
+               ar9003_hw_prog_ini(ah, &ah->iniMac[i], modesIndex);
+               ar9003_hw_prog_ini(ah, &ah->iniBB[i], modesIndex);
+               ar9003_hw_prog_ini(ah, &ah->iniRadio[i], modesIndex);
+       }
+
+       REG_WRITE_ARRAY(&ah->iniModesRxGain, 1, regWrites);
+       REG_WRITE_ARRAY(&ah->iniModesTxGain, modesIndex, regWrites);
+
+       /*
+        * For 5GHz channels requiring Fast Clock, apply
+        * different modal values.
+        */
+       if (IS_CHAN_A_5MHZ_SPACED(chan))
+               REG_WRITE_ARRAY(&ah->iniModesAdditional,
+                               modesIndex, regWrites);
+
+       ar9003_hw_override_ini(ah);
+       ar9003_hw_set_channel_regs(ah, chan);
+       ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask);
+
+       /* Set TX power */
+       ah->eep_ops->set_txpower(ah, chan,
+                                ath9k_regd_get_ctl(regulatory, chan),
+                                channel->max_antenna_gain * 2,
+                                channel->max_power * 2,
+                                min((u32) MAX_RATE_POWER,
+                                (u32) regulatory->power_limit));
+
+       return 0;
+}
+
+static void ar9003_hw_set_rfmode(struct ath_hw *ah,
+                                struct ath9k_channel *chan)
+{
+       u32 rfMode = 0;
+
+       if (chan == NULL)
+               return;
+
+       rfMode |= (IS_CHAN_B(chan) || IS_CHAN_G(chan))
+               ? AR_PHY_MODE_DYNAMIC : AR_PHY_MODE_OFDM;
+
+       if (IS_CHAN_A_5MHZ_SPACED(chan))
+               rfMode |= (AR_PHY_MODE_DYNAMIC | AR_PHY_MODE_DYN_CCK_DISABLE);
+
+       REG_WRITE(ah, AR_PHY_MODE, rfMode);
+}
+
+static void ar9003_hw_mark_phy_inactive(struct ath_hw *ah)
+{
+       REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS);
+}
+
+static void ar9003_hw_set_delta_slope(struct ath_hw *ah,
+                                     struct ath9k_channel *chan)
+{
+       u32 coef_scaled, ds_coef_exp, ds_coef_man;
+       u32 clockMhzScaled = 0x64000000;
+       struct chan_centers centers;
+
+       /*
+        * half and quarter rate can divide the scaled clock by 2 or 4
+        * scale for selected channel bandwidth
+        */
+       if (IS_CHAN_HALF_RATE(chan))
+               clockMhzScaled = clockMhzScaled >> 1;
+       else if (IS_CHAN_QUARTER_RATE(chan))
+               clockMhzScaled = clockMhzScaled >> 2;
+
+       /*
+        * ALGO -> coef = 1e8/fcarrier*fclock/40;
+        * scaled coef to provide precision for this floating calculation
+        */
+       ath9k_hw_get_channel_centers(ah, chan, &centers);
+       coef_scaled = clockMhzScaled / centers.synth_center;
+
+       ath9k_hw_get_delta_slope_vals(ah, coef_scaled, &ds_coef_man,
+                                     &ds_coef_exp);
+
+       REG_RMW_FIELD(ah, AR_PHY_TIMING3,
+                     AR_PHY_TIMING3_DSC_MAN, ds_coef_man);
+       REG_RMW_FIELD(ah, AR_PHY_TIMING3,
+                     AR_PHY_TIMING3_DSC_EXP, ds_coef_exp);
+
+       /*
+        * For Short GI,
+        * scaled coeff is 9/10 that of normal coeff
+        */
+       coef_scaled = (9 * coef_scaled) / 10;
+
+       ath9k_hw_get_delta_slope_vals(ah, coef_scaled, &ds_coef_man,
+                                     &ds_coef_exp);
+
+       /* for short gi */
+       REG_RMW_FIELD(ah, AR_PHY_SGI_DELTA,
+                     AR_PHY_SGI_DSC_MAN, ds_coef_man);
+       REG_RMW_FIELD(ah, AR_PHY_SGI_DELTA,
+                     AR_PHY_SGI_DSC_EXP, ds_coef_exp);
+}
+
+static bool ar9003_hw_rfbus_req(struct ath_hw *ah)
+{
+       REG_WRITE(ah, AR_PHY_RFBUS_REQ, AR_PHY_RFBUS_REQ_EN);
+       return ath9k_hw_wait(ah, AR_PHY_RFBUS_GRANT, AR_PHY_RFBUS_GRANT_EN,
+                            AR_PHY_RFBUS_GRANT_EN, AH_WAIT_TIMEOUT);
+}
+
+/*
+ * Wait for the frequency synth to settle (synth goes on via PHY_ACTIVE_EN).
+ * Read the phy active delay register. Value is in 100ns increments.
+ */
+static void ar9003_hw_rfbus_done(struct ath_hw *ah)
+{
+       u32 synthDelay = REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY;
+       if (IS_CHAN_B(ah->curchan))
+               synthDelay = (4 * synthDelay) / 22;
+       else
+               synthDelay /= 10;
+
+       udelay(synthDelay + BASE_ACTIVATE_DELAY);
+
+       REG_WRITE(ah, AR_PHY_RFBUS_REQ, 0);
+}
+
+/*
+ * Set the interrupt and GPIO values so the ISR can disable RF
+ * on a switch signal.  Assumes GPIO port and interrupt polarity
+ * are set prior to call.
+ */
+static void ar9003_hw_enable_rfkill(struct ath_hw *ah)
+{
+       /* Connect rfsilent_bb_l to baseband */
+       REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL,
+                   AR_GPIO_INPUT_EN_VAL_RFSILENT_BB);
+       /* Set input mux for rfsilent_bb_l to GPIO #0 */
+       REG_CLR_BIT(ah, AR_GPIO_INPUT_MUX2,
+                   AR_GPIO_INPUT_MUX2_RFSILENT);
+
+       /*
+        * Configure the desired GPIO port for input and
+        * enable baseband rf silence.
+        */
+       ath9k_hw_cfg_gpio_input(ah, ah->rfkill_gpio);
+       REG_SET_BIT(ah, AR_PHY_TEST, RFSILENT_BB);
+}
+
+static void ar9003_hw_set_diversity(struct ath_hw *ah, bool value)
+{
+       u32 v = REG_READ(ah, AR_PHY_CCK_DETECT);
+       if (value)
+               v |= AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV;
+       else
+               v &= ~AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV;
+       REG_WRITE(ah, AR_PHY_CCK_DETECT, v);
+}
+
+static bool ar9003_hw_ani_control(struct ath_hw *ah,
+                                 enum ath9k_ani_cmd cmd, int param)
+{
+       struct ar5416AniState *aniState = ah->curani;
+       struct ath_common *common = ath9k_hw_common(ah);
+
+       switch (cmd & ah->ani_function) {
+       case ATH9K_ANI_NOISE_IMMUNITY_LEVEL:{
+               u32 level = param;
+
+               if (level >= ARRAY_SIZE(ah->totalSizeDesired)) {
+                       ath_print(common, ATH_DBG_ANI,
+                                 "level out of range (%u > %u)\n",
+                                 level,
+                                 (unsigned)ARRAY_SIZE(ah->totalSizeDesired));
+                       return false;
+               }
+
+               REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ,
+                             AR_PHY_DESIRED_SZ_TOT_DES,
+                             ah->totalSizeDesired[level]);
+               REG_RMW_FIELD(ah, AR_PHY_AGC,
+                             AR_PHY_AGC_COARSE_LOW,
+                             ah->coarse_low[level]);
+               REG_RMW_FIELD(ah, AR_PHY_AGC,
+                             AR_PHY_AGC_COARSE_HIGH,
+                             ah->coarse_high[level]);
+               REG_RMW_FIELD(ah, AR_PHY_FIND_SIG,
+                             AR_PHY_FIND_SIG_FIRPWR, ah->firpwr[level]);
+
+               if (level > aniState->noiseImmunityLevel)
+                       ah->stats.ast_ani_niup++;
+               else if (level < aniState->noiseImmunityLevel)
+                       ah->stats.ast_ani_nidown++;
+               aniState->noiseImmunityLevel = level;
+               break;
+       }
+       case ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION:{
+               const int m1ThreshLow[] = { 127, 50 };
+               const int m2ThreshLow[] = { 127, 40 };
+               const int m1Thresh[] = { 127, 0x4d };
+               const int m2Thresh[] = { 127, 0x40 };
+               const int m2CountThr[] = { 31, 16 };
+               const int m2CountThrLow[] = { 63, 48 };
+               u32 on = param ? 1 : 0;
+
+               REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
+                             AR_PHY_SFCORR_LOW_M1_THRESH_LOW,
+                             m1ThreshLow[on]);
+               REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
+                             AR_PHY_SFCORR_LOW_M2_THRESH_LOW,
+                             m2ThreshLow[on]);
+               REG_RMW_FIELD(ah, AR_PHY_SFCORR,
+                             AR_PHY_SFCORR_M1_THRESH, m1Thresh[on]);
+               REG_RMW_FIELD(ah, AR_PHY_SFCORR,
+                             AR_PHY_SFCORR_M2_THRESH, m2Thresh[on]);
+               REG_RMW_FIELD(ah, AR_PHY_SFCORR,
+                             AR_PHY_SFCORR_M2COUNT_THR, m2CountThr[on]);
+               REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
+                             AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW,
+                             m2CountThrLow[on]);
+
+               REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
+                             AR_PHY_SFCORR_EXT_M1_THRESH_LOW, m1ThreshLow[on]);
+               REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
+                             AR_PHY_SFCORR_EXT_M2_THRESH_LOW, m2ThreshLow[on]);
+               REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
+                             AR_PHY_SFCORR_EXT_M1_THRESH, m1Thresh[on]);
+               REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
+                             AR_PHY_SFCORR_EXT_M2_THRESH, m2Thresh[on]);
+
+               if (on)
+                       REG_SET_BIT(ah, AR_PHY_SFCORR_LOW,
+                                   AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW);
+               else
+                       REG_CLR_BIT(ah, AR_PHY_SFCORR_LOW,
+                                   AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW);
+
+               if (!on != aniState->ofdmWeakSigDetectOff) {
+                       if (on)
+                               ah->stats.ast_ani_ofdmon++;
+                       else
+                               ah->stats.ast_ani_ofdmoff++;
+                       aniState->ofdmWeakSigDetectOff = !on;
+               }
+               break;
+       }
+       case ATH9K_ANI_CCK_WEAK_SIGNAL_THR:{
+               const int weakSigThrCck[] = { 8, 6 };
+               u32 high = param ? 1 : 0;
+
+               REG_RMW_FIELD(ah, AR_PHY_CCK_DETECT,
+                             AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK,
+                             weakSigThrCck[high]);
+               if (high != aniState->cckWeakSigThreshold) {
+                       if (high)
+                               ah->stats.ast_ani_cckhigh++;
+                       else
+                               ah->stats.ast_ani_ccklow++;
+                       aniState->cckWeakSigThreshold = high;
+               }
+               break;
+       }
+       case ATH9K_ANI_FIRSTEP_LEVEL:{
+               const int firstep[] = { 0, 4, 8 };
+               u32 level = param;
+
+               if (level >= ARRAY_SIZE(firstep)) {
+                       ath_print(common, ATH_DBG_ANI,
+                                 "level out of range (%u > %u)\n",
+                                 level,
+                                 (unsigned) ARRAY_SIZE(firstep));
+                       return false;
+               }
+               REG_RMW_FIELD(ah, AR_PHY_FIND_SIG,
+                             AR_PHY_FIND_SIG_FIRSTEP,
+                             firstep[level]);
+               if (level > aniState->firstepLevel)
+                       ah->stats.ast_ani_stepup++;
+               else if (level < aniState->firstepLevel)
+                       ah->stats.ast_ani_stepdown++;
+               aniState->firstepLevel = level;
+               break;
+       }
+       case ATH9K_ANI_SPUR_IMMUNITY_LEVEL:{
+               const int cycpwrThr1[] = { 2, 4, 6, 8, 10, 12, 14, 16 };
+               u32 level = param;
+
+               if (level >= ARRAY_SIZE(cycpwrThr1)) {
+                       ath_print(common, ATH_DBG_ANI,
+                                 "level out of range (%u > %u)\n",
+                                 level,
+                                 (unsigned) ARRAY_SIZE(cycpwrThr1));
+                       return false;
+               }
+               REG_RMW_FIELD(ah, AR_PHY_TIMING5,
+                             AR_PHY_TIMING5_CYCPWR_THR1,
+                             cycpwrThr1[level]);
+               if (level > aniState->spurImmunityLevel)
+                       ah->stats.ast_ani_spurup++;
+               else if (level < aniState->spurImmunityLevel)
+                       ah->stats.ast_ani_spurdown++;
+               aniState->spurImmunityLevel = level;
+               break;
+       }
+       case ATH9K_ANI_PRESENT:
+               break;
+       default:
+               ath_print(common, ATH_DBG_ANI,
+                         "invalid cmd %u\n", cmd);
+               return false;
+       }
+
+       ath_print(common, ATH_DBG_ANI, "ANI parameters:\n");
+       ath_print(common, ATH_DBG_ANI,
+                 "noiseImmunityLevel=%d, spurImmunityLevel=%d, "
+                 "ofdmWeakSigDetectOff=%d\n",
+                 aniState->noiseImmunityLevel,
+                 aniState->spurImmunityLevel,
+                 !aniState->ofdmWeakSigDetectOff);
+       ath_print(common, ATH_DBG_ANI,
+                 "cckWeakSigThreshold=%d, "
+                 "firstepLevel=%d, listenTime=%d\n",
+                 aniState->cckWeakSigThreshold,
+                 aniState->firstepLevel,
+                 aniState->listenTime);
+       ath_print(common, ATH_DBG_ANI,
+               "cycleCount=%d, ofdmPhyErrCount=%d, cckPhyErrCount=%d\n\n",
+               aniState->cycleCount,
+               aniState->ofdmPhyErrCount,
+               aniState->cckPhyErrCount);
+
+       return true;
+}
+
+static void ar9003_hw_nf_sanitize_2g(struct ath_hw *ah, s16 *nf)
+{
+       struct ath_common *common = ath9k_hw_common(ah);
+
+       if (*nf > ah->nf_2g_max) {
+               ath_print(common, ATH_DBG_CALIBRATE,
+                         "2 GHz NF (%d) > MAX (%d), "
+                         "correcting to MAX",
+                         *nf, ah->nf_2g_max);
+               *nf = ah->nf_2g_max;
+       } else if (*nf < ah->nf_2g_min) {
+               ath_print(common, ATH_DBG_CALIBRATE,
+                         "2 GHz NF (%d) < MIN (%d), "
+                         "correcting to MIN",
+                         *nf, ah->nf_2g_min);
+               *nf = ah->nf_2g_min;
+       }
+}
+
+static void ar9003_hw_nf_sanitize_5g(struct ath_hw *ah, s16 *nf)
+{
+       struct ath_common *common = ath9k_hw_common(ah);
+
+       if (*nf > ah->nf_5g_max) {
+               ath_print(common, ATH_DBG_CALIBRATE,
+                         "5 GHz NF (%d) > MAX (%d), "
+                         "correcting to MAX",
+                         *nf, ah->nf_5g_max);
+               *nf = ah->nf_5g_max;
+       } else if (*nf < ah->nf_5g_min) {
+               ath_print(common, ATH_DBG_CALIBRATE,
+                         "5 GHz NF (%d) < MIN (%d), "
+                         "correcting to MIN",
+                         *nf, ah->nf_5g_min);
+               *nf = ah->nf_5g_min;
+       }
+}
+
+static void ar9003_hw_nf_sanitize(struct ath_hw *ah, s16 *nf)
+{
+       if (IS_CHAN_2GHZ(ah->curchan))
+               ar9003_hw_nf_sanitize_2g(ah, nf);
+       else
+               ar9003_hw_nf_sanitize_5g(ah, nf);
+}
+
+static void ar9003_hw_do_getnf(struct ath_hw *ah,
+                             int16_t nfarray[NUM_NF_READINGS])
+{
+       struct ath_common *common = ath9k_hw_common(ah);
+       int16_t nf;
+
+       nf = MS(REG_READ(ah, AR_PHY_CCA_0), AR_PHY_MINCCA_PWR);
+       if (nf & 0x100)
+               nf = 0 - ((nf ^ 0x1ff) + 1);
+       ar9003_hw_nf_sanitize(ah, &nf);
+       ath_print(common, ATH_DBG_CALIBRATE,
+                 "NF calibrated [ctl] [chain 0] is %d\n", nf);
+       nfarray[0] = nf;
+
+       nf = MS(REG_READ(ah, AR_PHY_CCA_1), AR_PHY_CH1_MINCCA_PWR);
+       if (nf & 0x100)
+               nf = 0 - ((nf ^ 0x1ff) + 1);
+       ar9003_hw_nf_sanitize(ah, &nf);
+       ath_print(common, ATH_DBG_CALIBRATE,
+                 "NF calibrated [ctl] [chain 1] is %d\n", nf);
+       nfarray[1] = nf;
+
+       nf = MS(REG_READ(ah, AR_PHY_CCA_2), AR_PHY_CH2_MINCCA_PWR);
+       if (nf & 0x100)
+               nf = 0 - ((nf ^ 0x1ff) + 1);
+       ar9003_hw_nf_sanitize(ah, &nf);
+       ath_print(common, ATH_DBG_CALIBRATE,
+                 "NF calibrated [ctl] [chain 2] is %d\n", nf);
+       nfarray[2] = nf;
+
+       nf = MS(REG_READ(ah, AR_PHY_EXT_CCA), AR_PHY_EXT_MINCCA_PWR);
+       if (nf & 0x100)
+               nf = 0 - ((nf ^ 0x1ff) + 1);
+       ar9003_hw_nf_sanitize(ah, &nf);
+       ath_print(common, ATH_DBG_CALIBRATE,
+                 "NF calibrated [ext] [chain 0] is %d\n", nf);
+       nfarray[3] = nf;
+
+       nf = MS(REG_READ(ah, AR_PHY_EXT_CCA_1), AR_PHY_CH1_EXT_MINCCA_PWR);
+       if (nf & 0x100)
+               nf = 0 - ((nf ^ 0x1ff) + 1);
+       ar9003_hw_nf_sanitize(ah, &nf);
+       ath_print(common, ATH_DBG_CALIBRATE,
+                 "NF calibrated [ext] [chain 1] is %d\n", nf);
+       nfarray[4] = nf;
+
+       nf = MS(REG_READ(ah, AR_PHY_EXT_CCA_2), AR_PHY_CH2_EXT_MINCCA_PWR);
+       if (nf & 0x100)
+               nf = 0 - ((nf ^ 0x1ff) + 1);
+       ar9003_hw_nf_sanitize(ah, &nf);
+       ath_print(common, ATH_DBG_CALIBRATE,
+                 "NF calibrated [ext] [chain 2] is %d\n", nf);
+       nfarray[5] = nf;
+}
+
+void ar9003_hw_set_nf_limits(struct ath_hw *ah)
+{
+       ah->nf_2g_max = AR_PHY_CCA_MAX_GOOD_VAL_9300_2GHZ;
+       ah->nf_2g_min = AR_PHY_CCA_MIN_GOOD_VAL_9300_2GHZ;
+       ah->nf_5g_max = AR_PHY_CCA_MAX_GOOD_VAL_9300_5GHZ;
+       ah->nf_5g_min = AR_PHY_CCA_MIN_GOOD_VAL_9300_5GHZ;
+}
+
+/*
+ * Find out which of the RX chains are enabled
+ */
+static u32 ar9003_hw_get_rx_chainmask(struct ath_hw *ah)
+{
+       u32 chain = REG_READ(ah, AR_PHY_RX_CHAINMASK);
+       /*
+        * The bits [2:0] indicate the rx chain mask and are to be
+        * interpreted as follows:
+        * 00x => Only chain 0 is enabled
+        * 01x => Chain 1 and 0 enabled
+        * 1xx => Chain 2,1 and 0 enabled
+        */
+       return chain & 0x7;
+}
+
+static void ar9003_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)
+{
+       struct ath9k_nfcal_hist *h;
+       unsigned i, j;
+       int32_t val;
+       const u32 ar9300_cca_regs[6] = {
+               AR_PHY_CCA_0,
+               AR_PHY_CCA_1,
+               AR_PHY_CCA_2,
+               AR_PHY_EXT_CCA,
+               AR_PHY_EXT_CCA_1,
+               AR_PHY_EXT_CCA_2,
+       };
+       u8 chainmask, rx_chain_status;
+       struct ath_common *common = ath9k_hw_common(ah);
+
+       rx_chain_status = ar9003_hw_get_rx_chainmask(ah);
+
+       chainmask = 0x3F;
+       h = ah->nfCalHist;
+
+       for (i = 0; i < NUM_NF_READINGS; i++) {
+               if (chainmask & (1 << i)) {
+                       val = REG_READ(ah, ar9300_cca_regs[i]);
+                       val &= 0xFFFFFE00;
+                       val |= (((u32) (h[i].privNF) << 1) & 0x1ff);
+                       REG_WRITE(ah, ar9300_cca_regs[i], val);
+               }
+       }
+
+       /*
+        * Load software filtered NF value into baseband internal minCCApwr
+        * variable.
+        */
+       REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
+                   AR_PHY_AGC_CONTROL_ENABLE_NF);
+       REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
+                   AR_PHY_AGC_CONTROL_NO_UPDATE_NF);
+       REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
+
+       /*
+        * Wait for load to complete, should be fast, a few 10s of us.
+        * The max delay was changed from an original 250us to 10000us
+        * since 250us often results in NF load timeout and causes deaf
+        * condition during stress testing 12/12/2009
+        */
+       for (j = 0; j < 1000; j++) {
+               if ((REG_READ(ah, AR_PHY_AGC_CONTROL) &
+                    AR_PHY_AGC_CONTROL_NF) == 0)
+                       break;
+               udelay(10);
+       }
+
+       /*
+        * We timed out waiting for the noisefloor to load, probably due to an
+        * in-progress rx. Simply return here and allow the load plenty of time
+        * to complete before the next calibration interval.  We need to avoid
+        * trying to load -50 (which happens below) while the previous load is
+        * still in progress as this can cause rx deafness. Instead by returning
+        * here, the baseband nf cal will just be capped by our present
+        * noisefloor until the next calibration timer.
+        */
+       if (j == 1000) {
+               ath_print(common, ATH_DBG_ANY, "Timeout while waiting for nf "
+                         "to load: AR_PHY_AGC_CONTROL=0x%x\n",
+                         REG_READ(ah, AR_PHY_AGC_CONTROL));
+       }
+
+       /*
+        * Restore maxCCAPower register parameter again so that we're not capped
+        * by the median we just loaded.  This will be initial (and max) value
+        * of next noise floor calibration the baseband does.
+        */
+       for (i = 0; i < NUM_NF_READINGS; i++) {
+               if (chainmask & (1 << i)) {
+                       val = REG_READ(ah, ar9300_cca_regs[i]);
+                       val &= 0xFFFFFE00;
+                       val |= (((u32) (-50) << 1) & 0x1ff);
+                       REG_WRITE(ah, ar9300_cca_regs[i], val);
+               }
+       }
+}
+
+void ar9003_hw_attach_phy_ops(struct ath_hw *ah)
+{
+       struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
+
+       priv_ops->rf_set_freq = ar9003_hw_set_channel;
+       priv_ops->spur_mitigate_freq = ar9003_hw_spur_mitigate;
+       priv_ops->compute_pll_control = ar9003_hw_compute_pll_control;
+       priv_ops->set_channel_regs = ar9003_hw_set_channel_regs;
+       priv_ops->init_bb = ar9003_hw_init_bb;
+       priv_ops->process_ini = ar9003_hw_process_ini;
+       priv_ops->set_rfmode = ar9003_hw_set_rfmode;
+       priv_ops->mark_phy_inactive = ar9003_hw_mark_phy_inactive;
+       priv_ops->set_delta_slope = ar9003_hw_set_delta_slope;
+       priv_ops->rfbus_req = ar9003_hw_rfbus_req;
+       priv_ops->rfbus_done = ar9003_hw_rfbus_done;
+       priv_ops->enable_rfkill = ar9003_hw_enable_rfkill;
+       priv_ops->set_diversity = ar9003_hw_set_diversity;
+       priv_ops->ani_control = ar9003_hw_ani_control;
+       priv_ops->do_getnf = ar9003_hw_do_getnf;
+       priv_ops->loadnf = ar9003_hw_loadnf;
+}
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.h b/drivers/net/wireless/ath/ath9k/ar9003_phy.h
new file mode 100644 (file)
index 0000000..f08cc8b
--- /dev/null
@@ -0,0 +1,847 @@
+/*
+ * Copyright (c) 2002-2010 Atheros Communications, Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT 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.
+ */
+
+#ifndef AR9003_PHY_H
+#define AR9003_PHY_H
+
+/*
+ * Channel Register Map
+ */
+#define AR_CHAN_BASE   0x9800
+
+#define AR_PHY_TIMING1      (AR_CHAN_BASE + 0x0)
+#define AR_PHY_TIMING2      (AR_CHAN_BASE + 0x4)
+#define AR_PHY_TIMING3      (AR_CHAN_BASE + 0x8)
+#define AR_PHY_TIMING4      (AR_CHAN_BASE + 0xc)
+#define AR_PHY_TIMING5      (AR_CHAN_BASE + 0x10)
+#define AR_PHY_TIMING6      (AR_CHAN_BASE + 0x14)
+#define AR_PHY_TIMING11     (AR_CHAN_BASE + 0x18)
+#define AR_PHY_SPUR_REG     (AR_CHAN_BASE + 0x1c)
+#define AR_PHY_RX_IQCAL_CORR_B0    (AR_CHAN_BASE + 0xdc)
+#define AR_PHY_TX_IQCAL_CONTROL_3  (AR_CHAN_BASE + 0xb0)
+
+#define AR_PHY_TIMING11_SPUR_FREQ_SD    0x3FF00000
+#define AR_PHY_TIMING11_SPUR_FREQ_SD_S  20
+
+#define AR_PHY_TIMING11_SPUR_DELTA_PHASE 0x000FFFFF
+#define AR_PHY_TIMING11_SPUR_DELTA_PHASE_S 0
+
+#define AR_PHY_TIMING11_USE_SPUR_FILTER_IN_AGC 0x40000000
+#define AR_PHY_TIMING11_USE_SPUR_FILTER_IN_AGC_S 30
+
+#define AR_PHY_TIMING11_USE_SPUR_FILTER_IN_SELFCOR 0x80000000
+#define AR_PHY_TIMING11_USE_SPUR_FILTER_IN_SELFCOR_S 31
+
+#define AR_PHY_SPUR_REG_ENABLE_NF_RSSI_SPUR_MIT         0x4000000
+#define AR_PHY_SPUR_REG_ENABLE_NF_RSSI_SPUR_MIT_S       26
+
+#define AR_PHY_SPUR_REG_ENABLE_MASK_PPM                         0x20000     /* bins move with freq offset */
+#define AR_PHY_SPUR_REG_ENABLE_MASK_PPM_S                       17
+#define AR_PHY_SPUR_REG_SPUR_RSSI_THRESH            0x000000FF
+#define AR_PHY_SPUR_REG_SPUR_RSSI_THRESH_S          0
+#define AR_PHY_SPUR_REG_EN_VIT_SPUR_RSSI                        0x00000100
+#define AR_PHY_SPUR_REG_EN_VIT_SPUR_RSSI_S                      8
+#define AR_PHY_SPUR_REG_MASK_RATE_CNTL                          0x03FC0000
+#define AR_PHY_SPUR_REG_MASK_RATE_CNTL_S                       18
+
+#define AR_PHY_RX_IQCAL_CORR_B0_LOOPBACK_IQCORR_EN   0x20000000
+#define AR_PHY_RX_IQCAL_CORR_B0_LOOPBACK_IQCORR_EN_S         29
+
+#define AR_PHY_TX_IQCAL_CONTROL_3_IQCORR_EN   0x80000000
+#define AR_PHY_TX_IQCAL_CONTROL_3_IQCORR_EN_S         31
+
+#define AR_PHY_FIND_SIG_LOW  (AR_CHAN_BASE + 0x20)
+
+#define AR_PHY_SFCORR           (AR_CHAN_BASE + 0x24)
+#define AR_PHY_SFCORR_LOW       (AR_CHAN_BASE + 0x28)
+#define AR_PHY_SFCORR_EXT       (AR_CHAN_BASE + 0x2c)
+
+#define AR_PHY_EXT_CCA              (AR_CHAN_BASE + 0x30)
+#define AR_PHY_RADAR_0              (AR_CHAN_BASE + 0x34)
+#define AR_PHY_RADAR_1              (AR_CHAN_BASE + 0x38)
+#define AR_PHY_RADAR_EXT            (AR_CHAN_BASE + 0x3c)
+#define AR_PHY_MULTICHAIN_CTRL      (AR_CHAN_BASE + 0x80)
+#define AR_PHY_PERCHAIN_CSD         (AR_CHAN_BASE + 0x84)
+
+#define AR_PHY_TX_PHASE_RAMP_0      (AR_CHAN_BASE + 0xd0)
+#define AR_PHY_ADC_GAIN_DC_CORR_0   (AR_CHAN_BASE + 0xd4)
+#define AR_PHY_IQ_ADC_MEAS_0_B0     (AR_CHAN_BASE + 0xc0)
+#define AR_PHY_IQ_ADC_MEAS_1_B0     (AR_CHAN_BASE + 0xc4)
+#define AR_PHY_IQ_ADC_MEAS_2_B0     (AR_CHAN_BASE + 0xc8)
+#define AR_PHY_IQ_ADC_MEAS_3_B0     (AR_CHAN_BASE + 0xcc)
+
+/* The following registers changed position from AR9300 1.0 to AR9300 2.0 */
+#define AR_PHY_TX_PHASE_RAMP_0_9300_10      (AR_CHAN_BASE + 0xd0 - 0x10)
+#define AR_PHY_ADC_GAIN_DC_CORR_0_9300_10   (AR_CHAN_BASE + 0xd4 - 0x10)
+#define AR_PHY_IQ_ADC_MEAS_0_B0_9300_10     (AR_CHAN_BASE + 0xc0 + 0x8)
+#define AR_PHY_IQ_ADC_MEAS_1_B0_9300_10     (AR_CHAN_BASE + 0xc4 + 0x8)
+#define AR_PHY_IQ_ADC_MEAS_2_B0_9300_10     (AR_CHAN_BASE + 0xc8 + 0x8)
+#define AR_PHY_IQ_ADC_MEAS_3_B0_9300_10     (AR_CHAN_BASE + 0xcc + 0x8)
+
+#define AR_PHY_TX_CRC               (AR_CHAN_BASE + 0xa0)
+#define AR_PHY_TST_DAC_CONST        (AR_CHAN_BASE + 0xa4)
+#define AR_PHY_SPUR_REPORT_0        (AR_CHAN_BASE + 0xa8)
+#define AR_PHY_CHAN_INFO_TAB_0      (AR_CHAN_BASE + 0x300)
+
+/*
+ * Channel Field Definitions
+ */
+#define AR_PHY_TIMING2_USE_FORCE_PPM    0x00001000
+#define AR_PHY_TIMING2_FORCE_PPM_VAL    0x00000fff
+#define AR_PHY_TIMING3_DSC_MAN      0xFFFE0000
+#define AR_PHY_TIMING3_DSC_MAN_S    17
+#define AR_PHY_TIMING3_DSC_EXP      0x0001E000
+#define AR_PHY_TIMING3_DSC_EXP_S    13
+#define AR_PHY_TIMING4_IQCAL_LOG_COUNT_MAX 0xF000
+#define AR_PHY_TIMING4_IQCAL_LOG_COUNT_MAX_S   12
+#define AR_PHY_TIMING4_DO_CAL    0x10000
+
+#define AR_PHY_TIMING4_ENABLE_PILOT_MASK        0x10000000
+#define AR_PHY_TIMING4_ENABLE_PILOT_MASK_S      28
+#define AR_PHY_TIMING4_ENABLE_CHAN_MASK         0x20000000
+#define AR_PHY_TIMING4_ENABLE_CHAN_MASK_S       29
+
+#define AR_PHY_TIMING4_ENABLE_SPUR_FILTER 0x40000000
+#define AR_PHY_TIMING4_ENABLE_SPUR_FILTER_S 30
+#define AR_PHY_TIMING4_ENABLE_SPUR_RSSI 0x80000000
+#define AR_PHY_TIMING4_ENABLE_SPUR_RSSI_S 31
+
+#define AR_PHY_NEW_ADC_GAIN_CORR_ENABLE 0x40000000
+#define AR_PHY_NEW_ADC_DC_OFFSET_CORR_ENABLE 0x80000000
+#define AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW  0x00000001
+#define AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW    0x00003F00
+#define AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW_S  8
+#define AR_PHY_SFCORR_LOW_M1_THRESH_LOW      0x001FC000
+#define AR_PHY_SFCORR_LOW_M1_THRESH_LOW_S    14
+#define AR_PHY_SFCORR_LOW_M2_THRESH_LOW      0x0FE00000
+#define AR_PHY_SFCORR_LOW_M2_THRESH_LOW_S    21
+#define AR_PHY_SFCORR_M2COUNT_THR    0x0000001F
+#define AR_PHY_SFCORR_M2COUNT_THR_S  0
+#define AR_PHY_SFCORR_M1_THRESH      0x00FE0000
+#define AR_PHY_SFCORR_M1_THRESH_S    17
+#define AR_PHY_SFCORR_M2_THRESH      0x7F000000
+#define AR_PHY_SFCORR_M2_THRESH_S    24
+#define AR_PHY_SFCORR_EXT_M1_THRESH       0x0000007F
+#define AR_PHY_SFCORR_EXT_M1_THRESH_S     0
+#define AR_PHY_SFCORR_EXT_M2_THRESH       0x00003F80
+#define AR_PHY_SFCORR_EXT_M2_THRESH_S     7
+#define AR_PHY_SFCORR_EXT_M1_THRESH_LOW   0x001FC000
+#define AR_PHY_SFCORR_EXT_M1_THRESH_LOW_S 14
+#define AR_PHY_SFCORR_EXT_M2_THRESH_LOW   0x0FE00000
+#define AR_PHY_SFCORR_EXT_M2_THRESH_LOW_S 21
+#define AR_PHY_SFCORR_EXT_SPUR_SUBCHANNEL_SD 0x10000000
+#define AR_PHY_SFCORR_EXT_SPUR_SUBCHANNEL_SD_S 28
+#define AR_PHY_SFCORR_SPUR_SUBCHNL_SD_S   28
+#define AR_PHY_EXT_CCA_THRESH62 0x007F0000
+#define AR_PHY_EXT_CCA_THRESH62_S       16
+#define AR_PHY_EXT_MINCCA_PWR   0x01FF0000
+#define AR_PHY_EXT_MINCCA_PWR_S 16
+#define AR_PHY_TIMING5_CYCPWR_THR1  0x000000FE
+#define AR_PHY_TIMING5_CYCPWR_THR1_S    1
+#define AR_PHY_TIMING5_CYCPWR_THR1_ENABLE  0x00000001
+#define AR_PHY_TIMING5_CYCPWR_THR1_ENABLE_S    0
+#define AR_PHY_TIMING5_CYCPWR_THR1A  0x007F0000
+#define AR_PHY_TIMING5_CYCPWR_THR1A_S    16
+#define AR_PHY_TIMING5_RSSI_THR1A     (0x7F << 16)
+#define AR_PHY_TIMING5_RSSI_THR1A_S   16
+#define AR_PHY_TIMING5_RSSI_THR1A_ENA (0x1 << 15)
+#define AR_PHY_RADAR_0_ENA  0x00000001
+#define AR_PHY_RADAR_0_FFT_ENA  0x80000000
+#define AR_PHY_RADAR_0_INBAND   0x0000003e
+#define AR_PHY_RADAR_0_INBAND_S 1
+#define AR_PHY_RADAR_0_PRSSI    0x00000FC0
+#define AR_PHY_RADAR_0_PRSSI_S  6
+#define AR_PHY_RADAR_0_HEIGHT   0x0003F000
+#define AR_PHY_RADAR_0_HEIGHT_S 12
+#define AR_PHY_RADAR_0_RRSSI    0x00FC0000
+#define AR_PHY_RADAR_0_RRSSI_S  18
+#define AR_PHY_RADAR_0_FIRPWR   0x7F000000
+#define AR_PHY_RADAR_0_FIRPWR_S 24
+#define AR_PHY_RADAR_1_RELPWR_ENA       0x00800000
+#define AR_PHY_RADAR_1_USE_FIR128       0x00400000
+#define AR_PHY_RADAR_1_RELPWR_THRESH    0x003F0000
+#define AR_PHY_RADAR_1_RELPWR_THRESH_S  16
+#define AR_PHY_RADAR_1_BLOCK_CHECK      0x00008000
+#define AR_PHY_RADAR_1_MAX_RRSSI        0x00004000
+#define AR_PHY_RADAR_1_RELSTEP_CHECK    0x00002000
+#define AR_PHY_RADAR_1_RELSTEP_THRESH   0x00001F00
+#define AR_PHY_RADAR_1_RELSTEP_THRESH_S 8
+#define AR_PHY_RADAR_1_MAXLEN           0x000000FF
+#define AR_PHY_RADAR_1_MAXLEN_S         0
+#define AR_PHY_RADAR_EXT_ENA            0x00004000
+#define AR_PHY_RADAR_DC_PWR_THRESH      0x007f8000
+#define AR_PHY_RADAR_DC_PWR_THRESH_S    15
+#define AR_PHY_RADAR_LB_DC_CAP          0x7f800000
+#define AR_PHY_RADAR_LB_DC_CAP_S        23
+#define AR_PHY_FIND_SIG_LOW_FIRSTEP_LOW (0x3f << 6)
+#define AR_PHY_FIND_SIG_LOW_FIRSTEP_LOW_S   6
+#define AR_PHY_FIND_SIG_LOW_FIRPWR      (0x7f << 12)
+#define AR_PHY_FIND_SIG_LOW_FIRPWR_S    12
+#define AR_PHY_FIND_SIG_LOW_FIRPWR_SIGN_BIT 19
+#define AR_PHY_FIND_SIG_LOW_RELSTEP     0x1f
+#define AR_PHY_FIND_SIG_LOW_RELSTEP_S   0
+#define AR_PHY_FIND_SIG_LOW_RELSTEP_SIGN_BIT 5
+#define AR_PHY_CHAN_INFO_TAB_S2_READ    0x00000008
+#define AR_PHY_CHAN_INFO_TAB_S2_READ_S           3
+#define AR_PHY_RX_IQCAL_CORR_IQCORR_Q_Q_COFF 0x0000007F
+#define AR_PHY_RX_IQCAL_CORR_IQCORR_Q_Q_COFF_S   0
+#define AR_PHY_RX_IQCAL_CORR_IQCORR_Q_I_COFF 0x00003F80
+#define AR_PHY_RX_IQCAL_CORR_IQCORR_Q_I_COFF_S   7
+#define AR_PHY_RX_IQCAL_CORR_IQCORR_ENABLE   0x00004000
+#define AR_PHY_RX_IQCAL_CORR_LOOPBACK_IQCORR_Q_Q_COFF   0x003f8000
+#define AR_PHY_RX_IQCAL_CORR_LOOPBACK_IQCORR_Q_Q_COFF_S 15
+#define AR_PHY_RX_IQCAL_CORR_LOOPBACK_IQCORR_Q_I_COFF   0x1fc00000
+#define AR_PHY_RX_IQCAL_CORR_LOOPBACK_IQCORR_Q_I_COFF_S 22
+
+/*
+ * MRC Register Map
+ */
+#define AR_MRC_BASE    0x9c00
+
+#define AR_PHY_TIMING_3A       (AR_MRC_BASE + 0x0)
+#define AR_PHY_LDPC_CNTL1      (AR_MRC_BASE + 0x4)
+#define AR_PHY_LDPC_CNTL2      (AR_MRC_BASE + 0x8)
+#define AR_PHY_PILOT_SPUR_MASK (AR_MRC_BASE + 0xc)
+#define AR_PHY_CHAN_SPUR_MASK  (AR_MRC_BASE + 0x10)
+#define AR_PHY_SGI_DELTA       (AR_MRC_BASE + 0x14)
+#define AR_PHY_ML_CNTL_1       (AR_MRC_BASE + 0x18)
+#define AR_PHY_ML_CNTL_2       (AR_MRC_BASE + 0x1c)
+#define AR_PHY_TST_ADC         (AR_MRC_BASE + 0x20)
+
+#define AR_PHY_PILOT_SPUR_MASK_CF_PILOT_MASK_IDX_A              0x00000FE0
+#define AR_PHY_PILOT_SPUR_MASK_CF_PILOT_MASK_IDX_A_S    5
+#define AR_PHY_PILOT_SPUR_MASK_CF_PILOT_MASK_A                  0x1F
+#define AR_PHY_PILOT_SPUR_MASK_CF_PILOT_MASK_A_S                0
+
+#define AR_PHY_CHAN_SPUR_MASK_CF_CHAN_MASK_IDX_A        0x00000FE0
+#define AR_PHY_CHAN_SPUR_MASK_CF_CHAN_MASK_IDX_A_S      5
+#define AR_PHY_CHAN_SPUR_MASK_CF_CHAN_MASK_A            0x1F
+#define AR_PHY_CHAN_SPUR_MASK_CF_CHAN_MASK_A_S         0
+
+/*
+ * MRC Feild Definitions
+ */
+#define AR_PHY_SGI_DSC_MAN   0x0007FFF0
+#define AR_PHY_SGI_DSC_MAN_S 4
+#define AR_PHY_SGI_DSC_EXP   0x0000000F
+#define AR_PHY_SGI_DSC_EXP_S 0
+/*
+ * BBB Register Map
+ */
+#define AR_BBB_BASE    0x9d00
+
+/*
+ * AGC Register Map
+ */
+#define AR_AGC_BASE    0x9e00
+
+#define AR_PHY_SETTLING         (AR_AGC_BASE + 0x0)
+#define AR_PHY_FORCEMAX_GAINS_0 (AR_AGC_BASE + 0x4)
+#define AR_PHY_GAINS_MINOFF0    (AR_AGC_BASE + 0x8)
+#define AR_PHY_DESIRED_SZ       (AR_AGC_BASE + 0xc)
+#define AR_PHY_FIND_SIG         (AR_AGC_BASE + 0x10)
+#define AR_PHY_AGC              (AR_AGC_BASE + 0x14)
+#define AR_PHY_EXT_ATTEN_CTL_0  (AR_AGC_BASE + 0x18)
+#define AR_PHY_CCA_0            (AR_AGC_BASE + 0x1c)
+#define AR_PHY_EXT_CCA0         (AR_AGC_BASE + 0x20)
+#define AR_PHY_RESTART          (AR_AGC_BASE + 0x24)
+#define AR_PHY_MC_GAIN_CTRL     (AR_AGC_BASE + 0x28)
+#define AR_PHY_EXTCHN_PWRTHR1   (AR_AGC_BASE + 0x2c)
+#define AR_PHY_EXT_CHN_WIN      (AR_AGC_BASE + 0x30)
+#define AR_PHY_20_40_DET_THR    (AR_AGC_BASE + 0x34)
+#define AR_PHY_RIFS_SRCH        (AR_AGC_BASE + 0x38)
+#define AR_PHY_PEAK_DET_CTRL_1  (AR_AGC_BASE + 0x3c)
+#define AR_PHY_PEAK_DET_CTRL_2  (AR_AGC_BASE + 0x40)
+#define AR_PHY_RX_GAIN_BOUNDS_1 (AR_AGC_BASE + 0x44)
+#define AR_PHY_RX_GAIN_BOUNDS_2 (AR_AGC_BASE + 0x48)
+#define AR_PHY_RSSI_0           (AR_AGC_BASE + 0x180)
+#define AR_PHY_SPUR_CCK_REP0    (AR_AGC_BASE + 0x184)
+#define AR_PHY_CCK_DETECT       (AR_AGC_BASE + 0x1c0)
+#define AR_PHY_DAG_CTRLCCK      (AR_AGC_BASE + 0x1c4)
+#define AR_PHY_IQCORR_CTRL_CCK  (AR_AGC_BASE + 0x1c8)
+
+#define AR_PHY_CCK_SPUR_MIT     (AR_AGC_BASE + 0x1cc)
+#define AR_PHY_CCK_SPUR_MIT_SPUR_RSSI_THR                           0x000001fe
+#define AR_PHY_CCK_SPUR_MIT_SPUR_RSSI_THR_S                                  1
+#define AR_PHY_CCK_SPUR_MIT_SPUR_FILTER_TYPE                        0x60000000
+#define AR_PHY_CCK_SPUR_MIT_SPUR_FILTER_TYPE_S                              29
+#define AR_PHY_CCK_SPUR_MIT_USE_CCK_SPUR_MIT                        0x00000001
+#define AR_PHY_CCK_SPUR_MIT_USE_CCK_SPUR_MIT_S                               0
+#define AR_PHY_CCK_SPUR_MIT_CCK_SPUR_FREQ                           0x1ffffe00
+#define AR_PHY_CCK_SPUR_MIT_CCK_SPUR_FREQ_S                                  9
+
+#define AR_PHY_RX_OCGAIN        (AR_AGC_BASE + 0x200)
+
+#define AR_PHY_CCA_NOM_VAL_9300_2GHZ          -110
+#define AR_PHY_CCA_NOM_VAL_9300_5GHZ          -115
+#define AR_PHY_CCA_MIN_GOOD_VAL_9300_2GHZ     -125
+#define AR_PHY_CCA_MIN_GOOD_VAL_9300_5GHZ     -125
+#define AR_PHY_CCA_MAX_GOOD_VAL_9300_2GHZ     -95
+#define AR_PHY_CCA_MAX_GOOD_VAL_9300_5GHZ     -100
+
+/*
+ * AGC Field Definitions
+ */
+#define AR_PHY_EXT_ATTEN_CTL_RXTX_MARGIN    0x00FC0000
+#define AR_PHY_EXT_ATTEN_CTL_RXTX_MARGIN_S  18
+#define AR_PHY_EXT_ATTEN_CTL_BSW_MARGIN     0x00003C00
+#define AR_PHY_EXT_ATTEN_CTL_BSW_MARGIN_S   10
+#define AR_PHY_EXT_ATTEN_CTL_BSW_ATTEN      0x0000001F
+#define AR_PHY_EXT_ATTEN_CTL_BSW_ATTEN_S    0
+#define AR_PHY_EXT_ATTEN_CTL_XATTEN2_MARGIN     0x003E0000
+#define AR_PHY_EXT_ATTEN_CTL_XATTEN2_MARGIN_S   17
+#define AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN     0x0001F000
+#define AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN_S   12
+#define AR_PHY_EXT_ATTEN_CTL_XATTEN2_DB         0x00000FC0
+#define AR_PHY_EXT_ATTEN_CTL_XATTEN2_DB_S       6
+#define AR_PHY_EXT_ATTEN_CTL_XATTEN1_DB         0x0000003F
+#define AR_PHY_EXT_ATTEN_CTL_XATTEN1_DB_S       0
+#define AR_PHY_RXGAIN_TXRX_ATTEN    0x0003F000
+#define AR_PHY_RXGAIN_TXRX_ATTEN_S  12
+#define AR_PHY_RXGAIN_TXRX_RF_MAX   0x007C0000
+#define AR_PHY_RXGAIN_TXRX_RF_MAX_S 18
+#define AR9280_PHY_RXGAIN_TXRX_ATTEN    0x00003F80
+#define AR9280_PHY_RXGAIN_TXRX_ATTEN_S  7
+#define AR9280_PHY_RXGAIN_TXRX_MARGIN   0x001FC000
+#define AR9280_PHY_RXGAIN_TXRX_MARGIN_S 14
+#define AR_PHY_SETTLING_SWITCH  0x00003F80
+#define AR_PHY_SETTLING_SWITCH_S    7
+#define AR_PHY_DESIRED_SZ_ADC       0x000000FF
+#define AR_PHY_DESIRED_SZ_ADC_S     0
+#define AR_PHY_DESIRED_SZ_PGA       0x0000FF00
+#define AR_PHY_DESIRED_SZ_PGA_S     8
+#define AR_PHY_DESIRED_SZ_TOT_DES   0x0FF00000
+#define AR_PHY_DESIRED_SZ_TOT_DES_S 20
+#define AR_PHY_MINCCA_PWR       0x1FF00000
+#define AR_PHY_MINCCA_PWR_S     20
+#define AR_PHY_CCA_THRESH62     0x0007F000
+#define AR_PHY_CCA_THRESH62_S   12
+#define AR9280_PHY_MINCCA_PWR       0x1FF00000
+#define AR9280_PHY_MINCCA_PWR_S     20
+#define AR9280_PHY_CCA_THRESH62     0x000FF000
+#define AR9280_PHY_CCA_THRESH62_S   12
+#define AR_PHY_EXT_CCA0_THRESH62    0x000000FF
+#define AR_PHY_EXT_CCA0_THRESH62_S  0
+#define AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK          0x0000003F
+#define AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK_S        0
+#define AR_PHY_CCK_DETECT_ANT_SWITCH_TIME           0x00001FC0
+#define AR_PHY_CCK_DETECT_ANT_SWITCH_TIME_S         6
+#define AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV    0x2000
+
+#define AR_PHY_DAG_CTRLCCK_EN_RSSI_THR  0x00000200
+#define AR_PHY_DAG_CTRLCCK_EN_RSSI_THR_S  9
+#define AR_PHY_DAG_CTRLCCK_RSSI_THR 0x0001FC00
+#define AR_PHY_DAG_CTRLCCK_RSSI_THR_S   10
+
+#define AR_PHY_RIFS_INIT_DELAY         0x3ff0000
+#define AR_PHY_AGC_COARSE_LOW       0x00007F80
+#define AR_PHY_AGC_COARSE_LOW_S     7
+#define AR_PHY_AGC_COARSE_HIGH      0x003F8000
+#define AR_PHY_AGC_COARSE_HIGH_S    15
+#define AR_PHY_AGC_COARSE_PWR_CONST 0x0000007F
+#define AR_PHY_AGC_COARSE_PWR_CONST_S   0
+#define AR_PHY_FIND_SIG_FIRSTEP  0x0003F000
+#define AR_PHY_FIND_SIG_FIRSTEP_S        12
+#define AR_PHY_FIND_SIG_FIRPWR   0x03FC0000
+#define AR_PHY_FIND_SIG_FIRPWR_S         18
+#define AR_PHY_FIND_SIG_FIRPWR_SIGN_BIT  25
+#define AR_PHY_FIND_SIG_RELPWR   (0x1f << 6)
+#define AR_PHY_FIND_SIG_RELPWR_S          6
+#define AR_PHY_FIND_SIG_RELPWR_SIGN_BIT  11
+#define AR_PHY_FIND_SIG_RELSTEP        0x1f
+#define AR_PHY_FIND_SIG_RELSTEP_S         0
+#define AR_PHY_FIND_SIG_RELSTEP_SIGN_BIT  5
+#define AR_PHY_RESTART_DIV_GC   0x001C0000
+#define AR_PHY_RESTART_DIV_GC_S 18
+#define AR_PHY_RESTART_ENA      0x01
+#define AR_PHY_DC_RESTART_DIS   0x40000000
+
+#define AR_PHY_TPC_OLPC_GAIN_DELTA_PAL_ON       0xFF000000
+#define AR_PHY_TPC_OLPC_GAIN_DELTA_PAL_ON_S     24
+#define AR_PHY_TPC_OLPC_GAIN_DELTA              0x00FF0000
+#define AR_PHY_TPC_OLPC_GAIN_DELTA_S            16
+
+#define AR_PHY_TPC_6_ERROR_EST_MODE             0x03000000
+#define AR_PHY_TPC_6_ERROR_EST_MODE_S           24
+
+/*
+ * SM Register Map
+ */
+#define AR_SM_BASE     0xa200
+
+#define AR_PHY_D2_CHIP_ID        (AR_SM_BASE + 0x0)
+#define AR_PHY_GEN_CTRL          (AR_SM_BASE + 0x4)
+#define AR_PHY_MODE              (AR_SM_BASE + 0x8)
+#define AR_PHY_ACTIVE            (AR_SM_BASE + 0xc)
+#define AR_PHY_SPUR_MASK_A       (AR_SM_BASE + 0x20)
+#define AR_PHY_SPUR_MASK_B       (AR_SM_BASE + 0x24)
+#define AR_PHY_SPECTRAL_SCAN     (AR_SM_BASE + 0x28)
+#define AR_PHY_RADAR_BW_FILTER   (AR_SM_BASE + 0x2c)
+#define AR_PHY_SEARCH_START_DELAY (AR_SM_BASE + 0x30)
+#define AR_PHY_MAX_RX_LEN        (AR_SM_BASE + 0x34)
+#define AR_PHY_FRAME_CTL         (AR_SM_BASE + 0x38)
+#define AR_PHY_RFBUS_REQ         (AR_SM_BASE + 0x3c)
+#define AR_PHY_RFBUS_GRANT       (AR_SM_BASE + 0x40)
+#define AR_PHY_RIFS              (AR_SM_BASE + 0x44)
+#define AR_PHY_RX_CLR_DELAY      (AR_SM_BASE + 0x50)
+#define AR_PHY_RX_DELAY          (AR_SM_BASE + 0x54)
+
+#define AR_PHY_XPA_TIMING_CTL    (AR_SM_BASE + 0x64)
+#define AR_PHY_MISC_PA_CTL       (AR_SM_BASE + 0x80)
+#define AR_PHY_SWITCH_CHAIN_0    (AR_SM_BASE + 0x84)
+#define AR_PHY_SWITCH_COM        (AR_SM_BASE + 0x88)
+#define AR_PHY_SWITCH_COM_2      (AR_SM_BASE + 0x8c)
+#define AR_PHY_RX_CHAINMASK      (AR_SM_BASE + 0xa0)
+#define AR_PHY_CAL_CHAINMASK     (AR_SM_BASE + 0xc0)
+#define AR_PHY_CALMODE           (AR_SM_BASE + 0xc8)
+#define AR_PHY_FCAL_1            (AR_SM_BASE + 0xcc)
+#define AR_PHY_FCAL_2_0          (AR_SM_BASE + 0xd0)
+#define AR_PHY_DFT_TONE_CTL_0    (AR_SM_BASE + 0xd4)
+#define AR_PHY_CL_CAL_CTL        (AR_SM_BASE + 0xd8)
+#define AR_PHY_CL_TAB_0          (AR_SM_BASE + 0x100)
+#define AR_PHY_SYNTH_CONTROL     (AR_SM_BASE + 0x140)
+#define AR_PHY_ADDAC_CLK_SEL     (AR_SM_BASE + 0x144)
+#define AR_PHY_PLL_CTL           (AR_SM_BASE + 0x148)
+#define AR_PHY_ANALOG_SWAP       (AR_SM_BASE + 0x14c)
+#define AR_PHY_ADDAC_PARA_CTL    (AR_SM_BASE + 0x150)
+#define AR_PHY_XPA_CFG           (AR_SM_BASE + 0x158)
+
+#define AR_PHY_SPUR_MASK_A_CF_PUNC_MASK_IDX_A           0x0001FC00
+#define AR_PHY_SPUR_MASK_A_CF_PUNC_MASK_IDX_A_S         10
+#define AR_PHY_SPUR_MASK_A_CF_PUNC_MASK_A                       0x3FF
+#define AR_PHY_SPUR_MASK_A_CF_PUNC_MASK_A_S                     0
+
+#define AR_PHY_TEST              (AR_SM_BASE + 0x160)
+
+#define AR_PHY_TEST_BBB_OBS_SEL       0x780000
+#define AR_PHY_TEST_BBB_OBS_SEL_S     19
+
+#define AR_PHY_TEST_RX_OBS_SEL_BIT5_S 23
+#define AR_PHY_TEST_RX_OBS_SEL_BIT5   (1 << AR_PHY_TEST_RX_OBS_SEL_BIT5_S)
+
+#define AR_PHY_TEST_CHAIN_SEL      0xC0000000
+#define AR_PHY_TEST_CHAIN_SEL_S    30
+
+#define AR_PHY_TEST_CTL_STATUS   (AR_SM_BASE + 0x164)
+#define AR_PHY_TEST_CTL_TSTDAC_EN         0x1
+#define AR_PHY_TEST_CTL_TSTDAC_EN_S       0
+#define AR_PHY_TEST_CTL_TX_OBS_SEL        0x1C
+#define AR_PHY_TEST_CTL_TX_OBS_SEL_S      2
+#define AR_PHY_TEST_CTL_TX_OBS_MUX_SEL    0x60
+#define AR_PHY_TEST_CTL_TX_OBS_MUX_SEL_S  5
+#define AR_PHY_TEST_CTL_TSTADC_EN         0x100
+#define AR_PHY_TEST_CTL_TSTADC_EN_S       8
+#define AR_PHY_TEST_CTL_RX_OBS_SEL        0x3C00
+#define AR_PHY_TEST_CTL_RX_OBS_SEL_S      10
+
+
+#define AR_PHY_TSTDAC            (AR_SM_BASE + 0x168)
+
+#define AR_PHY_CHAN_STATUS       (AR_SM_BASE + 0x16c)
+#define AR_PHY_CHAN_INFO_MEMORY  (AR_SM_BASE + 0x170)
+#define AR_PHY_CHNINFO_NOISEPWR  (AR_SM_BASE + 0x174)
+#define AR_PHY_CHNINFO_GAINDIFF  (AR_SM_BASE + 0x178)
+#define AR_PHY_CHNINFO_FINETIM   (AR_SM_BASE + 0x17c)
+#define AR_PHY_CHAN_INFO_GAIN_0  (AR_SM_BASE + 0x180)
+#define AR_PHY_SCRAMBLER_SEED    (AR_SM_BASE + 0x190)
+#define AR_PHY_CCK_TX_CTRL       (AR_SM_BASE + 0x194)
+
+#define AR_PHY_HEAVYCLIP_CTL     (AR_SM_BASE + 0x1a4)
+#define AR_PHY_HEAVYCLIP_20      (AR_SM_BASE + 0x1a8)
+#define AR_PHY_HEAVYCLIP_40      (AR_SM_BASE + 0x1ac)
+#define AR_PHY_ILLEGAL_TXRATE    (AR_SM_BASE + 0x1b0)
+
+#define AR_PHY_PWRTX_MAX         (AR_SM_BASE + 0x1f0)
+#define AR_PHY_POWER_TX_SUB      (AR_SM_BASE + 0x1f4)
+
+#define AR_PHY_TPC_4_B0          (AR_SM_BASE + 0x204)
+#define AR_PHY_TPC_5_B0          (AR_SM_BASE + 0x208)
+#define AR_PHY_TPC_6_B0          (AR_SM_BASE + 0x20c)
+#define AR_PHY_TPC_11_B0         (AR_SM_BASE + 0x220)
+#define AR_PHY_TPC_18            (AR_SM_BASE + 0x23c)
+#define AR_PHY_TPC_19            (AR_SM_BASE + 0x240)
+
+#define AR_PHY_TX_FORCED_GAIN    (AR_SM_BASE + 0x258)
+
+#define AR_PHY_PDADC_TAB_0       (AR_SM_BASE + 0x280)
+
+#define AR_PHY_TX_IQCAL_CONTROL_1   (AR_SM_BASE + 0x448)
+#define AR_PHY_TX_IQCAL_START       (AR_SM_BASE + 0x440)
+#define AR_PHY_TX_IQCAL_STATUS_B0   (AR_SM_BASE + 0x48c)
+#define AR_PHY_TX_IQCAL_CORR_COEFF_01_B0    (AR_SM_BASE + 0x450)
+
+#define AR_PHY_PANIC_WD_STATUS      (AR_SM_BASE + 0x5c0)
+#define AR_PHY_PANIC_WD_CTL_1       (AR_SM_BASE + 0x5c4)
+#define AR_PHY_PANIC_WD_CTL_2       (AR_SM_BASE + 0x5c8)
+#define AR_PHY_BT_CTL               (AR_SM_BASE + 0x5cc)
+#define AR_PHY_ONLY_WARMRESET       (AR_SM_BASE + 0x5d0)
+#define AR_PHY_ONLY_CTL             (AR_SM_BASE + 0x5d4)
+#define AR_PHY_ECO_CTRL             (AR_SM_BASE + 0x5dc)
+#define AR_PHY_BB_THERM_ADC_1       (AR_SM_BASE + 0x248)
+
+#define AR_PHY_65NM_CH0_SYNTH4      0x1608c
+#define AR_PHY_SYNTH4_LONG_SHIFT_SELECT   0x00000002
+#define AR_PHY_SYNTH4_LONG_SHIFT_SELECT_S 1
+#define AR_PHY_65NM_CH0_SYNTH7      0x16098
+#define AR_PHY_65NM_CH0_BIAS1       0x160c0
+#define AR_PHY_65NM_CH0_BIAS2       0x160c4
+#define AR_PHY_65NM_CH0_BIAS4       0x160cc
+#define AR_PHY_65NM_CH0_RXTX4       0x1610c
+#define AR_PHY_65NM_CH0_THERM       0x16290
+
+#define AR_PHY_65NM_CH0_THERM_LOCAL   0x80000000
+#define AR_PHY_65NM_CH0_THERM_LOCAL_S 31
+#define AR_PHY_65NM_CH0_THERM_START   0x20000000
+#define AR_PHY_65NM_CH0_THERM_START_S 29
+#define AR_PHY_65NM_CH0_THERM_SAR_ADC_OUT   0x0000ff00
+#define AR_PHY_65NM_CH0_THERM_SAR_ADC_OUT_S 8
+
+#define AR_PHY_65NM_CH0_RXTX1       0x16100
+#define AR_PHY_65NM_CH0_RXTX2       0x16104
+#define AR_PHY_65NM_CH1_RXTX1       0x16500
+#define AR_PHY_65NM_CH1_RXTX2       0x16504
+#define AR_PHY_65NM_CH2_RXTX1       0x16900
+#define AR_PHY_65NM_CH2_RXTX2       0x16904
+
+#define AR_PHY_RX1DB_BIQUAD_LONG_SHIFT         0x00380000
+#define AR_PHY_RX1DB_BIQUAD_LONG_SHIFT_S       19
+#define AR_PHY_RX6DB_BIQUAD_LONG_SHIFT         0x00c00000
+#define AR_PHY_RX6DB_BIQUAD_LONG_SHIFT_S       22
+#define AR_PHY_LNAGAIN_LONG_SHIFT              0xe0000000
+#define AR_PHY_LNAGAIN_LONG_SHIFT_S            29
+#define AR_PHY_MXRGAIN_LONG_SHIFT              0x03000000
+#define AR_PHY_MXRGAIN_LONG_SHIFT_S            24
+#define AR_PHY_VGAGAIN_LONG_SHIFT              0x1c000000
+#define AR_PHY_VGAGAIN_LONG_SHIFT_S            26
+#define AR_PHY_SCFIR_GAIN_LONG_SHIFT           0x00000001
+#define AR_PHY_SCFIR_GAIN_LONG_SHIFT_S         0
+#define AR_PHY_MANRXGAIN_LONG_SHIFT            0x00000002
+#define AR_PHY_MANRXGAIN_LONG_SHIFT_S          1
+
+/*
+ * SM Field Definitions
+ */
+#define AR_PHY_CL_CAL_ENABLE          0x00000002
+#define AR_PHY_PARALLEL_CAL_ENABLE    0x00000001
+#define AR_PHY_TPCRG1_PD_CAL_ENABLE   0x00400000
+#define AR_PHY_TPCRG1_PD_CAL_ENABLE_S 22
+
+#define AR_PHY_ADDAC_PARACTL_OFF_PWDADC 0x00008000
+
+#define AR_PHY_FCAL20_CAP_STATUS_0    0x01f00000
+#define AR_PHY_FCAL20_CAP_STATUS_0_S  20
+
+#define AR_PHY_RFBUS_REQ_EN     0x00000001  /* request for RF bus */
+#define AR_PHY_RFBUS_GRANT_EN   0x00000001  /* RF bus granted */
+#define AR_PHY_GC_TURBO_MODE       0x00000001  /* set turbo mode bits */
+#define AR_PHY_GC_TURBO_SHORT      0x00000002  /* set short symbols to turbo mode setting */
+#define AR_PHY_GC_DYN2040_EN       0x00000004  /* enable dyn 20/40 mode */
+#define AR_PHY_GC_DYN2040_PRI_ONLY 0x00000008  /* dyn 20/40 - primary only */
+#define AR_PHY_GC_DYN2040_PRI_CH   0x00000010  /* dyn 20/40 - primary ch offset (0=+10MHz, 1=-10MHz)*/
+#define AR_PHY_GC_DYN2040_PRI_CH_S 4
+#define AR_PHY_GC_DYN2040_EXT_CH   0x00000020  /* dyn 20/40 - ext ch spacing (0=20MHz/ 1=25MHz) */
+#define AR_PHY_GC_HT_EN            0x00000040  /* ht enable */
+#define AR_PHY_GC_SHORT_GI_40      0x00000080  /* allow short GI for HT 40 */
+#define AR_PHY_GC_WALSH            0x00000100  /* walsh spatial spreading for 2 chains,2 streams TX */
+#define AR_PHY_GC_SINGLE_HT_LTF1   0x00000200  /* single length (4us) 1st HT long training symbol */
+#define AR_PHY_GC_GF_DETECT_EN     0x00000400  /* enable Green Field detection. Only affects rx, not tx */
+#define AR_PHY_GC_ENABLE_DAC_FIFO  0x00000800  /* fifo between bb and dac */
+#define AR_PHY_RX_DELAY_DELAY      0x00003FFF  /* delay from wakeup to rx ena */
+
+#define AR_PHY_CALMODE_IQ           0x00000000
+#define AR_PHY_CALMODE_ADC_GAIN     0x00000001
+#define AR_PHY_CALMODE_ADC_DC_PER   0x00000002
+#define AR_PHY_CALMODE_ADC_DC_INIT  0x00000003
+#define AR_PHY_SWAP_ALT_CHAIN       0x00000040
+#define AR_PHY_MODE_OFDM            0x00000000
+#define AR_PHY_MODE_CCK             0x00000001
+#define AR_PHY_MODE_DYNAMIC         0x00000004
+#define AR_PHY_MODE_DYNAMIC_S       2
+#define AR_PHY_MODE_HALF            0x00000020
+#define AR_PHY_MODE_QUARTER         0x00000040
+#define AR_PHY_MAC_CLK_MODE         0x00000080
+#define AR_PHY_MODE_DYN_CCK_DISABLE 0x00000100
+#define AR_PHY_MODE_SVD_HALF        0x00000200
+#define AR_PHY_ACTIVE_EN    0x00000001
+#define AR_PHY_ACTIVE_DIS   0x00000000
+#define AR_PHY_FORCE_XPA_CFG    0x000000001
+#define AR_PHY_FORCE_XPA_CFG_S  0
+#define AR_PHY_XPA_TIMING_CTL_TX_END_XPAB_OFF    0xFF000000
+#define AR_PHY_XPA_TIMING_CTL_TX_END_XPAB_OFF_S  24
+#define AR_PHY_XPA_TIMING_CTL_TX_END_XPAA_OFF    0x00FF0000
+#define AR_PHY_XPA_TIMING_CTL_TX_END_XPAA_OFF_S  16
+#define AR_PHY_XPA_TIMING_CTL_FRAME_XPAB_ON      0x0000FF00
+#define AR_PHY_XPA_TIMING_CTL_FRAME_XPAB_ON_S    8
+#define AR_PHY_XPA_TIMING_CTL_FRAME_XPAA_ON      0x000000FF
+#define AR_PHY_XPA_TIMING_CTL_FRAME_XPAA_ON_S    0
+#define AR_PHY_TX_END_TO_A2_RX_ON       0x00FF0000
+#define AR_PHY_TX_END_TO_A2_RX_ON_S     16
+#define AR_PHY_TX_END_DATA_START  0x000000FF
+#define AR_PHY_TX_END_DATA_START_S  0
+#define AR_PHY_TX_END_PA_ON       0x0000FF00
+#define AR_PHY_TX_END_PA_ON_S       8
+#define AR_PHY_TPCRG5_PD_GAIN_OVERLAP   0x0000000F
+#define AR_PHY_TPCRG5_PD_GAIN_OVERLAP_S     0
+#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1    0x000003F0
+#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1_S  4
+#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2    0x0000FC00
+#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2_S  10
+#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3    0x003F0000
+#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3_S  16
+#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4    0x0FC00000
+#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4_S  22
+#define AR_PHY_TPCRG1_NUM_PD_GAIN   0x0000c000
+#define AR_PHY_TPCRG1_NUM_PD_GAIN_S 14
+#define AR_PHY_TPCRG1_PD_GAIN_1    0x00030000
+#define AR_PHY_TPCRG1_PD_GAIN_1_S  16
+#define AR_PHY_TPCRG1_PD_GAIN_2    0x000C0000
+#define AR_PHY_TPCRG1_PD_GAIN_2_S  18
+#define AR_PHY_TPCRG1_PD_GAIN_3    0x00300000
+#define AR_PHY_TPCRG1_PD_GAIN_3_S  20
+#define AR_PHY_TPCGR1_FORCED_DAC_GAIN   0x0000003e
+#define AR_PHY_TPCGR1_FORCED_DAC_GAIN_S 1
+#define AR_PHY_TPCGR1_FORCE_DAC_GAIN    0x00000001
+#define AR_PHY_TXGAIN_FORCE               0x00000001
+#define AR_PHY_TXGAIN_FORCED_PADVGNRA     0x00003c00
+#define AR_PHY_TXGAIN_FORCED_PADVGNRA_S   10
+#define AR_PHY_TXGAIN_FORCED_PADVGNRB     0x0003c000
+#define AR_PHY_TXGAIN_FORCED_PADVGNRB_S   14
+#define AR_PHY_TXGAIN_FORCED_PADVGNRD     0x00c00000
+#define AR_PHY_TXGAIN_FORCED_PADVGNRD_S   22
+#define AR_PHY_TXGAIN_FORCED_TXMXRGAIN    0x000003c0
+#define AR_PHY_TXGAIN_FORCED_TXMXRGAIN_S  6
+#define AR_PHY_TXGAIN_FORCED_TXBB1DBGAIN  0x0000000e
+#define AR_PHY_TXGAIN_FORCED_TXBB1DBGAIN_S 1
+
+#define AR_PHY_POWER_TX_RATE1   0x9934
+#define AR_PHY_POWER_TX_RATE2   0x9938
+#define AR_PHY_POWER_TX_RATE_MAX    0x993c
+#define AR_PHY_POWER_TX_RATE_MAX_TPC_ENABLE 0x00000040
+#define PHY_AGC_CLR             0x10000000
+#define RFSILENT_BB             0x00002000
+#define AR_PHY_CHAN_INFO_GAIN_DIFF_PPM_MASK          0xFFF
+#define AR_PHY_CHAN_INFO_GAIN_DIFF_PPM_SIGNED_BIT    0x800
+#define AR_PHY_CHAN_INFO_GAIN_DIFF_UPPER_LIMIT         320
+#define AR_PHY_CHAN_INFO_MEMORY_CAPTURE_MASK         0x0001
+#define AR_PHY_RX_DELAY_DELAY   0x00003FFF
+#define AR_PHY_CCK_TX_CTRL_JAPAN    0x00000010
+#define AR_PHY_SPECTRAL_SCAN_ENABLE         0x00000001
+#define AR_PHY_SPECTRAL_SCAN_ENABLE_S       0
+#define AR_PHY_SPECTRAL_SCAN_ACTIVE         0x00000002
+#define AR_PHY_SPECTRAL_SCAN_ACTIVE_S       1
+#define AR_PHY_SPECTRAL_SCAN_FFT_PERIOD     0x000000F0
+#define AR_PHY_SPECTRAL_SCAN_FFT_PERIOD_S   4
+#define AR_PHY_SPECTRAL_SCAN_PERIOD         0x0000FF00
+#define AR_PHY_SPECTRAL_SCAN_PERIOD_S       8
+#define AR_PHY_SPECTRAL_SCAN_COUNT          0x00FF0000
+#define AR_PHY_SPECTRAL_SCAN_COUNT_S        16
+#define AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT   0x01000000
+#define AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT_S 24
+#define AR_PHY_CHANNEL_STATUS_RX_CLEAR      0x00000004
+#define AR_PHY_TX_IQCAQL_CONTROL_1_IQCORR_I_Q_COFF_DELPT             0x01fc0000
+#define AR_PHY_TX_IQCAQL_CONTROL_1_IQCORR_I_Q_COFF_DELPT_S                   18
+#define AR_PHY_TX_IQCAL_START_DO_CAL        0x00000001
+#define AR_PHY_TX_IQCAL_START_DO_CAL_S      0
+
+#define AR_PHY_TX_IQCAL_STATUS_FAILED    0x00000001
+#define AR_PHY_TX_IQCAL_CORR_COEFF_01_COEFF_TABLE      0x00003fff
+#define AR_PHY_TX_IQCAL_CORR_COEFF_01_COEFF_TABLE_S    0
+
+#define AR_PHY_TPC_18_THERM_CAL_VALUE           0xff
+#define AR_PHY_TPC_18_THERM_CAL_VALUE_S         0
+#define AR_PHY_TPC_19_ALPHA_THERM               0xff
+#define AR_PHY_TPC_19_ALPHA_THERM_S             0
+
+#define AR_PHY_65NM_CH0_RXTX4_THERM_ON          0x10000000
+#define AR_PHY_65NM_CH0_RXTX4_THERM_ON_S        28
+
+#define AR_PHY_BB_THERM_ADC_1_INIT_THERM        0x000000ff
+#define AR_PHY_BB_THERM_ADC_1_INIT_THERM_S      0
+
+/*
+ * Channel 1 Register Map
+ */
+#define AR_CHAN1_BASE  0xa800
+
+#define AR_PHY_EXT_CCA_1            (AR_CHAN1_BASE + 0x30)
+#define AR_PHY_TX_PHASE_RAMP_1      (AR_CHAN1_BASE + 0xd0)
+#define AR_PHY_ADC_GAIN_DC_CORR_1   (AR_CHAN1_BASE + 0xd4)
+
+#define AR_PHY_SPUR_REPORT_1        (AR_CHAN1_BASE + 0xa8)
+#define AR_PHY_CHAN_INFO_TAB_1      (AR_CHAN1_BASE + 0x300)
+#define AR_PHY_RX_IQCAL_CORR_B1     (AR_CHAN1_BASE + 0xdc)
+
+/*
+ * Channel 1 Field Definitions
+ */
+#define AR_PHY_CH1_EXT_MINCCA_PWR   0x01FF0000
+#define AR_PHY_CH1_EXT_MINCCA_PWR_S 16
+
+/*
+ * AGC 1 Register Map
+ */
+#define AR_AGC1_BASE   0xae00
+
+#define AR_PHY_FORCEMAX_GAINS_1      (AR_AGC1_BASE + 0x4)
+#define AR_PHY_EXT_ATTEN_CTL_1       (AR_AGC1_BASE + 0x18)
+#define AR_PHY_CCA_1                 (AR_AGC1_BASE + 0x1c)
+#define AR_PHY_CCA_CTRL_1            (AR_AGC1_BASE + 0x20)
+#define AR_PHY_RSSI_1                (AR_AGC1_BASE + 0x180)
+#define AR_PHY_SPUR_CCK_REP_1        (AR_AGC1_BASE + 0x184)
+#define AR_PHY_RX_OCGAIN_2           (AR_AGC1_BASE + 0x200)
+
+/*
+ * AGC 1 Field Definitions
+ */
+#define AR_PHY_CH1_MINCCA_PWR   0x1FF00000
+#define AR_PHY_CH1_MINCCA_PWR_S 20
+
+/*
+ * SM 1 Register Map
+ */
+#define AR_SM1_BASE    0xb200
+
+#define AR_PHY_SWITCH_CHAIN_1    (AR_SM1_BASE + 0x84)
+#define AR_PHY_FCAL_2_1          (AR_SM1_BASE + 0xd0)
+#define AR_PHY_DFT_TONE_CTL_1    (AR_SM1_BASE + 0xd4)
+#define AR_PHY_CL_TAB_1          (AR_SM1_BASE + 0x100)
+#define AR_PHY_CHAN_INFO_GAIN_1  (AR_SM1_BASE + 0x180)
+#define AR_PHY_TPC_4_B1          (AR_SM1_BASE + 0x204)
+#define AR_PHY_TPC_5_B1          (AR_SM1_BASE + 0x208)
+#define AR_PHY_TPC_6_B1          (AR_SM1_BASE + 0x20c)
+#define AR_PHY_TPC_11_B1         (AR_SM1_BASE + 0x220)
+#define AR_PHY_PDADC_TAB_1       (AR_SM1_BASE + 0x240)
+#define AR_PHY_TX_IQCAL_STATUS_B1   (AR_SM1_BASE + 0x48c)
+#define AR_PHY_TX_IQCAL_CORR_COEFF_01_B1    (AR_SM1_BASE + 0x450)
+
+/*
+ * Channel 2 Register Map
+ */
+#define AR_CHAN2_BASE  0xb800
+
+#define AR_PHY_EXT_CCA_2            (AR_CHAN2_BASE + 0x30)
+#define AR_PHY_TX_PHASE_RAMP_2      (AR_CHAN2_BASE + 0xd0)
+#define AR_PHY_ADC_GAIN_DC_CORR_2   (AR_CHAN2_BASE + 0xd4)
+
+#define AR_PHY_SPUR_REPORT_2        (AR_CHAN2_BASE + 0xa8)
+#define AR_PHY_CHAN_INFO_TAB_2      (AR_CHAN2_BASE + 0x300)
+#define AR_PHY_RX_IQCAL_CORR_B2     (AR_CHAN2_BASE + 0xdc)
+
+/*
+ * Channel 2 Field Definitions
+ */
+#define AR_PHY_CH2_EXT_MINCCA_PWR   0x01FF0000
+#define AR_PHY_CH2_EXT_MINCCA_PWR_S 16
+/*
+ * AGC 2 Register Map
+ */
+#define AR_AGC2_BASE   0xbe00
+
+#define AR_PHY_FORCEMAX_GAINS_2      (AR_AGC2_BASE + 0x4)
+#define AR_PHY_EXT_ATTEN_CTL_2       (AR_AGC2_BASE + 0x18)
+#define AR_PHY_CCA_2                 (AR_AGC2_BASE + 0x1c)
+#define AR_PHY_CCA_CTRL_2            (AR_AGC2_BASE + 0x20)
+#define AR_PHY_RSSI_2                (AR_AGC2_BASE + 0x180)
+
+/*
+ * AGC 2 Field Definitions
+ */
+#define AR_PHY_CH2_MINCCA_PWR   0x1FF00000
+#define AR_PHY_CH2_MINCCA_PWR_S 20
+
+/*
+ * SM 2 Register Map
+ */
+#define AR_SM2_BASE    0xc200
+
+#define AR_PHY_SWITCH_CHAIN_2    (AR_SM2_BASE + 0x84)
+#define AR_PHY_FCAL_2_2          (AR_SM2_BASE + 0xd0)
+#define AR_PHY_DFT_TONE_CTL_2    (AR_SM2_BASE + 0xd4)
+#define AR_PHY_CL_TAB_2          (AR_SM2_BASE + 0x100)
+#define AR_PHY_CHAN_INFO_GAIN_2  (AR_SM2_BASE + 0x180)
+#define AR_PHY_TPC_4_B2          (AR_SM2_BASE + 0x204)
+#define AR_PHY_TPC_5_B2          (AR_SM2_BASE + 0x208)
+#define AR_PHY_TPC_6_B2          (AR_SM2_BASE + 0x20c)
+#define AR_PHY_TPC_11_B2         (AR_SM2_BASE + 0x220)
+#define AR_PHY_PDADC_TAB_2       (AR_SM2_BASE + 0x240)
+#define AR_PHY_TX_IQCAL_STATUS_B2   (AR_SM2_BASE + 0x48c)
+#define AR_PHY_TX_IQCAL_CORR_COEFF_01_B2    (AR_SM2_BASE + 0x450)
+
+#define AR_PHY_TX_IQCAL_STATUS_B2_FAILED    0x00000001
+
+/*
+ * AGC 3 Register Map
+ */
+#define AR_AGC3_BASE   0xce00
+
+#define AR_PHY_RSSI_3            (AR_AGC3_BASE + 0x180)
+
+/*
+ * Misc helper defines
+ */
+#define AR_PHY_CHAIN_OFFSET     (AR_CHAN1_BASE - AR_CHAN_BASE)
+
+#define AR_PHY_NEW_ADC_DC_GAIN_CORR(_i) (AR_PHY_ADC_GAIN_DC_CORR_0 + (AR_PHY_CHAIN_OFFSET * (_i)))
+#define AR_PHY_NEW_ADC_DC_GAIN_CORR_9300_10(_i) (AR_PHY_ADC_GAIN_DC_CORR_0_9300_10 + (AR_PHY_CHAIN_OFFSET * (_i)))
+#define AR_PHY_SWITCH_CHAIN(_i)     (AR_PHY_SWITCH_CHAIN_0 + (AR_PHY_CHAIN_OFFSET * (_i)))
+#define AR_PHY_EXT_ATTEN_CTL(_i)    (AR_PHY_EXT_ATTEN_CTL_0 + (AR_PHY_CHAIN_OFFSET * (_i)))
+
+#define AR_PHY_RXGAIN(_i)           (AR_PHY_FORCEMAX_GAINS_0 + (AR_PHY_CHAIN_OFFSET * (_i)))
+#define AR_PHY_TPCRG5(_i)           (AR_PHY_TPC_5_B0 + (AR_PHY_CHAIN_OFFSET * (_i)))
+#define AR_PHY_PDADC_TAB(_i)        (AR_PHY_PDADC_TAB_0 + (AR_PHY_CHAIN_OFFSET * (_i)))
+
+#define AR_PHY_CAL_MEAS_0(_i)       (AR_PHY_IQ_ADC_MEAS_0_B0 + (AR_PHY_CHAIN_OFFSET * (_i)))
+#define AR_PHY_CAL_MEAS_1(_i)       (AR_PHY_IQ_ADC_MEAS_1_B0 + (AR_PHY_CHAIN_OFFSET * (_i)))
+#define AR_PHY_CAL_MEAS_2(_i)       (AR_PHY_IQ_ADC_MEAS_2_B0 + (AR_PHY_CHAIN_OFFSET * (_i)))
+#define AR_PHY_CAL_MEAS_3(_i)       (AR_PHY_IQ_ADC_MEAS_3_B0 + (AR_PHY_CHAIN_OFFSET * (_i)))
+#define AR_PHY_CAL_MEAS_0_9300_10(_i) (AR_PHY_IQ_ADC_MEAS_0_B0_9300_10 + (AR_PHY_CHAIN_OFFSET * (_i)))
+#define AR_PHY_CAL_MEAS_1_9300_10(_i) (AR_PHY_IQ_ADC_MEAS_1_B0_9300_10 + (AR_PHY_CHAIN_OFFSET * (_i)))
+#define AR_PHY_CAL_MEAS_2_9300_10(_i) (AR_PHY_IQ_ADC_MEAS_2_B0_9300_10 + (AR_PHY_CHAIN_OFFSET * (_i)))
+#define AR_PHY_CAL_MEAS_3_9300_10(_i) (AR_PHY_IQ_ADC_MEAS_3_B0_9300_10 + (AR_PHY_CHAIN_OFFSET * (_i)))
+
+#define AR_PHY_BB_PANIC_NON_IDLE_ENABLE 0x00000001
+#define AR_PHY_BB_PANIC_IDLE_ENABLE     0x00000002
+#define AR_PHY_BB_PANIC_IDLE_MASK       0xFFFF0000
+#define AR_PHY_BB_PANIC_NON_IDLE_MASK   0x0000FFFC
+
+#define AR_PHY_BB_PANIC_RST_ENABLE      0x00000002
+#define AR_PHY_BB_PANIC_IRQ_ENABLE      0x00000004
+#define AR_PHY_BB_PANIC_CNTL2_MASK      0xFFFFFFF9
+
+#define AR_PHY_BB_WD_STATUS             0x00000007
+#define AR_PHY_BB_WD_STATUS_S           0
+#define AR_PHY_BB_WD_DET_HANG           0x00000008
+#define AR_PHY_BB_WD_DET_HANG_S         3
+#define AR_PHY_BB_WD_RADAR_SM           0x000000F0
+#define AR_PHY_BB_WD_RADAR_SM_S         4
+#define AR_PHY_BB_WD_RX_OFDM_SM         0x00000F00
+#define AR_PHY_BB_WD_RX_OFDM_SM_S       8
+#define AR_PHY_BB_WD_RX_CCK_SM          0x0000F000
+#define AR_PHY_BB_WD_RX_CCK_SM_S        12
+#define AR_PHY_BB_WD_TX_OFDM_SM         0x000F0000
+#define AR_PHY_BB_WD_TX_OFDM_SM_S       16
+#define AR_PHY_BB_WD_TX_CCK_SM          0x00F00000
+#define AR_PHY_BB_WD_TX_CCK_SM_S        20
+#define AR_PHY_BB_WD_AGC_SM             0x0F000000
+#define AR_PHY_BB_WD_AGC_SM_S           24
+#define AR_PHY_BB_WD_SRCH_SM            0xF0000000
+#define AR_PHY_BB_WD_SRCH_SM_S          28
+
+#define AR_PHY_BB_WD_STATUS_CLR         0x00000008
+
+void ar9003_hw_set_chain_masks(struct ath_hw *ah, u8 rx, u8 tx);
+
+#endif  /* AR9003_PHY_H */
index bdcd257ca7a4f3e82a717d01d59d85da0b8bcd79..fbb7dec6ddebc11beb49a7b57b6e7342b38f9188 100644 (file)
@@ -114,8 +114,10 @@ enum buffer_type {
 #define bf_isretried(bf)       (bf->bf_state.bf_type & BUF_RETRY)
 #define bf_isxretried(bf)      (bf->bf_state.bf_type & BUF_XRETRY)
 
+#define ATH_TXSTATUS_RING_SIZE 64
+
 struct ath_descdma {
-       struct ath_desc *dd_desc;
+       void *dd_desc;
        dma_addr_t dd_desc_paddr;
        u32 dd_desc_len;
        struct ath_buf *dd_bufptr;
@@ -123,7 +125,7 @@ struct ath_descdma {
 
 int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
                      struct list_head *head, const char *name,
-                     int nbuf, int ndesc);
+                     int nbuf, int ndesc, bool is_tx);
 void ath_descdma_cleanup(struct ath_softc *sc, struct ath_descdma *dd,
                         struct list_head *head);
 
@@ -188,6 +190,7 @@ enum ATH_AGGR_STATUS {
        ATH_AGGR_LIMITED,
 };
 
+#define ATH_TXFIFO_DEPTH 8
 struct ath_txq {
        u32 axq_qnum;
        u32 *axq_link;
@@ -197,6 +200,10 @@ struct ath_txq {
        bool stopped;
        bool axq_tx_inprogress;
        struct list_head axq_acq;
+       struct list_head txq_fifo[ATH_TXFIFO_DEPTH];
+       struct list_head txq_fifo_pending;
+       u8 txq_headidx;
+       u8 txq_tailidx;
 };
 
 #define AGGR_CLEANUP         BIT(1)
@@ -223,6 +230,12 @@ struct ath_tx {
        struct ath_descdma txdma;
 };
 
+struct ath_rx_edma {
+       struct sk_buff_head rx_fifo;
+       struct sk_buff_head rx_buffers;
+       u32 rx_fifo_hwsize;
+};
+
 struct ath_rx {
        u8 defant;
        u8 rxotherant;
@@ -232,6 +245,8 @@ struct ath_rx {
        spinlock_t rxbuflock;
        struct list_head rxbuf;
        struct ath_descdma rxdma;
+       struct ath_buf *rx_bufptr;
+       struct ath_rx_edma rx_edma[ATH9K_RX_QUEUE_MAX];
 };
 
 int ath_startrecv(struct ath_softc *sc);
@@ -240,7 +255,7 @@ void ath_flushrecv(struct ath_softc *sc);
 u32 ath_calcrxfilter(struct ath_softc *sc);
 int ath_rx_init(struct ath_softc *sc, int nbufs);
 void ath_rx_cleanup(struct ath_softc *sc);
-int ath_rx_tasklet(struct ath_softc *sc, int flush);
+int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp);
 struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype);
 void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq);
 int ath_tx_setup(struct ath_softc *sc, int haltype);
@@ -258,6 +273,7 @@ int ath_txq_update(struct ath_softc *sc, int qnum,
 int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
                 struct ath_tx_control *txctl);
 void ath_tx_tasklet(struct ath_softc *sc);
+void ath_tx_edma_tasklet(struct ath_softc *sc);
 void ath_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb);
 bool ath_tx_aggr_check(struct ath_softc *sc, struct ath_node *an, u8 tidno);
 void ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta,
@@ -507,6 +523,8 @@ struct ath_softc {
        struct ath_beacon_config cur_beacon_conf;
        struct delayed_work tx_complete_work;
        struct ath_btcoex btcoex;
+
+       struct ath_descdma txsdma;
 };
 
 struct ath_wiphy {
index 22375a754718febe15707b3a2c2ca398e7318e19..c8a4558f79ba0573a674829b53d6cfef2258e347 100644 (file)
@@ -93,8 +93,6 @@ static void ath_beacon_setup(struct ath_softc *sc, struct ath_vif *avp,
                antenna = ((sc->beacon.ast_be_xmit / sc->nbcnvifs) & 1 ? 2 : 1);
        }
 
-       ds->ds_data = bf->bf_buf_addr;
-
        sband = &sc->sbands[common->hw->conf.channel->band];
        rate = sband->bitrates[rateidx].hw_value;
        if (sc->sc_flags & SC_OP_PREAMBLE_SHORT)
@@ -109,7 +107,8 @@ static void ath_beacon_setup(struct ath_softc *sc, struct ath_vif *avp,
 
        /* NB: beacon's BufLen must be a multiple of 4 bytes */
        ath9k_hw_filltxdesc(ah, ds, roundup(skb->len, 4),
-                           true, true, ds);
+                           true, true, ds, bf->bf_buf_addr,
+                           sc->beacon.beaconq);
 
        memset(series, 0, sizeof(struct ath9k_11n_rate_series) * 4);
        series[0].Tries = 1;
index 064f5b51dfcd8e2f197bde8b56974eee0039df2e..6982577043b8fb13449dbf4629e233aeea47818d 100644 (file)
  */
 
 #include "hw.h"
+#include "hw-ops.h"
+
+/* Common calibration code */
 
 /* We can tune this as we go by monitoring really low values */
 #define ATH9K_NF_TOO_LOW       -60
-#define AR9285_CLCAL_REDO_THRESH    1
 
 /* AR5416 may return very high value (like -31 dBm), in those cases the nf
  * is incorrect and we should use the static NF value. Later we can try to
@@ -87,98 +89,9 @@ static void ath9k_hw_update_nfcal_hist_buffer(struct ath9k_nfcal_hist *h,
        return;
 }
 
-static void ath9k_hw_do_getnf(struct ath_hw *ah,
-                             int16_t nfarray[NUM_NF_READINGS])
-{
-       struct ath_common *common = ath9k_hw_common(ah);
-       int16_t nf;
-
-       if (AR_SREV_9280_10_OR_LATER(ah))
-               nf = MS(REG_READ(ah, AR_PHY_CCA), AR9280_PHY_MINCCA_PWR);
-       else
-               nf = MS(REG_READ(ah, AR_PHY_CCA), AR_PHY_MINCCA_PWR);
-
-       if (nf & 0x100)
-               nf = 0 - ((nf ^ 0x1ff) + 1);
-       ath_print(common, ATH_DBG_CALIBRATE,
-                 "NF calibrated [ctl] [chain 0] is %d\n", nf);
-
-       if (AR_SREV_9271(ah) && (nf >= -114))
-               nf = -116;
-
-       nfarray[0] = nf;
-
-       if (!AR_SREV_9285(ah) && !AR_SREV_9271(ah)) {
-               if (AR_SREV_9280_10_OR_LATER(ah))
-                       nf = MS(REG_READ(ah, AR_PHY_CH1_CCA),
-                                       AR9280_PHY_CH1_MINCCA_PWR);
-               else
-                       nf = MS(REG_READ(ah, AR_PHY_CH1_CCA),
-                                       AR_PHY_CH1_MINCCA_PWR);
-
-               if (nf & 0x100)
-                       nf = 0 - ((nf ^ 0x1ff) + 1);
-               ath_print(common, ATH_DBG_CALIBRATE,
-                         "NF calibrated [ctl] [chain 1] is %d\n", nf);
-               nfarray[1] = nf;
-
-               if (!AR_SREV_9280(ah) && !AR_SREV_9287(ah)) {
-                       nf = MS(REG_READ(ah, AR_PHY_CH2_CCA),
-                                       AR_PHY_CH2_MINCCA_PWR);
-                       if (nf & 0x100)
-                               nf = 0 - ((nf ^ 0x1ff) + 1);
-                       ath_print(common, ATH_DBG_CALIBRATE,
-                                 "NF calibrated [ctl] [chain 2] is %d\n", nf);
-                       nfarray[2] = nf;
-               }
-       }
-
-       if (AR_SREV_9280_10_OR_LATER(ah))
-               nf = MS(REG_READ(ah, AR_PHY_EXT_CCA),
-                       AR9280_PHY_EXT_MINCCA_PWR);
-       else
-               nf = MS(REG_READ(ah, AR_PHY_EXT_CCA),
-                       AR_PHY_EXT_MINCCA_PWR);
-
-       if (nf & 0x100)
-               nf = 0 - ((nf ^ 0x1ff) + 1);
-       ath_print(common, ATH_DBG_CALIBRATE,
-                 "NF calibrated [ext] [chain 0] is %d\n", nf);
-
-       if (AR_SREV_9271(ah) && (nf >= -114))
-               nf = -116;
-
-       nfarray[3] = nf;
-
-       if (!AR_SREV_9285(ah) && !AR_SREV_9271(ah)) {
-               if (AR_SREV_9280_10_OR_LATER(ah))
-                       nf = MS(REG_READ(ah, AR_PHY_CH1_EXT_CCA),
-                                       AR9280_PHY_CH1_EXT_MINCCA_PWR);
-               else
-                       nf = MS(REG_READ(ah, AR_PHY_CH1_EXT_CCA),
-                                       AR_PHY_CH1_EXT_MINCCA_PWR);
-
-               if (nf & 0x100)
-                       nf = 0 - ((nf ^ 0x1ff) + 1);
-               ath_print(common, ATH_DBG_CALIBRATE,
-                         "NF calibrated [ext] [chain 1] is %d\n", nf);
-               nfarray[4] = nf;
-
-               if (!AR_SREV_9280(ah) && !AR_SREV_9287(ah)) {
-                       nf = MS(REG_READ(ah, AR_PHY_CH2_EXT_CCA),
-                                       AR_PHY_CH2_EXT_MINCCA_PWR);
-                       if (nf & 0x100)
-                               nf = 0 - ((nf ^ 0x1ff) + 1);
-                       ath_print(common, ATH_DBG_CALIBRATE,
-                                 "NF calibrated [ext] [chain 2] is %d\n", nf);
-                       nfarray[5] = nf;
-               }
-       }
-}
-
-static bool getNoiseFloorThresh(struct ath_hw *ah,
-                               enum ieee80211_band band,
-                               int16_t *nft)
+static bool ath9k_hw_get_nf_thresh(struct ath_hw *ah,
+                                  enum ieee80211_band band,
+                                  int16_t *nft)
 {
        switch (band) {
        case IEEE80211_BAND_5GHZ:
@@ -195,44 +108,8 @@ static bool getNoiseFloorThresh(struct ath_hw *ah,
        return true;
 }
 
-static void ath9k_hw_setup_calibration(struct ath_hw *ah,
-                                      struct ath9k_cal_list *currCal)
-{
-       struct ath_common *common = ath9k_hw_common(ah);
-
-       REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(0),
-                     AR_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX,
-                     currCal->calData->calCountMax);
-
-       switch (currCal->calData->calType) {
-       case IQ_MISMATCH_CAL:
-               REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_IQ);
-               ath_print(common, ATH_DBG_CALIBRATE,
-                         "starting IQ Mismatch Calibration\n");
-               break;
-       case ADC_GAIN_CAL:
-               REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_GAIN);
-               ath_print(common, ATH_DBG_CALIBRATE,
-                         "starting ADC Gain Calibration\n");
-               break;
-       case ADC_DC_CAL:
-               REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_DC_PER);
-               ath_print(common, ATH_DBG_CALIBRATE,
-                         "starting ADC DC Calibration\n");
-               break;
-       case ADC_DC_INIT_CAL:
-               REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_DC_INIT);
-               ath_print(common, ATH_DBG_CALIBRATE,
-                         "starting Init ADC DC Calibration\n");
-               break;
-       }
-
-       REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4(0),
-                   AR_PHY_TIMING_CTRL4_DO_CAL);
-}
-
-static void ath9k_hw_reset_calibration(struct ath_hw *ah,
-                                      struct ath9k_cal_list *currCal)
+void ath9k_hw_reset_calibration(struct ath_hw *ah,
+                               struct ath9k_cal_list *currCal)
 {
        int i;
 
@@ -250,324 +127,6 @@ static void ath9k_hw_reset_calibration(struct ath_hw *ah,
        ah->cal_samples = 0;
 }
 
-static bool ath9k_hw_per_calibration(struct ath_hw *ah,
-                                    struct ath9k_channel *ichan,
-                                    u8 rxchainmask,
-                                    struct ath9k_cal_list *currCal)
-{
-       bool iscaldone = false;
-
-       if (currCal->calState == CAL_RUNNING) {
-               if (!(REG_READ(ah, AR_PHY_TIMING_CTRL4(0)) &
-                     AR_PHY_TIMING_CTRL4_DO_CAL)) {
-
-                       currCal->calData->calCollect(ah);
-                       ah->cal_samples++;
-
-                       if (ah->cal_samples >= currCal->calData->calNumSamples) {
-                               int i, numChains = 0;
-                               for (i = 0; i < AR5416_MAX_CHAINS; i++) {
-                                       if (rxchainmask & (1 << i))
-                                               numChains++;
-                               }
-
-                               currCal->calData->calPostProc(ah, numChains);
-                               ichan->CalValid |= currCal->calData->calType;
-                               currCal->calState = CAL_DONE;
-                               iscaldone = true;
-                       } else {
-                               ath9k_hw_setup_calibration(ah, currCal);
-                       }
-               }
-       } else if (!(ichan->CalValid & currCal->calData->calType)) {
-               ath9k_hw_reset_calibration(ah, currCal);
-       }
-
-       return iscaldone;
-}
-
-/* Assumes you are talking about the currently configured channel */
-static bool ath9k_hw_iscal_supported(struct ath_hw *ah,
-                                    enum ath9k_cal_types calType)
-{
-       struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;
-
-       switch (calType & ah->supp_cals) {
-       case IQ_MISMATCH_CAL: /* Both 2 GHz and 5 GHz support OFDM */
-               return true;
-       case ADC_GAIN_CAL:
-       case ADC_DC_CAL:
-               if (!(conf->channel->band == IEEE80211_BAND_2GHZ &&
-                     conf_is_ht20(conf)))
-                       return true;
-               break;
-       }
-       return false;
-}
-
-static void ath9k_hw_iqcal_collect(struct ath_hw *ah)
-{
-       int i;
-
-       for (i = 0; i < AR5416_MAX_CHAINS; i++) {
-               ah->totalPowerMeasI[i] +=
-                       REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
-               ah->totalPowerMeasQ[i] +=
-                       REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
-               ah->totalIqCorrMeas[i] +=
-                       (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
-               ath_print(ath9k_hw_common(ah), ATH_DBG_CALIBRATE,
-                         "%d: Chn %d pmi=0x%08x;pmq=0x%08x;iqcm=0x%08x;\n",
-                         ah->cal_samples, i, ah->totalPowerMeasI[i],
-                         ah->totalPowerMeasQ[i],
-                         ah->totalIqCorrMeas[i]);
-       }
-}
-
-static void ath9k_hw_adc_gaincal_collect(struct ath_hw *ah)
-{
-       int i;
-
-       for (i = 0; i < AR5416_MAX_CHAINS; i++) {
-               ah->totalAdcIOddPhase[i] +=
-                       REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
-               ah->totalAdcIEvenPhase[i] +=
-                       REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
-               ah->totalAdcQOddPhase[i] +=
-                       REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
-               ah->totalAdcQEvenPhase[i] +=
-                       REG_READ(ah, AR_PHY_CAL_MEAS_3(i));
-
-               ath_print(ath9k_hw_common(ah), ATH_DBG_CALIBRATE,
-                         "%d: Chn %d oddi=0x%08x; eveni=0x%08x; "
-                         "oddq=0x%08x; evenq=0x%08x;\n",
-                         ah->cal_samples, i,
-                         ah->totalAdcIOddPhase[i],
-                         ah->totalAdcIEvenPhase[i],
-                         ah->totalAdcQOddPhase[i],
-                         ah->totalAdcQEvenPhase[i]);
-       }
-}
-
-static void ath9k_hw_adc_dccal_collect(struct ath_hw *ah)
-{
-       int i;
-
-       for (i = 0; i < AR5416_MAX_CHAINS; i++) {
-               ah->totalAdcDcOffsetIOddPhase[i] +=
-                       (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
-               ah->totalAdcDcOffsetIEvenPhase[i] +=
-                       (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
-               ah->totalAdcDcOffsetQOddPhase[i] +=
-                       (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
-               ah->totalAdcDcOffsetQEvenPhase[i] +=
-                       (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_3(i));
-
-               ath_print(ath9k_hw_common(ah), ATH_DBG_CALIBRATE,
-                         "%d: Chn %d oddi=0x%08x; eveni=0x%08x; "
-                         "oddq=0x%08x; evenq=0x%08x;\n",
-                         ah->cal_samples, i,
-                         ah->totalAdcDcOffsetIOddPhase[i],
-                         ah->totalAdcDcOffsetIEvenPhase[i],
-                         ah->totalAdcDcOffsetQOddPhase[i],
-                         ah->totalAdcDcOffsetQEvenPhase[i]);
-       }
-}
-
-static void ath9k_hw_iqcalibrate(struct ath_hw *ah, u8 numChains)
-{
-       struct ath_common *common = ath9k_hw_common(ah);
-       u32 powerMeasQ, powerMeasI, iqCorrMeas;
-       u32 qCoffDenom, iCoffDenom;
-       int32_t qCoff, iCoff;
-       int iqCorrNeg, i;
-
-       for (i = 0; i < numChains; i++) {
-               powerMeasI = ah->totalPowerMeasI[i];
-               powerMeasQ = ah->totalPowerMeasQ[i];
-               iqCorrMeas = ah->totalIqCorrMeas[i];
-
-               ath_print(common, ATH_DBG_CALIBRATE,
-                         "Starting IQ Cal and Correction for Chain %d\n",
-                         i);
-
-               ath_print(common, ATH_DBG_CALIBRATE,
-                         "Orignal: Chn %diq_corr_meas = 0x%08x\n",
-                         i, ah->totalIqCorrMeas[i]);
-
-               iqCorrNeg = 0;
-
-               if (iqCorrMeas > 0x80000000) {
-                       iqCorrMeas = (0xffffffff - iqCorrMeas) + 1;
-                       iqCorrNeg = 1;
-               }
-
-               ath_print(common, ATH_DBG_CALIBRATE,
-                         "Chn %d pwr_meas_i = 0x%08x\n", i, powerMeasI);
-               ath_print(common, ATH_DBG_CALIBRATE,
-                         "Chn %d pwr_meas_q = 0x%08x\n", i, powerMeasQ);
-               ath_print(common, ATH_DBG_CALIBRATE, "iqCorrNeg is 0x%08x\n",
-                         iqCorrNeg);
-
-               iCoffDenom = (powerMeasI / 2 + powerMeasQ / 2) / 128;
-               qCoffDenom = powerMeasQ / 64;
-
-               if ((powerMeasQ != 0) && (iCoffDenom != 0) &&
-                   (qCoffDenom != 0)) {
-                       iCoff = iqCorrMeas / iCoffDenom;
-                       qCoff = powerMeasI / qCoffDenom - 64;
-                       ath_print(common, ATH_DBG_CALIBRATE,
-                                 "Chn %d iCoff = 0x%08x\n", i, iCoff);
-                       ath_print(common, ATH_DBG_CALIBRATE,
-                                 "Chn %d qCoff = 0x%08x\n", i, qCoff);
-
-                       iCoff = iCoff & 0x3f;
-                       ath_print(common, ATH_DBG_CALIBRATE,
-                                 "New: Chn %d iCoff = 0x%08x\n", i, iCoff);
-                       if (iqCorrNeg == 0x0)
-                               iCoff = 0x40 - iCoff;
-
-                       if (qCoff > 15)
-                               qCoff = 15;
-                       else if (qCoff <= -16)
-                               qCoff = 16;
-
-                       ath_print(common, ATH_DBG_CALIBRATE,
-                                 "Chn %d : iCoff = 0x%x  qCoff = 0x%x\n",
-                                 i, iCoff, qCoff);
-
-                       REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(i),
-                                     AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF,
-                                     iCoff);
-                       REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(i),
-                                     AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF,
-                                     qCoff);
-                       ath_print(common, ATH_DBG_CALIBRATE,
-                                 "IQ Cal and Correction done for Chain %d\n",
-                                 i);
-               }
-       }
-
-       REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4(0),
-                   AR_PHY_TIMING_CTRL4_IQCORR_ENABLE);
-}
-
-static void ath9k_hw_adc_gaincal_calibrate(struct ath_hw *ah, u8 numChains)
-{
-       struct ath_common *common = ath9k_hw_common(ah);
-       u32 iOddMeasOffset, iEvenMeasOffset, qOddMeasOffset, qEvenMeasOffset;
-       u32 qGainMismatch, iGainMismatch, val, i;
-
-       for (i = 0; i < numChains; i++) {
-               iOddMeasOffset = ah->totalAdcIOddPhase[i];
-               iEvenMeasOffset = ah->totalAdcIEvenPhase[i];
-               qOddMeasOffset = ah->totalAdcQOddPhase[i];
-               qEvenMeasOffset = ah->totalAdcQEvenPhase[i];
-
-               ath_print(common, ATH_DBG_CALIBRATE,
-                         "Starting ADC Gain Cal for Chain %d\n", i);
-
-               ath_print(common, ATH_DBG_CALIBRATE,
-                         "Chn %d pwr_meas_odd_i = 0x%08x\n", i,
-                         iOddMeasOffset);
-               ath_print(common, ATH_DBG_CALIBRATE,
-                         "Chn %d pwr_meas_even_i = 0x%08x\n", i,
-                         iEvenMeasOffset);
-               ath_print(common, ATH_DBG_CALIBRATE,
-                         "Chn %d pwr_meas_odd_q = 0x%08x\n", i,
-                         qOddMeasOffset);
-               ath_print(common, ATH_DBG_CALIBRATE,
-                         "Chn %d pwr_meas_even_q = 0x%08x\n", i,
-                         qEvenMeasOffset);
-
-               if (iOddMeasOffset != 0 && qEvenMeasOffset != 0) {
-                       iGainMismatch =
-                               ((iEvenMeasOffset * 32) /
-                                iOddMeasOffset) & 0x3f;
-                       qGainMismatch =
-                               ((qOddMeasOffset * 32) /
-                                qEvenMeasOffset) & 0x3f;
-
-                       ath_print(common, ATH_DBG_CALIBRATE,
-                                 "Chn %d gain_mismatch_i = 0x%08x\n", i,
-                                 iGainMismatch);
-                       ath_print(common, ATH_DBG_CALIBRATE,
-                                 "Chn %d gain_mismatch_q = 0x%08x\n", i,
-                                 qGainMismatch);
-
-                       val = REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i));
-                       val &= 0xfffff000;
-                       val |= (qGainMismatch) | (iGainMismatch << 6);
-                       REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i), val);
-
-                       ath_print(common, ATH_DBG_CALIBRATE,
-                                 "ADC Gain Cal done for Chain %d\n", i);
-               }
-       }
-
-       REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0),
-                 REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0)) |
-                 AR_PHY_NEW_ADC_GAIN_CORR_ENABLE);
-}
-
-static void ath9k_hw_adc_dccal_calibrate(struct ath_hw *ah, u8 numChains)
-{
-       struct ath_common *common = ath9k_hw_common(ah);
-       u32 iOddMeasOffset, iEvenMeasOffset, val, i;
-       int32_t qOddMeasOffset, qEvenMeasOffset, qDcMismatch, iDcMismatch;
-       const struct ath9k_percal_data *calData =
-               ah->cal_list_curr->calData;
-       u32 numSamples =
-               (1 << (calData->calCountMax + 5)) * calData->calNumSamples;
-
-       for (i = 0; i < numChains; i++) {
-               iOddMeasOffset = ah->totalAdcDcOffsetIOddPhase[i];
-               iEvenMeasOffset = ah->totalAdcDcOffsetIEvenPhase[i];
-               qOddMeasOffset = ah->totalAdcDcOffsetQOddPhase[i];
-               qEvenMeasOffset = ah->totalAdcDcOffsetQEvenPhase[i];
-
-               ath_print(common, ATH_DBG_CALIBRATE,
-                          "Starting ADC DC Offset Cal for Chain %d\n", i);
-
-               ath_print(common, ATH_DBG_CALIBRATE,
-                         "Chn %d pwr_meas_odd_i = %d\n", i,
-                         iOddMeasOffset);
-               ath_print(common, ATH_DBG_CALIBRATE,
-                         "Chn %d pwr_meas_even_i = %d\n", i,
-                         iEvenMeasOffset);
-               ath_print(common, ATH_DBG_CALIBRATE,
-                         "Chn %d pwr_meas_odd_q = %d\n", i,
-                         qOddMeasOffset);
-               ath_print(common, ATH_DBG_CALIBRATE,
-                         "Chn %d pwr_meas_even_q = %d\n", i,
-                         qEvenMeasOffset);
-
-               iDcMismatch = (((iEvenMeasOffset - iOddMeasOffset) * 2) /
-                              numSamples) & 0x1ff;
-               qDcMismatch = (((qOddMeasOffset - qEvenMeasOffset) * 2) /
-                              numSamples) & 0x1ff;
-
-               ath_print(common, ATH_DBG_CALIBRATE,
-                         "Chn %d dc_offset_mismatch_i = 0x%08x\n", i,
-                         iDcMismatch);
-               ath_print(common, ATH_DBG_CALIBRATE,
-                         "Chn %d dc_offset_mismatch_q = 0x%08x\n", i,
-                         qDcMismatch);
-
-               val = REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i));
-               val &= 0xc0000fff;
-               val |= (qDcMismatch << 12) | (iDcMismatch << 21);
-               REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i), val);
-
-               ath_print(common, ATH_DBG_CALIBRATE,
-                         "ADC DC Offset Cal done for Chain %d\n", i);
-       }
-
-       REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0),
-                 REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0)) |
-                 AR_PHY_NEW_ADC_DC_OFFSET_CORR_ENABLE);
-}
-
 /* This is done for the currently configured channel */
 bool ath9k_hw_reset_calvalid(struct ath_hw *ah)
 {
@@ -614,72 +173,6 @@ void ath9k_hw_start_nfcal(struct ath_hw *ah)
        REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
 }
 
-void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)
-{
-       struct ath9k_nfcal_hist *h;
-       int i, j;
-       int32_t val;
-       const u32 ar5416_cca_regs[6] = {
-               AR_PHY_CCA,
-               AR_PHY_CH1_CCA,
-               AR_PHY_CH2_CCA,
-               AR_PHY_EXT_CCA,
-               AR_PHY_CH1_EXT_CCA,
-               AR_PHY_CH2_EXT_CCA
-       };
-       u8 chainmask, rx_chain_status;
-
-       rx_chain_status = REG_READ(ah, AR_PHY_RX_CHAINMASK);
-       if (AR_SREV_9285(ah) || AR_SREV_9271(ah))
-               chainmask = 0x9;
-       else if (AR_SREV_9280(ah) || AR_SREV_9287(ah)) {
-               if ((rx_chain_status & 0x2) || (rx_chain_status & 0x4))
-                       chainmask = 0x1B;
-               else
-                       chainmask = 0x09;
-       } else {
-               if (rx_chain_status & 0x4)
-                       chainmask = 0x3F;
-               else if (rx_chain_status & 0x2)
-                       chainmask = 0x1B;
-               else
-                       chainmask = 0x09;
-       }
-
-       h = ah->nfCalHist;
-
-       for (i = 0; i < NUM_NF_READINGS; i++) {
-               if (chainmask & (1 << i)) {
-                       val = REG_READ(ah, ar5416_cca_regs[i]);
-                       val &= 0xFFFFFE00;
-                       val |= (((u32) (h[i].privNF) << 1) & 0x1ff);
-                       REG_WRITE(ah, ar5416_cca_regs[i], val);
-               }
-       }
-
-       REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
-                   AR_PHY_AGC_CONTROL_ENABLE_NF);
-       REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
-                   AR_PHY_AGC_CONTROL_NO_UPDATE_NF);
-       REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
-
-       for (j = 0; j < 5; j++) {
-               if ((REG_READ(ah, AR_PHY_AGC_CONTROL) &
-                    AR_PHY_AGC_CONTROL_NF) == 0)
-                       break;
-               udelay(50);
-       }
-
-       for (i = 0; i < NUM_NF_READINGS; i++) {
-               if (chainmask & (1 << i)) {
-                       val = REG_READ(ah, ar5416_cca_regs[i]);
-                       val &= 0xFFFFFE00;
-                       val |= (((u32) (-50) << 1) & 0x1ff);
-                       REG_WRITE(ah, ar5416_cca_regs[i], val);
-               }
-       }
-}
-
 int16_t ath9k_hw_getnf(struct ath_hw *ah,
                       struct ath9k_channel *chan)
 {
@@ -699,7 +192,7 @@ int16_t ath9k_hw_getnf(struct ath_hw *ah,
        } else {
                ath9k_hw_do_getnf(ah, nfarray);
                nf = nfarray[0];
-               if (getNoiseFloorThresh(ah, c->band, &nfThresh)
+               if (ath9k_hw_get_nf_thresh(ah, c->band, &nfThresh)
                    && nf > nfThresh) {
                        ath_print(common, ATH_DBG_CALIBRATE,
                                  "noise floor failed detected; "
@@ -757,567 +250,3 @@ s16 ath9k_hw_getchan_noise(struct ath_hw *ah, struct ath9k_channel *chan)
        return nf;
 }
 EXPORT_SYMBOL(ath9k_hw_getchan_noise);
-
-static void ath9k_olc_temp_compensation_9287(struct ath_hw *ah)
-{
-       u32 rddata;
-       int32_t delta, currPDADC, slope;
-
-       rddata = REG_READ(ah, AR_PHY_TX_PWRCTRL4);
-       currPDADC = MS(rddata, AR_PHY_TX_PWRCTRL_PD_AVG_OUT);
-
-       if (ah->initPDADC == 0 || currPDADC == 0) {
-               /*
-                * Zero value indicates that no frames have been transmitted yet,
-                * can't do temperature compensation until frames are transmitted.
-                */
-               return;
-       } else {
-               slope = ah->eep_ops->get_eeprom(ah, EEP_TEMPSENSE_SLOPE);
-
-               if (slope == 0) { /* to avoid divide by zero case */
-                       delta = 0;
-               } else {
-                       delta = ((currPDADC - ah->initPDADC)*4) / slope;
-               }
-               REG_RMW_FIELD(ah, AR_PHY_CH0_TX_PWRCTRL11,
-                             AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP, delta);
-               REG_RMW_FIELD(ah, AR_PHY_CH1_TX_PWRCTRL11,
-                             AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP, delta);
-       }
-}
-
-static void ath9k_olc_temp_compensation(struct ath_hw *ah)
-{
-       u32 rddata, i;
-       int delta, currPDADC, regval;
-
-       if (OLC_FOR_AR9287_10_LATER) {
-               ath9k_olc_temp_compensation_9287(ah);
-       } else {
-               rddata = REG_READ(ah, AR_PHY_TX_PWRCTRL4);
-               currPDADC = MS(rddata, AR_PHY_TX_PWRCTRL_PD_AVG_OUT);
-
-               if (ah->initPDADC == 0 || currPDADC == 0) {
-                       return;
-               } else {
-                       if (ah->eep_ops->get_eeprom(ah, EEP_DAC_HPWR_5G))
-                               delta = (currPDADC - ah->initPDADC + 4) / 8;
-                       else
-                               delta = (currPDADC - ah->initPDADC + 5) / 10;
-
-                       if (delta != ah->PDADCdelta) {
-                               ah->PDADCdelta = delta;
-                               for (i = 1; i < AR9280_TX_GAIN_TABLE_SIZE; i++) {
-                                       regval = ah->originalGain[i] - delta;
-                                       if (regval < 0)
-                                               regval = 0;
-
-                                       REG_RMW_FIELD(ah,
-                                                     AR_PHY_TX_GAIN_TBL1 + i * 4,
-                                                     AR_PHY_TX_GAIN, regval);
-                               }
-                       }
-               }
-       }
-}
-
-static void ath9k_hw_9271_pa_cal(struct ath_hw *ah, bool is_reset)
-{
-       u32 regVal;
-       unsigned int i;
-       u32 regList [][2] = {
-               { 0x786c, 0 },
-               { 0x7854, 0 },
-               { 0x7820, 0 },
-               { 0x7824, 0 },
-               { 0x7868, 0 },
-               { 0x783c, 0 },
-               { 0x7838, 0 } ,
-               { 0x7828, 0 } ,
-       };
-
-       for (i = 0; i < ARRAY_SIZE(regList); i++)
-               regList[i][1] = REG_READ(ah, regList[i][0]);
-
-       regVal = REG_READ(ah, 0x7834);
-       regVal &= (~(0x1));
-       REG_WRITE(ah, 0x7834, regVal);
-       regVal = REG_READ(ah, 0x9808);
-       regVal |= (0x1 << 27);
-       REG_WRITE(ah, 0x9808, regVal);
-
-       /* 786c,b23,1, pwddac=1 */
-       REG_RMW_FIELD(ah, AR9285_AN_TOP3, AR9285_AN_TOP3_PWDDAC, 1);
-       /* 7854, b5,1, pdrxtxbb=1 */
-       REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDRXTXBB1, 1);
-       /* 7854, b7,1, pdv2i=1 */
-       REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDV2I, 1);
-       /* 7854, b8,1, pddacinterface=1 */
-       REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDDACIF, 1);
-       /* 7824,b12,0, offcal=0 */
-       REG_RMW_FIELD(ah, AR9285_AN_RF2G2, AR9285_AN_RF2G2_OFFCAL, 0);
-       /* 7838, b1,0, pwddb=0 */
-       REG_RMW_FIELD(ah, AR9285_AN_RF2G7, AR9285_AN_RF2G7_PWDDB, 0);
-       /* 7820,b11,0, enpacal=0 */
-       REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_ENPACAL, 0);
-       /* 7820,b25,1, pdpadrv1=0 */
-       REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPADRV1, 0);
-       /* 7820,b24,0, pdpadrv2=0 */
-       REG_RMW_FIELD(ah, AR9285_AN_RF2G1,AR9285_AN_RF2G1_PDPADRV2,0);
-       /* 7820,b23,0, pdpaout=0 */
-       REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPAOUT, 0);
-       /* 783c,b14-16,7, padrvgn2tab_0=7 */
-       REG_RMW_FIELD(ah, AR9285_AN_RF2G8,AR9285_AN_RF2G8_PADRVGN2TAB0, 7);
-       /*
-        * 7838,b29-31,0, padrvgn1tab_0=0
-        * does not matter since we turn it off
-        */
-       REG_RMW_FIELD(ah, AR9285_AN_RF2G7,AR9285_AN_RF2G7_PADRVGN2TAB0, 0);
-
-       REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9271_AN_RF2G3_CCOMP, 0xfff);
-
-       /* Set:
-        * localmode=1,bmode=1,bmoderxtx=1,synthon=1,
-        * txon=1,paon=1,oscon=1,synthon_force=1
-        */
-       REG_WRITE(ah, AR9285_AN_TOP2, 0xca0358a0);
-       udelay(30);
-       REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9271_AN_RF2G6_OFFS, 0);
-
-       /* find off_6_1; */
-       for (i = 6; i > 0; i--) {
-               regVal = REG_READ(ah, 0x7834);
-               regVal |= (1 << (20 + i));
-               REG_WRITE(ah, 0x7834, regVal);
-               udelay(1);
-               //regVal = REG_READ(ah, 0x7834);
-               regVal &= (~(0x1 << (20 + i)));
-               regVal |= (MS(REG_READ(ah, 0x7840), AR9285_AN_RXTXBB1_SPARE9)
-                           << (20 + i));
-               REG_WRITE(ah, 0x7834, regVal);
-       }
-
-       regVal = (regVal >>20) & 0x7f;
-
-       /* Update PA cal info */
-       if ((!is_reset) && (ah->pacal_info.prev_offset == regVal)) {
-               if (ah->pacal_info.max_skipcount < MAX_PACAL_SKIPCOUNT)
-                       ah->pacal_info.max_skipcount =
-                               2 * ah->pacal_info.max_skipcount;
-               ah->pacal_info.skipcount = ah->pacal_info.max_skipcount;
-       } else {
-               ah->pacal_info.max_skipcount = 1;
-               ah->pacal_info.skipcount = 0;
-               ah->pacal_info.prev_offset = regVal;
-       }
-
-       regVal = REG_READ(ah, 0x7834);
-       regVal |= 0x1;
-       REG_WRITE(ah, 0x7834, regVal);
-       regVal = REG_READ(ah, 0x9808);
-       regVal &= (~(0x1 << 27));
-       REG_WRITE(ah, 0x9808, regVal);
-
-       for (i = 0; i < ARRAY_SIZE(regList); i++)
-               REG_WRITE(ah, regList[i][0], regList[i][1]);
-}
-
-static inline void ath9k_hw_9285_pa_cal(struct ath_hw *ah, bool is_reset)
-{
-       struct ath_common *common = ath9k_hw_common(ah);
-       u32 regVal;
-       int i, offset, offs_6_1, offs_0;
-       u32 ccomp_org, reg_field;
-       u32 regList[][2] = {
-               { 0x786c, 0 },
-               { 0x7854, 0 },
-               { 0x7820, 0 },
-               { 0x7824, 0 },
-               { 0x7868, 0 },
-               { 0x783c, 0 },
-               { 0x7838, 0 },
-       };
-
-       ath_print(common, ATH_DBG_CALIBRATE, "Running PA Calibration\n");
-
-       /* PA CAL is not needed for high power solution */
-       if (ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE) ==
-           AR5416_EEP_TXGAIN_HIGH_POWER)
-               return;
-
-       if (AR_SREV_9285_11(ah)) {
-               REG_WRITE(ah, AR9285_AN_TOP4, (AR9285_AN_TOP4_DEFAULT | 0x14));
-               udelay(10);
-       }
-
-       for (i = 0; i < ARRAY_SIZE(regList); i++)
-               regList[i][1] = REG_READ(ah, regList[i][0]);
-
-       regVal = REG_READ(ah, 0x7834);
-       regVal &= (~(0x1));
-       REG_WRITE(ah, 0x7834, regVal);
-       regVal = REG_READ(ah, 0x9808);
-       regVal |= (0x1 << 27);
-       REG_WRITE(ah, 0x9808, regVal);
-
-       REG_RMW_FIELD(ah, AR9285_AN_TOP3, AR9285_AN_TOP3_PWDDAC, 1);
-       REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDRXTXBB1, 1);
-       REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDV2I, 1);
-       REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDDACIF, 1);
-       REG_RMW_FIELD(ah, AR9285_AN_RF2G2, AR9285_AN_RF2G2_OFFCAL, 0);
-       REG_RMW_FIELD(ah, AR9285_AN_RF2G7, AR9285_AN_RF2G7_PWDDB, 0);
-       REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_ENPACAL, 0);
-       REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPADRV1, 0);
-       REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPADRV2, 0);
-       REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPAOUT, 0);
-       REG_RMW_FIELD(ah, AR9285_AN_RF2G8, AR9285_AN_RF2G8_PADRVGN2TAB0, 7);
-       REG_RMW_FIELD(ah, AR9285_AN_RF2G7, AR9285_AN_RF2G7_PADRVGN2TAB0, 0);
-       ccomp_org = MS(REG_READ(ah, AR9285_AN_RF2G6), AR9285_AN_RF2G6_CCOMP);
-       REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9285_AN_RF2G6_CCOMP, 0xf);
-
-       REG_WRITE(ah, AR9285_AN_TOP2, 0xca0358a0);
-       udelay(30);
-       REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9285_AN_RF2G6_OFFS, 0);
-       REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9285_AN_RF2G3_PDVCCOMP, 0);
-
-       for (i = 6; i > 0; i--) {
-               regVal = REG_READ(ah, 0x7834);
-               regVal |= (1 << (19 + i));
-               REG_WRITE(ah, 0x7834, regVal);
-               udelay(1);
-               regVal = REG_READ(ah, 0x7834);
-               regVal &= (~(0x1 << (19 + i)));
-               reg_field = MS(REG_READ(ah, 0x7840), AR9285_AN_RXTXBB1_SPARE9);
-               regVal |= (reg_field << (19 + i));
-               REG_WRITE(ah, 0x7834, regVal);
-       }
-
-       REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9285_AN_RF2G3_PDVCCOMP, 1);
-       udelay(1);
-       reg_field = MS(REG_READ(ah, AR9285_AN_RF2G9), AR9285_AN_RXTXBB1_SPARE9);
-       REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9285_AN_RF2G3_PDVCCOMP, reg_field);
-       offs_6_1 = MS(REG_READ(ah, AR9285_AN_RF2G6), AR9285_AN_RF2G6_OFFS);
-       offs_0   = MS(REG_READ(ah, AR9285_AN_RF2G3), AR9285_AN_RF2G3_PDVCCOMP);
-
-       offset = (offs_6_1<<1) | offs_0;
-       offset = offset - 0;
-       offs_6_1 = offset>>1;
-       offs_0 = offset & 1;
-
-       if ((!is_reset) && (ah->pacal_info.prev_offset == offset)) {
-               if (ah->pacal_info.max_skipcount < MAX_PACAL_SKIPCOUNT)
-                       ah->pacal_info.max_skipcount =
-                               2 * ah->pacal_info.max_skipcount;
-               ah->pacal_info.skipcount = ah->pacal_info.max_skipcount;
-       } else {
-               ah->pacal_info.max_skipcount = 1;
-               ah->pacal_info.skipcount = 0;
-               ah->pacal_info.prev_offset = offset;
-       }
-
-       REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9285_AN_RF2G6_OFFS, offs_6_1);
-       REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9285_AN_RF2G3_PDVCCOMP, offs_0);
-
-       regVal = REG_READ(ah, 0x7834);
-       regVal |= 0x1;
-       REG_WRITE(ah, 0x7834, regVal);
-       regVal = REG_READ(ah, 0x9808);
-       regVal &= (~(0x1 << 27));
-       REG_WRITE(ah, 0x9808, regVal);
-
-       for (i = 0; i < ARRAY_SIZE(regList); i++)
-               REG_WRITE(ah, regList[i][0], regList[i][1]);
-
-       REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9285_AN_RF2G6_CCOMP, ccomp_org);
-
-       if (AR_SREV_9285_11(ah))
-               REG_WRITE(ah, AR9285_AN_TOP4, AR9285_AN_TOP4_DEFAULT);
-
-}
-
-bool ath9k_hw_calibrate(struct ath_hw *ah, struct ath9k_channel *chan,
-                       u8 rxchainmask, bool longcal)
-{
-       bool iscaldone = true;
-       struct ath9k_cal_list *currCal = ah->cal_list_curr;
-
-       if (currCal &&
-           (currCal->calState == CAL_RUNNING ||
-            currCal->calState == CAL_WAITING)) {
-               iscaldone = ath9k_hw_per_calibration(ah, chan,
-                                                    rxchainmask, currCal);
-               if (iscaldone) {
-                       ah->cal_list_curr = currCal = currCal->calNext;
-
-                       if (currCal->calState == CAL_WAITING) {
-                               iscaldone = false;
-                               ath9k_hw_reset_calibration(ah, currCal);
-                       }
-               }
-       }
-
-       /* Do NF cal only at longer intervals */
-       if (longcal) {
-               /* Do periodic PAOffset Cal */
-               if (AR_SREV_9271(ah)) {
-                       if (!ah->pacal_info.skipcount)
-                               ath9k_hw_9271_pa_cal(ah, false);
-                       else
-                               ah->pacal_info.skipcount--;
-               } else if (AR_SREV_9285_11_OR_LATER(ah)) {
-                       if (!ah->pacal_info.skipcount)
-                               ath9k_hw_9285_pa_cal(ah, false);
-                       else
-                               ah->pacal_info.skipcount--;
-               }
-
-               if (OLC_FOR_AR9280_20_LATER || OLC_FOR_AR9287_10_LATER)
-                       ath9k_olc_temp_compensation(ah);
-
-               /* Get the value from the previous NF cal and update history buffer */
-               ath9k_hw_getnf(ah, chan);
-
-               /*
-                * Load the NF from history buffer of the current channel.
-                * NF is slow time-variant, so it is OK to use a historical value.
-                */
-               ath9k_hw_loadnf(ah, ah->curchan);
-
-               ath9k_hw_start_nfcal(ah);
-       }
-
-       return iscaldone;
-}
-EXPORT_SYMBOL(ath9k_hw_calibrate);
-
-/* Carrier leakage Calibration fix */
-static bool ar9285_cl_cal(struct ath_hw *ah, struct ath9k_channel *chan)
-{
-       struct ath_common *common = ath9k_hw_common(ah);
-
-       REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
-       if (IS_CHAN_HT20(chan)) {
-               REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_PARALLEL_CAL_ENABLE);
-               REG_SET_BIT(ah, AR_PHY_TURBO, AR_PHY_FC_DYN2040_EN);
-               REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
-                           AR_PHY_AGC_CONTROL_FLTR_CAL);
-               REG_CLR_BIT(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_CAL_ENABLE);
-               REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL);
-               if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL,
-                                 AR_PHY_AGC_CONTROL_CAL, 0, AH_WAIT_TIMEOUT)) {
-                       ath_print(common, ATH_DBG_CALIBRATE, "offset "
-                                 "calibration failed to complete in "
-                                 "1ms; noisy ??\n");
-                       return false;
-               }
-               REG_CLR_BIT(ah, AR_PHY_TURBO, AR_PHY_FC_DYN2040_EN);
-               REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_PARALLEL_CAL_ENABLE);
-               REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
-       }
-       REG_CLR_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC);
-       REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL);
-       REG_SET_BIT(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_CAL_ENABLE);
-       REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL);
-       if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL,
-                         0, AH_WAIT_TIMEOUT)) {
-               ath_print(common, ATH_DBG_CALIBRATE, "offset calibration "
-                         "failed to complete in 1ms; noisy ??\n");
-               return false;
-       }
-
-       REG_SET_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC);
-       REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
-       REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL);
-
-       return true;
-}
-
-static bool ar9285_clc(struct ath_hw *ah, struct ath9k_channel *chan)
-{
-       int i;
-       u_int32_t txgain_max;
-       u_int32_t clc_gain, gain_mask = 0, clc_num = 0;
-       u_int32_t reg_clc_I0, reg_clc_Q0;
-       u_int32_t i0_num = 0;
-       u_int32_t q0_num = 0;
-       u_int32_t total_num = 0;
-       u_int32_t reg_rf2g5_org;
-       bool retv = true;
-
-       if (!(ar9285_cl_cal(ah, chan)))
-               return false;
-
-       txgain_max = MS(REG_READ(ah, AR_PHY_TX_PWRCTRL7),
-                       AR_PHY_TX_PWRCTRL_TX_GAIN_TAB_MAX);
-
-       for (i = 0; i < (txgain_max+1); i++) {
-               clc_gain = (REG_READ(ah, (AR_PHY_TX_GAIN_TBL1+(i<<2))) &
-                          AR_PHY_TX_GAIN_CLC) >> AR_PHY_TX_GAIN_CLC_S;
-               if (!(gain_mask & (1 << clc_gain))) {
-                       gain_mask |= (1 << clc_gain);
-                       clc_num++;
-               }
-       }
-
-       for (i = 0; i < clc_num; i++) {
-               reg_clc_I0 = (REG_READ(ah, (AR_PHY_CLC_TBL1 + (i << 2)))
-                             & AR_PHY_CLC_I0) >> AR_PHY_CLC_I0_S;
-               reg_clc_Q0 = (REG_READ(ah, (AR_PHY_CLC_TBL1 + (i << 2)))
-                             & AR_PHY_CLC_Q0) >> AR_PHY_CLC_Q0_S;
-               if (reg_clc_I0 == 0)
-                       i0_num++;
-
-               if (reg_clc_Q0 == 0)
-                       q0_num++;
-       }
-       total_num = i0_num + q0_num;
-       if (total_num > AR9285_CLCAL_REDO_THRESH) {
-               reg_rf2g5_org = REG_READ(ah, AR9285_RF2G5);
-               if (AR_SREV_9285E_20(ah)) {
-                       REG_WRITE(ah, AR9285_RF2G5,
-                                 (reg_rf2g5_org & AR9285_RF2G5_IC50TX) |
-                                 AR9285_RF2G5_IC50TX_XE_SET);
-               } else {
-                       REG_WRITE(ah, AR9285_RF2G5,
-                                 (reg_rf2g5_org & AR9285_RF2G5_IC50TX) |
-                                 AR9285_RF2G5_IC50TX_SET);
-               }
-               retv = ar9285_cl_cal(ah, chan);
-               REG_WRITE(ah, AR9285_RF2G5, reg_rf2g5_org);
-       }
-       return retv;
-}
-
-bool ath9k_hw_init_cal(struct ath_hw *ah, struct ath9k_channel *chan)
-{
-       struct ath_common *common = ath9k_hw_common(ah);
-
-       if (AR_SREV_9271(ah) || AR_SREV_9285_12_OR_LATER(ah)) {
-               if (!ar9285_clc(ah, chan))
-                       return false;
-       } else {
-               if (AR_SREV_9280_10_OR_LATER(ah)) {
-                       if (!AR_SREV_9287_10_OR_LATER(ah))
-                               REG_CLR_BIT(ah, AR_PHY_ADC_CTL,
-                                           AR_PHY_ADC_CTL_OFF_PWDADC);
-                       REG_SET_BIT(ah, AR_PHY_AGC_CONTROL,
-                                   AR_PHY_AGC_CONTROL_FLTR_CAL);
-               }
-
-               /* Calibrate the AGC */
-               REG_WRITE(ah, AR_PHY_AGC_CONTROL,
-                         REG_READ(ah, AR_PHY_AGC_CONTROL) |
-                         AR_PHY_AGC_CONTROL_CAL);
-
-               /* Poll for offset calibration complete */
-               if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL,
-                                  0, AH_WAIT_TIMEOUT)) {
-                       ath_print(common, ATH_DBG_CALIBRATE,
-                                 "offset calibration failed to "
-                                 "complete in 1ms; noisy environment?\n");
-                       return false;
-               }
-
-               if (AR_SREV_9280_10_OR_LATER(ah)) {
-                       if (!AR_SREV_9287_10_OR_LATER(ah))
-                               REG_SET_BIT(ah, AR_PHY_ADC_CTL,
-                                           AR_PHY_ADC_CTL_OFF_PWDADC);
-                       REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
-                                   AR_PHY_AGC_CONTROL_FLTR_CAL);
-               }
-       }
-
-       /* Do PA Calibration */
-       if (AR_SREV_9271(ah))
-               ath9k_hw_9271_pa_cal(ah, true);
-       else if (AR_SREV_9285_11_OR_LATER(ah))
-               ath9k_hw_9285_pa_cal(ah, true);
-
-       /* Do NF Calibration after DC offset and other calibrations */
-       REG_WRITE(ah, AR_PHY_AGC_CONTROL,
-                 REG_READ(ah, AR_PHY_AGC_CONTROL) | AR_PHY_AGC_CONTROL_NF);
-
-       ah->cal_list = ah->cal_list_last = ah->cal_list_curr = NULL;
-
-       /* Enable IQ, ADC Gain and ADC DC offset CALs */
-       if (AR_SREV_9100(ah) || AR_SREV_9160_10_OR_LATER(ah)) {
-               if (ath9k_hw_iscal_supported(ah, ADC_GAIN_CAL)) {
-                       INIT_CAL(&ah->adcgain_caldata);
-                       INSERT_CAL(ah, &ah->adcgain_caldata);
-                       ath_print(common, ATH_DBG_CALIBRATE,
-                                 "enabling ADC Gain Calibration.\n");
-               }
-               if (ath9k_hw_iscal_supported(ah, ADC_DC_CAL)) {
-                       INIT_CAL(&ah->adcdc_caldata);
-                       INSERT_CAL(ah, &ah->adcdc_caldata);
-                       ath_print(common, ATH_DBG_CALIBRATE,
-                                 "enabling ADC DC Calibration.\n");
-               }
-               if (ath9k_hw_iscal_supported(ah, IQ_MISMATCH_CAL)) {
-                       INIT_CAL(&ah->iq_caldata);
-                       INSERT_CAL(ah, &ah->iq_caldata);
-                       ath_print(common, ATH_DBG_CALIBRATE,
-                                 "enabling IQ Calibration.\n");
-               }
-
-               ah->cal_list_curr = ah->cal_list;
-
-               if (ah->cal_list_curr)
-                       ath9k_hw_reset_calibration(ah, ah->cal_list_curr);
-       }
-
-       chan->CalValid = 0;
-
-       return true;
-}
-
-const struct ath9k_percal_data iq_cal_multi_sample = {
-       IQ_MISMATCH_CAL,
-       MAX_CAL_SAMPLES,
-       PER_MIN_LOG_COUNT,
-       ath9k_hw_iqcal_collect,
-       ath9k_hw_iqcalibrate
-};
-const struct ath9k_percal_data iq_cal_single_sample = {
-       IQ_MISMATCH_CAL,
-       MIN_CAL_SAMPLES,
-       PER_MAX_LOG_COUNT,
-       ath9k_hw_iqcal_collect,
-       ath9k_hw_iqcalibrate
-};
-const struct ath9k_percal_data adc_gain_cal_multi_sample = {
-       ADC_GAIN_CAL,
-       MAX_CAL_SAMPLES,
-       PER_MIN_LOG_COUNT,
-       ath9k_hw_adc_gaincal_collect,
-       ath9k_hw_adc_gaincal_calibrate
-};
-const struct ath9k_percal_data adc_gain_cal_single_sample = {
-       ADC_GAIN_CAL,
-       MIN_CAL_SAMPLES,
-       PER_MAX_LOG_COUNT,
-       ath9k_hw_adc_gaincal_collect,
-       ath9k_hw_adc_gaincal_calibrate
-};
-const struct ath9k_percal_data adc_dc_cal_multi_sample = {
-       ADC_DC_CAL,
-       MAX_CAL_SAMPLES,
-       PER_MIN_LOG_COUNT,
-       ath9k_hw_adc_dccal_collect,
-       ath9k_hw_adc_dccal_calibrate
-};
-const struct ath9k_percal_data adc_dc_cal_single_sample = {
-       ADC_DC_CAL,
-       MIN_CAL_SAMPLES,
-       PER_MAX_LOG_COUNT,
-       ath9k_hw_adc_dccal_collect,
-       ath9k_hw_adc_dccal_calibrate
-};
-const struct ath9k_percal_data adc_init_dc_cal = {
-       ADC_DC_INIT_CAL,
-       MIN_CAL_SAMPLES,
-       INIT_LOG_COUNT,
-       ath9k_hw_adc_dccal_collect,
-       ath9k_hw_adc_dccal_calibrate
-};
index b2c873e974856895fbe77ff4138bc0b96be16a47..24538bdb9126c9239402206275bdbefddb1a4451 100644 (file)
 
 #include "hw.h"
 
-extern const struct ath9k_percal_data iq_cal_multi_sample;
-extern const struct ath9k_percal_data iq_cal_single_sample;
-extern const struct ath9k_percal_data adc_gain_cal_multi_sample;
-extern const struct ath9k_percal_data adc_gain_cal_single_sample;
-extern const struct ath9k_percal_data adc_dc_cal_multi_sample;
-extern const struct ath9k_percal_data adc_dc_cal_single_sample;
-extern const struct ath9k_percal_data adc_init_dc_cal;
-
 #define AR_PHY_CCA_MAX_AR5416_GOOD_VALUE       -85
 #define AR_PHY_CCA_MAX_AR9280_GOOD_VALUE       -112
 #define AR_PHY_CCA_MAX_AR9285_GOOD_VALUE       -118
@@ -76,7 +68,8 @@ enum ath9k_cal_types {
        ADC_DC_INIT_CAL = 0x1,
        ADC_GAIN_CAL = 0x2,
        ADC_DC_CAL = 0x4,
-       IQ_MISMATCH_CAL = 0x8
+       IQ_MISMATCH_CAL = 0x8,
+       TEMP_COMP_CAL = 0x10,
 };
 
 enum ath9k_cal_state {
@@ -122,14 +115,12 @@ struct ath9k_pacal_info{
 
 bool ath9k_hw_reset_calvalid(struct ath_hw *ah);
 void ath9k_hw_start_nfcal(struct ath_hw *ah);
-void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan);
 int16_t ath9k_hw_getnf(struct ath_hw *ah,
                       struct ath9k_channel *chan);
 void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah);
 s16 ath9k_hw_getchan_noise(struct ath_hw *ah, struct ath9k_channel *chan);
-bool ath9k_hw_calibrate(struct ath_hw *ah, struct ath9k_channel *chan,
-                       u8 rxchainmask, bool longcal);
-bool ath9k_hw_init_cal(struct ath_hw *ah,
-                      struct ath9k_channel *chan);
+void ath9k_hw_reset_calibration(struct ath_hw *ah,
+                               struct ath9k_cal_list *currCal);
+
 
 #endif /* CALIB_H */
index 72a835d9e97fc1a55693d2ecc75bf20d9ca9759b..e08f7e5a26e0e90072a36c5ac46a311907e7a8a3 100644 (file)
@@ -20,6 +20,7 @@
 #include "../debug.h"
 
 #include "hw.h"
+#include "hw-ops.h"
 
 /* Common header for Atheros 802.11n base driver cores */
 
@@ -76,11 +77,12 @@ struct ath_buf {
                                           an aggregate) */
        struct ath_buf *bf_next;        /* next subframe in the aggregate */
        struct sk_buff *bf_mpdu;        /* enclosing frame structure */
-       struct ath_desc *bf_desc;       /* virtual addr of desc */
+       void *bf_desc;                  /* virtual addr of desc */
        dma_addr_t bf_daddr;            /* physical addr of desc */
        dma_addr_t bf_buf_addr;         /* physical addr of data buffer */
        bool bf_stale;
        bool bf_isnullfunc;
+       bool bf_tx_aborted;
        u16 bf_flags;
        struct ath_buf_state bf_state;
        dma_addr_t bf_dmacontext;
index 9a8e419398f94f66fdd2d6e2fb2977cff58c6ddd..64e30cd45d057a4b289c414029f7170ca2db26f3 100644 (file)
@@ -180,8 +180,15 @@ void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status)
 {
        if (status)
                sc->debug.stats.istats.total++;
-       if (status & ATH9K_INT_RX)
-               sc->debug.stats.istats.rxok++;
+       if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
+               if (status & ATH9K_INT_RXLP)
+                       sc->debug.stats.istats.rxlp++;
+               if (status & ATH9K_INT_RXHP)
+                       sc->debug.stats.istats.rxhp++;
+       } else {
+               if (status & ATH9K_INT_RX)
+                       sc->debug.stats.istats.rxok++;
+       }
        if (status & ATH9K_INT_RXEOL)
                sc->debug.stats.istats.rxeol++;
        if (status & ATH9K_INT_RXORN)
@@ -223,8 +230,15 @@ static ssize_t read_file_interrupt(struct file *file, char __user *user_buf,
        char buf[512];
        unsigned int len = 0;
 
-       len += snprintf(buf + len, sizeof(buf) - len,
-               "%8s: %10u\n", "RX", sc->debug.stats.istats.rxok);
+       if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
+               len += snprintf(buf + len, sizeof(buf) - len,
+                       "%8s: %10u\n", "RXLP", sc->debug.stats.istats.rxlp);
+               len += snprintf(buf + len, sizeof(buf) - len,
+                       "%8s: %10u\n", "RXHP", sc->debug.stats.istats.rxhp);
+       } else {
+               len += snprintf(buf + len, sizeof(buf) - len,
+                       "%8s: %10u\n", "RX", sc->debug.stats.istats.rxok);
+       }
        len += snprintf(buf + len, sizeof(buf) - len,
                "%8s: %10u\n", "RXEOL", sc->debug.stats.istats.rxeol);
        len += snprintf(buf + len, sizeof(buf) - len,
index b2af9de755e64c38098b0027fc831ff5ce4f78eb..c545960e7ec5190fe045117e9abfb70315daa946 100644 (file)
@@ -35,6 +35,8 @@ struct ath_buf;
  * struct ath_interrupt_stats - Contains statistics about interrupts
  * @total: Total no. of interrupts generated so far
  * @rxok: RX with no errors
+ * @rxlp: RX with low priority RX
+ * @rxhp: RX with high priority, uapsd only
  * @rxeol: RX with no more RXDESC available
  * @rxorn: RX FIFO overrun
  * @txok: TX completed at the requested rate
@@ -55,6 +57,8 @@ struct ath_buf;
 struct ath_interrupt_stats {
        u32 total;
        u32 rxok;
+       u32 rxlp;
+       u32 rxhp;
        u32 rxeol;
        u32 rxorn;
        u32 txok;
index dacaae9341480dc253d3c4a42bc00c508e431c05..bd9dff3293dcad8aca448a9c7bcc8124d60fc5a0 100644 (file)
@@ -256,14 +256,13 @@ int ath9k_hw_eeprom_init(struct ath_hw *ah)
 {
        int status;
 
-       if (AR_SREV_9287(ah)) {
-               ah->eep_map = EEP_MAP_AR9287;
-               ah->eep_ops = &eep_AR9287_ops;
+       if (AR_SREV_9300_20_OR_LATER(ah))
+               ah->eep_ops = &eep_ar9300_ops;
+       else if (AR_SREV_9287(ah)) {
+               ah->eep_ops = &eep_ar9287_ops;
        } else if (AR_SREV_9285(ah) || AR_SREV_9271(ah)) {
-               ah->eep_map = EEP_MAP_4KBITS;
                ah->eep_ops = &eep_4k_ops;
        } else {
-               ah->eep_map = EEP_MAP_DEFAULT;
                ah->eep_ops = &eep_def_ops;
        }
 
index 2f2993b50e2ffb2159261ad97a4c4632ded5b31d..fb9c8c92eabeb79fde04c928f977cb16de882aae 100644 (file)
@@ -19,6 +19,7 @@
 
 #include "../ath.h"
 #include <net/cfg80211.h>
+#include "ar9003_eeprom.h"
 
 #define AH_USE_EEPROM   0x1
 
@@ -93,7 +94,6 @@
  */
 #define AR9285_RDEXT_DEFAULT    0x1F
 
-#define AR_EEPROM_MAC(i)       (0x1d+(i))
 #define ATH9K_POW_SM(_r, _s)   (((_r) & 0x3f) << (_s))
 #define FREQ2FBIN(x, y)                ((y) ? ((x) - 2300) : (((x) - 4800) / 5))
 #define ath9k_hw_use_flash(_ah)        (!(_ah->ah_flags & AH_USE_EEPROM))
 #define AR5416_BCHAN_UNUSED             0xFF
 #define AR5416_MAX_PWR_RANGE_IN_HALF_DB 64
 #define AR5416_MAX_CHAINS               3
+#define AR9300_MAX_CHAINS              3
 #define AR5416_PWR_TABLE_OFFSET_DB     -5
 
 /* Rx gain type values */
@@ -249,16 +250,20 @@ enum eeprom_param {
        EEP_MINOR_REV,
        EEP_TX_MASK,
        EEP_RX_MASK,
+       EEP_FSTCLK_5G,
        EEP_RXGAIN_TYPE,
-       EEP_TXGAIN_TYPE,
        EEP_OL_PWRCTRL,
+       EEP_TXGAIN_TYPE,
        EEP_RC_CHAIN_MASK,
        EEP_DAC_HPWR_5G,
        EEP_FRAC_N_5G,
        EEP_DEV_TYPE,
        EEP_TEMPSENSE_SLOPE,
        EEP_TEMPSENSE_SLOPE_PAL_ON,
-       EEP_PWR_TABLE_OFFSET
+       EEP_PWR_TABLE_OFFSET,
+       EEP_DRIVE_STRENGTH,
+       EEP_INTERNAL_REGULATOR,
+       EEP_SWREG
 };
 
 enum ar5416_rates {
@@ -656,13 +661,6 @@ struct ath9k_country_entry {
        u8 iso[3];
 };
 
-enum ath9k_eep_map {
-       EEP_MAP_DEFAULT = 0x0,
-       EEP_MAP_4KBITS,
-       EEP_MAP_AR9287,
-       EEP_MAP_MAX
-};
-
 struct eeprom_ops {
        int (*check_eeprom)(struct ath_hw *hw);
        u32 (*get_eeprom)(struct ath_hw *hw, enum eeprom_param param);
@@ -713,6 +711,8 @@ int ath9k_hw_eeprom_init(struct ath_hw *ah);
 
 extern const struct eeprom_ops eep_def_ops;
 extern const struct eeprom_ops eep_4k_ops;
-extern const struct eeprom_ops eep_AR9287_ops;
+extern const struct eeprom_ops eep_ar9287_ops;
+extern const struct eeprom_ops eep_ar9287_ops;
+extern const struct eeprom_ops eep_ar9300_ops;
 
 #endif /* EEPROM_H */
index 0354fe50f8e009b3c9bf00d53fcaae4eebad2c14..41a77d1bd43981a4e39a3b40bae55c2a1ae63664 100644 (file)
@@ -15,6 +15,7 @@
  */
 
 #include "hw.h"
+#include "ar9002_phy.h"
 
 static int ath9k_hw_4k_get_eeprom_ver(struct ath_hw *ah)
 {
@@ -182,11 +183,11 @@ static u32 ath9k_hw_4k_get_eeprom(struct ath_hw *ah,
        switch (param) {
        case EEP_NFTHRESH_2:
                return pModal->noiseFloorThreshCh[0];
-       case AR_EEPROM_MAC(0):
+       case EEP_MAC_LSW:
                return pBase->macAddr[0] << 8 | pBase->macAddr[1];
-       case AR_EEPROM_MAC(1):
+       case EEP_MAC_MID:
                return pBase->macAddr[2] << 8 | pBase->macAddr[3];
-       case AR_EEPROM_MAC(2):
+       case EEP_MAC_MSW:
                return pBase->macAddr[4] << 8 | pBase->macAddr[5];
        case EEP_REG_0:
                return pBase->regDmn[0];
@@ -453,6 +454,8 @@ static void ath9k_hw_set_4k_power_cal_table(struct ath_hw *ah,
                                            &tMinCalPower, gainBoundaries,
                                            pdadcValues, numXpdGain);
 
+                       ENABLE_REGWRITE_BUFFER(ah);
+
                        if ((i == 0) || AR_SREV_5416_20_OR_LATER(ah)) {
                                REG_WRITE(ah, AR_PHY_TPCRG5 + regChainOffset,
                                          SM(pdGainOverlap_t2,
@@ -493,6 +496,9 @@ static void ath9k_hw_set_4k_power_cal_table(struct ath_hw *ah,
 
                                regOffset += 4;
                        }
+
+                       REGWRITE_BUFFER_FLUSH(ah);
+                       DISABLE_REGWRITE_BUFFER(ah);
                }
        }
 
@@ -758,6 +764,8 @@ static void ath9k_hw_4k_set_txpower(struct ath_hw *ah,
                        ratesArray[i] -= AR5416_PWR_TABLE_OFFSET_DB * 2;
        }
 
+       ENABLE_REGWRITE_BUFFER(ah);
+
        /* OFDM power per rate */
        REG_WRITE(ah, AR_PHY_POWER_TX_RATE1,
                  ATH9K_POW_SM(ratesArray[rate18mb], 24)
@@ -820,6 +828,9 @@ static void ath9k_hw_4k_set_txpower(struct ath_hw *ah,
                          | ATH9K_POW_SM(ratesArray[rateDupOfdm], 8)
                          | ATH9K_POW_SM(ratesArray[rateDupCck], 0));
        }
+
+       REGWRITE_BUFFER_FLUSH(ah);
+       DISABLE_REGWRITE_BUFFER(ah);
 }
 
 static void ath9k_hw_4k_set_addac(struct ath_hw *ah,
index d8ca94c3fa0cdc8fdb288763d617c8a6392610c6..b471db5fb82d80d1b51564ad497b67e375a497f9 100644 (file)
@@ -15,6 +15,7 @@
  */
 
 #include "hw.h"
+#include "ar9002_phy.h"
 
 static int ath9k_hw_AR9287_get_eeprom_ver(struct ath_hw *ah)
 {
@@ -172,11 +173,11 @@ static u32 ath9k_hw_AR9287_get_eeprom(struct ath_hw *ah,
        switch (param) {
        case EEP_NFTHRESH_2:
                return pModal->noiseFloorThreshCh[0];
-       case AR_EEPROM_MAC(0):
+       case EEP_MAC_LSW:
                return pBase->macAddr[0] << 8 | pBase->macAddr[1];
-       case AR_EEPROM_MAC(1):
+       case EEP_MAC_MID:
                return pBase->macAddr[2] << 8 | pBase->macAddr[3];
-       case AR_EEPROM_MAC(2):
+       case EEP_MAC_MSW:
                return pBase->macAddr[4] << 8 | pBase->macAddr[5];
        case EEP_REG_0:
                return pBase->regDmn[0];
@@ -1169,7 +1170,7 @@ static u16 ath9k_hw_AR9287_get_spur_channel(struct ath_hw *ah,
 #undef EEP_MAP9287_SPURCHAN
 }
 
-const struct eeprom_ops eep_AR9287_ops = {
+const struct eeprom_ops eep_ar9287_ops = {
        .check_eeprom           = ath9k_hw_AR9287_check_eeprom,
        .get_eeprom             = ath9k_hw_AR9287_get_eeprom,
        .fill_eeprom            = ath9k_hw_AR9287_fill_eeprom,
index 404a0341242c4531e49777d1639cd7600afbfdb1..cf59799ef3073553673e938c96e80be22556a1ee 100644 (file)
@@ -15,6 +15,7 @@
  */
 
 #include "hw.h"
+#include "ar9002_phy.h"
 
 static void ath9k_get_txgain_index(struct ath_hw *ah,
                struct ath9k_channel *chan,
@@ -222,6 +223,12 @@ static int ath9k_hw_def_check_eeprom(struct ath_hw *ah)
                return -EINVAL;
        }
 
+       /* Enable fixup for AR_AN_TOP2 if necessary */
+       if (AR_SREV_9280_10_OR_LATER(ah) &&
+           (eep->baseEepHeader.version & 0xff) > 0x0a &&
+           eep->baseEepHeader.pwdclkind == 0)
+               ah->need_an_top2_fixup = 1;
+
        return 0;
 }
 
@@ -237,11 +244,11 @@ static u32 ath9k_hw_def_get_eeprom(struct ath_hw *ah,
                return pModal[0].noiseFloorThreshCh[0];
        case EEP_NFTHRESH_2:
                return pModal[1].noiseFloorThreshCh[0];
-       case AR_EEPROM_MAC(0):
+       case EEP_MAC_LSW:
                return pBase->macAddr[0] << 8 | pBase->macAddr[1];
-       case AR_EEPROM_MAC(1):
+       case EEP_MAC_MID:
                return pBase->macAddr[2] << 8 | pBase->macAddr[3];
-       case AR_EEPROM_MAC(2):
+       case EEP_MAC_MSW:
                return pBase->macAddr[4] << 8 | pBase->macAddr[5];
        case EEP_REG_0:
                return pBase->regDmn[0];
index fe994e229898520056d8db5dde65932806fe0df4..3091bb3cef9be6c182cdd41131c6bfac3f3e6208 100644 (file)
@@ -129,6 +129,7 @@ static void hif_usb_tx_cb(struct urb *urb)
                                TX_STAT_INC(skb_completed);
                        } else {
                                dev_kfree_skb_any(skb);
+                               TX_STAT_INC(skb_dropped);
                        }
                }
 
@@ -149,11 +150,15 @@ static void hif_usb_tx_cb(struct urb *urb)
        }
 }
 
-static inline void ath9k_skb_queue_purge(struct sk_buff_head *list)
+static inline void ath9k_skb_queue_purge(struct hif_device_usb *hif_dev,
+                                        struct sk_buff_head *list)
 {
        struct sk_buff *skb;
-       while ((skb = __skb_dequeue(list)) != NULL)
+
+       while ((skb = __skb_dequeue(list)) != NULL) {
                dev_kfree_skb_any(skb);
+               TX_STAT_INC(skb_dropped);
+       }
 }
 
 /* TX lock has to be taken */
@@ -214,7 +219,7 @@ static int __hif_usb_tx(struct hif_device_usb *hif_dev)
        ret = usb_submit_urb(tx_buf->urb, GFP_ATOMIC);
        if (ret) {
                tx_buf->len = tx_buf->offset = 0;
-               ath9k_skb_queue_purge(&tx_buf->skb_queue);
+               ath9k_skb_queue_purge(hif_dev, &tx_buf->skb_queue);
                __skb_queue_head_init(&tx_buf->skb_queue);
                list_move_tail(&tx_buf->list, &hif_dev->tx.tx_buf);
                hif_dev->tx.tx_buf_cnt++;
@@ -281,7 +286,7 @@ static void hif_usb_stop(void *hif_handle, u8 pipe_id)
        unsigned long flags;
 
        spin_lock_irqsave(&hif_dev->tx.tx_lock, flags);
-       ath9k_skb_queue_purge(&hif_dev->tx.tx_skb_queue);
+       ath9k_skb_queue_purge(hif_dev, &hif_dev->tx.tx_skb_queue);
        hif_dev->tx.tx_skb_cnt = 0;
        hif_dev->tx.flags |= HIF_USB_TX_STOP;
        spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags);
index 78213fc71b09bf55d4320f04bf43d480b560053f..c765ff4a505c54ea265b423c83d3dc1b752ddb3d 100644 (file)
@@ -124,13 +124,13 @@ struct ath9k_htc_cap_target {
 struct ath9k_htc_target_vif {
        u8 index;
        u8 des_bssid[ETH_ALEN];
-       enum htc_opmode opmode;
+       __be32 opmode;
        u8 myaddr[ETH_ALEN];
        u8 bssid[ETH_ALEN];
        u32 flags;
        u32 flags_ext;
        u16 ps_sta;
-       u16 rtsthreshold;
+       __be16 rtsthreshold;
        u8 ath_cap;
        u8 node;
        s8 mcast_rate;
@@ -151,7 +151,7 @@ struct ath9k_htc_target_sta {
        u8 sta_index;
        u8 vif_index;
        u8 vif_sta;
-       u16 flags; /* ATH_HTC_STA_* */
+       __be16 flags; /* ATH_HTC_STA_* */
        u16 htcap;
        u8 valid;
        u16 capinfo;
@@ -191,16 +191,16 @@ struct ath9k_htc_rate {
 struct ath9k_htc_target_rate {
        u8 sta_index;
        u8 isnew;
-       u32 capflags;
+       __be32 capflags;
        struct ath9k_htc_rate rates;
 };
 
 struct ath9k_htc_target_stats {
-       u32 tx_shortretry;
-       u32 tx_longretry;
-       u32 tx_xretries;
-       u32 ht_txunaggr_xretry;
-       u32 ht_tx_xretries;
+       __be32 tx_shortretry;
+       __be32 tx_longretry;
+       __be32 tx_xretries;
+       __be32 ht_txunaggr_xretry;
+       __be32 ht_tx_xretries;
 } __packed;
 
 struct ath9k_htc_vif {
@@ -261,6 +261,7 @@ struct ath_tx_stats {
        u32 buf_completed;
        u32 skb_queued;
        u32 skb_completed;
+       u32 skb_dropped;
 };
 
 struct ath_rx_stats {
index 5e21f4d92ff5ca761ee4b075563231e471fc7f02..7cb55f5b071c76be349ace16e4f25f6a5d8d812b 100644 (file)
@@ -26,7 +26,8 @@ static void ath9k_htc_beacon_config_sta(struct ath9k_htc_priv *priv,
        enum ath9k_int imask = 0;
        int dtimperiod, dtimcount, sleepduration;
        int cfpperiod, cfpcount, bmiss_timeout;
-       u32 nexttbtt = 0, intval, tsftu, htc_imask = 0;
+       u32 nexttbtt = 0, intval, tsftu;
+       __be32 htc_imask = 0;
        u64 tsf;
        int num_beacons, offset, dtim_dec_count, cfp_dec_count;
        int ret;
@@ -142,7 +143,8 @@ static void ath9k_htc_beacon_config_adhoc(struct ath9k_htc_priv *priv,
 {
        struct ath_common *common = ath9k_hw_common(priv->ah);
        enum ath9k_int imask = 0;
-       u32 nexttbtt, intval, htc_imask = 0;
+       u32 nexttbtt, intval;
+       __be32 htc_imask = 0;
        int ret;
        u8 cmd_rsp;
 
@@ -244,25 +246,20 @@ void ath9k_htc_beacon_config(struct ath9k_htc_priv *priv,
                             struct ieee80211_vif *vif)
 {
        struct ath_common *common = ath9k_hw_common(priv->ah);
-       enum nl80211_iftype iftype;
        struct htc_beacon_config *cur_conf = &priv->cur_beacon_conf;
+       struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
 
-       if (vif) {
-               struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
-               iftype = vif->type;
-               cur_conf->beacon_interval = bss_conf->beacon_int;
-               cur_conf->dtim_period = bss_conf->dtim_period;
-               cur_conf->listen_interval = 1;
-               cur_conf->dtim_count = 1;
-               cur_conf->bmiss_timeout =
-                       ATH_DEFAULT_BMISS_LIMIT * cur_conf->beacon_interval;
-       } else
-               iftype = priv->ah->opmode;
-
+       cur_conf->beacon_interval = bss_conf->beacon_int;
        if (cur_conf->beacon_interval == 0)
                cur_conf->beacon_interval = 100;
 
-       switch (iftype) {
+       cur_conf->dtim_period = bss_conf->dtim_period;
+       cur_conf->listen_interval = 1;
+       cur_conf->dtim_count = 1;
+       cur_conf->bmiss_timeout =
+               ATH_DEFAULT_BMISS_LIMIT * cur_conf->beacon_interval;
+
+       switch (vif->type) {
        case NL80211_IFTYPE_STATION:
                ath9k_htc_beacon_config_sta(priv, cur_conf);
                break;
index aed53573c5471a9ee1a6716e72c741e8fbc1b108..a86189629d92bd41f310803270ff4ecb2f6066e9 100644 (file)
@@ -213,7 +213,7 @@ static int ath9k_reg_notifier(struct wiphy *wiphy,
                                      ath9k_hw_regulatory(priv->ah));
 }
 
-static unsigned int ath9k_ioread32(void *hw_priv, u32 reg_offset)
+static unsigned int ath9k_regread(void *hw_priv, u32 reg_offset)
 {
        struct ath_hw *ah = (struct ath_hw *) hw_priv;
        struct ath_common *common = ath9k_hw_common(ah);
@@ -235,7 +235,7 @@ static unsigned int ath9k_ioread32(void *hw_priv, u32 reg_offset)
        return be32_to_cpu(val);
 }
 
-static void ath9k_iowrite32(void *hw_priv, u32 val, u32 reg_offset)
+static void ath9k_regwrite_single(void *hw_priv, u32 val, u32 reg_offset)
 {
        struct ath_hw *ah = (struct ath_hw *) hw_priv;
        struct ath_common *common = ath9k_hw_common(ah);
@@ -257,9 +257,105 @@ static void ath9k_iowrite32(void *hw_priv, u32 val, u32 reg_offset)
        }
 }
 
+static void ath9k_regwrite_buffer(void *hw_priv, u32 val, u32 reg_offset)
+{
+       struct ath_hw *ah = (struct ath_hw *) hw_priv;
+       struct ath_common *common = ath9k_hw_common(ah);
+       struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv;
+       u32 rsp_status;
+       int r;
+
+       mutex_lock(&priv->wmi->multi_write_mutex);
+
+       /* Store the register/value */
+       priv->wmi->multi_write[priv->wmi->multi_write_idx].reg =
+               cpu_to_be32(reg_offset);
+       priv->wmi->multi_write[priv->wmi->multi_write_idx].val =
+               cpu_to_be32(val);
+
+       priv->wmi->multi_write_idx++;
+
+       /* If the buffer is full, send it out. */
+       if (priv->wmi->multi_write_idx == MAX_CMD_NUMBER) {
+               r = ath9k_wmi_cmd(priv->wmi, WMI_REG_WRITE_CMDID,
+                         (u8 *) &priv->wmi->multi_write,
+                         sizeof(struct register_write) * priv->wmi->multi_write_idx,
+                         (u8 *) &rsp_status, sizeof(rsp_status),
+                         100);
+               if (unlikely(r)) {
+                       ath_print(common, ATH_DBG_WMI,
+                                 "REGISTER WRITE FAILED, multi len: %d\n",
+                                 priv->wmi->multi_write_idx);
+               }
+               priv->wmi->multi_write_idx = 0;
+       }
+
+       mutex_unlock(&priv->wmi->multi_write_mutex);
+}
+
+static void ath9k_regwrite(void *hw_priv, u32 val, u32 reg_offset)
+{
+       struct ath_hw *ah = (struct ath_hw *) hw_priv;
+       struct ath_common *common = ath9k_hw_common(ah);
+       struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv;
+
+       if (atomic_read(&priv->wmi->mwrite_cnt))
+               ath9k_regwrite_buffer(hw_priv, val, reg_offset);
+       else
+               ath9k_regwrite_single(hw_priv, val, reg_offset);
+}
+
+static void ath9k_enable_regwrite_buffer(void *hw_priv)
+{
+       struct ath_hw *ah = (struct ath_hw *) hw_priv;
+       struct ath_common *common = ath9k_hw_common(ah);
+       struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv;
+
+       atomic_inc(&priv->wmi->mwrite_cnt);
+}
+
+static void ath9k_disable_regwrite_buffer(void *hw_priv)
+{
+       struct ath_hw *ah = (struct ath_hw *) hw_priv;
+       struct ath_common *common = ath9k_hw_common(ah);
+       struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv;
+
+       atomic_dec(&priv->wmi->mwrite_cnt);
+}
+
+static void ath9k_regwrite_flush(void *hw_priv)
+{
+       struct ath_hw *ah = (struct ath_hw *) hw_priv;
+       struct ath_common *common = ath9k_hw_common(ah);
+       struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv;
+       u32 rsp_status;
+       int r;
+
+       mutex_lock(&priv->wmi->multi_write_mutex);
+
+       if (priv->wmi->multi_write_idx) {
+               r = ath9k_wmi_cmd(priv->wmi, WMI_REG_WRITE_CMDID,
+                         (u8 *) &priv->wmi->multi_write,
+                         sizeof(struct register_write) * priv->wmi->multi_write_idx,
+                         (u8 *) &rsp_status, sizeof(rsp_status),
+                         100);
+               if (unlikely(r)) {
+                       ath_print(common, ATH_DBG_WMI,
+                                 "REGISTER WRITE FAILED, multi len: %d\n",
+                                 priv->wmi->multi_write_idx);
+               }
+               priv->wmi->multi_write_idx = 0;
+       }
+
+       mutex_unlock(&priv->wmi->multi_write_mutex);
+}
+
 static const struct ath_ops ath9k_common_ops = {
-       .read = ath9k_ioread32,
-       .write = ath9k_iowrite32,
+       .read = ath9k_regread,
+       .write = ath9k_regwrite,
+       .enable_write_buffer = ath9k_enable_regwrite_buffer,
+       .disable_write_buffer = ath9k_disable_regwrite_buffer,
+       .write_flush = ath9k_regwrite_flush,
 };
 
 static void ath_usb_read_cachesize(struct ath_common *common, int *csz)
index eb7722b2cfcca62611f0e4636a38683cc456e0ca..ec7bcc8696ecf257f420085b16f75c8560be75ef 100644 (file)
@@ -125,7 +125,7 @@ static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv,
        bool fastcc = true;
        struct ieee80211_channel *channel = hw->conf.channel;
        enum htc_phymode mode;
-       u16 htc_mode;
+       __be16 htc_mode;
        u8 cmd_rsp;
        int ret;
 
@@ -378,7 +378,7 @@ static int ath9k_htc_init_rate(struct ath9k_htc_priv *priv,
        priv->tgt_rate.sta_index = ista->index;
        priv->tgt_rate.isnew = 1;
        trate = priv->tgt_rate;
-       priv->tgt_rate.capflags = caps;
+       priv->tgt_rate.capflags = cpu_to_be32(caps);
        trate.capflags = cpu_to_be32(caps);
 
        WMI_CMD_BUF(WMI_RC_RATE_UPDATE_CMDID, &trate);
@@ -426,6 +426,7 @@ static void ath9k_htc_rc_update(struct ath9k_htc_priv *priv, bool is_cw40)
        struct ath9k_htc_target_rate trate;
        struct ath_common *common = ath9k_hw_common(priv->ah);
        int ret;
+       u32 caps = be32_to_cpu(priv->tgt_rate.capflags);
        u8 cmd_rsp;
 
        memset(&trate, 0, sizeof(trate));
@@ -433,11 +434,12 @@ static void ath9k_htc_rc_update(struct ath9k_htc_priv *priv, bool is_cw40)
        trate = priv->tgt_rate;
 
        if (is_cw40)
-               priv->tgt_rate.capflags |= WLAN_RC_40_FLAG;
+               caps |= WLAN_RC_40_FLAG;
        else
-               priv->tgt_rate.capflags &= ~WLAN_RC_40_FLAG;
+               caps &= ~WLAN_RC_40_FLAG;
 
-       trate.capflags = cpu_to_be32(priv->tgt_rate.capflags);
+       priv->tgt_rate.capflags = cpu_to_be32(caps);
+       trate.capflags = cpu_to_be32(caps);
 
        WMI_CMD_BUF(WMI_RC_RATE_UPDATE_CMDID, &trate);
        if (ret) {
@@ -609,6 +611,9 @@ static ssize_t read_file_xmit(struct file *file, char __user *user_buf,
        len += snprintf(buf + len, sizeof(buf) - len,
                        "%20s : %10u\n", "SKBs completed",
                        priv->debug.tx_stats.skb_completed);
+       len += snprintf(buf + len, sizeof(buf) - len,
+                       "%20s : %10u\n", "SKBs dropped",
+                       priv->debug.tx_stats.skb_dropped);
 
        return simple_read_from_buffer(user_buf, count, ppos, buf, len);
 }
@@ -960,7 +965,6 @@ void ath9k_deinit_leds(struct ath9k_htc_priv *priv)
        ath9k_unregister_led(&priv->tx_led);
        ath9k_unregister_led(&priv->rx_led);
        ath9k_unregister_led(&priv->radio_led);
-       ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin, 1);
 }
 
 void ath9k_init_leds(struct ath9k_htc_priv *priv)
@@ -1102,7 +1106,7 @@ static int ath9k_htc_start(struct ieee80211_hw *hw)
        struct ath9k_channel *init_channel;
        int ret = 0;
        enum htc_phymode mode;
-       u16 htc_mode;
+       __be16 htc_mode;
        u8 cmd_rsp;
 
        ath_print(common, ATH_DBG_CONFIG,
@@ -1687,7 +1691,7 @@ static void ath9k_htc_sw_scan_complete(struct ieee80211_hw *hw)
        spin_unlock_bh(&priv->beacon_lock);
        priv->op_flags |= OP_FULL_RESET;
        if (priv->op_flags & OP_ASSOCIATED)
-               ath9k_htc_beacon_config(priv, NULL);
+               ath9k_htc_beacon_config(priv, priv->vif);
        ath_start_ani(priv);
        mutex_unlock(&priv->mutex);
        ath9k_htc_ps_restore(priv);
index 0a7cb30af5b480c05f247fde51c102dea1d02d8c..2c3c51007dd362908ac8e0ec60191ef718c67277 100644 (file)
@@ -530,7 +530,7 @@ static bool ath9k_rx_prepare(struct ath9k_htc_priv *priv,
                        priv->ah->stats.avgbrssi = rxbuf->rxstatus.rs_rssi;
        }
 
-       rx_status->mactime = rxbuf->rxstatus.rs_tstamp;
+       rx_status->mactime = be64_to_cpu(rxbuf->rxstatus.rs_tstamp);
        rx_status->band = hw->conf.channel->band;
        rx_status->freq = hw->conf.channel->center_freq;
        rx_status->signal =  rxbuf->rxstatus.rs_rssi + ATH_DEFAULT_NOISE_FLOOR;
@@ -634,13 +634,8 @@ void ath9k_htc_rxep(void *drv_priv, struct sk_buff *skb,
 
        rxstatus = (struct ath_htc_rx_status *)skb->data;
 
-       rxstatus->rs_tstamp = be64_to_cpu(rxstatus->rs_tstamp);
-       rxstatus->rs_datalen = be16_to_cpu(rxstatus->rs_datalen);
-       rxstatus->evm0 = be32_to_cpu(rxstatus->evm0);
-       rxstatus->evm1 = be32_to_cpu(rxstatus->evm1);
-       rxstatus->evm2 = be32_to_cpu(rxstatus->evm2);
-
-       if (rxstatus->rs_datalen - (len - HTC_RX_FRAME_HEADER_SIZE) != 0) {
+       if (be16_to_cpu(rxstatus->rs_datalen) -
+           (len - HTC_RX_FRAME_HEADER_SIZE) != 0) {
                ath_print(common, ATH_DBG_FATAL,
                          "Corrupted RX data len, dropping "
                          "(epid: %d, dlen: %d, skblen: %d)\n",
index 587d98ed098903bd85e9c45acc13e468d70c7b23..f2dca258bdc2b520b8aedd66e87a15f0baf556f5 100644 (file)
@@ -368,7 +368,7 @@ void ath9k_htc_rx_msg(struct htc_target *htc_handle,
        struct htc_frame_hdr *htc_hdr;
        enum htc_endpoint_id epid;
        struct htc_endpoint *endpoint;
-       u16 *msg_id;
+       __be16 *msg_id;
 
        if (!htc_handle || !skb)
                return;
@@ -388,14 +388,14 @@ void ath9k_htc_rx_msg(struct htc_target *htc_handle,
 
                /* Handle trailer */
                if (htc_hdr->flags & HTC_FLAGS_RECV_TRAILER) {
-                       if (be32_to_cpu(*(u32 *) skb->data) == 0x00C60000)
+                       if (be32_to_cpu(*(__be32 *) skb->data) == 0x00C60000)
                                /* Move past the Watchdog pattern */
                                htc_hdr = (struct htc_frame_hdr *)(skb->data + 4);
                }
 
                /* Get the message ID */
-               msg_id = (u16 *) ((void *) htc_hdr +
-                                          sizeof(struct htc_frame_hdr));
+               msg_id = (__be16 *) ((void *) htc_hdr +
+                                    sizeof(struct htc_frame_hdr));
 
                /* Now process HTC messages */
                switch (be16_to_cpu(*msg_id)) {
index cd7048ffd2396909efb80b64b5f5d280aafdc478..ea50ab032d205fa92c62aba023e540b64a4ee3ad 100644 (file)
@@ -59,20 +59,20 @@ enum htc_endpoint_id {
 struct htc_frame_hdr {
        u8 endpoint_id;
        u8 flags;
-       u16 payload_len;
+       __be16 payload_len;
        u8 control[4];
 } __packed;
 
 struct htc_ready_msg {
-       u16 message_id;
-       u16 credits;
-       u16 credit_size;
+       __be16 message_id;
+       __be16 credits;
+       __be16 credit_size;
        u8 max_endpoints;
        u8 pad;
 } __packed;
 
 struct htc_config_pipe_msg {
-       u16 message_id;
+       __be16 message_id;
        u8 pipe_id;
        u8 credits;
 } __packed;
@@ -192,9 +192,9 @@ enum htc_service_group_ids{
 #define WMI_DATA_BK_SVC   MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 8)
 
 struct htc_conn_svc_msg {
-       u16 msg_id;
-       u16 service_id;
-       u16 con_flags;
+       __be16 msg_id;
+       __be16 service_id;
+       __be16 con_flags;
        u8 dl_pipeid;
        u8 ul_pipeid;
        u8 svc_meta_len;
@@ -209,17 +209,17 @@ struct htc_conn_svc_msg {
 #define HTC_SERVICE_NO_MORE_EP   4
 
 struct htc_conn_svc_rspmsg {
-       u16 msg_id;
-       u16 service_id;
+       __be16 msg_id;
+       __be16 service_id;
        u8 status;
        u8 endpoint_id;
-       u16 max_msg_len;
+       __be16 max_msg_len;
        u8 svc_meta_len;
        u8 pad;
 } __packed;
 
 struct htc_comp_msg {
-       u16 msg_id;
+       __be16 msg_id;
 } __packed;
 
 int htc_init(struct htc_target *target);
diff --git a/drivers/net/wireless/ath/ath9k/hw-ops.h b/drivers/net/wireless/ath/ath9k/hw-ops.h
new file mode 100644 (file)
index 0000000..624422a
--- /dev/null
@@ -0,0 +1,280 @@
+/*
+ * Copyright (c) 2010 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT 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.
+ */
+
+#ifndef ATH9K_HW_OPS_H
+#define ATH9K_HW_OPS_H
+
+#include "hw.h"
+
+/* Hardware core and driver accessible callbacks */
+
+static inline void ath9k_hw_configpcipowersave(struct ath_hw *ah,
+                                              int restore,
+                                              int power_off)
+{
+       ath9k_hw_ops(ah)->config_pci_powersave(ah, restore, power_off);
+}
+
+static inline void ath9k_hw_rxena(struct ath_hw *ah)
+{
+       ath9k_hw_ops(ah)->rx_enable(ah);
+}
+
+static inline void ath9k_hw_set_desc_link(struct ath_hw *ah, void *ds,
+                                         u32 link)
+{
+       ath9k_hw_ops(ah)->set_desc_link(ds, link);
+}
+
+static inline void ath9k_hw_get_desc_link(struct ath_hw *ah, void *ds,
+                                         u32 **link)
+{
+       ath9k_hw_ops(ah)->get_desc_link(ds, link);
+}
+static inline bool ath9k_hw_calibrate(struct ath_hw *ah,
+                                     struct ath9k_channel *chan,
+                                     u8 rxchainmask,
+                                     bool longcal)
+{
+       return ath9k_hw_ops(ah)->calibrate(ah, chan, rxchainmask, longcal);
+}
+
+static inline bool ath9k_hw_getisr(struct ath_hw *ah, enum ath9k_int *masked)
+{
+       return ath9k_hw_ops(ah)->get_isr(ah, masked);
+}
+
+static inline void ath9k_hw_filltxdesc(struct ath_hw *ah, void *ds, u32 seglen,
+                                 bool is_firstseg, bool is_lastseg,
+                                 const void *ds0, dma_addr_t buf_addr,
+                                 unsigned int qcu)
+{
+       ath9k_hw_ops(ah)->fill_txdesc(ah, ds, seglen, is_firstseg, is_lastseg,
+                                     ds0, buf_addr, qcu);
+}
+
+static inline int ath9k_hw_txprocdesc(struct ath_hw *ah, void *ds,
+                                     struct ath_tx_status *ts)
+{
+       return ath9k_hw_ops(ah)->proc_txdesc(ah, ds, ts);
+}
+
+static inline void ath9k_hw_set11n_txdesc(struct ath_hw *ah, void *ds,
+                                         u32 pktLen, enum ath9k_pkt_type type,
+                                         u32 txPower, u32 keyIx,
+                                         enum ath9k_key_type keyType,
+                                         u32 flags)
+{
+       ath9k_hw_ops(ah)->set11n_txdesc(ah, ds, pktLen, type, txPower, keyIx,
+                                     keyType, flags);
+}
+
+static inline void ath9k_hw_set11n_ratescenario(struct ath_hw *ah, void *ds,
+                                       void *lastds,
+                                       u32 durUpdateEn, u32 rtsctsRate,
+                                       u32 rtsctsDuration,
+                                       struct ath9k_11n_rate_series series[],
+                                       u32 nseries, u32 flags)
+{
+       ath9k_hw_ops(ah)->set11n_ratescenario(ah, ds, lastds, durUpdateEn,
+                                           rtsctsRate, rtsctsDuration, series,
+                                           nseries, flags);
+}
+
+static inline void ath9k_hw_set11n_aggr_first(struct ath_hw *ah, void *ds,
+                                       u32 aggrLen)
+{
+       ath9k_hw_ops(ah)->set11n_aggr_first(ah, ds, aggrLen);
+}
+
+static inline void ath9k_hw_set11n_aggr_middle(struct ath_hw *ah, void *ds,
+                                              u32 numDelims)
+{
+       ath9k_hw_ops(ah)->set11n_aggr_middle(ah, ds, numDelims);
+}
+
+static inline void ath9k_hw_set11n_aggr_last(struct ath_hw *ah, void *ds)
+{
+       ath9k_hw_ops(ah)->set11n_aggr_last(ah, ds);
+}
+
+static inline void ath9k_hw_clr11n_aggr(struct ath_hw *ah, void *ds)
+{
+       ath9k_hw_ops(ah)->clr11n_aggr(ah, ds);
+}
+
+static inline void ath9k_hw_set11n_burstduration(struct ath_hw *ah, void *ds,
+                                                u32 burstDuration)
+{
+       ath9k_hw_ops(ah)->set11n_burstduration(ah, ds, burstDuration);
+}
+
+static inline void ath9k_hw_set11n_virtualmorefrag(struct ath_hw *ah, void *ds,
+                                                  u32 vmf)
+{
+       ath9k_hw_ops(ah)->set11n_virtualmorefrag(ah, ds, vmf);
+}
+
+/* Private hardware call ops */
+
+/* PHY ops */
+
+static inline int ath9k_hw_rf_set_freq(struct ath_hw *ah,
+                                      struct ath9k_channel *chan)
+{
+       return ath9k_hw_private_ops(ah)->rf_set_freq(ah, chan);
+}
+
+static inline void ath9k_hw_spur_mitigate_freq(struct ath_hw *ah,
+                                              struct ath9k_channel *chan)
+{
+       ath9k_hw_private_ops(ah)->spur_mitigate_freq(ah, chan);
+}
+
+static inline int ath9k_hw_rf_alloc_ext_banks(struct ath_hw *ah)
+{
+       if (!ath9k_hw_private_ops(ah)->rf_alloc_ext_banks)
+               return 0;
+
+       return ath9k_hw_private_ops(ah)->rf_alloc_ext_banks(ah);
+}
+
+static inline void ath9k_hw_rf_free_ext_banks(struct ath_hw *ah)
+{
+       if (!ath9k_hw_private_ops(ah)->rf_free_ext_banks)
+               return;
+
+       ath9k_hw_private_ops(ah)->rf_free_ext_banks(ah);
+}
+
+static inline bool ath9k_hw_set_rf_regs(struct ath_hw *ah,
+                                       struct ath9k_channel *chan,
+                                       u16 modesIndex)
+{
+       if (!ath9k_hw_private_ops(ah)->set_rf_regs)
+               return true;
+
+       return ath9k_hw_private_ops(ah)->set_rf_regs(ah, chan, modesIndex);
+}
+
+static inline void ath9k_hw_init_bb(struct ath_hw *ah,
+                                   struct ath9k_channel *chan)
+{
+       return ath9k_hw_private_ops(ah)->init_bb(ah, chan);
+}
+
+static inline void ath9k_hw_set_channel_regs(struct ath_hw *ah,
+                                            struct ath9k_channel *chan)
+{
+       return ath9k_hw_private_ops(ah)->set_channel_regs(ah, chan);
+}
+
+static inline int ath9k_hw_process_ini(struct ath_hw *ah,
+                                       struct ath9k_channel *chan)
+{
+       return ath9k_hw_private_ops(ah)->process_ini(ah, chan);
+}
+
+static inline void ath9k_olc_init(struct ath_hw *ah)
+{
+       if (!ath9k_hw_private_ops(ah)->olc_init)
+               return;
+
+       return ath9k_hw_private_ops(ah)->olc_init(ah);
+}
+
+static inline void ath9k_hw_set_rfmode(struct ath_hw *ah,
+                                      struct ath9k_channel *chan)
+{
+       return ath9k_hw_private_ops(ah)->set_rfmode(ah, chan);
+}
+
+static inline void ath9k_hw_mark_phy_inactive(struct ath_hw *ah)
+{
+       return ath9k_hw_private_ops(ah)->mark_phy_inactive(ah);
+}
+
+static inline void ath9k_hw_set_delta_slope(struct ath_hw *ah,
+                                           struct ath9k_channel *chan)
+{
+       return ath9k_hw_private_ops(ah)->set_delta_slope(ah, chan);
+}
+
+static inline bool ath9k_hw_rfbus_req(struct ath_hw *ah)
+{
+       return ath9k_hw_private_ops(ah)->rfbus_req(ah);
+}
+
+static inline void ath9k_hw_rfbus_done(struct ath_hw *ah)
+{
+       return ath9k_hw_private_ops(ah)->rfbus_done(ah);
+}
+
+static inline void ath9k_enable_rfkill(struct ath_hw *ah)
+{
+       return ath9k_hw_private_ops(ah)->enable_rfkill(ah);
+}
+
+static inline void ath9k_hw_restore_chainmask(struct ath_hw *ah)
+{
+       if (!ath9k_hw_private_ops(ah)->restore_chainmask)
+               return;
+
+       return ath9k_hw_private_ops(ah)->restore_chainmask(ah);
+}
+
+static inline void ath9k_hw_set_diversity(struct ath_hw *ah, bool value)
+{
+       return ath9k_hw_private_ops(ah)->set_diversity(ah, value);
+}
+
+static inline bool ath9k_hw_ani_control(struct ath_hw *ah,
+                                       enum ath9k_ani_cmd cmd, int param)
+{
+       return ath9k_hw_private_ops(ah)->ani_control(ah, cmd, param);
+}
+
+static inline void ath9k_hw_do_getnf(struct ath_hw *ah,
+                                    int16_t nfarray[NUM_NF_READINGS])
+{
+       ath9k_hw_private_ops(ah)->do_getnf(ah, nfarray);
+}
+
+static inline void ath9k_hw_loadnf(struct ath_hw *ah,
+                                  struct ath9k_channel *chan)
+{
+       ath9k_hw_private_ops(ah)->loadnf(ah, chan);
+}
+
+static inline bool ath9k_hw_init_cal(struct ath_hw *ah,
+                                    struct ath9k_channel *chan)
+{
+       return ath9k_hw_private_ops(ah)->init_cal(ah, chan);
+}
+
+static inline void ath9k_hw_setup_calibration(struct ath_hw *ah,
+                                             struct ath9k_cal_list *currCal)
+{
+       ath9k_hw_private_ops(ah)->setup_calibration(ah, currCal);
+}
+
+static inline bool ath9k_hw_iscal_supported(struct ath_hw *ah,
+                                           enum ath9k_cal_types calType)
+{
+       return ath9k_hw_private_ops(ah)->iscal_supported(ah, calType);
+}
+
+#endif /* ATH9K_HW_OPS_H */
index af730c7d50e6fe540ba3355fb221ba6c704927fb..5a29048db3b192c496d3a5507961fe2ed7e5be94 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008-2009 Atheros Communications Inc.
+ * Copyright (c) 2008-2010 Atheros Communications Inc.
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
 #include <asm/unaligned.h>
 
 #include "hw.h"
+#include "hw-ops.h"
 #include "rc.h"
-#include "initvals.h"
+#include "ar9003_mac.h"
 
 #define ATH9K_CLOCK_RATE_CCK           22
 #define ATH9K_CLOCK_RATE_5GHZ_OFDM     40
 #define ATH9K_CLOCK_RATE_2GHZ_OFDM     44
 
 static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type);
-static void ath9k_hw_set_regs(struct ath_hw *ah, struct ath9k_channel *chan);
 
 MODULE_AUTHOR("Atheros Communications");
 MODULE_DESCRIPTION("Support for Atheros 802.11n wireless LAN cards.");
@@ -46,6 +46,39 @@ static void __exit ath9k_exit(void)
 }
 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 void ath9k_hw_init_mode_regs(struct ath_hw *ah)
+{
+       ath9k_hw_private_ops(ah)->init_mode_regs(ah);
+}
+
+static bool ath9k_hw_macversion_supported(struct ath_hw *ah)
+{
+       struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
+
+       return priv_ops->macversion_supported(ah->hw_version.macVersion);
+}
+
+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);
+}
+
 /********************/
 /* Helper Functions */
 /********************/
@@ -233,21 +266,6 @@ static void ath9k_hw_read_revisions(struct ath_hw *ah)
        }
 }
 
-static int ath9k_hw_get_radiorev(struct ath_hw *ah)
-{
-       u32 val;
-       int i;
-
-       REG_WRITE(ah, AR_PHY(0x36), 0x00007058);
-
-       for (i = 0; i < 8; i++)
-               REG_WRITE(ah, AR_PHY(0x20), 0x00010000);
-       val = (REG_READ(ah, AR_PHY(256)) >> 24) & 0xff;
-       val = ((val & 0xf0) >> 4) | ((val & 0x0f) << 4);
-
-       return ath9k_hw_reverse_bits(val, 8);
-}
-
 /************************************/
 /* HW Attach, Detach, Init Routines */
 /************************************/
@@ -257,6 +275,8 @@ static void ath9k_hw_disablepcie(struct ath_hw *ah)
        if (AR_SREV_9100(ah))
                return;
 
+       ENABLE_REGWRITE_BUFFER(ah);
+
        REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fc00);
        REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924);
        REG_WRITE(ah, AR_PCIE_SERDES, 0x28000029);
@@ -268,20 +288,30 @@ static void ath9k_hw_disablepcie(struct ath_hw *ah)
        REG_WRITE(ah, AR_PCIE_SERDES, 0x000e1007);
 
        REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
+
+       REGWRITE_BUFFER_FLUSH(ah);
+       DISABLE_REGWRITE_BUFFER(ah);
 }
 
+/* This should work for all families including legacy */
 static bool ath9k_hw_chip_test(struct ath_hw *ah)
 {
        struct ath_common *common = ath9k_hw_common(ah);
-       u32 regAddr[2] = { AR_STA_ID0, AR_PHY_BASE + (8 << 2) };
+       u32 regAddr[2] = { AR_STA_ID0 };
        u32 regHold[2];
        u32 patternData[4] = { 0x55555555,
                               0xaaaaaaaa,
                               0x66666666,
                               0x99999999 };
-       int i, j;
+       int i, j, loop_max;
 
-       for (i = 0; i < 2; i++) {
+       if (!AR_SREV_9300_20_OR_LATER(ah)) {
+               loop_max = 2;
+               regAddr[1] = AR_PHY_BASE + (8 << 2);
+       } else
+               loop_max = 1;
+
+       for (i = 0; i < loop_max; i++) {
                u32 addr = regAddr[i];
                u32 wrData, rdData;
 
@@ -336,7 +366,13 @@ static void ath9k_hw_init_config(struct ath_hw *ah)
        ah->config.ofdm_trig_high = 500;
        ah->config.cck_trig_high = 200;
        ah->config.cck_trig_low = 100;
-       ah->config.enable_ani = 1;
+
+       /*
+        * For now ANI is disabled for AR9003, it is still
+        * being tested.
+        */
+       if (!AR_SREV_9300_20_OR_LATER(ah))
+               ah->config.enable_ani = 1;
 
        for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
                ah->config.spurchans[i][0] = AR_NO_SPUR;
@@ -369,7 +405,6 @@ static void ath9k_hw_init_config(struct ath_hw *ah)
        if (num_possible_cpus() > 1)
                ah->config.serialize_regmode = SER_REG_MODE_AUTO;
 }
-EXPORT_SYMBOL(ath9k_hw_init);
 
 static void ath9k_hw_init_defaults(struct ath_hw *ah)
 {
@@ -383,8 +418,6 @@ static void ath9k_hw_init_defaults(struct ath_hw *ah)
        ah->hw_version.subvendorid = 0;
 
        ah->ah_flags = 0;
-       if (ah->hw_version.devid == AR5416_AR9100_DEVID)
-               ah->hw_version.macVersion = AR_SREV_VERSION_9100;
        if (!AR_SREV_9100(ah))
                ah->ah_flags = AH_USE_EEPROM;
 
@@ -397,44 +430,17 @@ static void ath9k_hw_init_defaults(struct ath_hw *ah)
        ah->power_mode = ATH9K_PM_UNDEFINED;
 }
 
-static int ath9k_hw_rf_claim(struct ath_hw *ah)
-{
-       u32 val;
-
-       REG_WRITE(ah, AR_PHY(0), 0x00000007);
-
-       val = ath9k_hw_get_radiorev(ah);
-       switch (val & AR_RADIO_SREV_MAJOR) {
-       case 0:
-               val = AR_RAD5133_SREV_MAJOR;
-               break;
-       case AR_RAD5133_SREV_MAJOR:
-       case AR_RAD5122_SREV_MAJOR:
-       case AR_RAD2133_SREV_MAJOR:
-       case AR_RAD2122_SREV_MAJOR:
-               break;
-       default:
-               ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL,
-                         "Radio Chip Rev 0x%02X not supported\n",
-                         val & AR_RADIO_SREV_MAJOR);
-               return -EOPNOTSUPP;
-       }
-
-       ah->hw_version.analog5GhzRev = val;
-
-       return 0;
-}
-
 static int ath9k_hw_init_macaddr(struct ath_hw *ah)
 {
        struct ath_common *common = ath9k_hw_common(ah);
        u32 sum;
        int i;
        u16 eeval;
+       u32 EEP_MAC[] = { EEP_MAC_LSW, EEP_MAC_MID, EEP_MAC_MSW };
 
        sum = 0;
        for (i = 0; i < 3; i++) {
-               eeval = ah->eep_ops->get_eeprom(ah, AR_EEPROM_MAC(i));
+               eeval = ah->eep_ops->get_eeprom(ah, EEP_MAC[i]);
                sum += eeval;
                common->macaddr[2 * i] = eeval >> 8;
                common->macaddr[2 * i + 1] = eeval & 0xff;
@@ -445,54 +451,6 @@ static int ath9k_hw_init_macaddr(struct ath_hw *ah)
        return 0;
 }
 
-static void ath9k_hw_init_rxgain_ini(struct ath_hw *ah)
-{
-       u32 rxgain_type;
-
-       if (ah->eep_ops->get_eeprom(ah, EEP_MINOR_REV) >= AR5416_EEP_MINOR_VER_17) {
-               rxgain_type = ah->eep_ops->get_eeprom(ah, EEP_RXGAIN_TYPE);
-
-               if (rxgain_type == AR5416_EEP_RXGAIN_13DB_BACKOFF)
-                       INIT_INI_ARRAY(&ah->iniModesRxGain,
-                       ar9280Modes_backoff_13db_rxgain_9280_2,
-                       ARRAY_SIZE(ar9280Modes_backoff_13db_rxgain_9280_2), 6);
-               else if (rxgain_type == AR5416_EEP_RXGAIN_23DB_BACKOFF)
-                       INIT_INI_ARRAY(&ah->iniModesRxGain,
-                       ar9280Modes_backoff_23db_rxgain_9280_2,
-                       ARRAY_SIZE(ar9280Modes_backoff_23db_rxgain_9280_2), 6);
-               else
-                       INIT_INI_ARRAY(&ah->iniModesRxGain,
-                       ar9280Modes_original_rxgain_9280_2,
-                       ARRAY_SIZE(ar9280Modes_original_rxgain_9280_2), 6);
-       } else {
-               INIT_INI_ARRAY(&ah->iniModesRxGain,
-                       ar9280Modes_original_rxgain_9280_2,
-                       ARRAY_SIZE(ar9280Modes_original_rxgain_9280_2), 6);
-       }
-}
-
-static void ath9k_hw_init_txgain_ini(struct ath_hw *ah)
-{
-       u32 txgain_type;
-
-       if (ah->eep_ops->get_eeprom(ah, EEP_MINOR_REV) >= AR5416_EEP_MINOR_VER_19) {
-               txgain_type = ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE);
-
-               if (txgain_type == AR5416_EEP_TXGAIN_HIGH_POWER)
-                       INIT_INI_ARRAY(&ah->iniModesTxGain,
-                       ar9280Modes_high_power_tx_gain_9280_2,
-                       ARRAY_SIZE(ar9280Modes_high_power_tx_gain_9280_2), 6);
-               else
-                       INIT_INI_ARRAY(&ah->iniModesTxGain,
-                       ar9280Modes_original_tx_gain_9280_2,
-                       ARRAY_SIZE(ar9280Modes_original_tx_gain_9280_2), 6);
-       } else {
-               INIT_INI_ARRAY(&ah->iniModesTxGain,
-               ar9280Modes_original_tx_gain_9280_2,
-               ARRAY_SIZE(ar9280Modes_original_tx_gain_9280_2), 6);
-       }
-}
-
 static int ath9k_hw_post_init(struct ath_hw *ah)
 {
        int ecode;
@@ -502,9 +460,11 @@ static int ath9k_hw_post_init(struct ath_hw *ah)
                        return -ENODEV;
        }
 
-       ecode = ath9k_hw_rf_claim(ah);
-       if (ecode != 0)
-               return ecode;
+       if (!AR_SREV_9300_20_OR_LATER(ah)) {
+               ecode = ar9002_hw_rf_claim(ah);
+               if (ecode != 0)
+                       return ecode;
+       }
 
        ecode = ath9k_hw_eeprom_init(ah);
        if (ecode != 0)
@@ -515,14 +475,12 @@ static int ath9k_hw_post_init(struct ath_hw *ah)
                  ah->eep_ops->get_eeprom_ver(ah),
                  ah->eep_ops->get_eeprom_rev(ah));
 
-        if (!AR_SREV_9280_10_OR_LATER(ah)) {
-               ecode = ath9k_hw_rf_alloc_ext_banks(ah);
-               if (ecode) {
-                       ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL,
-                                 "Failed allocating banks for "
-                                 "external radio\n");
-                       return ecode;
-               }
+       ecode = ath9k_hw_rf_alloc_ext_banks(ah);
+       if (ecode) {
+               ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL,
+                         "Failed allocating banks for "
+                         "external radio\n");
+               return ecode;
        }
 
        if (!AR_SREV_9100(ah)) {
@@ -533,344 +491,22 @@ static int ath9k_hw_post_init(struct ath_hw *ah)
        return 0;
 }
 
-static bool ath9k_hw_devid_supported(u16 devid)
-{
-       switch (devid) {
-       case AR5416_DEVID_PCI:
-       case AR5416_DEVID_PCIE:
-       case AR5416_AR9100_DEVID:
-       case AR9160_DEVID_PCI:
-       case AR9280_DEVID_PCI:
-       case AR9280_DEVID_PCIE:
-       case AR9285_DEVID_PCIE:
-       case AR5416_DEVID_AR9287_PCI:
-       case AR5416_DEVID_AR9287_PCIE:
-       case AR2427_DEVID_PCIE:
-               return true;
-       default:
-               break;
-       }
-       return false;
-}
-
-static bool ath9k_hw_macversion_supported(u32 macversion)
-{
-       switch (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:
-               return true;
-       default:
-               break;
-       }
-       return false;
-}
-
-static void ath9k_hw_init_cal_settings(struct ath_hw *ah)
-{
-       if (AR_SREV_9160_10_OR_LATER(ah)) {
-               if (AR_SREV_9280_10_OR_LATER(ah)) {
-                       ah->iq_caldata.calData = &iq_cal_single_sample;
-                       ah->adcgain_caldata.calData =
-                               &adc_gain_cal_single_sample;
-                       ah->adcdc_caldata.calData =
-                               &adc_dc_cal_single_sample;
-                       ah->adcdc_calinitdata.calData =
-                               &adc_init_dc_cal;
-               } else {
-                       ah->iq_caldata.calData = &iq_cal_multi_sample;
-                       ah->adcgain_caldata.calData =
-                               &adc_gain_cal_multi_sample;
-                       ah->adcdc_caldata.calData =
-                               &adc_dc_cal_multi_sample;
-                       ah->adcdc_calinitdata.calData =
-                               &adc_init_dc_cal;
-               }
-               ah->supp_cals = ADC_GAIN_CAL | ADC_DC_CAL | IQ_MISMATCH_CAL;
-       }
-}
-
-static void ath9k_hw_init_mode_regs(struct ath_hw *ah)
-{
-       if (AR_SREV_9271(ah)) {
-               INIT_INI_ARRAY(&ah->iniModes, ar9271Modes_9271,
-                              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;
-       }
-
-       if (AR_SREV_9287_11_OR_LATER(ah)) {
-               INIT_INI_ARRAY(&ah->iniModes, ar9287Modes_9287_1_1,
-                               ARRAY_SIZE(ar9287Modes_9287_1_1), 6);
-               INIT_INI_ARRAY(&ah->iniCommon, ar9287Common_9287_1_1,
-                               ARRAY_SIZE(ar9287Common_9287_1_1), 2);
-               if (ah->config.pcie_clock_req)
-                       INIT_INI_ARRAY(&ah->iniPcieSerdes,
-                       ar9287PciePhy_clkreq_off_L1_9287_1_1,
-                       ARRAY_SIZE(ar9287PciePhy_clkreq_off_L1_9287_1_1), 2);
-               else
-                       INIT_INI_ARRAY(&ah->iniPcieSerdes,
-                       ar9287PciePhy_clkreq_always_on_L1_9287_1_1,
-                       ARRAY_SIZE(ar9287PciePhy_clkreq_always_on_L1_9287_1_1),
-                                       2);
-       } else if (AR_SREV_9287_10_OR_LATER(ah)) {
-               INIT_INI_ARRAY(&ah->iniModes, ar9287Modes_9287_1_0,
-                               ARRAY_SIZE(ar9287Modes_9287_1_0), 6);
-               INIT_INI_ARRAY(&ah->iniCommon, ar9287Common_9287_1_0,
-                               ARRAY_SIZE(ar9287Common_9287_1_0), 2);
-
-               if (ah->config.pcie_clock_req)
-                       INIT_INI_ARRAY(&ah->iniPcieSerdes,
-                       ar9287PciePhy_clkreq_off_L1_9287_1_0,
-                       ARRAY_SIZE(ar9287PciePhy_clkreq_off_L1_9287_1_0), 2);
-               else
-                       INIT_INI_ARRAY(&ah->iniPcieSerdes,
-                       ar9287PciePhy_clkreq_always_on_L1_9287_1_0,
-                       ARRAY_SIZE(ar9287PciePhy_clkreq_always_on_L1_9287_1_0),
-                                 2);
-       } else if (AR_SREV_9285_12_OR_LATER(ah)) {
-
-
-               INIT_INI_ARRAY(&ah->iniModes, ar9285Modes_9285_1_2,
-                              ARRAY_SIZE(ar9285Modes_9285_1_2), 6);
-               INIT_INI_ARRAY(&ah->iniCommon, ar9285Common_9285_1_2,
-                              ARRAY_SIZE(ar9285Common_9285_1_2), 2);
-
-               if (ah->config.pcie_clock_req) {
-                       INIT_INI_ARRAY(&ah->iniPcieSerdes,
-                       ar9285PciePhy_clkreq_off_L1_9285_1_2,
-                       ARRAY_SIZE(ar9285PciePhy_clkreq_off_L1_9285_1_2), 2);
-               } else {
-                       INIT_INI_ARRAY(&ah->iniPcieSerdes,
-                       ar9285PciePhy_clkreq_always_on_L1_9285_1_2,
-                       ARRAY_SIZE(ar9285PciePhy_clkreq_always_on_L1_9285_1_2),
-                                 2);
-               }
-       } else if (AR_SREV_9285_10_OR_LATER(ah)) {
-               INIT_INI_ARRAY(&ah->iniModes, ar9285Modes_9285,
-                              ARRAY_SIZE(ar9285Modes_9285), 6);
-               INIT_INI_ARRAY(&ah->iniCommon, ar9285Common_9285,
-                              ARRAY_SIZE(ar9285Common_9285), 2);
-
-               if (ah->config.pcie_clock_req) {
-                       INIT_INI_ARRAY(&ah->iniPcieSerdes,
-                       ar9285PciePhy_clkreq_off_L1_9285,
-                       ARRAY_SIZE(ar9285PciePhy_clkreq_off_L1_9285), 2);
-               } else {
-                       INIT_INI_ARRAY(&ah->iniPcieSerdes,
-                       ar9285PciePhy_clkreq_always_on_L1_9285,
-                       ARRAY_SIZE(ar9285PciePhy_clkreq_always_on_L1_9285), 2);
-               }
-       } else if (AR_SREV_9280_20_OR_LATER(ah)) {
-               INIT_INI_ARRAY(&ah->iniModes, ar9280Modes_9280_2,
-                              ARRAY_SIZE(ar9280Modes_9280_2), 6);
-               INIT_INI_ARRAY(&ah->iniCommon, ar9280Common_9280_2,
-                              ARRAY_SIZE(ar9280Common_9280_2), 2);
-
-               if (ah->config.pcie_clock_req) {
-                       INIT_INI_ARRAY(&ah->iniPcieSerdes,
-                              ar9280PciePhy_clkreq_off_L1_9280,
-                              ARRAY_SIZE(ar9280PciePhy_clkreq_off_L1_9280),2);
-               } else {
-                       INIT_INI_ARRAY(&ah->iniPcieSerdes,
-                              ar9280PciePhy_clkreq_always_on_L1_9280,
-                              ARRAY_SIZE(ar9280PciePhy_clkreq_always_on_L1_9280), 2);
-               }
-               INIT_INI_ARRAY(&ah->iniModesAdditional,
-                              ar9280Modes_fast_clock_9280_2,
-                              ARRAY_SIZE(ar9280Modes_fast_clock_9280_2), 3);
-       } else if (AR_SREV_9280_10_OR_LATER(ah)) {
-               INIT_INI_ARRAY(&ah->iniModes, ar9280Modes_9280,
-                              ARRAY_SIZE(ar9280Modes_9280), 6);
-               INIT_INI_ARRAY(&ah->iniCommon, ar9280Common_9280,
-                              ARRAY_SIZE(ar9280Common_9280), 2);
-       } else if (AR_SREV_9160_10_OR_LATER(ah)) {
-               INIT_INI_ARRAY(&ah->iniModes, ar5416Modes_9160,
-                              ARRAY_SIZE(ar5416Modes_9160), 6);
-               INIT_INI_ARRAY(&ah->iniCommon, ar5416Common_9160,
-                              ARRAY_SIZE(ar5416Common_9160), 2);
-               INIT_INI_ARRAY(&ah->iniBank0, ar5416Bank0_9160,
-                              ARRAY_SIZE(ar5416Bank0_9160), 2);
-               INIT_INI_ARRAY(&ah->iniBB_RfGain, ar5416BB_RfGain_9160,
-                              ARRAY_SIZE(ar5416BB_RfGain_9160), 3);
-               INIT_INI_ARRAY(&ah->iniBank1, ar5416Bank1_9160,
-                              ARRAY_SIZE(ar5416Bank1_9160), 2);
-               INIT_INI_ARRAY(&ah->iniBank2, ar5416Bank2_9160,
-                              ARRAY_SIZE(ar5416Bank2_9160), 2);
-               INIT_INI_ARRAY(&ah->iniBank3, ar5416Bank3_9160,
-                              ARRAY_SIZE(ar5416Bank3_9160), 3);
-               INIT_INI_ARRAY(&ah->iniBank6, ar5416Bank6_9160,
-                              ARRAY_SIZE(ar5416Bank6_9160), 3);
-               INIT_INI_ARRAY(&ah->iniBank6TPC, ar5416Bank6TPC_9160,
-                              ARRAY_SIZE(ar5416Bank6TPC_9160), 3);
-               INIT_INI_ARRAY(&ah->iniBank7, ar5416Bank7_9160,
-                              ARRAY_SIZE(ar5416Bank7_9160), 2);
-               if (AR_SREV_9160_11(ah)) {
-                       INIT_INI_ARRAY(&ah->iniAddac,
-                                      ar5416Addac_91601_1,
-                                      ARRAY_SIZE(ar5416Addac_91601_1), 2);
-               } else {
-                       INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac_9160,
-                                      ARRAY_SIZE(ar5416Addac_9160), 2);
-               }
-       } else if (AR_SREV_9100_OR_LATER(ah)) {
-               INIT_INI_ARRAY(&ah->iniModes, ar5416Modes_9100,
-                              ARRAY_SIZE(ar5416Modes_9100), 6);
-               INIT_INI_ARRAY(&ah->iniCommon, ar5416Common_9100,
-                              ARRAY_SIZE(ar5416Common_9100), 2);
-               INIT_INI_ARRAY(&ah->iniBank0, ar5416Bank0_9100,
-                              ARRAY_SIZE(ar5416Bank0_9100), 2);
-               INIT_INI_ARRAY(&ah->iniBB_RfGain, ar5416BB_RfGain_9100,
-                              ARRAY_SIZE(ar5416BB_RfGain_9100), 3);
-               INIT_INI_ARRAY(&ah->iniBank1, ar5416Bank1_9100,
-                              ARRAY_SIZE(ar5416Bank1_9100), 2);
-               INIT_INI_ARRAY(&ah->iniBank2, ar5416Bank2_9100,
-                              ARRAY_SIZE(ar5416Bank2_9100), 2);
-               INIT_INI_ARRAY(&ah->iniBank3, ar5416Bank3_9100,
-                              ARRAY_SIZE(ar5416Bank3_9100), 3);
-               INIT_INI_ARRAY(&ah->iniBank6, ar5416Bank6_9100,
-                              ARRAY_SIZE(ar5416Bank6_9100), 3);
-               INIT_INI_ARRAY(&ah->iniBank6TPC, ar5416Bank6TPC_9100,
-                              ARRAY_SIZE(ar5416Bank6TPC_9100), 3);
-               INIT_INI_ARRAY(&ah->iniBank7, ar5416Bank7_9100,
-                              ARRAY_SIZE(ar5416Bank7_9100), 2);
-               INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac_9100,
-                              ARRAY_SIZE(ar5416Addac_9100), 2);
-       } else {
-               INIT_INI_ARRAY(&ah->iniModes, ar5416Modes,
-                              ARRAY_SIZE(ar5416Modes), 6);
-               INIT_INI_ARRAY(&ah->iniCommon, ar5416Common,
-                              ARRAY_SIZE(ar5416Common), 2);
-               INIT_INI_ARRAY(&ah->iniBank0, ar5416Bank0,
-                              ARRAY_SIZE(ar5416Bank0), 2);
-               INIT_INI_ARRAY(&ah->iniBB_RfGain, ar5416BB_RfGain,
-                              ARRAY_SIZE(ar5416BB_RfGain), 3);
-               INIT_INI_ARRAY(&ah->iniBank1, ar5416Bank1,
-                              ARRAY_SIZE(ar5416Bank1), 2);
-               INIT_INI_ARRAY(&ah->iniBank2, ar5416Bank2,
-                              ARRAY_SIZE(ar5416Bank2), 2);
-               INIT_INI_ARRAY(&ah->iniBank3, ar5416Bank3,
-                              ARRAY_SIZE(ar5416Bank3), 3);
-               INIT_INI_ARRAY(&ah->iniBank6, ar5416Bank6,
-                              ARRAY_SIZE(ar5416Bank6), 3);
-               INIT_INI_ARRAY(&ah->iniBank6TPC, ar5416Bank6TPC,
-                              ARRAY_SIZE(ar5416Bank6TPC), 3);
-               INIT_INI_ARRAY(&ah->iniBank7, ar5416Bank7,
-                              ARRAY_SIZE(ar5416Bank7), 2);
-               INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac,
-                              ARRAY_SIZE(ar5416Addac), 2);
-       }
-}
-
-static void ath9k_hw_init_mode_gain_regs(struct ath_hw *ah)
-{
-       if (AR_SREV_9287_11_OR_LATER(ah))
-               INIT_INI_ARRAY(&ah->iniModesRxGain,
-               ar9287Modes_rx_gain_9287_1_1,
-               ARRAY_SIZE(ar9287Modes_rx_gain_9287_1_1), 6);
-       else if (AR_SREV_9287_10(ah))
-               INIT_INI_ARRAY(&ah->iniModesRxGain,
-               ar9287Modes_rx_gain_9287_1_0,
-               ARRAY_SIZE(ar9287Modes_rx_gain_9287_1_0), 6);
-       else if (AR_SREV_9280_20(ah))
-               ath9k_hw_init_rxgain_ini(ah);
-
-       if (AR_SREV_9287_11_OR_LATER(ah)) {
-               INIT_INI_ARRAY(&ah->iniModesTxGain,
-               ar9287Modes_tx_gain_9287_1_1,
-               ARRAY_SIZE(ar9287Modes_tx_gain_9287_1_1), 6);
-       } else if (AR_SREV_9287_10(ah)) {
-               INIT_INI_ARRAY(&ah->iniModesTxGain,
-               ar9287Modes_tx_gain_9287_1_0,
-               ARRAY_SIZE(ar9287Modes_tx_gain_9287_1_0), 6);
-       } else if (AR_SREV_9280_20(ah)) {
-               ath9k_hw_init_txgain_ini(ah);
-       } else if (AR_SREV_9285_12_OR_LATER(ah)) {
-               u32 txgain_type = ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE);
-
-               /* txgain table */
-               if (txgain_type == AR5416_EEP_TXGAIN_HIGH_POWER) {
-                       if (AR_SREV_9285E_20(ah)) {
-                               INIT_INI_ARRAY(&ah->iniModesTxGain,
-                               ar9285Modes_XE2_0_high_power,
-                               ARRAY_SIZE(
-                                 ar9285Modes_XE2_0_high_power), 6);
-                       } else {
-                               INIT_INI_ARRAY(&ah->iniModesTxGain,
-                               ar9285Modes_high_power_tx_gain_9285_1_2,
-                               ARRAY_SIZE(
-                                 ar9285Modes_high_power_tx_gain_9285_1_2), 6);
-                       }
-               } else {
-                       if (AR_SREV_9285E_20(ah)) {
-                               INIT_INI_ARRAY(&ah->iniModesTxGain,
-                               ar9285Modes_XE2_0_normal_power,
-                               ARRAY_SIZE(
-                                 ar9285Modes_XE2_0_normal_power), 6);
-                       } else {
-                               INIT_INI_ARRAY(&ah->iniModesTxGain,
-                               ar9285Modes_original_tx_gain_9285_1_2,
-                               ARRAY_SIZE(
-                                 ar9285Modes_original_tx_gain_9285_1_2), 6);
-                       }
-               }
-       }
-}
-
-static void ath9k_hw_init_eeprom_fix(struct ath_hw *ah)
+static void ath9k_hw_attach_ops(struct ath_hw *ah)
 {
-       struct base_eep_header *pBase = &(ah->eeprom.def.baseEepHeader);
-       struct ath_common *common = ath9k_hw_common(ah);
-
-       ah->need_an_top2_fixup = (ah->hw_version.devid == AR9280_DEVID_PCI) &&
-                                (ah->eep_map != EEP_MAP_4KBITS) &&
-                                ((pBase->version & 0xff) > 0x0a) &&
-                                (pBase->pwdclkind == 0);
-
-       if (ah->need_an_top2_fixup)
-               ath_print(common, ATH_DBG_EEPROM,
-                         "needs fixup for AR_AN_TOP2 register\n");
+       if (AR_SREV_9300_20_OR_LATER(ah))
+               ar9003_hw_attach_ops(ah);
+       else
+               ar9002_hw_attach_ops(ah);
 }
 
-int ath9k_hw_init(struct ath_hw *ah)
+/* Called for all hardware families */
+static int __ath9k_hw_init(struct ath_hw *ah)
 {
        struct ath_common *common = ath9k_hw_common(ah);
        int r = 0;
 
-       if (common->bus_ops->ath_bus_type != ATH_USB) {
-               if (!ath9k_hw_devid_supported(ah->hw_version.devid)) {
-                       ath_print(common, ATH_DBG_FATAL,
-                                 "Unsupported device ID: 0x%0x\n",
-                                 ah->hw_version.devid);
-                       return -EOPNOTSUPP;
-               }
-       }
-
-       ath9k_hw_init_defaults(ah);
-       ath9k_hw_init_config(ah);
+       if (ah->hw_version.devid == AR5416_AR9100_DEVID)
+               ah->hw_version.macVersion = AR_SREV_VERSION_9100;
 
        if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_POWER_ON)) {
                ath_print(common, ATH_DBG_FATAL,
@@ -878,6 +514,11 @@ int ath9k_hw_init(struct ath_hw *ah)
                return -EIO;
        }
 
+       ath9k_hw_init_defaults(ah);
+       ath9k_hw_init_config(ah);
+
+       ath9k_hw_attach_ops(ah);
+
        if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) {
                ath_print(common, ATH_DBG_FATAL, "Couldn't wakeup chip\n");
                return -EIO;
@@ -902,7 +543,7 @@ int ath9k_hw_init(struct ath_hw *ah)
        else
                ah->config.max_txtrig_level = MAX_TX_FIFO_THRESHOLD;
 
-       if (!ath9k_hw_macversion_supported(ah->hw_version.macVersion)) {
+       if (!ath9k_hw_macversion_supported(ah)) {
                ath_print(common, ATH_DBG_FATAL,
                          "Mac Chip Rev 0x%02x.%x is not supported by "
                          "this driver\n", ah->hw_version.macVersion,
@@ -910,28 +551,15 @@ int ath9k_hw_init(struct ath_hw *ah)
                return -EOPNOTSUPP;
        }
 
-       if (AR_SREV_9100(ah)) {
-               ah->iq_caldata.calData = &iq_cal_multi_sample;
-               ah->supp_cals = IQ_MISMATCH_CAL;
-               ah->is_pciexpress = false;
-       }
-
-       if (AR_SREV_9271(ah))
+       if (AR_SREV_9271(ah) || AR_SREV_9100(ah))
                ah->is_pciexpress = false;
 
        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_9280_10_OR_LATER(ah)) {
+       if (AR_SREV_9280_10_OR_LATER(ah) && !AR_SREV_9300_20_OR_LATER(ah))
                ah->ani_function &= ~ATH9K_ANI_NOISE_IMMUNITY_LEVEL;
-               ah->ath9k_hw_rf_set_freq = &ath9k_hw_ar9280_set_channel;
-               ah->ath9k_hw_spur_mitigate_freq = &ath9k_hw_9280_spur_mitigate;
-       } else {
-               ah->ath9k_hw_rf_set_freq = &ath9k_hw_set_channel;
-               ah->ath9k_hw_spur_mitigate_freq = &ath9k_hw_spur_mitigate;
-       }
 
        ath9k_hw_init_mode_regs(ah);
 
@@ -940,15 +568,8 @@ int ath9k_hw_init(struct ath_hw *ah)
        else
                ath9k_hw_disablepcie(ah);
 
-       /* Support for Japan ch.14 (2484) spread */
-       if (AR_SREV_9287_11_OR_LATER(ah)) {
-               INIT_INI_ARRAY(&ah->iniCckfirNormal,
-                      ar9287Common_normal_cck_fir_coeff_92871_1,
-                      ARRAY_SIZE(ar9287Common_normal_cck_fir_coeff_92871_1), 2);
-               INIT_INI_ARRAY(&ah->iniCckfirJapan2484,
-                      ar9287Common_japan_2484_cck_fir_coeff_92871_1,
-                      ARRAY_SIZE(ar9287Common_japan_2484_cck_fir_coeff_92871_1), 2);
-       }
+       if (!AR_SREV_9300_20_OR_LATER(ah))
+               ar9002_hw_cck_chan14_spread(ah);
 
        r = ath9k_hw_post_init(ah);
        if (r)
@@ -959,8 +580,6 @@ int ath9k_hw_init(struct ath_hw *ah)
        if (r)
                return r;
 
-       ath9k_hw_init_eeprom_fix(ah);
-
        r = ath9k_hw_init_macaddr(ah);
        if (r) {
                ath_print(common, ATH_DBG_FATAL,
@@ -973,6 +592,9 @@ int ath9k_hw_init(struct ath_hw *ah)
        else
                ah->tx_trig_level = (AR_FTRIG_512B >> AR_FTRIG_S);
 
+       if (AR_SREV_9300_20_OR_LATER(ah))
+               ar9003_hw_set_nf_limits(ah);
+
        ath9k_init_nfcal_hist_buffer(ah);
 
        common->state = ATH_HW_INITIALIZED;
@@ -980,24 +602,50 @@ int ath9k_hw_init(struct ath_hw *ah)
        return 0;
 }
 
-static void ath9k_hw_init_bb(struct ath_hw *ah,
-                            struct ath9k_channel *chan)
+int ath9k_hw_init(struct ath_hw *ah)
 {
-       u32 synthDelay;
+       int ret;
+       struct ath_common *common = ath9k_hw_common(ah);
 
-       synthDelay = REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY;
-       if (IS_CHAN_B(chan))
-               synthDelay = (4 * synthDelay) / 22;
-       else
-               synthDelay /= 10;
+       /* These are all the AR5008/AR9001/AR9002 hardware family of chipsets */
+       switch (ah->hw_version.devid) {
+       case AR5416_DEVID_PCI:
+       case AR5416_DEVID_PCIE:
+       case AR5416_AR9100_DEVID:
+       case AR9160_DEVID_PCI:
+       case AR9280_DEVID_PCI:
+       case AR9280_DEVID_PCIE:
+       case AR9285_DEVID_PCIE:
+       case AR9287_DEVID_PCI:
+       case AR9287_DEVID_PCIE:
+       case AR2427_DEVID_PCIE:
+       case AR9300_DEVID_PCIE:
+               break;
+       default:
+               if (common->bus_ops->ath_bus_type == ATH_USB)
+                       break;
+               ath_print(common, ATH_DBG_FATAL,
+                         "Hardware device ID 0x%04x not supported\n",
+                         ah->hw_version.devid);
+               return -EOPNOTSUPP;
+       }
 
-       REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
+       ret = __ath9k_hw_init(ah);
+       if (ret) {
+               ath_print(common, ATH_DBG_FATAL,
+                         "Unable to initialize hardware; "
+                         "initialization status: %d\n", ret);
+               return ret;
+       }
 
-       udelay(synthDelay + BASE_ACTIVATE_DELAY);
+       return 0;
 }
+EXPORT_SYMBOL(ath9k_hw_init);
 
 static void ath9k_hw_init_qos(struct ath_hw *ah)
 {
+       ENABLE_REGWRITE_BUFFER(ah);
+
        REG_WRITE(ah, AR_MIC_QOS_CONTROL, 0x100aa);
        REG_WRITE(ah, AR_MIC_QOS_SELECT, 0x3210);
 
@@ -1011,69 +659,16 @@ static void ath9k_hw_init_qos(struct ath_hw *ah)
        REG_WRITE(ah, AR_TXOP_4_7, 0xFFFFFFFF);
        REG_WRITE(ah, AR_TXOP_8_11, 0xFFFFFFFF);
        REG_WRITE(ah, AR_TXOP_12_15, 0xFFFFFFFF);
+
+       REGWRITE_BUFFER_FLUSH(ah);
+       DISABLE_REGWRITE_BUFFER(ah);
 }
 
 static void ath9k_hw_init_pll(struct ath_hw *ah,
                              struct ath9k_channel *chan)
 {
-       u32 pll;
-
-       if (AR_SREV_9100(ah)) {
-               if (chan && IS_CHAN_5GHZ(chan))
-                       pll = 0x1450;
-               else
-                       pll = 0x1458;
-       } else {
-               if (AR_SREV_9280_10_OR_LATER(ah)) {
-                       pll = SM(0x5, AR_RTC_9160_PLL_REFDIV);
-
-                       if (chan && IS_CHAN_HALF_RATE(chan))
-                               pll |= SM(0x1, AR_RTC_9160_PLL_CLKSEL);
-                       else if (chan && IS_CHAN_QUARTER_RATE(chan))
-                               pll |= SM(0x2, AR_RTC_9160_PLL_CLKSEL);
-
-                       if (chan && IS_CHAN_5GHZ(chan)) {
-                               pll |= SM(0x28, AR_RTC_9160_PLL_DIV);
-
-
-                               if (AR_SREV_9280_20(ah)) {
-                                       if (((chan->channel % 20) == 0)
-                                           || ((chan->channel % 10) == 0))
-                                               pll = 0x2850;
-                                       else
-                                               pll = 0x142c;
-                               }
-                       } else {
-                               pll |= SM(0x2c, AR_RTC_9160_PLL_DIV);
-                       }
+       u32 pll = ath9k_hw_compute_pll_control(ah, chan);
 
-               } else if (AR_SREV_9160_10_OR_LATER(ah)) {
-
-                       pll = SM(0x5, AR_RTC_9160_PLL_REFDIV);
-
-                       if (chan && IS_CHAN_HALF_RATE(chan))
-                               pll |= SM(0x1, AR_RTC_9160_PLL_CLKSEL);
-                       else if (chan && IS_CHAN_QUARTER_RATE(chan))
-                               pll |= SM(0x2, AR_RTC_9160_PLL_CLKSEL);
-
-                       if (chan && IS_CHAN_5GHZ(chan))
-                               pll |= SM(0x50, AR_RTC_9160_PLL_DIV);
-                       else
-                               pll |= SM(0x58, AR_RTC_9160_PLL_DIV);
-               } else {
-                       pll = AR_RTC_PLL_REFDIV_5 | AR_RTC_PLL_DIV2;
-
-                       if (chan && IS_CHAN_HALF_RATE(chan))
-                               pll |= SM(0x1, AR_RTC_PLL_CLKSEL);
-                       else if (chan && IS_CHAN_QUARTER_RATE(chan))
-                               pll |= SM(0x2, AR_RTC_PLL_CLKSEL);
-
-                       if (chan && IS_CHAN_5GHZ(chan))
-                               pll |= SM(0xa, AR_RTC_PLL_DIV);
-                       else
-                               pll |= SM(0xb, AR_RTC_PLL_DIV);
-               }
-       }
        REG_WRITE(ah, AR_RTC_PLL_CONTROL, pll);
 
        /* Switch the core clock for ar9271 to 117Mhz */
@@ -1087,43 +682,6 @@ static void ath9k_hw_init_pll(struct ath_hw *ah,
        REG_WRITE(ah, AR_RTC_SLEEP_CLK, AR_RTC_FORCE_DERIVED_CLK);
 }
 
-static void ath9k_hw_init_chain_masks(struct ath_hw *ah)
-{
-       int rx_chainmask, tx_chainmask;
-
-       rx_chainmask = ah->rxchainmask;
-       tx_chainmask = ah->txchainmask;
-
-       switch (rx_chainmask) {
-       case 0x5:
-               REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP,
-                           AR_PHY_SWAP_ALT_CHAIN);
-       case 0x3:
-               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;
-               }
-       case 0x1:
-       case 0x2:
-       case 0x7:
-               REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx_chainmask);
-               REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx_chainmask);
-               break;
-       default:
-               break;
-       }
-
-       REG_WRITE(ah, AR_SELFGEN_MASK, tx_chainmask);
-       if (tx_chainmask == 0x5) {
-               REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP,
-                           AR_PHY_SWAP_ALT_CHAIN);
-       }
-       if (AR_SREV_9100(ah))
-               REG_WRITE(ah, AR_PHY_ANALOG_SWAP,
-                         REG_READ(ah, AR_PHY_ANALOG_SWAP) | 0x00000001);
-}
-
 static void ath9k_hw_init_interrupt_masks(struct ath_hw *ah,
                                          enum nl80211_iftype opmode)
 {
@@ -1133,16 +691,30 @@ static void ath9k_hw_init_interrupt_masks(struct ath_hw *ah,
                AR_IMR_RXORN |
                AR_IMR_BCNMISC;
 
-       if (ah->config.rx_intr_mitigation)
-               imr_reg |= AR_IMR_RXINTM | AR_IMR_RXMINTR;
-       else
-               imr_reg |= AR_IMR_RXOK;
+       if (AR_SREV_9300_20_OR_LATER(ah)) {
+               imr_reg |= AR_IMR_RXOK_HP;
+               if (ah->config.rx_intr_mitigation)
+                       imr_reg |= AR_IMR_RXINTM | AR_IMR_RXMINTR;
+               else
+                       imr_reg |= AR_IMR_RXOK_LP;
 
-       imr_reg |= AR_IMR_TXOK;
+       } else {
+               if (ah->config.rx_intr_mitigation)
+                       imr_reg |= AR_IMR_RXINTM | AR_IMR_RXMINTR;
+               else
+                       imr_reg |= AR_IMR_RXOK;
+       }
+
+       if (ah->config.tx_intr_mitigation)
+               imr_reg |= AR_IMR_TXINTM | AR_IMR_TXMINTR;
+       else
+               imr_reg |= AR_IMR_TXOK;
 
        if (opmode == NL80211_IFTYPE_AP)
                imr_reg |= AR_IMR_MIB;
 
+       ENABLE_REGWRITE_BUFFER(ah);
+
        REG_WRITE(ah, AR_IMR, imr_reg);
        ah->imrs2_reg |= AR_IMR_S2_GTT;
        REG_WRITE(ah, AR_IMR_S2, ah->imrs2_reg);
@@ -1152,6 +724,16 @@ static void ath9k_hw_init_interrupt_masks(struct ath_hw *ah,
                REG_WRITE(ah, AR_INTR_SYNC_ENABLE, AR_INTR_SYNC_DEFAULT);
                REG_WRITE(ah, AR_INTR_SYNC_MASK, 0);
        }
+
+       REGWRITE_BUFFER_FLUSH(ah);
+       DISABLE_REGWRITE_BUFFER(ah);
+
+       if (AR_SREV_9300_20_OR_LATER(ah)) {
+               REG_WRITE(ah, AR_INTR_PRIO_ASYNC_ENABLE, 0);
+               REG_WRITE(ah, AR_INTR_PRIO_ASYNC_MASK, 0);
+               REG_WRITE(ah, AR_INTR_PRIO_SYNC_ENABLE, 0);
+               REG_WRITE(ah, AR_INTR_PRIO_SYNC_MASK, 0);
+       }
 }
 
 static void ath9k_hw_setslottime(struct ath_hw *ah, u32 us)
@@ -1243,8 +825,7 @@ void ath9k_hw_deinit(struct ath_hw *ah)
        ath9k_hw_setpower(ah, ATH9K_PM_FULL_SLEEP);
 
 free_hw:
-       if (!AR_SREV_9280_10_OR_LATER(ah))
-               ath9k_hw_rf_free_ext_banks(ah);
+       ath9k_hw_rf_free_ext_banks(ah);
 }
 EXPORT_SYMBOL(ath9k_hw_deinit);
 
@@ -1252,73 +833,7 @@ EXPORT_SYMBOL(ath9k_hw_deinit);
 /* INI */
 /*******/
 
-static void ath9k_hw_override_ini(struct ath_hw *ah,
-                                 struct ath9k_channel *chan)
-{
-       u32 val;
-
-       /*
-        * Set the RX_ABORT and RX_DIS and clear if off only after
-        * RXE is set for MAC. This prevents frames with corrupted
-        * descriptor status.
-        */
-       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);
-
-               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);
-
-               REG_WRITE(ah, AR_PCU_MISC_MODE2, val);
-       }
-
-       if (!AR_SREV_5416_20_OR_LATER(ah) ||
-           AR_SREV_9280_10_OR_LATER(ah))
-               return;
-       /*
-        * Disable BB clock gating
-        * 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 void ath9k_olc_init(struct ath_hw *ah)
-{
-       u32 i;
-
-       if (OLC_FOR_AR9287_10_LATER) {
-               REG_SET_BIT(ah, AR_PHY_TX_PWRCTRL9,
-                               AR_PHY_TX_PWRCTRL9_RES_DC_REMOVAL);
-               ath9k_hw_analog_shift_rmw(ah, AR9287_AN_TXPC0,
-                               AR9287_AN_TXPC0_TXPCMODE,
-                               AR9287_AN_TXPC0_TXPCMODE_S,
-                               AR9287_AN_TXPC0_TXPCMODE_TEMPSENSE);
-               udelay(100);
-       } else {
-               for (i = 0; i < AR9280_TX_GAIN_TABLE_SIZE; i++)
-                       ah->originalGain[i] =
-                               MS(REG_READ(ah, AR_PHY_TX_GAIN_TBL1 + i * 4),
-                                               AR_PHY_TX_GAIN);
-               ah->PDADCdelta = 0;
-       }
-}
-
-static u32 ath9k_regd_get_ctl(struct ath_regulatory *reg,
-                             struct ath9k_channel *chan)
+u32 ath9k_regd_get_ctl(struct ath_regulatory *reg, struct ath9k_channel *chan)
 {
        u32 ctl = ath_regd_get_band_ctl(reg, chan->chan->band);
 
@@ -1332,193 +847,24 @@ static u32 ath9k_regd_get_ctl(struct ath_regulatory *reg,
        return ctl;
 }
 
-static int ath9k_hw_process_ini(struct ath_hw *ah,
-                               struct ath9k_channel *chan)
-{
-       struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
-       int i, regWrites = 0;
-       struct ieee80211_channel *channel = chan->chan;
-       u32 modesIndex, freqIndex;
-
-       switch (chan->chanmode) {
-       case CHANNEL_A:
-       case CHANNEL_A_HT20:
-               modesIndex = 1;
-               freqIndex = 1;
-               break;
-       case CHANNEL_A_HT40PLUS:
-       case CHANNEL_A_HT40MINUS:
-               modesIndex = 2;
-               freqIndex = 1;
-               break;
-       case CHANNEL_G:
-       case CHANNEL_G_HT20:
-       case CHANNEL_B:
-               modesIndex = 4;
-               freqIndex = 2;
-               break;
-       case CHANNEL_G_HT40PLUS:
-       case CHANNEL_G_HT40MINUS:
-               modesIndex = 3;
-               freqIndex = 2;
-               break;
-
-       default:
-               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);
-
-       if (AR_SREV_5416_22_OR_LATER(ah)) {
-               REG_WRITE_ARRAY(&ah->iniAddac, 1, regWrites);
-       } else {
-               struct ar5416IniArray temp;
-               u32 addacSize =
-                       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;
-               temp.ia_columns = ah->iniAddac.ia_columns;
-               temp.ia_rows = ah->iniAddac.ia_rows;
-               REG_WRITE_ARRAY(&temp, 1, regWrites);
-       }
-
-       REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_INTERNAL_ADDAC);
-
-       for (i = 0; i < ah->iniModes.ia_rows; i++) {
-               u32 reg = INI_RA(&ah->iniModes, i, 0);
-               u32 val = INI_RA(&ah->iniModes, i, modesIndex);
-
-               if (reg == AR_AN_TOP2 && ah->need_an_top2_fixup)
-                       val &= ~AR_AN_TOP2_PWDCLKIND;
-
-               REG_WRITE(ah, reg, val);
-
-               if (reg >= 0x7800 && reg < 0x78a0
-                   && ah->config.analog_shiftreg) {
-                       udelay(100);
-               }
-
-               DO_DELAY(regWrites);
-       }
-
-       if (AR_SREV_9280(ah) || AR_SREV_9287_10_OR_LATER(ah))
-               REG_WRITE_ARRAY(&ah->iniModesRxGain, modesIndex, regWrites);
-
-       if (AR_SREV_9280(ah) || AR_SREV_9285_12_OR_LATER(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);
-
-               REG_WRITE(ah, reg, val);
-
-               if (reg >= 0x7800 && reg < 0x78a0
-                   && ah->config.analog_shiftreg) {
-                       udelay(100);
-               }
-
-               DO_DELAY(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);
-       }
-
-       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,
-                               regWrites);
-       }
-
-       ath9k_hw_override_ini(ah, chan);
-       ath9k_hw_set_regs(ah, chan);
-       ath9k_hw_init_chain_masks(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,
-                                channel->max_power * 2,
-                                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");
-               return -EIO;
-       }
-
-       return 0;
-}
-
-/****************************************/
-/* Reset and Channel Switching Routines */
-/****************************************/
-
-static void ath9k_hw_set_rfmode(struct ath_hw *ah, struct ath9k_channel *chan)
-{
-       u32 rfMode = 0;
-
-       if (chan == NULL)
-               return;
-
-       rfMode |= (IS_CHAN_B(chan) || IS_CHAN_G(chan))
-               ? AR_PHY_MODE_DYNAMIC : AR_PHY_MODE_OFDM;
-
-       if (!AR_SREV_9280_10_OR_LATER(ah))
-               rfMode |= (IS_CHAN_5GHZ(chan)) ?
-                       AR_PHY_MODE_RF5GHZ : AR_PHY_MODE_RF2GHZ;
-
-       if (AR_SREV_9280_20(ah) && IS_CHAN_A_5MHZ_SPACED(chan))
-               rfMode |= (AR_PHY_MODE_DYNAMIC | AR_PHY_MODE_DYN_CCK_DISABLE);
-
-       REG_WRITE(ah, AR_PHY_MODE, rfMode);
-}
-
-static void ath9k_hw_mark_phy_inactive(struct ath_hw *ah)
-{
-       REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS);
-}
+/****************************************/
+/* Reset and Channel Switching Routines */
+/****************************************/
 
 static inline void ath9k_hw_set_dma(struct ath_hw *ah)
 {
+       struct ath_common *common = ath9k_hw_common(ah);
        u32 regval;
 
+       ENABLE_REGWRITE_BUFFER(ah);
+
        /*
         * set AHB_MODE not to do cacheline prefetches
        */
-       regval = REG_READ(ah, AR_AHB_MODE);
-       REG_WRITE(ah, AR_AHB_MODE, regval | AR_AHB_PREFETCH_RD_EN);
+       if (!AR_SREV_9300_20_OR_LATER(ah)) {
+               regval = REG_READ(ah, AR_AHB_MODE);
+               REG_WRITE(ah, AR_AHB_MODE, regval | AR_AHB_PREFETCH_RD_EN);
+       }
 
        /*
         * let mac dma reads be in 128 byte chunks
@@ -1526,12 +872,18 @@ static inline void ath9k_hw_set_dma(struct ath_hw *ah)
        regval = REG_READ(ah, AR_TXCFG) & ~AR_TXCFG_DMASZ_MASK;
        REG_WRITE(ah, AR_TXCFG, regval | AR_TXCFG_DMASZ_128B);
 
+       REGWRITE_BUFFER_FLUSH(ah);
+       DISABLE_REGWRITE_BUFFER(ah);
+
        /*
         * Restore TX Trigger Level to its pre-reset value.
         * The initial value depends on whether aggregation is enabled, and is
         * adjusted whenever underruns are detected.
         */
-       REG_RMW_FIELD(ah, AR_TXCFG, AR_FTRIG, ah->tx_trig_level);
+       if (!AR_SREV_9300_20_OR_LATER(ah))
+               REG_RMW_FIELD(ah, AR_TXCFG, AR_FTRIG, ah->tx_trig_level);
+
+       ENABLE_REGWRITE_BUFFER(ah);
 
        /*
         * let mac dma writes be in 128 byte chunks
@@ -1544,6 +896,14 @@ static inline void ath9k_hw_set_dma(struct ath_hw *ah)
         */
        REG_WRITE(ah, AR_RXFIFO_CFG, 0x200);
 
+       if (AR_SREV_9300_20_OR_LATER(ah)) {
+               REG_RMW_FIELD(ah, AR_RXBP_THRESH, AR_RXBP_THRESH_HP, 0x1);
+               REG_RMW_FIELD(ah, AR_RXBP_THRESH, AR_RXBP_THRESH_LP, 0x1);
+
+               ath9k_hw_set_rx_bufsize(ah, common->rx_bufsize -
+                       ah->caps.rx_status_len);
+       }
+
        /*
         * reduce the number of usable entries in PCU TXBUF to avoid
         * wrap around issues.
@@ -1559,6 +919,12 @@ static inline void ath9k_hw_set_dma(struct ath_hw *ah)
                REG_WRITE(ah, AR_PCU_TXBUF_CTRL,
                          AR_PCU_TXBUF_CTRL_USABLE_SIZE);
        }
+
+       REGWRITE_BUFFER_FLUSH(ah);
+       DISABLE_REGWRITE_BUFFER(ah);
+
+       if (AR_SREV_9300_20_OR_LATER(ah))
+               ath9k_hw_reset_txstatus_ring(ah);
 }
 
 static void ath9k_hw_set_operating_mode(struct ath_hw *ah, int opmode)
@@ -1586,10 +952,8 @@ static void ath9k_hw_set_operating_mode(struct ath_hw *ah, int opmode)
        }
 }
 
-static inline void ath9k_hw_get_delta_slope_vals(struct ath_hw *ah,
-                                                u32 coef_scaled,
-                                                u32 *coef_mantissa,
-                                                u32 *coef_exponent)
+void ath9k_hw_get_delta_slope_vals(struct ath_hw *ah, u32 coef_scaled,
+                                  u32 *coef_mantissa, u32 *coef_exponent)
 {
        u32 coef_exp, coef_man;
 
@@ -1605,40 +969,6 @@ static inline void ath9k_hw_get_delta_slope_vals(struct ath_hw *ah,
        *coef_exponent = coef_exp - 16;
 }
 
-static void ath9k_hw_set_delta_slope(struct ath_hw *ah,
-                                    struct ath9k_channel *chan)
-{
-       u32 coef_scaled, ds_coef_exp, ds_coef_man;
-       u32 clockMhzScaled = 0x64000000;
-       struct chan_centers centers;
-
-       if (IS_CHAN_HALF_RATE(chan))
-               clockMhzScaled = clockMhzScaled >> 1;
-       else if (IS_CHAN_QUARTER_RATE(chan))
-               clockMhzScaled = clockMhzScaled >> 2;
-
-       ath9k_hw_get_channel_centers(ah, chan, &centers);
-       coef_scaled = clockMhzScaled / centers.synth_center;
-
-       ath9k_hw_get_delta_slope_vals(ah, coef_scaled, &ds_coef_man,
-                                     &ds_coef_exp);
-
-       REG_RMW_FIELD(ah, AR_PHY_TIMING3,
-                     AR_PHY_TIMING3_DSC_MAN, ds_coef_man);
-       REG_RMW_FIELD(ah, AR_PHY_TIMING3,
-                     AR_PHY_TIMING3_DSC_EXP, ds_coef_exp);
-
-       coef_scaled = (9 * coef_scaled) / 10;
-
-       ath9k_hw_get_delta_slope_vals(ah, coef_scaled, &ds_coef_man,
-                                     &ds_coef_exp);
-
-       REG_RMW_FIELD(ah, AR_PHY_HALFGI,
-                     AR_PHY_HALFGI_DSC_MAN, ds_coef_man);
-       REG_RMW_FIELD(ah, AR_PHY_HALFGI,
-                     AR_PHY_HALFGI_DSC_EXP, ds_coef_exp);
-}
-
 static bool ath9k_hw_set_reset(struct ath_hw *ah, int type)
 {
        u32 rst_flags;
@@ -1652,6 +982,8 @@ static bool ath9k_hw_set_reset(struct ath_hw *ah, int type)
                (void)REG_READ(ah, AR_RTC_DERIVED_CLK);
        }
 
+       ENABLE_REGWRITE_BUFFER(ah);
+
        REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN |
                  AR_RTC_FORCE_WAKE_ON_INT);
 
@@ -1663,11 +995,16 @@ static bool ath9k_hw_set_reset(struct ath_hw *ah, int type)
                if (tmpReg &
                    (AR_INTR_SYNC_LOCAL_TIMEOUT |
                     AR_INTR_SYNC_RADM_CPL_TIMEOUT)) {
+                       u32 val;
                        REG_WRITE(ah, AR_INTR_SYNC_ENABLE, 0);
-                       REG_WRITE(ah, AR_RC, AR_RC_AHB | AR_RC_HOSTIF);
-               } else {
+
+                       val = AR_RC_HOSTIF;
+                       if (!AR_SREV_9300_20_OR_LATER(ah))
+                               val |= AR_RC_AHB;
+                       REG_WRITE(ah, AR_RC, val);
+
+               } else if (!AR_SREV_9300_20_OR_LATER(ah))
                        REG_WRITE(ah, AR_RC, AR_RC_AHB);
-               }
 
                rst_flags = AR_RTC_RC_MAC_WARM;
                if (type == ATH9K_RESET_COLD)
@@ -1675,6 +1012,10 @@ static bool ath9k_hw_set_reset(struct ath_hw *ah, int type)
        }
 
        REG_WRITE(ah, AR_RTC_RC, rst_flags);
+
+       REGWRITE_BUFFER_FLUSH(ah);
+       DISABLE_REGWRITE_BUFFER(ah);
+
        udelay(50);
 
        REG_WRITE(ah, AR_RTC_RC, 0);
@@ -1695,16 +1036,23 @@ static bool ath9k_hw_set_reset(struct ath_hw *ah, int type)
 
 static bool ath9k_hw_set_reset_power_on(struct ath_hw *ah)
 {
+       ENABLE_REGWRITE_BUFFER(ah);
+
        REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN |
                  AR_RTC_FORCE_WAKE_ON_INT);
 
-       if (!AR_SREV_9100(ah))
+       if (!AR_SREV_9100(ah) && !AR_SREV_9300_20_OR_LATER(ah))
                REG_WRITE(ah, AR_RC, AR_RC_AHB);
 
        REG_WRITE(ah, AR_RTC_RESET, 0);
-       udelay(2);
 
-       if (!AR_SREV_9100(ah))
+       REGWRITE_BUFFER_FLUSH(ah);
+       DISABLE_REGWRITE_BUFFER(ah);
+
+       if (!AR_SREV_9300_20_OR_LATER(ah))
+               udelay(2);
+
+       if (!AR_SREV_9100(ah) && !AR_SREV_9300_20_OR_LATER(ah))
                REG_WRITE(ah, AR_RC, 0);
 
        REG_WRITE(ah, AR_RTC_RESET, 1);
@@ -1740,34 +1088,6 @@ static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type)
        }
 }
 
-static void ath9k_hw_set_regs(struct ath_hw *ah, struct ath9k_channel *chan)
-{
-       u32 phymode;
-       u32 enableDacFifo = 0;
-
-       if (AR_SREV_9285_10_OR_LATER(ah))
-               enableDacFifo = (REG_READ(ah, AR_PHY_TURBO) &
-                                        AR_PHY_FC_ENABLE_DAC_FIFO);
-
-       phymode = AR_PHY_FC_HT_EN | AR_PHY_FC_SHORT_GI_40
-               | AR_PHY_FC_SINGLE_HT_LTF1 | AR_PHY_FC_WALSH | enableDacFifo;
-
-       if (IS_CHAN_HT40(chan)) {
-               phymode |= AR_PHY_FC_DYN2040_EN;
-
-               if ((chan->chanmode == CHANNEL_A_HT40PLUS) ||
-                   (chan->chanmode == CHANNEL_G_HT40PLUS))
-                       phymode |= AR_PHY_FC_DYN2040_PRI_CH;
-
-       }
-       REG_WRITE(ah, AR_PHY_TURBO, phymode);
-
-       ath9k_hw_set11nmac2040(ah);
-
-       REG_WRITE(ah, AR_GTXTO, 25 << AR_GTXTO_TIMEOUT_LIMIT_S);
-       REG_WRITE(ah, AR_CST, 0xF << AR_CST_TIMEOUT_LIMIT_S);
-}
-
 static bool ath9k_hw_chip_reset(struct ath_hw *ah,
                                struct ath9k_channel *chan)
 {
@@ -1793,7 +1113,7 @@ static bool ath9k_hw_channel_change(struct ath_hw *ah,
        struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
        struct ath_common *common = ath9k_hw_common(ah);
        struct ieee80211_channel *channel = chan->chan;
-       u32 synthDelay, qnum;
+       u32 qnum;
        int r;
 
        for (qnum = 0; qnum < AR_NUM_QCU; qnum++) {
@@ -1805,17 +1125,15 @@ static bool ath9k_hw_channel_change(struct ath_hw *ah,
                }
        }
 
-       REG_WRITE(ah, AR_PHY_RFBUS_REQ, AR_PHY_RFBUS_REQ_EN);
-       if (!ath9k_hw_wait(ah, AR_PHY_RFBUS_GRANT, AR_PHY_RFBUS_GRANT_EN,
-                          AR_PHY_RFBUS_GRANT_EN, AH_WAIT_TIMEOUT)) {
+       if (!ath9k_hw_rfbus_req(ah)) {
                ath_print(common, ATH_DBG_FATAL,
                          "Could not kill baseband RX\n");
                return false;
        }
 
-       ath9k_hw_set_regs(ah, chan);
+       ath9k_hw_set_channel_regs(ah, chan);
 
-       r = ah->ath9k_hw_rf_set_freq(ah, chan);
+       r = ath9k_hw_rf_set_freq(ah, chan);
        if (r) {
                ath_print(common, ATH_DBG_FATAL,
                          "Failed to set channel\n");
@@ -1829,20 +1147,12 @@ static bool ath9k_hw_channel_change(struct ath_hw *ah,
                             min((u32) MAX_RATE_POWER,
                             (u32) regulatory->power_limit));
 
-       synthDelay = REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY;
-       if (IS_CHAN_B(chan))
-               synthDelay = (4 * synthDelay) / 22;
-       else
-               synthDelay /= 10;
-
-       udelay(synthDelay + BASE_ACTIVATE_DELAY);
-
-       REG_WRITE(ah, AR_PHY_RFBUS_REQ, 0);
+       ath9k_hw_rfbus_done(ah);
 
        if (IS_CHAN_OFDM(chan) || IS_CHAN_HT(chan))
                ath9k_hw_set_delta_slope(ah, chan);
 
-       ah->ath9k_hw_spur_mitigate_freq(ah, chan);
+       ath9k_hw_spur_mitigate_freq(ah, chan);
 
        if (!chan->oneTimeCalsDone)
                chan->oneTimeCalsDone = true;
@@ -1850,17 +1160,33 @@ static bool ath9k_hw_channel_change(struct ath_hw *ah,
        return true;
 }
 
-static void ath9k_enable_rfkill(struct ath_hw *ah)
+bool ath9k_hw_check_alive(struct ath_hw *ah)
 {
-       REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL,
-                   AR_GPIO_INPUT_EN_VAL_RFSILENT_BB);
+       int count = 50;
+       u32 reg;
+
+       if (AR_SREV_9285_10_OR_LATER(ah))
+               return true;
+
+       do {
+               reg = REG_READ(ah, AR_OBS_BUS_1);
 
-       REG_CLR_BIT(ah, AR_GPIO_INPUT_MUX2,
-                   AR_GPIO_INPUT_MUX2_RFSILENT);
+               if ((reg & 0x7E7FFFEF) == 0x00702400)
+                       continue;
+
+               switch (reg & 0x7E000B00) {
+               case 0x1E000000:
+               case 0x52000B00:
+               case 0x18000B00:
+                       continue;
+               default:
+                       return true;
+               }
+       } while (count-- > 0);
 
-       ath9k_hw_cfg_gpio_input(ah, ah->rfkill_gpio);
-       REG_SET_BIT(ah, AR_PHY_TEST, RFSILENT_BB);
+       return false;
 }
+EXPORT_SYMBOL(ath9k_hw_check_alive);
 
 int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
                    bool bChannelChange)
@@ -1871,11 +1197,18 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
        u32 saveDefAntenna;
        u32 macStaId1;
        u64 tsf = 0;
-       int i, rx_chainmask, r;
+       int i, r;
 
        ah->txchainmask = common->tx_chainmask;
        ah->rxchainmask = common->rx_chainmask;
 
+       if (!ah->chip_fullsleep) {
+               ath9k_hw_abortpcurecv(ah);
+               if (!ath9k_hw_stopdmarecv(ah))
+                       ath_print(common, ATH_DBG_XMIT,
+                               "Failed to stop receive dma\n");
+       }
+
        if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
                return -EIO;
 
@@ -1943,16 +1276,6 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
        if (AR_SREV_9280_10_OR_LATER(ah))
                REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL, AR_GPIO_JTAG_DISABLE);
 
-       if (AR_SREV_9287_12_OR_LATER(ah)) {
-               /* Enable ASYNC FIFO */
-               REG_SET_BIT(ah, AR_MAC_PCU_ASYNC_FIFO_REG3,
-                               AR_MAC_PCU_ASYNC_FIFO_REG3_DATAPATH_SEL);
-               REG_SET_BIT(ah, AR_PHY_MODE, AR_PHY_MODE_ASYNCFIFO);
-               REG_CLR_BIT(ah, AR_MAC_PCU_ASYNC_FIFO_REG3,
-                               AR_MAC_PCU_ASYNC_FIFO_REG3_SOFT_RESET);
-               REG_SET_BIT(ah, AR_MAC_PCU_ASYNC_FIFO_REG3,
-                               AR_MAC_PCU_ASYNC_FIFO_REG3_SOFT_RESET);
-       }
        r = ath9k_hw_process_ini(ah, chan);
        if (r)
                return r;
@@ -1977,9 +1300,13 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
        if (IS_CHAN_OFDM(chan) || IS_CHAN_HT(chan))
                ath9k_hw_set_delta_slope(ah, chan);
 
-       ah->ath9k_hw_spur_mitigate_freq(ah, chan);
+       ath9k_hw_spur_mitigate_freq(ah, chan);
        ah->eep_ops->set_board_values(ah, chan);
 
+       ath9k_hw_set_operating_mode(ah, ah->opmode);
+
+       ENABLE_REGWRITE_BUFFER(ah);
+
        REG_WRITE(ah, AR_STA_ID0, get_unaligned_le32(common->macaddr));
        REG_WRITE(ah, AR_STA_ID1, get_unaligned_le16(common->macaddr + 4)
                  | macStaId1
@@ -1987,25 +1314,27 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
                  | (ah->config.
                     ack_6mb ? AR_STA_ID1_ACKCTS_6MB : 0)
                  | ah->sta_id1_defaults);
-       ath9k_hw_set_operating_mode(ah, ah->opmode);
-
        ath_hw_setbssidmask(common);
-
        REG_WRITE(ah, AR_DEF_ANTENNA, saveDefAntenna);
-
        ath9k_hw_write_associd(ah);
-
        REG_WRITE(ah, AR_ISR, ~0);
-
        REG_WRITE(ah, AR_RSSI_THR, INIT_RSSI_THR);
 
-       r = ah->ath9k_hw_rf_set_freq(ah, chan);
+       REGWRITE_BUFFER_FLUSH(ah);
+       DISABLE_REGWRITE_BUFFER(ah);
+
+       r = ath9k_hw_rf_set_freq(ah, chan);
        if (r)
                return r;
 
+       ENABLE_REGWRITE_BUFFER(ah);
+
        for (i = 0; i < AR_NUM_DCU; i++)
                REG_WRITE(ah, AR_DQCUMASK(i), 1 << i);
 
+       REGWRITE_BUFFER_FLUSH(ah);
+       DISABLE_REGWRITE_BUFFER(ah);
+
        ah->intr_txqs = 0;
        for (i = 0; i < ah->caps.total_queues; i++)
                ath9k_hw_resettxqueue(ah, i);
@@ -2018,25 +1347,9 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
 
        ath9k_hw_init_global_settings(ah);
 
-       if (AR_SREV_9287_12_OR_LATER(ah)) {
-               REG_WRITE(ah, AR_D_GBL_IFS_SIFS,
-                         AR_D_GBL_IFS_SIFS_ASYNC_FIFO_DUR);
-               REG_WRITE(ah, AR_D_GBL_IFS_SLOT,
-                         AR_D_GBL_IFS_SLOT_ASYNC_FIFO_DUR);
-               REG_WRITE(ah, AR_D_GBL_IFS_EIFS,
-                         AR_D_GBL_IFS_EIFS_ASYNC_FIFO_DUR);
-
-               REG_WRITE(ah, AR_TIME_OUT, AR_TIME_OUT_ACK_CTS_ASYNC_FIFO_DUR);
-               REG_WRITE(ah, AR_USEC, AR_USEC_ASYNC_FIFO_DUR);
-
-               REG_SET_BIT(ah, AR_MAC_PCU_LOGIC_ANALYZER,
-                           AR_MAC_PCU_LOGIC_ANALYZER_DISBUG20768);
-               REG_RMW_FIELD(ah, AR_AHB_MODE, AR_AHB_CUSTOM_BURST_EN,
-                             AR_AHB_CUSTOM_BURST_ASYNC_FIFO_VAL);
-       }
-       if (AR_SREV_9287_12_OR_LATER(ah)) {
-               REG_SET_BIT(ah, AR_PCU_MISC_MODE2,
-                               AR_PCU_MISC_MODE2_ENABLE_AGGWEP);
+       if (!AR_SREV_9300_20_OR_LATER(ah)) {
+               ar9002_hw_enable_async_fifo(ah);
+               ar9002_hw_enable_wep_aggregation(ah);
        }
 
        REG_WRITE(ah, AR_STA_ID1,
@@ -2051,19 +1364,24 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
                REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_FIRST, 2000);
        }
 
+       if (ah->config.tx_intr_mitigation) {
+               REG_RMW_FIELD(ah, AR_TIMT, AR_TIMT_LAST, 300);
+               REG_RMW_FIELD(ah, AR_TIMT, AR_TIMT_FIRST, 750);
+       }
+
        ath9k_hw_init_bb(ah, chan);
 
        if (!ath9k_hw_init_cal(ah, chan))
                return -EIO;
 
-       rx_chainmask = ah->rxchainmask;
-       if ((rx_chainmask == 0x5) || (rx_chainmask == 0x3)) {
-               REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx_chainmask);
-               REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx_chainmask);
-       }
+       ENABLE_REGWRITE_BUFFER(ah);
 
+       ath9k_hw_restore_chainmask(ah);
        REG_WRITE(ah, AR_CFG_LED, saveLedState | AR_CFG_SCLK_32KHZ);
 
+       REGWRITE_BUFFER_FLUSH(ah);
+       DISABLE_REGWRITE_BUFFER(ah);
+
        /*
         * For big endian systems turn on swapping for descriptors
         */
@@ -2093,6 +1411,11 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
        if (ah->btcoex_hw.enabled)
                ath9k_hw_btcoex_enable(ah);
 
+       if (AR_SREV_9300_20_OR_LATER(ah)) {
+               ath9k_hw_loadnf(ah, curchan);
+               ath9k_hw_start_nfcal(ah);
+       }
+
        return 0;
 }
 EXPORT_SYMBOL(ath9k_hw_reset);
@@ -2379,21 +1702,35 @@ EXPORT_SYMBOL(ath9k_hw_keyisvalid);
 /* Power Management (Chipset) */
 /******************************/
 
+/*
+ * Notify Power Mgt is disabled in self-generated frames.
+ * If requested, force chip to sleep.
+ */
 static void ath9k_set_power_sleep(struct ath_hw *ah, int setChip)
 {
        REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV);
        if (setChip) {
+               /*
+                * Clear the RTC force wake bit to allow the
+                * mac to go to sleep.
+                */
                REG_CLR_BIT(ah, AR_RTC_FORCE_WAKE,
                            AR_RTC_FORCE_WAKE_EN);
-               if (!AR_SREV_9100(ah))
+               if (!AR_SREV_9100(ah) && !AR_SREV_9300_20_OR_LATER(ah))
                        REG_WRITE(ah, AR_RC, AR_RC_AHB | AR_RC_HOSTIF);
 
+               /* Shutdown chip. Active low */
                if (!AR_SREV_5416(ah) && !AR_SREV_9271(ah))
                        REG_CLR_BIT(ah, (AR_RTC_RESET),
                                    AR_RTC_RESET_EN);
        }
 }
 
+/*
+ * Notify Power Management is enabled in self-generating
+ * frames. If request, set power mode of chip to
+ * auto/normal.  Duration in units of 128us (1/8 TU).
+ */
 static void ath9k_set_power_network_sleep(struct ath_hw *ah, int setChip)
 {
        REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV);
@@ -2401,9 +1738,14 @@ static void ath9k_set_power_network_sleep(struct ath_hw *ah, int setChip)
                struct ath9k_hw_capabilities *pCap = &ah->caps;
 
                if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) {
+                       /* Set WakeOnInterrupt bit; clear ForceWake bit */
                        REG_WRITE(ah, AR_RTC_FORCE_WAKE,
                                  AR_RTC_FORCE_WAKE_ON_INT);
                } else {
+                       /*
+                        * Clear the RTC force wake bit to allow the
+                        * mac to go to sleep.
+                        */
                        REG_CLR_BIT(ah, AR_RTC_FORCE_WAKE,
                                    AR_RTC_FORCE_WAKE_EN);
                }
@@ -2422,7 +1764,8 @@ static bool ath9k_hw_set_power_awake(struct ath_hw *ah, int setChip)
                                           ATH9K_RESET_POWER_ON) != true) {
                                return false;
                        }
-                       ath9k_hw_init_pll(ah, NULL);
+                       if (!AR_SREV_9300_20_OR_LATER(ah))
+                               ath9k_hw_init_pll(ah, NULL);
                }
                if (AR_SREV_9100(ah))
                        REG_SET_BIT(ah, AR_RTC_RESET,
@@ -2492,420 +1835,6 @@ bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode)
 }
 EXPORT_SYMBOL(ath9k_hw_setpower);
 
-/*
- * Helper for ASPM support.
- *
- * Disable PLL when in L0s as well as receiver clock when in L1.
- * This power saving option must be enabled through the SerDes.
- *
- * Programming the SerDes must go through the same 288 bit serial shift
- * register as the other analog registers.  Hence the 9 writes.
- */
-void ath9k_hw_configpcipowersave(struct ath_hw *ah, int restore, int power_off)
-{
-       u8 i;
-       u32 val;
-
-       if (ah->is_pciexpress != true)
-               return;
-
-       /* Do not touch SerDes registers */
-       if (ah->config.pcie_powersave_enable == 2)
-               return;
-
-       /* Nothing to do on restore for 11N */
-       if (!restore) {
-               if (AR_SREV_9280_20_OR_LATER(ah)) {
-                       /*
-                        * AR9280 2.0 or later chips use SerDes values from the
-                        * initvals.h initialized depending on chipset during
-                        * ath9k_hw_init()
-                        */
-                       for (i = 0; i < ah->iniPcieSerdes.ia_rows; i++) {
-                               REG_WRITE(ah, INI_RA(&ah->iniPcieSerdes, i, 0),
-                                         INI_RA(&ah->iniPcieSerdes, i, 1));
-                       }
-               } else if (AR_SREV_9280(ah) &&
-                          (ah->hw_version.macRev == AR_SREV_REVISION_9280_10)) {
-                       REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fd00);
-                       REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924);
-
-                       /* RX shut off when elecidle is asserted */
-                       REG_WRITE(ah, AR_PCIE_SERDES, 0xa8000019);
-                       REG_WRITE(ah, AR_PCIE_SERDES, 0x13160820);
-                       REG_WRITE(ah, AR_PCIE_SERDES, 0xe5980560);
-
-                       /* Shut off CLKREQ active in L1 */
-                       if (ah->config.pcie_clock_req)
-                               REG_WRITE(ah, AR_PCIE_SERDES, 0x401deffc);
-                       else
-                               REG_WRITE(ah, AR_PCIE_SERDES, 0x401deffd);
-
-                       REG_WRITE(ah, AR_PCIE_SERDES, 0x1aaabe40);
-                       REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554);
-                       REG_WRITE(ah, AR_PCIE_SERDES, 0x00043007);
-
-                       /* Load the new settings */
-                       REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
-
-               } else {
-                       REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fc00);
-                       REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924);
-
-                       /* RX shut off when elecidle is asserted */
-                       REG_WRITE(ah, AR_PCIE_SERDES, 0x28000039);
-                       REG_WRITE(ah, AR_PCIE_SERDES, 0x53160824);
-                       REG_WRITE(ah, AR_PCIE_SERDES, 0xe5980579);
-
-                       /*
-                        * Ignore ah->ah_config.pcie_clock_req setting for
-                        * pre-AR9280 11n
-                        */
-                       REG_WRITE(ah, AR_PCIE_SERDES, 0x001defff);
-
-                       REG_WRITE(ah, AR_PCIE_SERDES, 0x1aaabe40);
-                       REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554);
-                       REG_WRITE(ah, AR_PCIE_SERDES, 0x000e3007);
-
-                       /* Load the new settings */
-                       REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
-               }
-
-               udelay(1000);
-
-               /* set bit 19 to allow forcing of pcie core into L1 state */
-               REG_SET_BIT(ah, AR_PCIE_PM_CTRL, AR_PCIE_PM_CTRL_ENA);
-
-               /* Several PCIe massages to ensure proper behaviour */
-               if (ah->config.pcie_waen) {
-                       val = ah->config.pcie_waen;
-                       if (!power_off)
-                               val &= (~AR_WA_D3_L1_DISABLE);
-               } else {
-                       if (AR_SREV_9285(ah) || AR_SREV_9271(ah) ||
-                           AR_SREV_9287(ah)) {
-                               val = AR9285_WA_DEFAULT;
-                               if (!power_off)
-                                       val &= (~AR_WA_D3_L1_DISABLE);
-                       } else if (AR_SREV_9280(ah)) {
-                               /*
-                                * On AR9280 chips bit 22 of 0x4004 needs to be
-                                * set otherwise card may disappear.
-                                */
-                               val = AR9280_WA_DEFAULT;
-                               if (!power_off)
-                                       val &= (~AR_WA_D3_L1_DISABLE);
-                       } else
-                               val = AR_WA_DEFAULT;
-               }
-
-               REG_WRITE(ah, AR_WA, val);
-       }
-
-       if (power_off) {
-               /*
-                * Set PCIe workaround bits
-                * bit 14 in WA register (disable L1) should only
-                * be set when device enters D3 and be cleared
-                * when device comes back to D0.
-                */
-               if (ah->config.pcie_waen) {
-                       if (ah->config.pcie_waen & AR_WA_D3_L1_DISABLE)
-                               REG_SET_BIT(ah, AR_WA, AR_WA_D3_L1_DISABLE);
-               } else {
-                       if (((AR_SREV_9285(ah) || AR_SREV_9271(ah) ||
-                             AR_SREV_9287(ah)) &&
-                            (AR9285_WA_DEFAULT & AR_WA_D3_L1_DISABLE)) ||
-                           (AR_SREV_9280(ah) &&
-                            (AR9280_WA_DEFAULT & AR_WA_D3_L1_DISABLE))) {
-                               REG_SET_BIT(ah, AR_WA, AR_WA_D3_L1_DISABLE);
-                       }
-               }
-       }
-}
-EXPORT_SYMBOL(ath9k_hw_configpcipowersave);
-
-/**********************/
-/* Interrupt Handling */
-/**********************/
-
-bool ath9k_hw_intrpend(struct ath_hw *ah)
-{
-       u32 host_isr;
-
-       if (AR_SREV_9100(ah))
-               return true;
-
-       host_isr = REG_READ(ah, AR_INTR_ASYNC_CAUSE);
-       if ((host_isr & AR_INTR_MAC_IRQ) && (host_isr != AR_INTR_SPURIOUS))
-               return true;
-
-       host_isr = REG_READ(ah, AR_INTR_SYNC_CAUSE);
-       if ((host_isr & AR_INTR_SYNC_DEFAULT)
-           && (host_isr != AR_INTR_SPURIOUS))
-               return true;
-
-       return false;
-}
-EXPORT_SYMBOL(ath9k_hw_intrpend);
-
-bool ath9k_hw_getisr(struct ath_hw *ah, enum ath9k_int *masked)
-{
-       u32 isr = 0;
-       u32 mask2 = 0;
-       struct ath9k_hw_capabilities *pCap = &ah->caps;
-       u32 sync_cause = 0;
-       bool fatal_int = false;
-       struct ath_common *common = ath9k_hw_common(ah);
-
-       if (!AR_SREV_9100(ah)) {
-               if (REG_READ(ah, AR_INTR_ASYNC_CAUSE) & AR_INTR_MAC_IRQ) {
-                       if ((REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M)
-                           == AR_RTC_STATUS_ON) {
-                               isr = REG_READ(ah, AR_ISR);
-                       }
-               }
-
-               sync_cause = REG_READ(ah, AR_INTR_SYNC_CAUSE) &
-                       AR_INTR_SYNC_DEFAULT;
-
-               *masked = 0;
-
-               if (!isr && !sync_cause)
-                       return false;
-       } else {
-               *masked = 0;
-               isr = REG_READ(ah, AR_ISR);
-       }
-
-       if (isr) {
-               if (isr & AR_ISR_BCNMISC) {
-                       u32 isr2;
-                       isr2 = REG_READ(ah, AR_ISR_S2);
-                       if (isr2 & AR_ISR_S2_TIM)
-                               mask2 |= ATH9K_INT_TIM;
-                       if (isr2 & AR_ISR_S2_DTIM)
-                               mask2 |= ATH9K_INT_DTIM;
-                       if (isr2 & AR_ISR_S2_DTIMSYNC)
-                               mask2 |= ATH9K_INT_DTIMSYNC;
-                       if (isr2 & (AR_ISR_S2_CABEND))
-                               mask2 |= ATH9K_INT_CABEND;
-                       if (isr2 & AR_ISR_S2_GTT)
-                               mask2 |= ATH9K_INT_GTT;
-                       if (isr2 & AR_ISR_S2_CST)
-                               mask2 |= ATH9K_INT_CST;
-                       if (isr2 & AR_ISR_S2_TSFOOR)
-                               mask2 |= ATH9K_INT_TSFOOR;
-               }
-
-               isr = REG_READ(ah, AR_ISR_RAC);
-               if (isr == 0xffffffff) {
-                       *masked = 0;
-                       return false;
-               }
-
-               *masked = isr & ATH9K_INT_COMMON;
-
-               if (ah->config.rx_intr_mitigation) {
-                       if (isr & (AR_ISR_RXMINTR | AR_ISR_RXINTM))
-                               *masked |= ATH9K_INT_RX;
-               }
-
-               if (isr & (AR_ISR_RXOK | AR_ISR_RXERR))
-                       *masked |= ATH9K_INT_RX;
-               if (isr &
-                   (AR_ISR_TXOK | AR_ISR_TXDESC | AR_ISR_TXERR |
-                    AR_ISR_TXEOL)) {
-                       u32 s0_s, s1_s;
-
-                       *masked |= ATH9K_INT_TX;
-
-                       s0_s = REG_READ(ah, AR_ISR_S0_S);
-                       ah->intr_txqs |= MS(s0_s, AR_ISR_S0_QCU_TXOK);
-                       ah->intr_txqs |= MS(s0_s, AR_ISR_S0_QCU_TXDESC);
-
-                       s1_s = REG_READ(ah, AR_ISR_S1_S);
-                       ah->intr_txqs |= MS(s1_s, AR_ISR_S1_QCU_TXERR);
-                       ah->intr_txqs |= MS(s1_s, AR_ISR_S1_QCU_TXEOL);
-               }
-
-               if (isr & AR_ISR_RXORN) {
-                       ath_print(common, ATH_DBG_INTERRUPT,
-                                 "receive FIFO overrun interrupt\n");
-               }
-
-               if (!AR_SREV_9100(ah)) {
-                       if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) {
-                               u32 isr5 = REG_READ(ah, AR_ISR_S5_S);
-                               if (isr5 & AR_ISR_S5_TIM_TIMER)
-                                       *masked |= ATH9K_INT_TIM_TIMER;
-                       }
-               }
-
-               *masked |= mask2;
-       }
-
-       if (AR_SREV_9100(ah))
-               return true;
-
-       if (isr & AR_ISR_GENTMR) {
-               u32 s5_s;
-
-               s5_s = REG_READ(ah, AR_ISR_S5_S);
-               if (isr & AR_ISR_GENTMR) {
-                       ah->intr_gen_timer_trigger =
-                               MS(s5_s, AR_ISR_S5_GENTIMER_TRIG);
-
-                       ah->intr_gen_timer_thresh =
-                               MS(s5_s, AR_ISR_S5_GENTIMER_THRESH);
-
-                       if (ah->intr_gen_timer_trigger)
-                               *masked |= ATH9K_INT_GENTIMER;
-
-               }
-       }
-
-       if (sync_cause) {
-               fatal_int =
-                       (sync_cause &
-                        (AR_INTR_SYNC_HOST1_FATAL | AR_INTR_SYNC_HOST1_PERR))
-                       ? true : false;
-
-               if (fatal_int) {
-                       if (sync_cause & AR_INTR_SYNC_HOST1_FATAL) {
-                               ath_print(common, ATH_DBG_ANY,
-                                         "received PCI FATAL interrupt\n");
-                       }
-                       if (sync_cause & AR_INTR_SYNC_HOST1_PERR) {
-                               ath_print(common, ATH_DBG_ANY,
-                                         "received PCI PERR interrupt\n");
-                       }
-                       *masked |= ATH9K_INT_FATAL;
-               }
-               if (sync_cause & AR_INTR_SYNC_RADM_CPL_TIMEOUT) {
-                       ath_print(common, ATH_DBG_INTERRUPT,
-                                 "AR_INTR_SYNC_RADM_CPL_TIMEOUT\n");
-                       REG_WRITE(ah, AR_RC, AR_RC_HOSTIF);
-                       REG_WRITE(ah, AR_RC, 0);
-                       *masked |= ATH9K_INT_FATAL;
-               }
-               if (sync_cause & AR_INTR_SYNC_LOCAL_TIMEOUT) {
-                       ath_print(common, ATH_DBG_INTERRUPT,
-                                 "AR_INTR_SYNC_LOCAL_TIMEOUT\n");
-               }
-
-               REG_WRITE(ah, AR_INTR_SYNC_CAUSE_CLR, sync_cause);
-               (void) REG_READ(ah, AR_INTR_SYNC_CAUSE_CLR);
-       }
-
-       return true;
-}
-EXPORT_SYMBOL(ath9k_hw_getisr);
-
-enum ath9k_int ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints)
-{
-       enum ath9k_int omask = ah->imask;
-       u32 mask, mask2;
-       struct ath9k_hw_capabilities *pCap = &ah->caps;
-       struct ath_common *common = ath9k_hw_common(ah);
-
-       ath_print(common, ATH_DBG_INTERRUPT, "0x%x => 0x%x\n", omask, ints);
-
-       if (omask & ATH9K_INT_GLOBAL) {
-               ath_print(common, ATH_DBG_INTERRUPT, "disable IER\n");
-               REG_WRITE(ah, AR_IER, AR_IER_DISABLE);
-               (void) REG_READ(ah, AR_IER);
-               if (!AR_SREV_9100(ah)) {
-                       REG_WRITE(ah, AR_INTR_ASYNC_ENABLE, 0);
-                       (void) REG_READ(ah, AR_INTR_ASYNC_ENABLE);
-
-                       REG_WRITE(ah, AR_INTR_SYNC_ENABLE, 0);
-                       (void) REG_READ(ah, AR_INTR_SYNC_ENABLE);
-               }
-       }
-
-       mask = ints & ATH9K_INT_COMMON;
-       mask2 = 0;
-
-       if (ints & ATH9K_INT_TX) {
-               if (ah->txok_interrupt_mask)
-                       mask |= AR_IMR_TXOK;
-               if (ah->txdesc_interrupt_mask)
-                       mask |= AR_IMR_TXDESC;
-               if (ah->txerr_interrupt_mask)
-                       mask |= AR_IMR_TXERR;
-               if (ah->txeol_interrupt_mask)
-                       mask |= AR_IMR_TXEOL;
-       }
-       if (ints & ATH9K_INT_RX) {
-               mask |= AR_IMR_RXERR;
-               if (ah->config.rx_intr_mitigation)
-                       mask |= AR_IMR_RXMINTR | AR_IMR_RXINTM;
-               else
-                       mask |= AR_IMR_RXOK | AR_IMR_RXDESC;
-               if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP))
-                       mask |= AR_IMR_GENTMR;
-       }
-
-       if (ints & (ATH9K_INT_BMISC)) {
-               mask |= AR_IMR_BCNMISC;
-               if (ints & ATH9K_INT_TIM)
-                       mask2 |= AR_IMR_S2_TIM;
-               if (ints & ATH9K_INT_DTIM)
-                       mask2 |= AR_IMR_S2_DTIM;
-               if (ints & ATH9K_INT_DTIMSYNC)
-                       mask2 |= AR_IMR_S2_DTIMSYNC;
-               if (ints & ATH9K_INT_CABEND)
-                       mask2 |= AR_IMR_S2_CABEND;
-               if (ints & ATH9K_INT_TSFOOR)
-                       mask2 |= AR_IMR_S2_TSFOOR;
-       }
-
-       if (ints & (ATH9K_INT_GTT | ATH9K_INT_CST)) {
-               mask |= AR_IMR_BCNMISC;
-               if (ints & ATH9K_INT_GTT)
-                       mask2 |= AR_IMR_S2_GTT;
-               if (ints & ATH9K_INT_CST)
-                       mask2 |= AR_IMR_S2_CST;
-       }
-
-       ath_print(common, ATH_DBG_INTERRUPT, "new IMR 0x%x\n", mask);
-       REG_WRITE(ah, AR_IMR, mask);
-       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);
-
-       if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) {
-               if (ints & ATH9K_INT_TIM_TIMER)
-                       REG_SET_BIT(ah, AR_IMR_S5, AR_IMR_S5_TIM_TIMER);
-               else
-                       REG_CLR_BIT(ah, AR_IMR_S5, AR_IMR_S5_TIM_TIMER);
-       }
-
-       if (ints & ATH9K_INT_GLOBAL) {
-               ath_print(common, ATH_DBG_INTERRUPT, "enable IER\n");
-               REG_WRITE(ah, AR_IER, AR_IER_ENABLE);
-               if (!AR_SREV_9100(ah)) {
-                       REG_WRITE(ah, AR_INTR_ASYNC_ENABLE,
-                                 AR_INTR_MAC_IRQ);
-                       REG_WRITE(ah, AR_INTR_ASYNC_MASK, AR_INTR_MAC_IRQ);
-
-
-                       REG_WRITE(ah, AR_INTR_SYNC_ENABLE,
-                                 AR_INTR_SYNC_DEFAULT);
-                       REG_WRITE(ah, AR_INTR_SYNC_MASK,
-                                 AR_INTR_SYNC_DEFAULT);
-               }
-               ath_print(common, ATH_DBG_INTERRUPT, "AR_IMR 0x%x IER 0x%x\n",
-                         REG_READ(ah, AR_IMR), REG_READ(ah, AR_IER));
-       }
-
-       return omask;
-}
-EXPORT_SYMBOL(ath9k_hw_set_interrupts);
-
 /*******************/
 /* Beacon Handling */
 /*******************/
@@ -2916,6 +1845,8 @@ void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period)
 
        ah->beacon_interval = beacon_period;
 
+       ENABLE_REGWRITE_BUFFER(ah);
+
        switch (ah->opmode) {
        case NL80211_IFTYPE_STATION:
        case NL80211_IFTYPE_MONITOR:
@@ -2959,6 +1890,9 @@ void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period)
        REG_WRITE(ah, AR_SWBA_PERIOD, TU_TO_USEC(beacon_period));
        REG_WRITE(ah, AR_NDP_PERIOD, TU_TO_USEC(beacon_period));
 
+       REGWRITE_BUFFER_FLUSH(ah);
+       DISABLE_REGWRITE_BUFFER(ah);
+
        beacon_period &= ~ATH9K_BEACON_ENA;
        if (beacon_period & ATH9K_BEACON_RESET_TSF) {
                ath9k_hw_reset_tsf(ah);
@@ -2975,6 +1909,8 @@ void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah,
        struct ath9k_hw_capabilities *pCap = &ah->caps;
        struct ath_common *common = ath9k_hw_common(ah);
 
+       ENABLE_REGWRITE_BUFFER(ah);
+
        REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(bs->bs_nexttbtt));
 
        REG_WRITE(ah, AR_BEACON_PERIOD,
@@ -2982,6 +1918,9 @@ void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah,
        REG_WRITE(ah, AR_DMA_BEACON_PERIOD,
                  TU_TO_USEC(bs->bs_intval & ATH9K_BEACON_PERIOD));
 
+       REGWRITE_BUFFER_FLUSH(ah);
+       DISABLE_REGWRITE_BUFFER(ah);
+
        REG_RMW_FIELD(ah, AR_RSSI_THR,
                      AR_RSSI_THR_BM_THR, bs->bs_bmissthreshold);
 
@@ -3004,6 +1943,8 @@ void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah,
        ath_print(common, ATH_DBG_BEACON, "beacon period %d\n", beaconintval);
        ath_print(common, ATH_DBG_BEACON, "DTIM period %d\n", dtimperiod);
 
+       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));
@@ -3023,6 +1964,9 @@ void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah,
        REG_WRITE(ah, AR_TIM_PERIOD, TU_TO_USEC(beaconintval));
        REG_WRITE(ah, AR_DTIM_PERIOD, TU_TO_USEC(dtimperiod));
 
+       REGWRITE_BUFFER_FLUSH(ah);
+       DISABLE_REGWRITE_BUFFER(ah);
+
        REG_SET_BIT(ah, AR_TIMER_MODE,
                    AR_TBTT_TIMER_EN | AR_TIM_TIMER_EN |
                    AR_DTIM_TIMER_EN);
@@ -3241,6 +2185,20 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
                btcoex_hw->scheme = ATH_BTCOEX_CFG_NONE;
        }
 
+       if (AR_SREV_9300_20_OR_LATER(ah)) {
+               pCap->hw_caps |= ATH9K_HW_CAP_EDMA | ATH9K_HW_CAP_LDPC;
+               pCap->rx_hp_qdepth = ATH9K_HW_RX_HP_QDEPTH;
+               pCap->rx_lp_qdepth = ATH9K_HW_RX_LP_QDEPTH;
+               pCap->rx_status_len = sizeof(struct ar9003_rxs);
+               pCap->tx_desc_len = sizeof(struct ar9003_txc);
+               pCap->txs_len = sizeof(struct ar9003_txs);
+       } else {
+               pCap->tx_desc_len = sizeof(struct ath_desc);
+       }
+
+       if (AR_SREV_9300_20_OR_LATER(ah))
+               pCap->hw_caps |= ATH9K_HW_CAP_RAC_SUPPORTED;
+
        return 0;
 }
 
@@ -3273,10 +2231,6 @@ bool ath9k_hw_getcapability(struct ath_hw *ah, enum ath9k_capability_type type,
        case ATH9K_CAP_TKIP_SPLIT:
                return (ah->misc_mode & AR_PCU_MIC_NEW_LOC_ENA) ?
                        false : true;
-       case ATH9K_CAP_DIVERSITY:
-               return (REG_READ(ah, AR_PHY_CCK_DETECT) &
-                       AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV) ?
-                       true : false;
        case ATH9K_CAP_MCAST_KEYSRCH:
                switch (capability) {
                case 0:
@@ -3319,8 +2273,6 @@ EXPORT_SYMBOL(ath9k_hw_getcapability);
 bool ath9k_hw_setcapability(struct ath_hw *ah, enum ath9k_capability_type type,
                            u32 capability, u32 setting, int *status)
 {
-       u32 v;
-
        switch (type) {
        case ATH9K_CAP_TKIP_MIC:
                if (setting)
@@ -3330,14 +2282,6 @@ bool ath9k_hw_setcapability(struct ath_hw *ah, enum ath9k_capability_type type,
                        ah->sta_id1_defaults &=
                                ~AR_STA_ID1_CRPT_MIC_ENABLE;
                return true;
-       case ATH9K_CAP_DIVERSITY:
-               v = REG_READ(ah, AR_PHY_CCK_DETECT);
-               if (setting)
-                       v |= AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV;
-               else
-                       v &= ~AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV;
-               REG_WRITE(ah, AR_PHY_CCK_DETECT, v);
-               return true;
        case ATH9K_CAP_MCAST_KEYSRCH:
                if (setting)
                        ah->sta_id1_defaults |= AR_STA_ID1_MCAST_KSRCH;
@@ -3405,7 +2349,9 @@ u32 ath9k_hw_gpio_get(struct ath_hw *ah, u32 gpio)
        if (gpio >= ah->caps.num_gpio_pins)
                return 0xffffffff;
 
-       if (AR_SREV_9271(ah))
+       if (AR_SREV_9300_20_OR_LATER(ah))
+               return MS_REG_READ(AR9300, gpio) != 0;
+       else 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;
@@ -3478,6 +2424,8 @@ void ath9k_hw_setrxfilter(struct ath_hw *ah, u32 bits)
 {
        u32 phybits;
 
+       ENABLE_REGWRITE_BUFFER(ah);
+
        REG_WRITE(ah, AR_RX_FILTER, bits);
 
        phybits = 0;
@@ -3493,6 +2441,9 @@ void ath9k_hw_setrxfilter(struct ath_hw *ah, u32 bits)
        else
                REG_WRITE(ah, AR_RXCFG,
                          REG_READ(ah, AR_RXCFG) & ~AR_RXCFG_ZLFDMA);
+
+       REGWRITE_BUFFER_FLUSH(ah);
+       DISABLE_REGWRITE_BUFFER(ah);
 }
 EXPORT_SYMBOL(ath9k_hw_setrxfilter);
 
@@ -3565,14 +2516,25 @@ void ath9k_hw_write_associd(struct ath_hw *ah)
 }
 EXPORT_SYMBOL(ath9k_hw_write_associd);
 
+#define ATH9K_MAX_TSF_READ 10
+
 u64 ath9k_hw_gettsf64(struct ath_hw *ah)
 {
-       u64 tsf;
+       u32 tsf_lower, tsf_upper1, tsf_upper2;
+       int i;
+
+       tsf_upper1 = REG_READ(ah, AR_TSF_U32);
+       for (i = 0; i < ATH9K_MAX_TSF_READ; i++) {
+               tsf_lower = REG_READ(ah, AR_TSF_L32);
+               tsf_upper2 = REG_READ(ah, AR_TSF_U32);
+               if (tsf_upper2 == tsf_upper1)
+                       break;
+               tsf_upper1 = tsf_upper2;
+       }
 
-       tsf = REG_READ(ah, AR_TSF_U32);
-       tsf = (tsf << 32) | REG_READ(ah, AR_TSF_L32);
+       WARN_ON( i == ATH9K_MAX_TSF_READ );
 
-       return tsf;
+       return (((u64)tsf_upper1 << 32) | tsf_lower);
 }
 EXPORT_SYMBOL(ath9k_hw_gettsf64);
 
@@ -3847,6 +2809,7 @@ static struct {
        { AR_SREV_VERSION_9285,         "9285" },
        { AR_SREV_VERSION_9287,         "9287" },
        { AR_SREV_VERSION_9271,         "9271" },
+       { AR_SREV_VERSION_9300,         "9300" },
 };
 
 /* For devices with external radios */
index f4821cf33b87c873d98bee773ba9255b34a62dbd..a78e09bab431225bd438db738d95dc34e979a8e1 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008-2009 Atheros Communications Inc.
+ * Copyright (c) 2008-2010 Atheros Communications Inc.
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -41,6 +41,9 @@
 #define AR9280_DEVID_PCIE      0x002a
 #define AR9285_DEVID_PCIE      0x002b
 #define AR2427_DEVID_PCIE      0x002c
+#define AR9287_DEVID_PCI       0x002d
+#define AR9287_DEVID_PCIE      0x002e
+#define AR9300_DEVID_PCIE      0x0030
 
 #define AR5416_AR9100_DEVID    0x000b
 
@@ -48,9 +51,6 @@
 #define AR_SUBVENDOR_ID_NEW_A  0x7065
 #define AR5416_MAGIC           0x19641014
 
-#define AR5416_DEVID_AR9287_PCI  0x002D
-#define AR5416_DEVID_AR9287_PCIE 0x002E
-
 #define AR9280_COEX2WIRE_SUBSYSID      0x309b
 #define AT9285_COEX3WIRE_SA_SUBSYSID   0x30aa
 #define AT9285_COEX3WIRE_DA_SUBSYSID   0x30ab
 #define REG_READ(_ah, _reg) \
        ath9k_hw_common(_ah)->ops->read((_ah), (_reg))
 
+#define ENABLE_REGWRITE_BUFFER(_ah)                                    \
+       do {                                                            \
+               if (AR_SREV_9271(_ah))                                  \
+                       ath9k_hw_common(_ah)->ops->enable_write_buffer((_ah)); \
+       } while (0)
+
+#define DISABLE_REGWRITE_BUFFER(_ah)                                   \
+       do {                                                            \
+               if (AR_SREV_9271(_ah))                                  \
+                       ath9k_hw_common(_ah)->ops->disable_write_buffer((_ah)); \
+       } while (0)
+
+#define REGWRITE_BUFFER_FLUSH(_ah)                                     \
+       do {                                                            \
+               if (AR_SREV_9271(_ah))                                  \
+                       ath9k_hw_common(_ah)->ops->write_flush((_ah));  \
+       } while (0)
+
 #define SM(_v, _f)  (((_v) << _f##_S) & _f)
 #define MS(_v, _f)  (((_v) & _f) >> _f##_S)
 #define REG_RMW(_a, _r, _set, _clr)    \
@@ -75,6 +93,8 @@
 #define REG_RMW_FIELD(_a, _r, _f, _v) \
        REG_WRITE(_a, _r, \
        (REG_READ(_a, _r) & ~_f) | (((_v) << _f##_S) & _f))
+#define REG_READ_FIELD(_a, _r, _f) \
+       (((REG_READ(_a, _r) & _f) >> _f##_S))
 #define REG_SET_BIT(_a, _r, _f) \
        REG_WRITE(_a, _r, REG_READ(_a, _r) | _f)
 #define REG_CLR_BIT(_a, _r, _f) \
 
 #define TU_TO_USEC(_tu)             ((_tu) << 10)
 
+#define ATH9K_HW_RX_HP_QDEPTH  16
+#define ATH9K_HW_RX_LP_QDEPTH  128
+
+enum ath_ini_subsys {
+       ATH_INI_PRE = 0,
+       ATH_INI_CORE,
+       ATH_INI_POST,
+       ATH_INI_NUM_SPLIT,
+};
+
 enum wireless_mode {
        ATH9K_MODE_11A = 0,
        ATH9K_MODE_11G,
@@ -165,13 +195,15 @@ enum ath9k_hw_caps {
        ATH9K_HW_CAP_ENHANCEDPM                 = BIT(14),
        ATH9K_HW_CAP_AUTOSLEEP                  = BIT(15),
        ATH9K_HW_CAP_4KB_SPLITTRANS             = BIT(16),
+       ATH9K_HW_CAP_EDMA                       = BIT(17),
+       ATH9K_HW_CAP_RAC_SUPPORTED              = BIT(18),
+       ATH9K_HW_CAP_LDPC                       = BIT(19),
 };
 
 enum ath9k_capability_type {
        ATH9K_CAP_CIPHER = 0,
        ATH9K_CAP_TKIP_MIC,
        ATH9K_CAP_TKIP_SPLIT,
-       ATH9K_CAP_DIVERSITY,
        ATH9K_CAP_TXPOW,
        ATH9K_CAP_MCAST_KEYSRCH,
        ATH9K_CAP_DS
@@ -192,6 +224,11 @@ struct ath9k_hw_capabilities {
        u8 num_gpio_pins;
        u8 num_antcfg_2ghz;
        u8 num_antcfg_5ghz;
+       u8 rx_hp_qdepth;
+       u8 rx_lp_qdepth;
+       u8 rx_status_len;
+       u8 tx_desc_len;
+       u8 txs_len;
 };
 
 struct ath9k_ops_config {
@@ -212,6 +249,7 @@ struct ath9k_ops_config {
        u32 enable_ani;
        int serialize_regmode;
        bool rx_intr_mitigation;
+       bool tx_intr_mitigation;
 #define SPUR_DISABLE           0
 #define SPUR_ENABLE_IOCTL      1
 #define SPUR_ENABLE_EEPROM     2
@@ -231,6 +269,8 @@ struct ath9k_ops_config {
 enum ath9k_int {
        ATH9K_INT_RX = 0x00000001,
        ATH9K_INT_RXDESC = 0x00000002,
+       ATH9K_INT_RXHP = 0x00000001,
+       ATH9K_INT_RXLP = 0x00000002,
        ATH9K_INT_RXNOFRM = 0x00000008,
        ATH9K_INT_RXEOL = 0x00000010,
        ATH9K_INT_RXORN = 0x00000020,
@@ -363,6 +403,12 @@ enum ser_reg_mode {
        SER_REG_MODE_AUTO = 2,
 };
 
+enum ath9k_rx_qtype {
+       ATH9K_RX_QUEUE_HP,
+       ATH9K_RX_QUEUE_LP,
+       ATH9K_RX_QUEUE_MAX,
+};
+
 struct ath9k_beacon_state {
        u32 bs_nexttbtt;
        u32 bs_nextdtim;
@@ -440,6 +486,124 @@ struct ath_gen_timer_table {
        } timer_mask;
 };
 
+/**
+ * struct ath_hw_private_ops - callbacks used internally by hardware code
+ *
+ * This structure contains private callbacks designed to only be used internally
+ * by the hardware core.
+ *
+ * @init_cal_settings: setup types of calibrations supported
+ * @init_cal: starts actual calibration
+ *
+ * @init_mode_regs: Initializes mode registers
+ * @init_mode_gain_regs: Initialize TX/RX gain registers
+ * @macversion_supported: If this specific mac revision is supported
+ *
+ * @rf_set_freq: change frequency
+ * @spur_mitigate_freq: spur mitigation
+ * @rf_alloc_ext_banks:
+ * @rf_free_ext_banks:
+ * @set_rf_regs:
+ * @compute_pll_control: compute the PLL control value to use for
+ *     AR_RTC_PLL_CONTROL for a given channel
+ * @setup_calibration: set up calibration
+ * @iscal_supported: used to query if a type of calibration is supported
+ * @loadnf: load noise floor read from each chain on the CCA registers
+ */
+struct ath_hw_private_ops {
+       /* Calibration ops */
+       void (*init_cal_settings)(struct ath_hw *ah);
+       bool (*init_cal)(struct ath_hw *ah, struct ath9k_channel *chan);
+
+       void (*init_mode_regs)(struct ath_hw *ah);
+       void (*init_mode_gain_regs)(struct ath_hw *ah);
+       bool (*macversion_supported)(u32 macversion);
+       void (*setup_calibration)(struct ath_hw *ah,
+                                 struct ath9k_cal_list *currCal);
+       bool (*iscal_supported)(struct ath_hw *ah,
+                               enum ath9k_cal_types calType);
+
+       /* PHY ops */
+       int (*rf_set_freq)(struct ath_hw *ah,
+                          struct ath9k_channel *chan);
+       void (*spur_mitigate_freq)(struct ath_hw *ah,
+                                  struct ath9k_channel *chan);
+       int (*rf_alloc_ext_banks)(struct ath_hw *ah);
+       void (*rf_free_ext_banks)(struct ath_hw *ah);
+       bool (*set_rf_regs)(struct ath_hw *ah,
+                           struct ath9k_channel *chan,
+                           u16 modesIndex);
+       void (*set_channel_regs)(struct ath_hw *ah, struct ath9k_channel *chan);
+       void (*init_bb)(struct ath_hw *ah,
+                       struct ath9k_channel *chan);
+       int (*process_ini)(struct ath_hw *ah, struct ath9k_channel *chan);
+       void (*olc_init)(struct ath_hw *ah);
+       void (*set_rfmode)(struct ath_hw *ah, struct ath9k_channel *chan);
+       void (*mark_phy_inactive)(struct ath_hw *ah);
+       void (*set_delta_slope)(struct ath_hw *ah, struct ath9k_channel *chan);
+       bool (*rfbus_req)(struct ath_hw *ah);
+       void (*rfbus_done)(struct ath_hw *ah);
+       void (*enable_rfkill)(struct ath_hw *ah);
+       void (*restore_chainmask)(struct ath_hw *ah);
+       void (*set_diversity)(struct ath_hw *ah, bool value);
+       u32 (*compute_pll_control)(struct ath_hw *ah,
+                                  struct ath9k_channel *chan);
+       bool (*ani_control)(struct ath_hw *ah, enum ath9k_ani_cmd cmd,
+                           int param);
+       void (*do_getnf)(struct ath_hw *ah, int16_t nfarray[NUM_NF_READINGS]);
+       void (*loadnf)(struct ath_hw *ah, struct ath9k_channel *chan);
+};
+
+/**
+ * struct ath_hw_ops - callbacks used by hardware code and driver code
+ *
+ * This structure contains callbacks designed to to be used internally by
+ * hardware code and also by the lower level driver.
+ *
+ * @config_pci_powersave:
+ * @calibrate: periodic calibration for NF, ANI, IQ, ADC gain, ADC-DC
+ */
+struct ath_hw_ops {
+       void (*config_pci_powersave)(struct ath_hw *ah,
+                                    int restore,
+                                    int power_off);
+       void (*rx_enable)(struct ath_hw *ah);
+       void (*set_desc_link)(void *ds, u32 link);
+       void (*get_desc_link)(void *ds, u32 **link);
+       bool (*calibrate)(struct ath_hw *ah,
+                         struct ath9k_channel *chan,
+                         u8 rxchainmask,
+                         bool longcal);
+       bool (*get_isr)(struct ath_hw *ah, enum ath9k_int *masked);
+       void (*fill_txdesc)(struct ath_hw *ah, void *ds, u32 seglen,
+                           bool is_firstseg, bool is_is_lastseg,
+                           const void *ds0, dma_addr_t buf_addr,
+                           unsigned int qcu);
+       int (*proc_txdesc)(struct ath_hw *ah, void *ds,
+                          struct ath_tx_status *ts);
+       void (*set11n_txdesc)(struct ath_hw *ah, void *ds,
+                             u32 pktLen, enum ath9k_pkt_type type,
+                             u32 txPower, u32 keyIx,
+                             enum ath9k_key_type keyType,
+                             u32 flags);
+       void (*set11n_ratescenario)(struct ath_hw *ah, void *ds,
+                               void *lastds,
+                               u32 durUpdateEn, u32 rtsctsRate,
+                               u32 rtsctsDuration,
+                               struct ath9k_11n_rate_series series[],
+                               u32 nseries, u32 flags);
+       void (*set11n_aggr_first)(struct ath_hw *ah, void *ds,
+                                 u32 aggrLen);
+       void (*set11n_aggr_middle)(struct ath_hw *ah, void *ds,
+                                  u32 numDelims);
+       void (*set11n_aggr_last)(struct ath_hw *ah, void *ds);
+       void (*clr11n_aggr)(struct ath_hw *ah, void *ds);
+       void (*set11n_burstduration)(struct ath_hw *ah, void *ds,
+                                    u32 burstDuration);
+       void (*set11n_virtualmorefrag)(struct ath_hw *ah, void *ds,
+                                      u32 vmf);
+};
+
 struct ath_hw {
        struct ieee80211_hw *hw;
        struct ath_common common;
@@ -453,14 +617,18 @@ struct ath_hw {
                struct ar5416_eeprom_def def;
                struct ar5416_eeprom_4k map4k;
                struct ar9287_eeprom map9287;
+               struct ar9300_eeprom ar9300_eep;
        } eeprom;
        const struct eeprom_ops *eep_ops;
-       enum ath9k_eep_map eep_map;
 
        bool sw_mgmt_crypto;
        bool is_pciexpress;
        bool need_an_top2_fixup;
        u16 tx_trig_level;
+       s16 nf_2g_max;
+       s16 nf_2g_min;
+       s16 nf_5g_max;
+       s16 nf_5g_min;
        u16 rfsilent;
        u32 rfkill_gpio;
        u32 rfkill_polarity;
@@ -493,6 +661,7 @@ struct ath_hw {
        struct ath9k_cal_list adcgain_caldata;
        struct ath9k_cal_list adcdc_calinitdata;
        struct ath9k_cal_list adcdc_caldata;
+       struct ath9k_cal_list tempCompCalData;
        struct ath9k_cal_list *cal_list;
        struct ath9k_cal_list *cal_list_last;
        struct ath9k_cal_list *cal_list_curr;
@@ -533,12 +702,10 @@ struct ath_hw {
                DONT_USE_32KHZ,
        } enable_32kHz_clock;
 
-       /* Callback for radio frequency change */
-       int (*ath9k_hw_rf_set_freq)(struct ath_hw *ah, struct ath9k_channel *chan);
-
-       /* Callback for baseband spur frequency */
-       void (*ath9k_hw_spur_mitigate_freq)(struct ath_hw *ah,
-                                           struct ath9k_channel *chan);
+       /* Private to hardware code */
+       struct ath_hw_private_ops private_ops;
+       /* Accessed by the lower level driver */
+       struct ath_hw_ops ops;
 
        /* Used to program the radio on non single-chip devices */
        u32 *analogBank0Data;
@@ -592,6 +759,7 @@ struct ath_hw {
        struct ar5416IniArray iniBank7;
        struct ar5416IniArray iniAddac;
        struct ar5416IniArray iniPcieSerdes;
+       struct ar5416IniArray iniPcieSerdesLowPower;
        struct ar5416IniArray iniModesAdditional;
        struct ar5416IniArray iniModesRxGain;
        struct ar5416IniArray iniModesTxGain;
@@ -604,9 +772,21 @@ struct ath_hw {
        struct ar5416IniArray iniModes_high_power_tx_gain_9271;
        struct ar5416IniArray iniModes_normal_power_tx_gain_9271;
 
+       struct ar5416IniArray iniMac[ATH_INI_NUM_SPLIT];
+       struct ar5416IniArray iniBB[ATH_INI_NUM_SPLIT];
+       struct ar5416IniArray iniRadio[ATH_INI_NUM_SPLIT];
+       struct ar5416IniArray iniSOC[ATH_INI_NUM_SPLIT];
+
        u32 intr_gen_timer_trigger;
        u32 intr_gen_timer_thresh;
        struct ath_gen_timer_table hw_gen_timers;
+
+       struct ar9003_txs *ts_ring;
+       void *ts_start;
+       u32 ts_paddr_start;
+       u32 ts_paddr_end;
+       u16 ts_tail;
+       u8 ts_size;
 };
 
 static inline struct ath_common *ath9k_hw_common(struct ath_hw *ah)
@@ -619,6 +799,16 @@ static inline struct ath_regulatory *ath9k_hw_regulatory(struct ath_hw *ah)
        return &(ath9k_hw_common(ah)->regulatory);
 }
 
+static inline struct ath_hw_private_ops *ath9k_hw_private_ops(struct ath_hw *ah)
+{
+       return &ah->private_ops;
+}
+
+static inline struct ath_hw_ops *ath9k_hw_ops(struct ath_hw *ah)
+{
+       return &ah->ops;
+}
+
 /* Initialization, Detach, Reset */
 const char *ath9k_hw_probe(u16 vendorid, u16 devid);
 void ath9k_hw_deinit(struct ath_hw *ah);
@@ -630,6 +820,7 @@ bool ath9k_hw_getcapability(struct ath_hw *ah, enum ath9k_capability_type type,
                            u32 capability, u32 *result);
 bool ath9k_hw_setcapability(struct ath_hw *ah, enum ath9k_capability_type type,
                            u32 capability, u32 setting, int *status);
+u32 ath9k_regd_get_ctl(struct ath_regulatory *reg, struct ath9k_channel *chan);
 
 /* Key Cache Management */
 bool ath9k_hw_keyreset(struct ath_hw *ah, u16 entry);
@@ -678,16 +869,10 @@ void ath9k_hw_set11nmac2040(struct ath_hw *ah);
 void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period);
 void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah,
                                    const struct ath9k_beacon_state *bs);
+bool ath9k_hw_check_alive(struct ath_hw *ah);
 
 bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode);
 
-void ath9k_hw_configpcipowersave(struct ath_hw *ah, int restore, int power_off);
-
-/* Interrupt Handling */
-bool ath9k_hw_intrpend(struct ath_hw *ah);
-bool ath9k_hw_getisr(struct ath_hw *ah, enum ath9k_int *masked);
-enum ath9k_int ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints);
-
 /* Generic hw timer primitives */
 struct ath_gen_timer *ath_gen_timer_alloc(struct ath_hw *ah,
                                          void (*trigger)(void *),
@@ -709,6 +894,36 @@ void ath9k_hw_name(struct ath_hw *ah, char *hw_name, size_t len);
 /* HTC */
 void ath9k_hw_htc_resetinit(struct ath_hw *ah);
 
+/* PHY */
+void ath9k_hw_get_delta_slope_vals(struct ath_hw *ah, u32 coef_scaled,
+                                  u32 *coef_mantissa, u32 *coef_exponent);
+
+/*
+ * Code Specific to AR5008, AR9001 or AR9002,
+ * we stuff these here to avoid callbacks for AR9003.
+ */
+void ar9002_hw_cck_chan14_spread(struct ath_hw *ah);
+int ar9002_hw_rf_claim(struct ath_hw *ah);
+void ar9002_hw_enable_async_fifo(struct ath_hw *ah);
+void ar9002_hw_enable_wep_aggregation(struct ath_hw *ah);
+
+/*
+ * Code specifric to AR9003, we stuff these here to avoid callbacks
+ * for older families
+ */
+void ar9003_hw_set_nf_limits(struct ath_hw *ah);
+
+/* Hardware family op attach helpers */
+void ar5008_hw_attach_phy_ops(struct ath_hw *ah);
+void ar9002_hw_attach_phy_ops(struct ath_hw *ah);
+void ar9003_hw_attach_phy_ops(struct ath_hw *ah);
+
+void ar9002_hw_attach_calib_ops(struct ath_hw *ah);
+void ar9003_hw_attach_calib_ops(struct ath_hw *ah);
+
+void ar9002_hw_attach_ops(struct ath_hw *ah);
+void ar9003_hw_attach_ops(struct ath_hw *ah);
+
 #define ATH_PCIE_CAP_LINK_CTRL 0x70
 #define ATH_PCIE_CAP_LINK_L0S  1
 #define ATH_PCIE_CAP_LINK_L1   2
index b78308c3c4d4ccdc29bcd0b73c03a06c95e3cff7..8c795488ebc307076f62ad4b47472aee4a4c2de8 100644 (file)
@@ -175,6 +175,18 @@ static const struct ath_ops ath9k_common_ops = {
        .write = ath9k_iowrite32,
 };
 
+static int count_streams(unsigned int chainmask, int max)
+{
+       int streams = 0;
+
+       do {
+               if (++streams == max)
+                       break;
+       } while ((chainmask = chainmask & (chainmask - 1)));
+
+       return streams;
+}
+
 /**************************/
 /*     Initialization     */
 /**************************/
@@ -182,8 +194,10 @@ static const struct ath_ops ath9k_common_ops = {
 static void setup_ht_cap(struct ath_softc *sc,
                         struct ieee80211_sta_ht_cap *ht_info)
 {
-       struct ath_common *common = ath9k_hw_common(sc->sc_ah);
+       struct ath_hw *ah = sc->sc_ah;
+       struct ath_common *common = ath9k_hw_common(ah);
        u8 tx_streams, rx_streams;
+       int i, max_streams;
 
        ht_info->ht_supported = true;
        ht_info->cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
@@ -191,28 +205,40 @@ static void setup_ht_cap(struct ath_softc *sc,
                       IEEE80211_HT_CAP_SGI_40 |
                       IEEE80211_HT_CAP_DSSSCCK40;
 
+       if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_LDPC)
+               ht_info->cap |= IEEE80211_HT_CAP_LDPC_CODING;
+
        ht_info->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
        ht_info->ampdu_density = IEEE80211_HT_MPDU_DENSITY_8;
 
+       if (AR_SREV_9300_20_OR_LATER(ah))
+               max_streams = 3;
+       else
+               max_streams = 2;
+
+       if (AR_SREV_9280_10_OR_LATER(ah)) {
+               if (max_streams >= 2)
+                       ht_info->cap |= IEEE80211_HT_CAP_TX_STBC;
+               ht_info->cap |= (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT);
+       }
+
        /* set up supported mcs set */
        memset(&ht_info->mcs, 0, sizeof(ht_info->mcs));
-       tx_streams = !(common->tx_chainmask & (common->tx_chainmask - 1)) ?
-                    1 : 2;
-       rx_streams = !(common->rx_chainmask & (common->rx_chainmask - 1)) ?
-                    1 : 2;
+       tx_streams = count_streams(common->tx_chainmask, max_streams);
+       rx_streams = count_streams(common->rx_chainmask, max_streams);
+
+       ath_print(common, ATH_DBG_CONFIG,
+                 "TX streams %d, RX streams: %d\n",
+                 tx_streams, rx_streams);
 
        if (tx_streams != rx_streams) {
-               ath_print(common, ATH_DBG_CONFIG,
-                         "TX streams %d, RX streams: %d\n",
-                         tx_streams, rx_streams);
                ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_RX_DIFF;
                ht_info->mcs.tx_params |= ((tx_streams - 1) <<
                                IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT);
        }
 
-       ht_info->mcs.rx_mask[0] = 0xff;
-       if (rx_streams >= 2)
-               ht_info->mcs.rx_mask[1] = 0xff;
+       for (i = 0; i < rx_streams; i++)
+               ht_info->mcs.rx_mask[i] = 0xff;
 
        ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_DEFINED;
 }
@@ -235,31 +261,37 @@ static int ath9k_reg_notifier(struct wiphy *wiphy,
 */
 int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
                      struct list_head *head, const char *name,
-                     int nbuf, int ndesc)
+                     int nbuf, int ndesc, bool is_tx)
 {
 #define        DS2PHYS(_dd, _ds)                                               \
        ((_dd)->dd_desc_paddr + ((caddr_t)(_ds) - (caddr_t)(_dd)->dd_desc))
 #define ATH_DESC_4KB_BOUND_CHECK(_daddr) ((((_daddr) & 0xFFF) > 0xF7F) ? 1 : 0)
 #define ATH_DESC_4KB_BOUND_NUM_SKIPPED(_len) ((_len) / 4096)
        struct ath_common *common = ath9k_hw_common(sc->sc_ah);
-       struct ath_desc *ds;
+       u8 *ds;
        struct ath_buf *bf;
-       int i, bsize, error;
+       int i, bsize, error, desc_len;
 
        ath_print(common, ATH_DBG_CONFIG, "%s DMA: %u buffers %u desc/buf\n",
                  name, nbuf, ndesc);
 
        INIT_LIST_HEAD(head);
+
+       if (is_tx)
+               desc_len = sc->sc_ah->caps.tx_desc_len;
+       else
+               desc_len = sizeof(struct ath_desc);
+
        /* ath_desc must be a multiple of DWORDs */
-       if ((sizeof(struct ath_desc) % 4) != 0) {
+       if ((desc_len % 4) != 0) {
                ath_print(common, ATH_DBG_FATAL,
                          "ath_desc not DWORD aligned\n");
-               BUG_ON((sizeof(struct ath_desc) % 4) != 0);
+               BUG_ON((desc_len % 4) != 0);
                error = -ENOMEM;
                goto fail;
        }
 
-       dd->dd_desc_len = sizeof(struct ath_desc) * nbuf * ndesc;
+       dd->dd_desc_len = desc_len * nbuf * ndesc;
 
        /*
         * Need additional DMA memory because we can't use
@@ -272,7 +304,7 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
                u32 dma_len;
 
                while (ndesc_skipped) {
-                       dma_len = ndesc_skipped * sizeof(struct ath_desc);
+                       dma_len = ndesc_skipped * desc_len;
                        dd->dd_desc_len += dma_len;
 
                        ndesc_skipped = ATH_DESC_4KB_BOUND_NUM_SKIPPED(dma_len);
@@ -286,7 +318,7 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
                error = -ENOMEM;
                goto fail;
        }
-       ds = dd->dd_desc;
+       ds = (u8 *) dd->dd_desc;
        ath_print(common, ATH_DBG_CONFIG, "%s DMA map: %p (%u) -> %llx (%u)\n",
                  name, ds, (u32) dd->dd_desc_len,
                  ito64(dd->dd_desc_paddr), /*XXX*/(u32) dd->dd_desc_len);
@@ -300,7 +332,7 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
        }
        dd->dd_bufptr = bf;
 
-       for (i = 0; i < nbuf; i++, bf++, ds += ndesc) {
+       for (i = 0; i < nbuf; i++, bf++, ds += (desc_len * ndesc)) {
                bf->bf_desc = ds;
                bf->bf_daddr = DS2PHYS(dd, ds);
 
@@ -316,7 +348,7 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
                                       ((caddr_t) dd->dd_desc +
                                        dd->dd_desc_len));
 
-                               ds += ndesc;
+                               ds += (desc_len * ndesc);
                                bf->bf_desc = ds;
                                bf->bf_daddr = DS2PHYS(dd, ds);
                        }
@@ -514,7 +546,7 @@ static void ath9k_init_misc(struct ath_softc *sc)
        common->tx_chainmask = sc->sc_ah->caps.tx_chainmask;
        common->rx_chainmask = sc->sc_ah->caps.rx_chainmask;
 
-       ath9k_hw_setcapability(sc->sc_ah, ATH9K_CAP_DIVERSITY, 1, true, NULL);
+       ath9k_hw_set_diversity(sc->sc_ah, true);
        sc->rx.defant = ath9k_hw_getdefantenna(sc->sc_ah);
 
        if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK)
@@ -568,13 +600,10 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid,
        ath_read_cachesize(common, &csz);
        common->cachelsz = csz << 2; /* convert to bytes */
 
+       /* Initializes the hardware for all supported chipsets */
        ret = ath9k_hw_init(ah);
-       if (ret) {
-               ath_print(common, ATH_DBG_FATAL,
-                         "Unable to initialize hardware; "
-                         "initialization status: %d\n", ret);
+       if (ret)
                goto err_hw;
-       }
 
        ret = ath9k_init_debug(ah);
        if (ret) {
index 4a2060e5a7774616e438bb5f9dd4567e36d6c677..7bbf502563bc046e7863ad26613d435d054d0c05 100644 (file)
@@ -25,6 +25,8 @@ static void ath9k_hw_set_txq_interrupts(struct ath_hw *ah,
                  ah->txdesc_interrupt_mask, ah->txeol_interrupt_mask,
                  ah->txurn_interrupt_mask);
 
+       ENABLE_REGWRITE_BUFFER(ah);
+
        REG_WRITE(ah, AR_IMR_S0,
                  SM(ah->txok_interrupt_mask, AR_IMR_S0_QCU_TXOK)
                  | SM(ah->txdesc_interrupt_mask, AR_IMR_S0_QCU_TXDESC));
@@ -35,6 +37,9 @@ static void ath9k_hw_set_txq_interrupts(struct ath_hw *ah,
        ah->imrs2_reg &= ~AR_IMR_S2_QCU_TXURN;
        ah->imrs2_reg |= (ah->txurn_interrupt_mask & AR_IMR_S2_QCU_TXURN);
        REG_WRITE(ah, AR_IMR_S2, ah->imrs2_reg);
+
+       REGWRITE_BUFFER_FLUSH(ah);
+       DISABLE_REGWRITE_BUFFER(ah);
 }
 
 u32 ath9k_hw_gettxbuf(struct ath_hw *ah, u32 q)
@@ -57,6 +62,18 @@ void ath9k_hw_txstart(struct ath_hw *ah, u32 q)
 }
 EXPORT_SYMBOL(ath9k_hw_txstart);
 
+void ath9k_hw_cleartxdesc(struct ath_hw *ah, void *ds)
+{
+       struct ar5416_desc *ads = AR5416DESC(ds);
+
+       ads->ds_txstatus0 = ads->ds_txstatus1 = 0;
+       ads->ds_txstatus2 = ads->ds_txstatus3 = 0;
+       ads->ds_txstatus4 = ads->ds_txstatus5 = 0;
+       ads->ds_txstatus6 = ads->ds_txstatus7 = 0;
+       ads->ds_txstatus8 = ads->ds_txstatus9 = 0;
+}
+EXPORT_SYMBOL(ath9k_hw_cleartxdesc);
+
 u32 ath9k_hw_numtxpending(struct ath_hw *ah, u32 q)
 {
        u32 npend;
@@ -207,281 +224,6 @@ bool ath9k_hw_stoptxdma(struct ath_hw *ah, u32 q)
 }
 EXPORT_SYMBOL(ath9k_hw_stoptxdma);
 
-void ath9k_hw_filltxdesc(struct ath_hw *ah, struct ath_desc *ds,
-                        u32 segLen, bool firstSeg,
-                        bool lastSeg, const struct ath_desc *ds0)
-{
-       struct ar5416_desc *ads = AR5416DESC(ds);
-
-       if (firstSeg) {
-               ads->ds_ctl1 |= segLen | (lastSeg ? 0 : AR_TxMore);
-       } else if (lastSeg) {
-               ads->ds_ctl0 = 0;
-               ads->ds_ctl1 = segLen;
-               ads->ds_ctl2 = AR5416DESC_CONST(ds0)->ds_ctl2;
-               ads->ds_ctl3 = AR5416DESC_CONST(ds0)->ds_ctl3;
-       } else {
-               ads->ds_ctl0 = 0;
-               ads->ds_ctl1 = segLen | AR_TxMore;
-               ads->ds_ctl2 = 0;
-               ads->ds_ctl3 = 0;
-       }
-       ads->ds_txstatus0 = ads->ds_txstatus1 = 0;
-       ads->ds_txstatus2 = ads->ds_txstatus3 = 0;
-       ads->ds_txstatus4 = ads->ds_txstatus5 = 0;
-       ads->ds_txstatus6 = ads->ds_txstatus7 = 0;
-       ads->ds_txstatus8 = ads->ds_txstatus9 = 0;
-}
-EXPORT_SYMBOL(ath9k_hw_filltxdesc);
-
-void ath9k_hw_cleartxdesc(struct ath_hw *ah, struct ath_desc *ds)
-{
-       struct ar5416_desc *ads = AR5416DESC(ds);
-
-       ads->ds_txstatus0 = ads->ds_txstatus1 = 0;
-       ads->ds_txstatus2 = ads->ds_txstatus3 = 0;
-       ads->ds_txstatus4 = ads->ds_txstatus5 = 0;
-       ads->ds_txstatus6 = ads->ds_txstatus7 = 0;
-       ads->ds_txstatus8 = ads->ds_txstatus9 = 0;
-}
-EXPORT_SYMBOL(ath9k_hw_cleartxdesc);
-
-int ath9k_hw_txprocdesc(struct ath_hw *ah, struct ath_desc *ds,
-                       struct ath_tx_status *ts)
-{
-       struct ar5416_desc *ads = AR5416DESC(ds);
-
-       if ((ads->ds_txstatus9 & AR_TxDone) == 0)
-               return -EINPROGRESS;
-
-       ts->ts_seqnum = MS(ads->ds_txstatus9, AR_SeqNum);
-       ts->ts_tstamp = ads->AR_SendTimestamp;
-       ts->ts_status = 0;
-       ts->ts_flags = 0;
-
-       if (ads->ds_txstatus1 & AR_FrmXmitOK)
-               ts->ts_status |= ATH9K_TX_ACKED;
-       if (ads->ds_txstatus1 & AR_ExcessiveRetries)
-               ts->ts_status |= ATH9K_TXERR_XRETRY;
-       if (ads->ds_txstatus1 & AR_Filtered)
-               ts->ts_status |= ATH9K_TXERR_FILT;
-       if (ads->ds_txstatus1 & AR_FIFOUnderrun) {
-               ts->ts_status |= ATH9K_TXERR_FIFO;
-               ath9k_hw_updatetxtriglevel(ah, true);
-       }
-       if (ads->ds_txstatus9 & AR_TxOpExceeded)
-               ts->ts_status |= ATH9K_TXERR_XTXOP;
-       if (ads->ds_txstatus1 & AR_TxTimerExpired)
-               ts->ts_status |= ATH9K_TXERR_TIMER_EXPIRED;
-
-       if (ads->ds_txstatus1 & AR_DescCfgErr)
-               ts->ts_flags |= ATH9K_TX_DESC_CFG_ERR;
-       if (ads->ds_txstatus1 & AR_TxDataUnderrun) {
-               ts->ts_flags |= ATH9K_TX_DATA_UNDERRUN;
-               ath9k_hw_updatetxtriglevel(ah, true);
-       }
-       if (ads->ds_txstatus1 & AR_TxDelimUnderrun) {
-               ts->ts_flags |= ATH9K_TX_DELIM_UNDERRUN;
-               ath9k_hw_updatetxtriglevel(ah, true);
-       }
-       if (ads->ds_txstatus0 & AR_TxBaStatus) {
-               ts->ts_flags |= ATH9K_TX_BA;
-               ts->ba_low = ads->AR_BaBitmapLow;
-               ts->ba_high = ads->AR_BaBitmapHigh;
-       }
-
-       ts->ts_rateindex = MS(ads->ds_txstatus9, AR_FinalTxIdx);
-       switch (ts->ts_rateindex) {
-       case 0:
-               ts->ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate0);
-               break;
-       case 1:
-               ts->ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate1);
-               break;
-       case 2:
-               ts->ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate2);
-               break;
-       case 3:
-               ts->ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate3);
-               break;
-       }
-
-       ts->ts_rssi = MS(ads->ds_txstatus5, AR_TxRSSICombined);
-       ts->ts_rssi_ctl0 = MS(ads->ds_txstatus0, AR_TxRSSIAnt00);
-       ts->ts_rssi_ctl1 = MS(ads->ds_txstatus0, AR_TxRSSIAnt01);
-       ts->ts_rssi_ctl2 = MS(ads->ds_txstatus0, AR_TxRSSIAnt02);
-       ts->ts_rssi_ext0 = MS(ads->ds_txstatus5, AR_TxRSSIAnt10);
-       ts->ts_rssi_ext1 = MS(ads->ds_txstatus5, AR_TxRSSIAnt11);
-       ts->ts_rssi_ext2 = MS(ads->ds_txstatus5, AR_TxRSSIAnt12);
-       ts->evm0 = ads->AR_TxEVM0;
-       ts->evm1 = ads->AR_TxEVM1;
-       ts->evm2 = ads->AR_TxEVM2;
-       ts->ts_shortretry = MS(ads->ds_txstatus1, AR_RTSFailCnt);
-       ts->ts_longretry = MS(ads->ds_txstatus1, AR_DataFailCnt);
-       ts->ts_virtcol = MS(ads->ds_txstatus1, AR_VirtRetryCnt);
-       ts->ts_antenna = 0;
-
-       return 0;
-}
-EXPORT_SYMBOL(ath9k_hw_txprocdesc);
-
-void ath9k_hw_set11n_txdesc(struct ath_hw *ah, struct ath_desc *ds,
-                           u32 pktLen, enum ath9k_pkt_type type, u32 txPower,
-                           u32 keyIx, enum ath9k_key_type keyType, u32 flags)
-{
-       struct ar5416_desc *ads = AR5416DESC(ds);
-
-       txPower += ah->txpower_indexoffset;
-       if (txPower > 63)
-               txPower = 63;
-
-       ads->ds_ctl0 = (pktLen & AR_FrameLen)
-               | (flags & ATH9K_TXDESC_VMF ? AR_VirtMoreFrag : 0)
-               | SM(txPower, AR_XmitPower)
-               | (flags & ATH9K_TXDESC_VEOL ? AR_VEOL : 0)
-               | (flags & ATH9K_TXDESC_CLRDMASK ? AR_ClrDestMask : 0)
-               | (flags & ATH9K_TXDESC_INTREQ ? AR_TxIntrReq : 0)
-               | (keyIx != ATH9K_TXKEYIX_INVALID ? AR_DestIdxValid : 0);
-
-       ads->ds_ctl1 =
-               (keyIx != ATH9K_TXKEYIX_INVALID ? SM(keyIx, AR_DestIdx) : 0)
-               | SM(type, AR_FrameType)
-               | (flags & ATH9K_TXDESC_NOACK ? AR_NoAck : 0)
-               | (flags & ATH9K_TXDESC_EXT_ONLY ? AR_ExtOnly : 0)
-               | (flags & ATH9K_TXDESC_EXT_AND_CTL ? AR_ExtAndCtl : 0);
-
-       ads->ds_ctl6 = SM(keyType, AR_EncrType);
-
-       if (AR_SREV_9285(ah) || AR_SREV_9271(ah)) {
-               ads->ds_ctl8 = 0;
-               ads->ds_ctl9 = 0;
-               ads->ds_ctl10 = 0;
-               ads->ds_ctl11 = 0;
-       }
-}
-EXPORT_SYMBOL(ath9k_hw_set11n_txdesc);
-
-void ath9k_hw_set11n_ratescenario(struct ath_hw *ah, struct ath_desc *ds,
-                                 struct ath_desc *lastds,
-                                 u32 durUpdateEn, u32 rtsctsRate,
-                                 u32 rtsctsDuration,
-                                 struct ath9k_11n_rate_series series[],
-                                 u32 nseries, u32 flags)
-{
-       struct ar5416_desc *ads = AR5416DESC(ds);
-       struct ar5416_desc *last_ads = AR5416DESC(lastds);
-       u32 ds_ctl0;
-
-       if (flags & (ATH9K_TXDESC_RTSENA | ATH9K_TXDESC_CTSENA)) {
-               ds_ctl0 = ads->ds_ctl0;
-
-               if (flags & ATH9K_TXDESC_RTSENA) {
-                       ds_ctl0 &= ~AR_CTSEnable;
-                       ds_ctl0 |= AR_RTSEnable;
-               } else {
-                       ds_ctl0 &= ~AR_RTSEnable;
-                       ds_ctl0 |= AR_CTSEnable;
-               }
-
-               ads->ds_ctl0 = ds_ctl0;
-       } else {
-               ads->ds_ctl0 =
-                       (ads->ds_ctl0 & ~(AR_RTSEnable | AR_CTSEnable));
-       }
-
-       ads->ds_ctl2 = set11nTries(series, 0)
-               | set11nTries(series, 1)
-               | set11nTries(series, 2)
-               | set11nTries(series, 3)
-               | (durUpdateEn ? AR_DurUpdateEna : 0)
-               | SM(0, AR_BurstDur);
-
-       ads->ds_ctl3 = set11nRate(series, 0)
-               | set11nRate(series, 1)
-               | set11nRate(series, 2)
-               | set11nRate(series, 3);
-
-       ads->ds_ctl4 = set11nPktDurRTSCTS(series, 0)
-               | set11nPktDurRTSCTS(series, 1);
-
-       ads->ds_ctl5 = set11nPktDurRTSCTS(series, 2)
-               | set11nPktDurRTSCTS(series, 3);
-
-       ads->ds_ctl7 = set11nRateFlags(series, 0)
-               | set11nRateFlags(series, 1)
-               | set11nRateFlags(series, 2)
-               | set11nRateFlags(series, 3)
-               | SM(rtsctsRate, AR_RTSCTSRate);
-       last_ads->ds_ctl2 = ads->ds_ctl2;
-       last_ads->ds_ctl3 = ads->ds_ctl3;
-}
-EXPORT_SYMBOL(ath9k_hw_set11n_ratescenario);
-
-void ath9k_hw_set11n_aggr_first(struct ath_hw *ah, struct ath_desc *ds,
-                               u32 aggrLen)
-{
-       struct ar5416_desc *ads = AR5416DESC(ds);
-
-       ads->ds_ctl1 |= (AR_IsAggr | AR_MoreAggr);
-       ads->ds_ctl6 &= ~AR_AggrLen;
-       ads->ds_ctl6 |= SM(aggrLen, AR_AggrLen);
-}
-EXPORT_SYMBOL(ath9k_hw_set11n_aggr_first);
-
-void ath9k_hw_set11n_aggr_middle(struct ath_hw *ah, struct ath_desc *ds,
-                                u32 numDelims)
-{
-       struct ar5416_desc *ads = AR5416DESC(ds);
-       unsigned int ctl6;
-
-       ads->ds_ctl1 |= (AR_IsAggr | AR_MoreAggr);
-
-       ctl6 = ads->ds_ctl6;
-       ctl6 &= ~AR_PadDelim;
-       ctl6 |= SM(numDelims, AR_PadDelim);
-       ads->ds_ctl6 = ctl6;
-}
-EXPORT_SYMBOL(ath9k_hw_set11n_aggr_middle);
-
-void ath9k_hw_set11n_aggr_last(struct ath_hw *ah, struct ath_desc *ds)
-{
-       struct ar5416_desc *ads = AR5416DESC(ds);
-
-       ads->ds_ctl1 |= AR_IsAggr;
-       ads->ds_ctl1 &= ~AR_MoreAggr;
-       ads->ds_ctl6 &= ~AR_PadDelim;
-}
-EXPORT_SYMBOL(ath9k_hw_set11n_aggr_last);
-
-void ath9k_hw_clr11n_aggr(struct ath_hw *ah, struct ath_desc *ds)
-{
-       struct ar5416_desc *ads = AR5416DESC(ds);
-
-       ads->ds_ctl1 &= (~AR_IsAggr & ~AR_MoreAggr);
-}
-EXPORT_SYMBOL(ath9k_hw_clr11n_aggr);
-
-void ath9k_hw_set11n_burstduration(struct ath_hw *ah, struct ath_desc *ds,
-                                  u32 burstDuration)
-{
-       struct ar5416_desc *ads = AR5416DESC(ds);
-
-       ads->ds_ctl2 &= ~AR_BurstDur;
-       ads->ds_ctl2 |= SM(burstDuration, AR_BurstDur);
-}
-EXPORT_SYMBOL(ath9k_hw_set11n_burstduration);
-
-void ath9k_hw_set11n_virtualmorefrag(struct ath_hw *ah, struct ath_desc *ds,
-                                    u32 vmf)
-{
-       struct ar5416_desc *ads = AR5416DESC(ds);
-
-       if (vmf)
-               ads->ds_ctl0 |= AR_VirtMoreFrag;
-       else
-               ads->ds_ctl0 &= ~AR_VirtMoreFrag;
-}
-
 void ath9k_hw_gettxintrtxqs(struct ath_hw *ah, u32 *txqs)
 {
        *txqs &= ah->intr_txqs;
@@ -733,6 +475,8 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
        } else
                cwMin = qi->tqi_cwmin;
 
+       ENABLE_REGWRITE_BUFFER(ah);
+
        REG_WRITE(ah, AR_DLCL_IFS(q),
                  SM(cwMin, AR_D_LCL_IFS_CWMIN) |
                  SM(qi->tqi_cwmax, AR_D_LCL_IFS_CWMAX) |
@@ -747,6 +491,8 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
        REG_WRITE(ah, AR_DMISC(q),
                  AR_D_MISC_CW_BKOFF_EN | AR_D_MISC_FRAG_WAIT_EN | 0x2);
 
+       REGWRITE_BUFFER_FLUSH(ah);
+
        if (qi->tqi_cbrPeriod) {
                REG_WRITE(ah, AR_QCBRCFG(q),
                          SM(qi->tqi_cbrPeriod, AR_Q_CBRCFG_INTERVAL) |
@@ -762,6 +508,8 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
                          AR_Q_RDYTIMECFG_EN);
        }
 
+       REGWRITE_BUFFER_FLUSH(ah);
+
        REG_WRITE(ah, AR_DCHNTIME(q),
                  SM(qi->tqi_burstTime, AR_D_CHNTIME_DUR) |
                  (qi->tqi_burstTime ? AR_D_CHNTIME_EN : 0));
@@ -779,6 +527,10 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
                          REG_READ(ah, AR_DMISC(q)) |
                          AR_D_MISC_POST_FR_BKOFF_DIS);
        }
+
+       REGWRITE_BUFFER_FLUSH(ah);
+       DISABLE_REGWRITE_BUFFER(ah);
+
        if (qi->tqi_qflags & TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE) {
                REG_WRITE(ah, AR_DMISC(q),
                          REG_READ(ah, AR_DMISC(q)) |
@@ -786,6 +538,8 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
        }
        switch (qi->tqi_type) {
        case ATH9K_TX_QUEUE_BEACON:
+               ENABLE_REGWRITE_BUFFER(ah);
+
                REG_WRITE(ah, AR_QMISC(q), REG_READ(ah, AR_QMISC(q))
                          | AR_Q_MISC_FSP_DBA_GATED
                          | AR_Q_MISC_BEACON_USE
@@ -796,8 +550,20 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
                             AR_D_MISC_ARB_LOCKOUT_CNTRL_S)
                          | AR_D_MISC_BEACON_USE
                          | AR_D_MISC_POST_FR_BKOFF_DIS);
+
+               REGWRITE_BUFFER_FLUSH(ah);
+               DISABLE_REGWRITE_BUFFER(ah);
+
+               /* cwmin and cwmax should be 0 for beacon queue */
+               if (AR_SREV_9300_20_OR_LATER(ah)) {
+                       REG_WRITE(ah, AR_DLCL_IFS(q), SM(0, AR_D_LCL_IFS_CWMIN)
+                                 | SM(0, AR_D_LCL_IFS_CWMAX)
+                                 | SM(qi->tqi_aifs, AR_D_LCL_IFS_AIFS));
+               }
                break;
        case ATH9K_TX_QUEUE_CAB:
+               ENABLE_REGWRITE_BUFFER(ah);
+
                REG_WRITE(ah, AR_QMISC(q), REG_READ(ah, AR_QMISC(q))
                          | AR_Q_MISC_FSP_DBA_GATED
                          | AR_Q_MISC_CBR_INCR_DIS1
@@ -811,6 +577,10 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
                REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q))
                          | (AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL <<
                             AR_D_MISC_ARB_LOCKOUT_CNTRL_S));
+
+               REGWRITE_BUFFER_FLUSH(ah);
+               DISABLE_REGWRITE_BUFFER(ah);
+
                break;
        case ATH9K_TX_QUEUE_PSPOLL:
                REG_WRITE(ah, AR_QMISC(q),
@@ -832,6 +602,9 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
                          AR_D_MISC_POST_FR_BKOFF_DIS);
        }
 
+       if (AR_SREV_9300_20_OR_LATER(ah))
+               REG_WRITE(ah, AR_Q_DESC_CRCCHK, AR_Q_DESC_CRCCHK_EN);
+
        if (qi->tqi_qflags & TXQ_FLAG_TXOKINT_ENABLE)
                ah->txok_interrupt_mask |= 1 << q;
        else
@@ -940,22 +713,6 @@ int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds,
 }
 EXPORT_SYMBOL(ath9k_hw_rxprocdesc);
 
-void ath9k_hw_setuprxdesc(struct ath_hw *ah, struct ath_desc *ds,
-                         u32 size, u32 flags)
-{
-       struct ar5416_desc *ads = AR5416DESC(ds);
-       struct ath9k_hw_capabilities *pCap = &ah->caps;
-
-       ads->ds_ctl1 = size & AR_BufLen;
-       if (flags & ATH9K_RXDESC_INTREQ)
-               ads->ds_ctl1 |= AR_RxIntrReq;
-
-       ads->ds_rxstatus8 &= ~AR_RxDone;
-       if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP))
-               memset(&(ads->u), 0, sizeof(ads->u));
-}
-EXPORT_SYMBOL(ath9k_hw_setuprxdesc);
-
 /*
  * This can stop or re-enables RX.
  *
@@ -999,12 +756,6 @@ void ath9k_hw_putrxbuf(struct ath_hw *ah, u32 rxdp)
 }
 EXPORT_SYMBOL(ath9k_hw_putrxbuf);
 
-void ath9k_hw_rxena(struct ath_hw *ah)
-{
-       REG_WRITE(ah, AR_CR, AR_CR_RXE);
-}
-EXPORT_SYMBOL(ath9k_hw_rxena);
-
 void ath9k_hw_startpcureceive(struct ath_hw *ah)
 {
        ath9k_enable_mib_counters(ah);
@@ -1023,6 +774,14 @@ void ath9k_hw_stoppcurecv(struct ath_hw *ah)
 }
 EXPORT_SYMBOL(ath9k_hw_stoppcurecv);
 
+void ath9k_hw_abortpcurecv(struct ath_hw *ah)
+{
+       REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_ABORT | AR_DIAG_RX_DIS);
+
+       ath9k_hw_disable_mib_counters(ah);
+}
+EXPORT_SYMBOL(ath9k_hw_abortpcurecv);
+
 bool ath9k_hw_stopdmarecv(struct ath_hw *ah)
 {
 #define AH_RX_STOP_DMA_TIMEOUT 10000   /* usec */
@@ -1068,3 +827,140 @@ int ath9k_hw_beaconq_setup(struct ath_hw *ah)
        return ath9k_hw_setuptxqueue(ah, ATH9K_TX_QUEUE_BEACON, &qi);
 }
 EXPORT_SYMBOL(ath9k_hw_beaconq_setup);
+
+bool ath9k_hw_intrpend(struct ath_hw *ah)
+{
+       u32 host_isr;
+
+       if (AR_SREV_9100(ah))
+               return true;
+
+       host_isr = REG_READ(ah, AR_INTR_ASYNC_CAUSE);
+       if ((host_isr & AR_INTR_MAC_IRQ) && (host_isr != AR_INTR_SPURIOUS))
+               return true;
+
+       host_isr = REG_READ(ah, AR_INTR_SYNC_CAUSE);
+       if ((host_isr & AR_INTR_SYNC_DEFAULT)
+           && (host_isr != AR_INTR_SPURIOUS))
+               return true;
+
+       return false;
+}
+EXPORT_SYMBOL(ath9k_hw_intrpend);
+
+enum ath9k_int ath9k_hw_set_interrupts(struct ath_hw *ah,
+                                             enum ath9k_int ints)
+{
+       enum ath9k_int omask = ah->imask;
+       u32 mask, mask2;
+       struct ath9k_hw_capabilities *pCap = &ah->caps;
+       struct ath_common *common = ath9k_hw_common(ah);
+
+       ath_print(common, ATH_DBG_INTERRUPT, "0x%x => 0x%x\n", omask, ints);
+
+       if (omask & ATH9K_INT_GLOBAL) {
+               ath_print(common, ATH_DBG_INTERRUPT, "disable IER\n");
+               REG_WRITE(ah, AR_IER, AR_IER_DISABLE);
+               (void) REG_READ(ah, AR_IER);
+               if (!AR_SREV_9100(ah)) {
+                       REG_WRITE(ah, AR_INTR_ASYNC_ENABLE, 0);
+                       (void) REG_READ(ah, AR_INTR_ASYNC_ENABLE);
+
+                       REG_WRITE(ah, AR_INTR_SYNC_ENABLE, 0);
+                       (void) REG_READ(ah, AR_INTR_SYNC_ENABLE);
+               }
+       }
+
+       /* TODO: global int Ref count */
+       mask = ints & ATH9K_INT_COMMON;
+       mask2 = 0;
+
+       if (ints & ATH9K_INT_TX) {
+               if (ah->config.tx_intr_mitigation)
+                       mask |= AR_IMR_TXMINTR | AR_IMR_TXINTM;
+               if (ah->txok_interrupt_mask)
+                       mask |= AR_IMR_TXOK;
+               if (ah->txdesc_interrupt_mask)
+                       mask |= AR_IMR_TXDESC;
+               if (ah->txerr_interrupt_mask)
+                       mask |= AR_IMR_TXERR;
+               if (ah->txeol_interrupt_mask)
+                       mask |= AR_IMR_TXEOL;
+       }
+       if (ints & ATH9K_INT_RX) {
+               if (AR_SREV_9300_20_OR_LATER(ah)) {
+                       mask |= AR_IMR_RXERR | AR_IMR_RXOK_HP;
+                       if (ah->config.rx_intr_mitigation) {
+                               mask &= ~AR_IMR_RXOK_LP;
+                               mask |=  AR_IMR_RXMINTR | AR_IMR_RXINTM;
+                       } else {
+                               mask |= AR_IMR_RXOK_LP;
+                       }
+               } else {
+                       if (ah->config.rx_intr_mitigation)
+                               mask |= AR_IMR_RXMINTR | AR_IMR_RXINTM;
+                       else
+                               mask |= AR_IMR_RXOK | AR_IMR_RXDESC;
+               }
+               if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP))
+                       mask |= AR_IMR_GENTMR;
+       }
+
+       if (ints & (ATH9K_INT_BMISC)) {
+               mask |= AR_IMR_BCNMISC;
+               if (ints & ATH9K_INT_TIM)
+                       mask2 |= AR_IMR_S2_TIM;
+               if (ints & ATH9K_INT_DTIM)
+                       mask2 |= AR_IMR_S2_DTIM;
+               if (ints & ATH9K_INT_DTIMSYNC)
+                       mask2 |= AR_IMR_S2_DTIMSYNC;
+               if (ints & ATH9K_INT_CABEND)
+                       mask2 |= AR_IMR_S2_CABEND;
+               if (ints & ATH9K_INT_TSFOOR)
+                       mask2 |= AR_IMR_S2_TSFOOR;
+       }
+
+       if (ints & (ATH9K_INT_GTT | ATH9K_INT_CST)) {
+               mask |= AR_IMR_BCNMISC;
+               if (ints & ATH9K_INT_GTT)
+                       mask2 |= AR_IMR_S2_GTT;
+               if (ints & ATH9K_INT_CST)
+                       mask2 |= AR_IMR_S2_CST;
+       }
+
+       ath_print(common, ATH_DBG_INTERRUPT, "new IMR 0x%x\n", mask);
+       REG_WRITE(ah, AR_IMR, mask);
+       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);
+
+       if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) {
+               if (ints & ATH9K_INT_TIM_TIMER)
+                       REG_SET_BIT(ah, AR_IMR_S5, AR_IMR_S5_TIM_TIMER);
+               else
+                       REG_CLR_BIT(ah, AR_IMR_S5, AR_IMR_S5_TIM_TIMER);
+       }
+
+       if (ints & ATH9K_INT_GLOBAL) {
+               ath_print(common, ATH_DBG_INTERRUPT, "enable IER\n");
+               REG_WRITE(ah, AR_IER, AR_IER_ENABLE);
+               if (!AR_SREV_9100(ah)) {
+                       REG_WRITE(ah, AR_INTR_ASYNC_ENABLE,
+                                 AR_INTR_MAC_IRQ);
+                       REG_WRITE(ah, AR_INTR_ASYNC_MASK, AR_INTR_MAC_IRQ);
+
+
+                       REG_WRITE(ah, AR_INTR_SYNC_ENABLE,
+                                 AR_INTR_SYNC_DEFAULT);
+                       REG_WRITE(ah, AR_INTR_SYNC_MASK,
+                                 AR_INTR_SYNC_DEFAULT);
+               }
+               ath_print(common, ATH_DBG_INTERRUPT, "AR_IMR 0x%x IER 0x%x\n",
+                         REG_READ(ah, AR_IMR), REG_READ(ah, AR_IER));
+       }
+
+       return omask;
+}
+EXPORT_SYMBOL(ath9k_hw_set_interrupts);
index 68dbd7a8ddca091502c536c4cb909a3195da9df7..00f3e0c7528a185e31abe85a2ce520e7524e2a12 100644 (file)
@@ -37,6 +37,8 @@
          AR_2040_##_index : 0)                                         \
         |((_series)[_index].RateFlags & ATH9K_RATESERIES_HALFGI ?      \
           AR_GI##_index : 0)                                           \
+        |((_series)[_index].RateFlags & ATH9K_RATESERIES_STBC ?        \
+          AR_STBC##_index : 0)                                         \
         |SM((_series)[_index].ChSel, AR_ChainSel##_index))
 
 #define CCK_SIFS_TIME        10
@@ -86,7 +88,6 @@
 #define ATH9K_TX_DESC_CFG_ERR      0x04
 #define ATH9K_TX_DATA_UNDERRUN     0x08
 #define ATH9K_TX_DELIM_UNDERRUN    0x10
-#define ATH9K_TX_SW_ABORTED        0x40
 #define ATH9K_TX_SW_FILTERED       0x80
 
 /* 64 bytes */
@@ -117,7 +118,10 @@ struct ath_tx_status {
        int8_t ts_rssi_ext0;
        int8_t ts_rssi_ext1;
        int8_t ts_rssi_ext2;
-       u8 pad[3];
+       u8 qid;
+       u16 desc_id;
+       u8 tid;
+       u8 pad[2];
        u32 ba_low;
        u32 ba_high;
        u32 evm0;
@@ -148,11 +152,13 @@ struct ath_rx_status {
        u32 evm0;
        u32 evm1;
        u32 evm2;
+       u32 evm3;
+       u32 evm4;
 };
 
 struct ath_htc_rx_status {
-       u64 rs_tstamp;
-       u16 rs_datalen;
+       __be64 rs_tstamp;
+       __be16 rs_datalen;
        u8 rs_status;
        u8 rs_phyerr;
        int8_t rs_rssi;
@@ -171,9 +177,9 @@ struct ath_htc_rx_status {
        u8 rs_num_delims;
        u8 rs_flags;
        u8 rs_dummy;
-       u32 evm0;
-       u32 evm1;
-       u32 evm2;
+       __be32 evm0;
+       __be32 evm1;
+       __be32 evm2;
 };
 
 #define ATH9K_RXERR_CRC           0x01
@@ -259,7 +265,8 @@ struct ath_desc {
 #define ATH9K_TXDESC_EXT_AND_CTL       0x0080
 #define ATH9K_TXDESC_VMF               0x0100
 #define ATH9K_TXDESC_FRAG_IS_ON        0x0200
-#define ATH9K_TXDESC_CAB               0x0400
+#define ATH9K_TXDESC_LOWRXCHAIN                0x0400
+#define ATH9K_TXDESC_LDPC              0x00010000
 
 #define ATH9K_RXDESC_INTREQ            0x0020
 
@@ -353,7 +360,6 @@ struct ar5416_desc {
 #define AR_DestIdxValid     0x40000000
 #define AR_CTSEnable        0x80000000
 
-#define AR_BufLen           0x00000fff
 #define AR_TxMore           0x00001000
 #define AR_DestIdx          0x000fe000
 #define AR_DestIdx_S        13
@@ -410,6 +416,7 @@ struct ar5416_desc {
 #define AR_EncrType         0x0c000000
 #define AR_EncrType_S       26
 #define AR_TxCtlRsvd61      0xf0000000
+#define AR_LDPC             0x80000000
 
 #define AR_2040_0           0x00000001
 #define AR_GI0              0x00000002
@@ -429,7 +436,10 @@ struct ar5416_desc {
 #define AR_ChainSel3_S      17
 #define AR_RTSCTSRate       0x0ff00000
 #define AR_RTSCTSRate_S     20
-#define AR_TxCtlRsvd70      0xf0000000
+#define AR_STBC0            0x10000000
+#define AR_STBC1            0x20000000
+#define AR_STBC2            0x40000000
+#define AR_STBC3            0x80000000
 
 #define AR_TxRSSIAnt00      0x000000ff
 #define AR_TxRSSIAnt00_S    0
@@ -493,7 +503,6 @@ struct ar5416_desc {
 
 #define AR_RxCTLRsvd00  0xffffffff
 
-#define AR_BufLen       0x00000fff
 #define AR_RxCtlRsvd00  0x00001000
 #define AR_RxIntrReq    0x00002000
 #define AR_RxCtlRsvd01  0xffffc000
@@ -643,6 +652,7 @@ enum ath9k_rx_filter {
 #define ATH9K_RATESERIES_RTS_CTS  0x0001
 #define ATH9K_RATESERIES_2040     0x0002
 #define ATH9K_RATESERIES_HALFGI   0x0004
+#define ATH9K_RATESERIES_STBC     0x0008
 
 struct ath9k_11n_rate_series {
        u32 Tries;
@@ -686,34 +696,10 @@ struct ath9k_channel;
 u32 ath9k_hw_gettxbuf(struct ath_hw *ah, u32 q);
 void ath9k_hw_puttxbuf(struct ath_hw *ah, u32 q, u32 txdp);
 void ath9k_hw_txstart(struct ath_hw *ah, u32 q);
+void ath9k_hw_cleartxdesc(struct ath_hw *ah, void *ds);
 u32 ath9k_hw_numtxpending(struct ath_hw *ah, u32 q);
 bool ath9k_hw_updatetxtriglevel(struct ath_hw *ah, bool bIncTrigLevel);
 bool ath9k_hw_stoptxdma(struct ath_hw *ah, u32 q);
-void ath9k_hw_filltxdesc(struct ath_hw *ah, struct ath_desc *ds,
-                        u32 segLen, bool firstSeg,
-                        bool lastSeg, const struct ath_desc *ds0);
-void ath9k_hw_cleartxdesc(struct ath_hw *ah, struct ath_desc *ds);
-int ath9k_hw_txprocdesc(struct ath_hw *ah, struct ath_desc *ds,
-                       struct ath_tx_status *ts);
-void ath9k_hw_set11n_txdesc(struct ath_hw *ah, struct ath_desc *ds,
-                           u32 pktLen, enum ath9k_pkt_type type, u32 txPower,
-                           u32 keyIx, enum ath9k_key_type keyType, u32 flags);
-void ath9k_hw_set11n_ratescenario(struct ath_hw *ah, struct ath_desc *ds,
-                                 struct ath_desc *lastds,
-                                 u32 durUpdateEn, u32 rtsctsRate,
-                                 u32 rtsctsDuration,
-                                 struct ath9k_11n_rate_series series[],
-                                 u32 nseries, u32 flags);
-void ath9k_hw_set11n_aggr_first(struct ath_hw *ah, struct ath_desc *ds,
-                               u32 aggrLen);
-void ath9k_hw_set11n_aggr_middle(struct ath_hw *ah, struct ath_desc *ds,
-                                u32 numDelims);
-void ath9k_hw_set11n_aggr_last(struct ath_hw *ah, struct ath_desc *ds);
-void ath9k_hw_clr11n_aggr(struct ath_hw *ah, struct ath_desc *ds);
-void ath9k_hw_set11n_burstduration(struct ath_hw *ah, struct ath_desc *ds,
-                                  u32 burstDuration);
-void ath9k_hw_set11n_virtualmorefrag(struct ath_hw *ah, struct ath_desc *ds,
-                                    u32 vmf);
 void ath9k_hw_gettxintrtxqs(struct ath_hw *ah, u32 *txqs);
 bool ath9k_hw_set_txq_props(struct ath_hw *ah, int q,
                            const struct ath9k_tx_queue_info *qinfo);
@@ -729,10 +715,17 @@ void ath9k_hw_setuprxdesc(struct ath_hw *ah, struct ath_desc *ds,
                          u32 size, u32 flags);
 bool ath9k_hw_setrxabort(struct ath_hw *ah, bool set);
 void ath9k_hw_putrxbuf(struct ath_hw *ah, u32 rxdp);
-void ath9k_hw_rxena(struct ath_hw *ah);
 void ath9k_hw_startpcureceive(struct ath_hw *ah);
 void ath9k_hw_stoppcurecv(struct ath_hw *ah);
+void ath9k_hw_abortpcurecv(struct ath_hw *ah);
 bool ath9k_hw_stopdmarecv(struct ath_hw *ah);
 int ath9k_hw_beaconq_setup(struct ath_hw *ah);
 
+/* Interrupt Handling */
+bool ath9k_hw_intrpend(struct ath_hw *ah);
+enum ath9k_int ath9k_hw_set_interrupts(struct ath_hw *ah,
+                                      enum ath9k_int ints);
+
+void ar9002_hw_attach_mac_ops(struct ath_hw *ah);
+
 #endif /* MAC_H */
index f7ef11407e27c016d20cbfdeee18a1f2e57b13a9..aad370a7f95b782049fc11b05277c48538ea0944 100644 (file)
@@ -401,23 +401,41 @@ void ath9k_tasklet(unsigned long data)
        struct ath_common *common = ath9k_hw_common(ah);
 
        u32 status = sc->intrstatus;
+       u32 rxmask;
 
        ath9k_ps_wakeup(sc);
 
-       if (status & ATH9K_INT_FATAL) {
+       if ((status & ATH9K_INT_FATAL) ||
+           !ath9k_hw_check_alive(ah)) {
                ath_reset(sc, false);
                ath9k_ps_restore(sc);
                return;
        }
 
-       if (status & (ATH9K_INT_RX | ATH9K_INT_RXEOL | ATH9K_INT_RXORN)) {
+       if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
+               rxmask = (ATH9K_INT_RXHP | ATH9K_INT_RXLP | ATH9K_INT_RXEOL |
+                         ATH9K_INT_RXORN);
+       else
+               rxmask = (ATH9K_INT_RX | ATH9K_INT_RXEOL | ATH9K_INT_RXORN);
+
+       if (status & rxmask) {
                spin_lock_bh(&sc->rx.rxflushlock);
-               ath_rx_tasklet(sc, 0);
+
+               /* Check for high priority Rx first */
+               if ((ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) &&
+                   (status & ATH9K_INT_RXHP))
+                       ath_rx_tasklet(sc, 0, true);
+
+               ath_rx_tasklet(sc, 0, false);
                spin_unlock_bh(&sc->rx.rxflushlock);
        }
 
-       if (status & ATH9K_INT_TX)
-               ath_tx_tasklet(sc);
+       if (status & ATH9K_INT_TX) {
+               if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
+                       ath_tx_edma_tasklet(sc);
+               else
+                       ath_tx_tasklet(sc);
+       }
 
        if ((status & ATH9K_INT_TSFOOR) && sc->ps_enabled) {
                /*
@@ -445,6 +463,8 @@ irqreturn_t ath_isr(int irq, void *dev)
                ATH9K_INT_RXORN |               \
                ATH9K_INT_RXEOL |               \
                ATH9K_INT_RX |                  \
+               ATH9K_INT_RXLP |                \
+               ATH9K_INT_RXHP |                \
                ATH9K_INT_TX |                  \
                ATH9K_INT_BMISS |               \
                ATH9K_INT_CST |                 \
@@ -496,7 +516,8 @@ irqreturn_t ath_isr(int irq, void *dev)
         * If a FATAL or RXORN interrupt is received, we have to reset the
         * chip immediately.
         */
-       if (status & (ATH9K_INT_FATAL | ATH9K_INT_RXORN))
+       if ((status & ATH9K_INT_FATAL) || ((status & ATH9K_INT_RXORN) &&
+           !(ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)))
                goto chip_reset;
 
        if (status & ATH9K_INT_SWBA)
@@ -505,6 +526,13 @@ irqreturn_t ath_isr(int irq, void *dev)
        if (status & ATH9K_INT_TXURN)
                ath9k_hw_updatetxtriglevel(ah, true);
 
+       if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
+               if (status & ATH9K_INT_RXEOL) {
+                       ah->imask &= ~(ATH9K_INT_RXEOL | ATH9K_INT_RXORN);
+                       ath9k_hw_set_interrupts(ah, ah->imask);
+               }
+       }
+
        if (status & ATH9K_INT_MIB) {
                /*
                 * Disable interrupts until we service the MIB
@@ -724,6 +752,7 @@ static int ath_key_config(struct ath_common *common,
        struct ath_hw *ah = common->ah;
        struct ath9k_keyval hk;
        const u8 *mac = NULL;
+       u8 gmac[ETH_ALEN];
        int ret = 0;
        int idx;
 
@@ -747,9 +776,30 @@ static int ath_key_config(struct ath_common *common,
        memcpy(hk.kv_val, key->key, key->keylen);
 
        if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) {
-               /* For now, use the default keys for broadcast keys. This may
-                * need to change with virtual interfaces. */
-               idx = key->keyidx;
+
+               if (key->ap_addr) {
+                       /*
+                        * Group keys on hardware that supports multicast frame
+                        * key search use a mac that is the sender's address with
+                        * the high bit set instead of the app-specified address.
+                        */
+                       memcpy(gmac, key->ap_addr, ETH_ALEN);
+                       gmac[0] |= 0x80;
+                       mac = gmac;
+
+                       if (key->alg == ALG_TKIP)
+                               idx = ath_reserve_key_cache_slot_tkip(common);
+                       else
+                               idx = ath_reserve_key_cache_slot(common);
+                       if (idx < 0)
+                               mac = NULL; /* no free key cache entries */
+               }
+
+               if (!mac) {
+                       /* For now, use the default keys for broadcast keys. This may
+                        * need to change with virtual interfaces. */
+                       idx = key->keyidx;
+               }
        } else if (key->keyidx) {
                if (WARN_ON(!sta))
                        return -EOPNOTSUPP;
@@ -1162,9 +1212,14 @@ static int ath9k_start(struct ieee80211_hw *hw)
        }
 
        /* Setup our intr mask. */
-       ah->imask = ATH9K_INT_RX | ATH9K_INT_TX
-               | ATH9K_INT_RXEOL | ATH9K_INT_RXORN
-               | ATH9K_INT_FATAL | ATH9K_INT_GLOBAL;
+       ah->imask = ATH9K_INT_TX | ATH9K_INT_RXEOL |
+                   ATH9K_INT_RXORN | ATH9K_INT_FATAL |
+                   ATH9K_INT_GLOBAL;
+
+       if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
+               ah->imask |= ATH9K_INT_RXHP | ATH9K_INT_RXLP;
+       else
+               ah->imask |= ATH9K_INT_RX;
 
        if (ah->caps.hw_caps & ATH9K_HW_CAP_GTT)
                ah->imask |= ATH9K_INT_GTT;
@@ -1436,7 +1491,8 @@ static int ath9k_add_interface(struct ieee80211_hw *hw,
        if ((vif->type == NL80211_IFTYPE_STATION) ||
            (vif->type == NL80211_IFTYPE_ADHOC) ||
            (vif->type == NL80211_IFTYPE_MESH_POINT)) {
-               ah->imask |= ATH9K_INT_MIB;
+               if (ah->config.enable_ani)
+                       ah->imask |= ATH9K_INT_MIB;
                ah->imask |= ATH9K_INT_TSFOOR;
        }
 
index 1ec836cf1c0da8defa709b6ba983cac744ba9799..257b10ba6f57e2b4c7e99872ef046709ba7c668f 100644 (file)
@@ -28,6 +28,7 @@ static DEFINE_PCI_DEVICE_TABLE(ath_pci_id_table) = {
        { PCI_VDEVICE(ATHEROS, 0x002C) }, /* PCI-E 802.11n bonded out */
        { PCI_VDEVICE(ATHEROS, 0x002D) }, /* PCI   */
        { PCI_VDEVICE(ATHEROS, 0x002E) }, /* PCI-E */
+       { PCI_VDEVICE(ATHEROS, 0x0030) }, /* PCI-E  AR9300 */
        { 0 }
 };
 
diff --git a/drivers/net/wireless/ath/ath9k/phy.c b/drivers/net/wireless/ath/ath9k/phy.c
deleted file mode 100644 (file)
index 2547b3c..0000000
+++ /dev/null
@@ -1,978 +0,0 @@
-/*
- * Copyright (c) 2008-2009 Atheros Communications Inc.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT 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.
- */
-
-/**
- * DOC: Programming Atheros 802.11n analog front end radios
- *
- * AR5416 MAC based PCI devices and AR518 MAC based PCI-Express
- * devices have either an external AR2133 analog front end radio for single
- * band 2.4 GHz communication or an AR5133 analog front end radio for dual
- * band 2.4 GHz / 5 GHz communication.
- *
- * All devices after the AR5416 and AR5418 family starting with the AR9280
- * have their analog front radios, MAC/BB and host PCIe/USB interface embedded
- * into a single-chip and require less programming.
- *
- * The following single-chips exist with a respective embedded radio:
- *
- * AR9280 - 11n dual-band 2x2 MIMO for PCIe
- * AR9281 - 11n single-band 1x2 MIMO for PCIe
- * AR9285 - 11n single-band 1x1 for PCIe
- * AR9287 - 11n single-band 2x2 MIMO for PCIe
- *
- * AR9220 - 11n dual-band 2x2 MIMO for PCI
- * AR9223 - 11n single-band 2x2 MIMO for PCI
- *
- * AR9287 - 11n single-band 1x1 MIMO for USB
- */
-
-#include <linux/slab.h>
-
-#include "hw.h"
-
-/**
- * ath9k_hw_write_regs - ??
- *
- * @ah: atheros hardware structure
- * @freqIndex:
- * @regWrites:
- *
- * Used for both the chipsets with an external AR2133/AR5133 radios and
- * single-chip devices.
- */
-void ath9k_hw_write_regs(struct ath_hw *ah, u32 freqIndex, int regWrites)
-{
-       REG_WRITE_ARRAY(&ah->iniBB_RfGain, freqIndex, regWrites);
-}
-
-/**
- * ath9k_hw_ar9280_set_channel - set channel on single-chip device
- * @ah: atheros hardware structure
- * @chan:
- *
- * This is the function to change channel on single-chip devices, that is
- * all devices after ar9280.
- *
- * This function takes the channel value in MHz and sets
- * hardware channel value. Assumes writes have been enabled to analog bus.
- *
- * Actual Expression,
- *
- * For 2GHz channel,
- * Channel Frequency = (3/4) * freq_ref * (chansel[8:0] + chanfrac[16:0]/2^17)
- * (freq_ref = 40MHz)
- *
- * For 5GHz channel,
- * Channel Frequency = (3/2) * freq_ref * (chansel[8:0] + chanfrac[16:0]/2^10)
- * (freq_ref = 40MHz/(24>>amodeRefSel))
- */
-int ath9k_hw_ar9280_set_channel(struct ath_hw *ah, struct ath9k_channel *chan)
-{
-       u16 bMode, fracMode, aModeRefSel = 0;
-       u32 freq, ndiv, channelSel = 0, channelFrac = 0, reg32 = 0;
-       struct chan_centers centers;
-       u32 refDivA = 24;
-
-       ath9k_hw_get_channel_centers(ah, chan, &centers);
-       freq = centers.synth_center;
-
-       reg32 = REG_READ(ah, AR_PHY_SYNTH_CONTROL);
-       reg32 &= 0xc0000000;
-
-       if (freq < 4800) { /* 2 GHz, fractional mode */
-               u32 txctl;
-               int regWrites = 0;
-
-               bMode = 1;
-               fracMode = 1;
-               aModeRefSel = 0;
-               channelSel = (freq * 0x10000) / 15;
-
-               if (AR_SREV_9287_11_OR_LATER(ah)) {
-                       if (freq == 2484) {
-                               /* Enable channel spreading for channel 14 */
-                               REG_WRITE_ARRAY(&ah->iniCckfirJapan2484,
-                                               1, regWrites);
-                       } else {
-                               REG_WRITE_ARRAY(&ah->iniCckfirNormal,
-                                               1, regWrites);
-                       }
-               } else {
-                       txctl = REG_READ(ah, AR_PHY_CCK_TX_CTRL);
-                       if (freq == 2484) {
-                               /* Enable channel spreading for channel 14 */
-                               REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
-                                         txctl | AR_PHY_CCK_TX_CTRL_JAPAN);
-                       } else {
-                               REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
-                                         txctl &~ AR_PHY_CCK_TX_CTRL_JAPAN);
-                       }
-               }
-       } else {
-               bMode = 0;
-               fracMode = 0;
-
-               switch(ah->eep_ops->get_eeprom(ah, EEP_FRAC_N_5G)) {
-               case 0:
-                       if ((freq % 20) == 0) {
-                               aModeRefSel = 3;
-                       } else if ((freq % 10) == 0) {
-                               aModeRefSel = 2;
-                       }
-                       if (aModeRefSel)
-                               break;
-               case 1:
-               default:
-                       aModeRefSel = 0;
-                       /*
-                        * Enable 2G (fractional) mode for channels
-                        * which are 5MHz spaced.
-                        */
-                       fracMode = 1;
-                       refDivA = 1;
-                       channelSel = (freq * 0x8000) / 15;
-
-                       /* RefDivA setting */
-                       REG_RMW_FIELD(ah, AR_AN_SYNTH9,
-                                     AR_AN_SYNTH9_REFDIVA, refDivA);
-
-               }
-
-               if (!fracMode) {
-                       ndiv = (freq * (refDivA >> aModeRefSel)) / 60;
-                       channelSel = ndiv & 0x1ff;
-                       channelFrac = (ndiv & 0xfffffe00) * 2;
-                       channelSel = (channelSel << 17) | channelFrac;
-               }
-       }
-
-       reg32 = reg32 |
-           (bMode << 29) |
-           (fracMode << 28) | (aModeRefSel << 26) | (channelSel);
-
-       REG_WRITE(ah, AR_PHY_SYNTH_CONTROL, reg32);
-
-       ah->curchan = chan;
-       ah->curchan_rad_index = -1;
-
-       return 0;
-}
-
-/**
- * ath9k_hw_9280_spur_mitigate - convert baseband spur frequency
- * @ah: atheros hardware structure
- * @chan:
- *
- * For single-chip solutions. Converts to baseband spur frequency given the
- * input channel frequency and compute register settings below.
- */
-void ath9k_hw_9280_spur_mitigate(struct ath_hw *ah, struct ath9k_channel *chan)
-{
-       int bb_spur = AR_NO_SPUR;
-       int freq;
-       int bin, cur_bin;
-       int bb_spur_off, spur_subchannel_sd;
-       int spur_freq_sd;
-       int spur_delta_phase;
-       int denominator;
-       int upper, lower, cur_vit_mask;
-       int tmp, newVal;
-       int i;
-       int pilot_mask_reg[4] = { AR_PHY_TIMING7, AR_PHY_TIMING8,
-                         AR_PHY_PILOT_MASK_01_30, AR_PHY_PILOT_MASK_31_60
-       };
-       int chan_mask_reg[4] = { AR_PHY_TIMING9, AR_PHY_TIMING10,
-                        AR_PHY_CHANNEL_MASK_01_30, AR_PHY_CHANNEL_MASK_31_60
-       };
-       int inc[4] = { 0, 100, 0, 0 };
-       struct chan_centers centers;
-
-       int8_t mask_m[123];
-       int8_t mask_p[123];
-       int8_t mask_amt;
-       int tmp_mask;
-       int cur_bb_spur;
-       bool is2GHz = IS_CHAN_2GHZ(chan);
-
-       memset(&mask_m, 0, sizeof(int8_t) * 123);
-       memset(&mask_p, 0, sizeof(int8_t) * 123);
-
-       ath9k_hw_get_channel_centers(ah, chan, &centers);
-       freq = centers.synth_center;
-
-       ah->config.spurmode = SPUR_ENABLE_EEPROM;
-       for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
-               cur_bb_spur = ah->eep_ops->get_spur_channel(ah, i, is2GHz);
-
-               if (is2GHz)
-                       cur_bb_spur = (cur_bb_spur / 10) + AR_BASE_FREQ_2GHZ;
-               else
-                       cur_bb_spur = (cur_bb_spur / 10) + AR_BASE_FREQ_5GHZ;
-
-               if (AR_NO_SPUR == cur_bb_spur)
-                       break;
-               cur_bb_spur = cur_bb_spur - freq;
-
-               if (IS_CHAN_HT40(chan)) {
-                       if ((cur_bb_spur > -AR_SPUR_FEEQ_BOUND_HT40) &&
-                           (cur_bb_spur < AR_SPUR_FEEQ_BOUND_HT40)) {
-                               bb_spur = cur_bb_spur;
-                               break;
-                       }
-               } else if ((cur_bb_spur > -AR_SPUR_FEEQ_BOUND_HT20) &&
-                          (cur_bb_spur < AR_SPUR_FEEQ_BOUND_HT20)) {
-                       bb_spur = cur_bb_spur;
-                       break;
-               }
-       }
-
-       if (AR_NO_SPUR == bb_spur) {
-               REG_CLR_BIT(ah, AR_PHY_FORCE_CLKEN_CCK,
-                           AR_PHY_FORCE_CLKEN_CCK_MRC_MUX);
-               return;
-       } else {
-               REG_CLR_BIT(ah, AR_PHY_FORCE_CLKEN_CCK,
-                           AR_PHY_FORCE_CLKEN_CCK_MRC_MUX);
-       }
-
-       bin = bb_spur * 320;
-
-       tmp = REG_READ(ah, AR_PHY_TIMING_CTRL4(0));
-
-       newVal = tmp | (AR_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI |
-                       AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER |
-                       AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK |
-                       AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK);
-       REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0), newVal);
-
-       newVal = (AR_PHY_SPUR_REG_MASK_RATE_CNTL |
-                 AR_PHY_SPUR_REG_ENABLE_MASK_PPM |
-                 AR_PHY_SPUR_REG_MASK_RATE_SELECT |
-                 AR_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI |
-                 SM(SPUR_RSSI_THRESH, AR_PHY_SPUR_REG_SPUR_RSSI_THRESH));
-       REG_WRITE(ah, AR_PHY_SPUR_REG, newVal);
-
-       if (IS_CHAN_HT40(chan)) {
-               if (bb_spur < 0) {
-                       spur_subchannel_sd = 1;
-                       bb_spur_off = bb_spur + 10;
-               } else {
-                       spur_subchannel_sd = 0;
-                       bb_spur_off = bb_spur - 10;
-               }
-       } else {
-               spur_subchannel_sd = 0;
-               bb_spur_off = bb_spur;
-       }
-
-       if (IS_CHAN_HT40(chan))
-               spur_delta_phase =
-                       ((bb_spur * 262144) /
-                        10) & AR_PHY_TIMING11_SPUR_DELTA_PHASE;
-       else
-               spur_delta_phase =
-                       ((bb_spur * 524288) /
-                        10) & AR_PHY_TIMING11_SPUR_DELTA_PHASE;
-
-       denominator = IS_CHAN_2GHZ(chan) ? 44 : 40;
-       spur_freq_sd = ((bb_spur_off * 2048) / denominator) & 0x3ff;
-
-       newVal = (AR_PHY_TIMING11_USE_SPUR_IN_AGC |
-                 SM(spur_freq_sd, AR_PHY_TIMING11_SPUR_FREQ_SD) |
-                 SM(spur_delta_phase, AR_PHY_TIMING11_SPUR_DELTA_PHASE));
-       REG_WRITE(ah, AR_PHY_TIMING11, newVal);
-
-       newVal = spur_subchannel_sd << AR_PHY_SFCORR_SPUR_SUBCHNL_SD_S;
-       REG_WRITE(ah, AR_PHY_SFCORR_EXT, newVal);
-
-       cur_bin = -6000;
-       upper = bin + 100;
-       lower = bin - 100;
-
-       for (i = 0; i < 4; i++) {
-               int pilot_mask = 0;
-               int chan_mask = 0;
-               int bp = 0;
-               for (bp = 0; bp < 30; bp++) {
-                       if ((cur_bin > lower) && (cur_bin < upper)) {
-                               pilot_mask = pilot_mask | 0x1 << bp;
-                               chan_mask = chan_mask | 0x1 << bp;
-                       }
-                       cur_bin += 100;
-               }
-               cur_bin += inc[i];
-               REG_WRITE(ah, pilot_mask_reg[i], pilot_mask);
-               REG_WRITE(ah, chan_mask_reg[i], chan_mask);
-       }
-
-       cur_vit_mask = 6100;
-       upper = bin + 120;
-       lower = bin - 120;
-
-       for (i = 0; i < 123; i++) {
-               if ((cur_vit_mask > lower) && (cur_vit_mask < upper)) {
-
-                       /* workaround for gcc bug #37014 */
-                       volatile int tmp_v = abs(cur_vit_mask - bin);
-
-                       if (tmp_v < 75)
-                               mask_amt = 1;
-                       else
-                               mask_amt = 0;
-                       if (cur_vit_mask < 0)
-                               mask_m[abs(cur_vit_mask / 100)] = mask_amt;
-                       else
-                               mask_p[cur_vit_mask / 100] = mask_amt;
-               }
-               cur_vit_mask -= 100;
-       }
-
-       tmp_mask = (mask_m[46] << 30) | (mask_m[47] << 28)
-               | (mask_m[48] << 26) | (mask_m[49] << 24)
-               | (mask_m[50] << 22) | (mask_m[51] << 20)
-               | (mask_m[52] << 18) | (mask_m[53] << 16)
-               | (mask_m[54] << 14) | (mask_m[55] << 12)
-               | (mask_m[56] << 10) | (mask_m[57] << 8)
-               | (mask_m[58] << 6) | (mask_m[59] << 4)
-               | (mask_m[60] << 2) | (mask_m[61] << 0);
-       REG_WRITE(ah, AR_PHY_BIN_MASK_1, tmp_mask);
-       REG_WRITE(ah, AR_PHY_VIT_MASK2_M_46_61, tmp_mask);
-
-       tmp_mask = (mask_m[31] << 28)
-               | (mask_m[32] << 26) | (mask_m[33] << 24)
-               | (mask_m[34] << 22) | (mask_m[35] << 20)
-               | (mask_m[36] << 18) | (mask_m[37] << 16)
-               | (mask_m[48] << 14) | (mask_m[39] << 12)
-               | (mask_m[40] << 10) | (mask_m[41] << 8)
-               | (mask_m[42] << 6) | (mask_m[43] << 4)
-               | (mask_m[44] << 2) | (mask_m[45] << 0);
-       REG_WRITE(ah, AR_PHY_BIN_MASK_2, tmp_mask);
-       REG_WRITE(ah, AR_PHY_MASK2_M_31_45, tmp_mask);
-
-       tmp_mask = (mask_m[16] << 30) | (mask_m[16] << 28)
-               | (mask_m[18] << 26) | (mask_m[18] << 24)
-               | (mask_m[20] << 22) | (mask_m[20] << 20)
-               | (mask_m[22] << 18) | (mask_m[22] << 16)
-               | (mask_m[24] << 14) | (mask_m[24] << 12)
-               | (mask_m[25] << 10) | (mask_m[26] << 8)
-               | (mask_m[27] << 6) | (mask_m[28] << 4)
-               | (mask_m[29] << 2) | (mask_m[30] << 0);
-       REG_WRITE(ah, AR_PHY_BIN_MASK_3, tmp_mask);
-       REG_WRITE(ah, AR_PHY_MASK2_M_16_30, tmp_mask);
-
-       tmp_mask = (mask_m[0] << 30) | (mask_m[1] << 28)
-               | (mask_m[2] << 26) | (mask_m[3] << 24)
-               | (mask_m[4] << 22) | (mask_m[5] << 20)
-               | (mask_m[6] << 18) | (mask_m[7] << 16)
-               | (mask_m[8] << 14) | (mask_m[9] << 12)
-               | (mask_m[10] << 10) | (mask_m[11] << 8)
-               | (mask_m[12] << 6) | (mask_m[13] << 4)
-               | (mask_m[14] << 2) | (mask_m[15] << 0);
-       REG_WRITE(ah, AR_PHY_MASK_CTL, tmp_mask);
-       REG_WRITE(ah, AR_PHY_MASK2_M_00_15, tmp_mask);
-
-       tmp_mask = (mask_p[15] << 28)
-               | (mask_p[14] << 26) | (mask_p[13] << 24)
-               | (mask_p[12] << 22) | (mask_p[11] << 20)
-               | (mask_p[10] << 18) | (mask_p[9] << 16)
-               | (mask_p[8] << 14) | (mask_p[7] << 12)
-               | (mask_p[6] << 10) | (mask_p[5] << 8)
-               | (mask_p[4] << 6) | (mask_p[3] << 4)
-               | (mask_p[2] << 2) | (mask_p[1] << 0);
-       REG_WRITE(ah, AR_PHY_BIN_MASK2_1, tmp_mask);
-       REG_WRITE(ah, AR_PHY_MASK2_P_15_01, tmp_mask);
-
-       tmp_mask = (mask_p[30] << 28)
-               | (mask_p[29] << 26) | (mask_p[28] << 24)
-               | (mask_p[27] << 22) | (mask_p[26] << 20)
-               | (mask_p[25] << 18) | (mask_p[24] << 16)
-               | (mask_p[23] << 14) | (mask_p[22] << 12)
-               | (mask_p[21] << 10) | (mask_p[20] << 8)
-               | (mask_p[19] << 6) | (mask_p[18] << 4)
-               | (mask_p[17] << 2) | (mask_p[16] << 0);
-       REG_WRITE(ah, AR_PHY_BIN_MASK2_2, tmp_mask);
-       REG_WRITE(ah, AR_PHY_MASK2_P_30_16, tmp_mask);
-
-       tmp_mask = (mask_p[45] << 28)
-               | (mask_p[44] << 26) | (mask_p[43] << 24)
-               | (mask_p[42] << 22) | (mask_p[41] << 20)
-               | (mask_p[40] << 18) | (mask_p[39] << 16)
-               | (mask_p[38] << 14) | (mask_p[37] << 12)
-               | (mask_p[36] << 10) | (mask_p[35] << 8)
-               | (mask_p[34] << 6) | (mask_p[33] << 4)
-               | (mask_p[32] << 2) | (mask_p[31] << 0);
-       REG_WRITE(ah, AR_PHY_BIN_MASK2_3, tmp_mask);
-       REG_WRITE(ah, AR_PHY_MASK2_P_45_31, tmp_mask);
-
-       tmp_mask = (mask_p[61] << 30) | (mask_p[60] << 28)
-               | (mask_p[59] << 26) | (mask_p[58] << 24)
-               | (mask_p[57] << 22) | (mask_p[56] << 20)
-               | (mask_p[55] << 18) | (mask_p[54] << 16)
-               | (mask_p[53] << 14) | (mask_p[52] << 12)
-               | (mask_p[51] << 10) | (mask_p[50] << 8)
-               | (mask_p[49] << 6) | (mask_p[48] << 4)
-               | (mask_p[47] << 2) | (mask_p[46] << 0);
-       REG_WRITE(ah, AR_PHY_BIN_MASK2_4, tmp_mask);
-       REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask);
-}
-
-/* All code below is for non single-chip solutions */
-
-/**
- * ath9k_phy_modify_rx_buffer() - perform analog swizzling of parameters
- * @rfbuf:
- * @reg32:
- * @numBits:
- * @firstBit:
- * @column:
- *
- * Performs analog "swizzling" of parameters into their location.
- * Used on external AR2133/AR5133 radios.
- */
-static void ath9k_phy_modify_rx_buffer(u32 *rfBuf, u32 reg32,
-                                      u32 numBits, u32 firstBit,
-                                      u32 column)
-{
-       u32 tmp32, mask, arrayEntry, lastBit;
-       int32_t bitPosition, bitsLeft;
-
-       tmp32 = ath9k_hw_reverse_bits(reg32, numBits);
-       arrayEntry = (firstBit - 1) / 8;
-       bitPosition = (firstBit - 1) % 8;
-       bitsLeft = numBits;
-       while (bitsLeft > 0) {
-               lastBit = (bitPosition + bitsLeft > 8) ?
-                   8 : bitPosition + bitsLeft;
-               mask = (((1 << lastBit) - 1) ^ ((1 << bitPosition) - 1)) <<
-                   (column * 8);
-               rfBuf[arrayEntry] &= ~mask;
-               rfBuf[arrayEntry] |= ((tmp32 << bitPosition) <<
-                                     (column * 8)) & mask;
-               bitsLeft -= 8 - bitPosition;
-               tmp32 = tmp32 >> (8 - bitPosition);
-               bitPosition = 0;
-               arrayEntry++;
-       }
-}
-
-/*
- * Fix on 2.4 GHz band for orientation sensitivity issue by increasing
- * rf_pwd_icsyndiv.
- *
- * Theoretical Rules:
- *   if 2 GHz band
- *      if forceBiasAuto
- *         if synth_freq < 2412
- *            bias = 0
- *         else if 2412 <= synth_freq <= 2422
- *            bias = 1
- *         else // synth_freq > 2422
- *            bias = 2
- *      else if forceBias > 0
- *         bias = forceBias & 7
- *      else
- *         no change, use value from ini file
- *   else
- *      no change, invalid band
- *
- *  1st Mod:
- *    2422 also uses value of 2
- *    <approved>
- *
- *  2nd Mod:
- *    Less than 2412 uses value of 0, 2412 and above uses value of 2
- */
-static void ath9k_hw_force_bias(struct ath_hw *ah, u16 synth_freq)
-{
-       struct ath_common *common = ath9k_hw_common(ah);
-       u32 tmp_reg;
-       int reg_writes = 0;
-       u32 new_bias = 0;
-
-       if (!AR_SREV_5416(ah) || synth_freq >= 3000) {
-               return;
-       }
-
-       BUG_ON(AR_SREV_9280_10_OR_LATER(ah));
-
-       if (synth_freq < 2412)
-               new_bias = 0;
-       else if (synth_freq < 2422)
-               new_bias = 1;
-       else
-               new_bias = 2;
-
-       /* pre-reverse this field */
-       tmp_reg = ath9k_hw_reverse_bits(new_bias, 3);
-
-       ath_print(common, ATH_DBG_CONFIG,
-                 "Force rf_pwd_icsyndiv to %1d on %4d\n",
-                 new_bias, synth_freq);
-
-       /* swizzle rf_pwd_icsyndiv */
-       ath9k_phy_modify_rx_buffer(ah->analogBank6Data, tmp_reg, 3, 181, 3);
-
-       /* write Bank 6 with new params */
-       REG_WRITE_RF_ARRAY(&ah->iniBank6, ah->analogBank6Data, reg_writes);
-}
-
-/**
- * ath9k_hw_set_channel - tune to a channel on the external AR2133/AR5133 radios
- * @ah: atheros hardware stucture
- * @chan:
- *
- * For the external AR2133/AR5133 radios, takes the MHz channel value and set
- * the channel value. Assumes writes enabled to analog bus and bank6 register
- * cache in ah->analogBank6Data.
- */
-int ath9k_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan)
-{
-       struct ath_common *common = ath9k_hw_common(ah);
-       u32 channelSel = 0;
-       u32 bModeSynth = 0;
-       u32 aModeRefSel = 0;
-       u32 reg32 = 0;
-       u16 freq;
-       struct chan_centers centers;
-
-       ath9k_hw_get_channel_centers(ah, chan, &centers);
-       freq = centers.synth_center;
-
-       if (freq < 4800) {
-               u32 txctl;
-
-               if (((freq - 2192) % 5) == 0) {
-                       channelSel = ((freq - 672) * 2 - 3040) / 10;
-                       bModeSynth = 0;
-               } else if (((freq - 2224) % 5) == 0) {
-                       channelSel = ((freq - 704) * 2 - 3040) / 10;
-                       bModeSynth = 1;
-               } else {
-                       ath_print(common, ATH_DBG_FATAL,
-                                 "Invalid channel %u MHz\n", freq);
-                       return -EINVAL;
-               }
-
-               channelSel = (channelSel << 2) & 0xff;
-               channelSel = ath9k_hw_reverse_bits(channelSel, 8);
-
-               txctl = REG_READ(ah, AR_PHY_CCK_TX_CTRL);
-               if (freq == 2484) {
-
-                       REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
-                                 txctl | AR_PHY_CCK_TX_CTRL_JAPAN);
-               } else {
-                       REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
-                                 txctl & ~AR_PHY_CCK_TX_CTRL_JAPAN);
-               }
-
-       } else if ((freq % 20) == 0 && freq >= 5120) {
-               channelSel =
-                   ath9k_hw_reverse_bits(((freq - 4800) / 20 << 2), 8);
-               aModeRefSel = ath9k_hw_reverse_bits(1, 2);
-       } else if ((freq % 10) == 0) {
-               channelSel =
-                   ath9k_hw_reverse_bits(((freq - 4800) / 10 << 1), 8);
-               if (AR_SREV_9100(ah) || AR_SREV_9160_10_OR_LATER(ah))
-                       aModeRefSel = ath9k_hw_reverse_bits(2, 2);
-               else
-                       aModeRefSel = ath9k_hw_reverse_bits(1, 2);
-       } else if ((freq % 5) == 0) {
-               channelSel = ath9k_hw_reverse_bits((freq - 4800) / 5, 8);
-               aModeRefSel = ath9k_hw_reverse_bits(1, 2);
-       } else {
-               ath_print(common, ATH_DBG_FATAL,
-                         "Invalid channel %u MHz\n", freq);
-               return -EINVAL;
-       }
-
-       ath9k_hw_force_bias(ah, freq);
-
-       reg32 =
-           (channelSel << 8) | (aModeRefSel << 2) | (bModeSynth << 1) |
-           (1 << 5) | 0x1;
-
-       REG_WRITE(ah, AR_PHY(0x37), reg32);
-
-       ah->curchan = chan;
-       ah->curchan_rad_index = -1;
-
-       return 0;
-}
-
-/**
- * ath9k_hw_spur_mitigate - convert baseband spur frequency for external radios
- * @ah: atheros hardware structure
- * @chan:
- *
- * For non single-chip solutions. Converts to baseband spur frequency given the
- * input channel frequency and compute register settings below.
- */
-void ath9k_hw_spur_mitigate(struct ath_hw *ah, struct ath9k_channel *chan)
-{
-       int bb_spur = AR_NO_SPUR;
-       int bin, cur_bin;
-       int spur_freq_sd;
-       int spur_delta_phase;
-       int denominator;
-       int upper, lower, cur_vit_mask;
-       int tmp, new;
-       int i;
-       int pilot_mask_reg[4] = { AR_PHY_TIMING7, AR_PHY_TIMING8,
-                         AR_PHY_PILOT_MASK_01_30, AR_PHY_PILOT_MASK_31_60
-       };
-       int chan_mask_reg[4] = { AR_PHY_TIMING9, AR_PHY_TIMING10,
-                        AR_PHY_CHANNEL_MASK_01_30, AR_PHY_CHANNEL_MASK_31_60
-       };
-       int inc[4] = { 0, 100, 0, 0 };
-
-       int8_t mask_m[123];
-       int8_t mask_p[123];
-       int8_t mask_amt;
-       int tmp_mask;
-       int cur_bb_spur;
-       bool is2GHz = IS_CHAN_2GHZ(chan);
-
-       memset(&mask_m, 0, sizeof(int8_t) * 123);
-       memset(&mask_p, 0, sizeof(int8_t) * 123);
-
-       for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
-               cur_bb_spur = ah->eep_ops->get_spur_channel(ah, i, is2GHz);
-               if (AR_NO_SPUR == cur_bb_spur)
-                       break;
-               cur_bb_spur = cur_bb_spur - (chan->channel * 10);
-               if ((cur_bb_spur > -95) && (cur_bb_spur < 95)) {
-                       bb_spur = cur_bb_spur;
-                       break;
-               }
-       }
-
-       if (AR_NO_SPUR == bb_spur)
-               return;
-
-       bin = bb_spur * 32;
-
-       tmp = REG_READ(ah, AR_PHY_TIMING_CTRL4(0));
-       new = tmp | (AR_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI |
-                    AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER |
-                    AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK |
-                    AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK);
-
-       REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0), new);
-
-       new = (AR_PHY_SPUR_REG_MASK_RATE_CNTL |
-              AR_PHY_SPUR_REG_ENABLE_MASK_PPM |
-              AR_PHY_SPUR_REG_MASK_RATE_SELECT |
-              AR_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI |
-              SM(SPUR_RSSI_THRESH, AR_PHY_SPUR_REG_SPUR_RSSI_THRESH));
-       REG_WRITE(ah, AR_PHY_SPUR_REG, new);
-
-       spur_delta_phase = ((bb_spur * 524288) / 100) &
-               AR_PHY_TIMING11_SPUR_DELTA_PHASE;
-
-       denominator = IS_CHAN_2GHZ(chan) ? 440 : 400;
-       spur_freq_sd = ((bb_spur * 2048) / denominator) & 0x3ff;
-
-       new = (AR_PHY_TIMING11_USE_SPUR_IN_AGC |
-              SM(spur_freq_sd, AR_PHY_TIMING11_SPUR_FREQ_SD) |
-              SM(spur_delta_phase, AR_PHY_TIMING11_SPUR_DELTA_PHASE));
-       REG_WRITE(ah, AR_PHY_TIMING11, new);
-
-       cur_bin = -6000;
-       upper = bin + 100;
-       lower = bin - 100;
-
-       for (i = 0; i < 4; i++) {
-               int pilot_mask = 0;
-               int chan_mask = 0;
-               int bp = 0;
-               for (bp = 0; bp < 30; bp++) {
-                       if ((cur_bin > lower) && (cur_bin < upper)) {
-                               pilot_mask = pilot_mask | 0x1 << bp;
-                               chan_mask = chan_mask | 0x1 << bp;
-                       }
-                       cur_bin += 100;
-               }
-               cur_bin += inc[i];
-               REG_WRITE(ah, pilot_mask_reg[i], pilot_mask);
-               REG_WRITE(ah, chan_mask_reg[i], chan_mask);
-       }
-
-       cur_vit_mask = 6100;
-       upper = bin + 120;
-       lower = bin - 120;
-
-       for (i = 0; i < 123; i++) {
-               if ((cur_vit_mask > lower) && (cur_vit_mask < upper)) {
-
-                       /* workaround for gcc bug #37014 */
-                       volatile int tmp_v = abs(cur_vit_mask - bin);
-
-                       if (tmp_v < 75)
-                               mask_amt = 1;
-                       else
-                               mask_amt = 0;
-                       if (cur_vit_mask < 0)
-                               mask_m[abs(cur_vit_mask / 100)] = mask_amt;
-                       else
-                               mask_p[cur_vit_mask / 100] = mask_amt;
-               }
-               cur_vit_mask -= 100;
-       }
-
-       tmp_mask = (mask_m[46] << 30) | (mask_m[47] << 28)
-               | (mask_m[48] << 26) | (mask_m[49] << 24)
-               | (mask_m[50] << 22) | (mask_m[51] << 20)
-               | (mask_m[52] << 18) | (mask_m[53] << 16)
-               | (mask_m[54] << 14) | (mask_m[55] << 12)
-               | (mask_m[56] << 10) | (mask_m[57] << 8)
-               | (mask_m[58] << 6) | (mask_m[59] << 4)
-               | (mask_m[60] << 2) | (mask_m[61] << 0);
-       REG_WRITE(ah, AR_PHY_BIN_MASK_1, tmp_mask);
-       REG_WRITE(ah, AR_PHY_VIT_MASK2_M_46_61, tmp_mask);
-
-       tmp_mask = (mask_m[31] << 28)
-               | (mask_m[32] << 26) | (mask_m[33] << 24)
-               | (mask_m[34] << 22) | (mask_m[35] << 20)
-               | (mask_m[36] << 18) | (mask_m[37] << 16)
-               | (mask_m[48] << 14) | (mask_m[39] << 12)
-               | (mask_m[40] << 10) | (mask_m[41] << 8)
-               | (mask_m[42] << 6) | (mask_m[43] << 4)
-               | (mask_m[44] << 2) | (mask_m[45] << 0);
-       REG_WRITE(ah, AR_PHY_BIN_MASK_2, tmp_mask);
-       REG_WRITE(ah, AR_PHY_MASK2_M_31_45, tmp_mask);
-
-       tmp_mask = (mask_m[16] << 30) | (mask_m[16] << 28)
-               | (mask_m[18] << 26) | (mask_m[18] << 24)
-               | (mask_m[20] << 22) | (mask_m[20] << 20)
-               | (mask_m[22] << 18) | (mask_m[22] << 16)
-               | (mask_m[24] << 14) | (mask_m[24] << 12)
-               | (mask_m[25] << 10) | (mask_m[26] << 8)
-               | (mask_m[27] << 6) | (mask_m[28] << 4)
-               | (mask_m[29] << 2) | (mask_m[30] << 0);
-       REG_WRITE(ah, AR_PHY_BIN_MASK_3, tmp_mask);
-       REG_WRITE(ah, AR_PHY_MASK2_M_16_30, tmp_mask);
-
-       tmp_mask = (mask_m[0] << 30) | (mask_m[1] << 28)
-               | (mask_m[2] << 26) | (mask_m[3] << 24)
-               | (mask_m[4] << 22) | (mask_m[5] << 20)
-               | (mask_m[6] << 18) | (mask_m[7] << 16)
-               | (mask_m[8] << 14) | (mask_m[9] << 12)
-               | (mask_m[10] << 10) | (mask_m[11] << 8)
-               | (mask_m[12] << 6) | (mask_m[13] << 4)
-               | (mask_m[14] << 2) | (mask_m[15] << 0);
-       REG_WRITE(ah, AR_PHY_MASK_CTL, tmp_mask);
-       REG_WRITE(ah, AR_PHY_MASK2_M_00_15, tmp_mask);
-
-       tmp_mask = (mask_p[15] << 28)
-               | (mask_p[14] << 26) | (mask_p[13] << 24)
-               | (mask_p[12] << 22) | (mask_p[11] << 20)
-               | (mask_p[10] << 18) | (mask_p[9] << 16)
-               | (mask_p[8] << 14) | (mask_p[7] << 12)
-               | (mask_p[6] << 10) | (mask_p[5] << 8)
-               | (mask_p[4] << 6) | (mask_p[3] << 4)
-               | (mask_p[2] << 2) | (mask_p[1] << 0);
-       REG_WRITE(ah, AR_PHY_BIN_MASK2_1, tmp_mask);
-       REG_WRITE(ah, AR_PHY_MASK2_P_15_01, tmp_mask);
-
-       tmp_mask = (mask_p[30] << 28)
-               | (mask_p[29] << 26) | (mask_p[28] << 24)
-               | (mask_p[27] << 22) | (mask_p[26] << 20)
-               | (mask_p[25] << 18) | (mask_p[24] << 16)
-               | (mask_p[23] << 14) | (mask_p[22] << 12)
-               | (mask_p[21] << 10) | (mask_p[20] << 8)
-               | (mask_p[19] << 6) | (mask_p[18] << 4)
-               | (mask_p[17] << 2) | (mask_p[16] << 0);
-       REG_WRITE(ah, AR_PHY_BIN_MASK2_2, tmp_mask);
-       REG_WRITE(ah, AR_PHY_MASK2_P_30_16, tmp_mask);
-
-       tmp_mask = (mask_p[45] << 28)
-               | (mask_p[44] << 26) | (mask_p[43] << 24)
-               | (mask_p[42] << 22) | (mask_p[41] << 20)
-               | (mask_p[40] << 18) | (mask_p[39] << 16)
-               | (mask_p[38] << 14) | (mask_p[37] << 12)
-               | (mask_p[36] << 10) | (mask_p[35] << 8)
-               | (mask_p[34] << 6) | (mask_p[33] << 4)
-               | (mask_p[32] << 2) | (mask_p[31] << 0);
-       REG_WRITE(ah, AR_PHY_BIN_MASK2_3, tmp_mask);
-       REG_WRITE(ah, AR_PHY_MASK2_P_45_31, tmp_mask);
-
-       tmp_mask = (mask_p[61] << 30) | (mask_p[60] << 28)
-               | (mask_p[59] << 26) | (mask_p[58] << 24)
-               | (mask_p[57] << 22) | (mask_p[56] << 20)
-               | (mask_p[55] << 18) | (mask_p[54] << 16)
-               | (mask_p[53] << 14) | (mask_p[52] << 12)
-               | (mask_p[51] << 10) | (mask_p[50] << 8)
-               | (mask_p[49] << 6) | (mask_p[48] << 4)
-               | (mask_p[47] << 2) | (mask_p[46] << 0);
-       REG_WRITE(ah, AR_PHY_BIN_MASK2_4, tmp_mask);
-       REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask);
-}
-
-/**
- * ath9k_hw_rf_alloc_ext_banks - allocates banks for external radio programming
- * @ah: atheros hardware structure
- *
- * Only required for older devices with external AR2133/AR5133 radios.
- */
-int ath9k_hw_rf_alloc_ext_banks(struct ath_hw *ah)
-{
-#define ATH_ALLOC_BANK(bank, size) do { \
-               bank = kzalloc((sizeof(u32) * size), GFP_KERNEL); \
-               if (!bank) { \
-                       ath_print(common, ATH_DBG_FATAL, \
-                                 "Cannot allocate RF banks\n"); \
-                       return -ENOMEM; \
-               } \
-       } while (0);
-
-       struct ath_common *common = ath9k_hw_common(ah);
-
-       BUG_ON(AR_SREV_9280_10_OR_LATER(ah));
-
-       ATH_ALLOC_BANK(ah->analogBank0Data, ah->iniBank0.ia_rows);
-       ATH_ALLOC_BANK(ah->analogBank1Data, ah->iniBank1.ia_rows);
-       ATH_ALLOC_BANK(ah->analogBank2Data, ah->iniBank2.ia_rows);
-       ATH_ALLOC_BANK(ah->analogBank3Data, ah->iniBank3.ia_rows);
-       ATH_ALLOC_BANK(ah->analogBank6Data, ah->iniBank6.ia_rows);
-       ATH_ALLOC_BANK(ah->analogBank6TPCData, ah->iniBank6TPC.ia_rows);
-       ATH_ALLOC_BANK(ah->analogBank7Data, ah->iniBank7.ia_rows);
-       ATH_ALLOC_BANK(ah->addac5416_21,
-                      ah->iniAddac.ia_rows * ah->iniAddac.ia_columns);
-       ATH_ALLOC_BANK(ah->bank6Temp, ah->iniBank6.ia_rows);
-
-       return 0;
-#undef ATH_ALLOC_BANK
-}
-
-
-/**
- * ath9k_hw_rf_free_ext_banks - Free memory for analog bank scratch buffers
- * @ah: atheros hardware struture
- * For the external AR2133/AR5133 radios banks.
- */
-void
-ath9k_hw_rf_free_ext_banks(struct ath_hw *ah)
-{
-#define ATH_FREE_BANK(bank) do { \
-               kfree(bank); \
-               bank = NULL; \
-       } while (0);
-
-       BUG_ON(AR_SREV_9280_10_OR_LATER(ah));
-
-       ATH_FREE_BANK(ah->analogBank0Data);
-       ATH_FREE_BANK(ah->analogBank1Data);
-       ATH_FREE_BANK(ah->analogBank2Data);
-       ATH_FREE_BANK(ah->analogBank3Data);
-       ATH_FREE_BANK(ah->analogBank6Data);
-       ATH_FREE_BANK(ah->analogBank6TPCData);
-       ATH_FREE_BANK(ah->analogBank7Data);
-       ATH_FREE_BANK(ah->addac5416_21);
-       ATH_FREE_BANK(ah->bank6Temp);
-
-#undef ATH_FREE_BANK
-}
-
-/* *
- * ath9k_hw_set_rf_regs - programs rf registers based on EEPROM
- * @ah: atheros hardware structure
- * @chan:
- * @modesIndex:
- *
- * Used for the external AR2133/AR5133 radios.
- *
- * Reads the EEPROM header info from the device structure and programs
- * all rf registers. This routine requires access to the analog
- * rf device. This is not required for single-chip devices.
- */
-bool ath9k_hw_set_rf_regs(struct ath_hw *ah, struct ath9k_channel *chan,
-                         u16 modesIndex)
-{
-       u32 eepMinorRev;
-       u32 ob5GHz = 0, db5GHz = 0;
-       u32 ob2GHz = 0, db2GHz = 0;
-       int regWrites = 0;
-
-       /*
-        * Software does not need to program bank data
-        * for single chip devices, that is AR9280 or anything
-        * after that.
-        */
-       if (AR_SREV_9280_10_OR_LATER(ah))
-               return true;
-
-       /* Setup rf parameters */
-       eepMinorRev = ah->eep_ops->get_eeprom(ah, EEP_MINOR_REV);
-
-       /* Setup Bank 0 Write */
-       RF_BANK_SETUP(ah->analogBank0Data, &ah->iniBank0, 1);
-
-       /* Setup Bank 1 Write */
-       RF_BANK_SETUP(ah->analogBank1Data, &ah->iniBank1, 1);
-
-       /* Setup Bank 2 Write */
-       RF_BANK_SETUP(ah->analogBank2Data, &ah->iniBank2, 1);
-
-       /* Setup Bank 6 Write */
-       RF_BANK_SETUP(ah->analogBank3Data, &ah->iniBank3,
-                     modesIndex);
-       {
-               int i;
-               for (i = 0; i < ah->iniBank6TPC.ia_rows; i++) {
-                       ah->analogBank6Data[i] =
-                           INI_RA(&ah->iniBank6TPC, i, modesIndex);
-               }
-       }
-
-       /* Only the 5 or 2 GHz OB/DB need to be set for a mode */
-       if (eepMinorRev >= 2) {
-               if (IS_CHAN_2GHZ(chan)) {
-                       ob2GHz = ah->eep_ops->get_eeprom(ah, EEP_OB_2);
-                       db2GHz = ah->eep_ops->get_eeprom(ah, EEP_DB_2);
-                       ath9k_phy_modify_rx_buffer(ah->analogBank6Data,
-                                                  ob2GHz, 3, 197, 0);
-                       ath9k_phy_modify_rx_buffer(ah->analogBank6Data,
-                                                  db2GHz, 3, 194, 0);
-               } else {
-                       ob5GHz = ah->eep_ops->get_eeprom(ah, EEP_OB_5);
-                       db5GHz = ah->eep_ops->get_eeprom(ah, EEP_DB_5);
-                       ath9k_phy_modify_rx_buffer(ah->analogBank6Data,
-                                                  ob5GHz, 3, 203, 0);
-                       ath9k_phy_modify_rx_buffer(ah->analogBank6Data,
-                                                  db5GHz, 3, 200, 0);
-               }
-       }
-
-       /* Setup Bank 7 Setup */
-       RF_BANK_SETUP(ah->analogBank7Data, &ah->iniBank7, 1);
-
-       /* Write Analog registers */
-       REG_WRITE_RF_ARRAY(&ah->iniBank0, ah->analogBank0Data,
-                          regWrites);
-       REG_WRITE_RF_ARRAY(&ah->iniBank1, ah->analogBank1Data,
-                          regWrites);
-       REG_WRITE_RF_ARRAY(&ah->iniBank2, ah->analogBank2Data,
-                          regWrites);
-       REG_WRITE_RF_ARRAY(&ah->iniBank3, ah->analogBank3Data,
-                          regWrites);
-       REG_WRITE_RF_ARRAY(&ah->iniBank6TPC, ah->analogBank6Data,
-                          regWrites);
-       REG_WRITE_RF_ARRAY(&ah->iniBank7, ah->analogBank7Data,
-                          regWrites);
-
-       return true;
-}
index 0132e4c9a9f9eca0a99b59a6ac87633b0534b979..e724c2c1ae2a320eb5e17e7c4d419a346c5b1bdf 100644 (file)
 #ifndef PHY_H
 #define PHY_H
 
-/* Common between single chip and non single-chip solutions */
-void ath9k_hw_write_regs(struct ath_hw *ah, u32 freqIndex, int regWrites);
-
-/* Single chip radio settings */
-int ath9k_hw_ar9280_set_channel(struct ath_hw *ah, struct ath9k_channel *chan);
-void ath9k_hw_9280_spur_mitigate(struct ath_hw *ah, struct ath9k_channel *chan);
-
-/* Routines below are for non single-chip solutions */
-int ath9k_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan);
-void ath9k_hw_spur_mitigate(struct ath_hw *ah, struct ath9k_channel *chan);
-
-int ath9k_hw_rf_alloc_ext_banks(struct ath_hw *ah);
-void ath9k_hw_rf_free_ext_banks(struct ath_hw *ah);
-
-bool ath9k_hw_set_rf_regs(struct ath_hw *ah,
-                         struct ath9k_channel *chan,
-                         u16 modesIndex);
+#define CHANSEL_DIV            15
+#define CHANSEL_2G(_freq)      (((_freq) * 0x10000) / CHANSEL_DIV)
+#define CHANSEL_5G(_freq)      (((_freq) * 0x8000) / CHANSEL_DIV)
 
 #define AR_PHY_BASE     0x9800
 #define AR_PHY(_n)      (AR_PHY_BASE + ((_n)<<2))
 
-#define AR_PHY_TEST             0x9800
-#define PHY_AGC_CLR             0x10000000
-#define RFSILENT_BB             0x00002000
-
-#define AR_PHY_TURBO                0x9804
-#define AR_PHY_FC_TURBO_MODE        0x00000001
-#define AR_PHY_FC_TURBO_SHORT       0x00000002
-#define AR_PHY_FC_DYN2040_EN        0x00000004
-#define AR_PHY_FC_DYN2040_PRI_ONLY  0x00000008
-#define AR_PHY_FC_DYN2040_PRI_CH    0x00000010
-/* For 25 MHz channel spacing -- not used but supported by hw */
-#define AR_PHY_FC_DYN2040_EXT_CH    0x00000020
-#define AR_PHY_FC_HT_EN             0x00000040
-#define AR_PHY_FC_SHORT_GI_40       0x00000080
-#define AR_PHY_FC_WALSH             0x00000100
-#define AR_PHY_FC_SINGLE_HT_LTF1    0x00000200
-#define AR_PHY_FC_ENABLE_DAC_FIFO   0x00000800
-
-#define AR_PHY_TEST2               0x9808
-
-#define AR_PHY_TIMING2           0x9810
-#define AR_PHY_TIMING3           0x9814
-#define AR_PHY_TIMING3_DSC_MAN   0xFFFE0000
-#define AR_PHY_TIMING3_DSC_MAN_S 17
-#define AR_PHY_TIMING3_DSC_EXP   0x0001E000
-#define AR_PHY_TIMING3_DSC_EXP_S 13
-
-#define AR_PHY_CHIP_ID            0x9818
-#define AR_PHY_CHIP_ID_REV_0      0x80
-#define AR_PHY_CHIP_ID_REV_1      0x81
-#define AR_PHY_CHIP_ID_9160_REV_0 0xb0
-
-#define AR_PHY_ACTIVE       0x981C
-#define AR_PHY_ACTIVE_EN    0x00000001
-#define AR_PHY_ACTIVE_DIS   0x00000000
-
-#define AR_PHY_RF_CTL2             0x9824
-#define AR_PHY_TX_END_DATA_START   0x000000FF
-#define AR_PHY_TX_END_DATA_START_S 0
-#define AR_PHY_TX_END_PA_ON        0x0000FF00
-#define AR_PHY_TX_END_PA_ON_S      8
-
-#define AR_PHY_RF_CTL3                  0x9828
-#define AR_PHY_TX_END_TO_A2_RX_ON       0x00FF0000
-#define AR_PHY_TX_END_TO_A2_RX_ON_S     16
-
-#define AR_PHY_ADC_CTL                  0x982C
-#define AR_PHY_ADC_CTL_OFF_INBUFGAIN    0x00000003
-#define AR_PHY_ADC_CTL_OFF_INBUFGAIN_S  0
-#define AR_PHY_ADC_CTL_OFF_PWDDAC       0x00002000
-#define AR_PHY_ADC_CTL_OFF_PWDBANDGAP   0x00004000
-#define AR_PHY_ADC_CTL_OFF_PWDADC       0x00008000
-#define AR_PHY_ADC_CTL_ON_INBUFGAIN     0x00030000
-#define AR_PHY_ADC_CTL_ON_INBUFGAIN_S   16
-
-#define AR_PHY_ADC_SERIAL_CTL       0x9830
-#define AR_PHY_SEL_INTERNAL_ADDAC   0x00000000
-#define AR_PHY_SEL_EXTERNAL_RADIO   0x00000001
-
-#define AR_PHY_RF_CTL4                    0x9834
-#define AR_PHY_RF_CTL4_TX_END_XPAB_OFF    0xFF000000
-#define AR_PHY_RF_CTL4_TX_END_XPAB_OFF_S  24
-#define AR_PHY_RF_CTL4_TX_END_XPAA_OFF    0x00FF0000
-#define AR_PHY_RF_CTL4_TX_END_XPAA_OFF_S  16
-#define AR_PHY_RF_CTL4_FRAME_XPAB_ON      0x0000FF00
-#define AR_PHY_RF_CTL4_FRAME_XPAB_ON_S    8
-#define AR_PHY_RF_CTL4_FRAME_XPAA_ON      0x000000FF
-#define AR_PHY_RF_CTL4_FRAME_XPAA_ON_S    0
-
-#define AR_PHY_TSTDAC_CONST               0x983c
-
-#define AR_PHY_SETTLING          0x9844
-#define AR_PHY_SETTLING_SWITCH   0x00003F80
-#define AR_PHY_SETTLING_SWITCH_S 7
-
-#define AR_PHY_RXGAIN                   0x9848
-#define AR_PHY_RXGAIN_TXRX_ATTEN        0x0003F000
-#define AR_PHY_RXGAIN_TXRX_ATTEN_S      12
-#define AR_PHY_RXGAIN_TXRX_RF_MAX       0x007C0000
-#define AR_PHY_RXGAIN_TXRX_RF_MAX_S     18
-#define AR9280_PHY_RXGAIN_TXRX_ATTEN    0x00003F80
-#define AR9280_PHY_RXGAIN_TXRX_ATTEN_S  7
-#define AR9280_PHY_RXGAIN_TXRX_MARGIN   0x001FC000
-#define AR9280_PHY_RXGAIN_TXRX_MARGIN_S 14
-
-#define AR_PHY_DESIRED_SZ           0x9850
-#define AR_PHY_DESIRED_SZ_ADC       0x000000FF
-#define AR_PHY_DESIRED_SZ_ADC_S     0
-#define AR_PHY_DESIRED_SZ_PGA       0x0000FF00
-#define AR_PHY_DESIRED_SZ_PGA_S     8
-#define AR_PHY_DESIRED_SZ_TOT_DES   0x0FF00000
-#define AR_PHY_DESIRED_SZ_TOT_DES_S 20
-
-#define AR_PHY_FIND_SIG           0x9858
-#define AR_PHY_FIND_SIG_FIRSTEP   0x0003F000
-#define AR_PHY_FIND_SIG_FIRSTEP_S 12
-#define AR_PHY_FIND_SIG_FIRPWR    0x03FC0000
-#define AR_PHY_FIND_SIG_FIRPWR_S  18
-
-#define AR_PHY_AGC_CTL1                  0x985C
-#define AR_PHY_AGC_CTL1_COARSE_LOW       0x00007F80
-#define AR_PHY_AGC_CTL1_COARSE_LOW_S     7
-#define AR_PHY_AGC_CTL1_COARSE_HIGH      0x003F8000
-#define AR_PHY_AGC_CTL1_COARSE_HIGH_S    15
-
-#define AR_PHY_AGC_CONTROL               0x9860
-#define AR_PHY_AGC_CONTROL_CAL           0x00000001
-#define AR_PHY_AGC_CONTROL_NF            0x00000002
-#define AR_PHY_AGC_CONTROL_ENABLE_NF     0x00008000
-#define AR_PHY_AGC_CONTROL_FLTR_CAL      0x00010000
-#define AR_PHY_AGC_CONTROL_NO_UPDATE_NF  0x00020000
-
-#define AR_PHY_CCA                  0x9864
-#define AR_PHY_MINCCA_PWR           0x0FF80000
-#define AR_PHY_MINCCA_PWR_S         19
-#define AR_PHY_CCA_THRESH62         0x0007F000
-#define AR_PHY_CCA_THRESH62_S       12
-#define AR9280_PHY_MINCCA_PWR       0x1FF00000
-#define AR9280_PHY_MINCCA_PWR_S     20
-#define AR9280_PHY_CCA_THRESH62     0x000FF000
-#define AR9280_PHY_CCA_THRESH62_S   12
-
-#define AR_PHY_SFCORR_LOW                    0x986C
-#define AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW  0x00000001
-#define AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW    0x00003F00
-#define AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW_S  8
-#define AR_PHY_SFCORR_LOW_M1_THRESH_LOW      0x001FC000
-#define AR_PHY_SFCORR_LOW_M1_THRESH_LOW_S    14
-#define AR_PHY_SFCORR_LOW_M2_THRESH_LOW      0x0FE00000
-#define AR_PHY_SFCORR_LOW_M2_THRESH_LOW_S    21
-
-#define AR_PHY_SFCORR                0x9868
-#define AR_PHY_SFCORR_M2COUNT_THR    0x0000001F
-#define AR_PHY_SFCORR_M2COUNT_THR_S  0
-#define AR_PHY_SFCORR_M1_THRESH      0x00FE0000
-#define AR_PHY_SFCORR_M1_THRESH_S    17
-#define AR_PHY_SFCORR_M2_THRESH      0x7F000000
-#define AR_PHY_SFCORR_M2_THRESH_S    24
-
-#define AR_PHY_SLEEP_CTR_CONTROL    0x9870
-#define AR_PHY_SLEEP_CTR_LIMIT      0x9874
-#define AR_PHY_SYNTH_CONTROL        0x9874
-#define AR_PHY_SLEEP_SCAL           0x9878
-
-#define AR_PHY_PLL_CTL          0x987c
-#define AR_PHY_PLL_CTL_40       0xaa
-#define AR_PHY_PLL_CTL_40_5413  0x04
-#define AR_PHY_PLL_CTL_44       0xab
-#define AR_PHY_PLL_CTL_44_2133  0xeb
-#define AR_PHY_PLL_CTL_40_2133  0xea
-
-#define AR_PHY_SPECTRAL_SCAN                   0x9910  /* AR9280 spectral scan configuration register */
-#define        AR_PHY_SPECTRAL_SCAN_ENABLE             0x1
-#define AR_PHY_SPECTRAL_SCAN_ENA               0x00000001  /* Enable spectral scan, reg 68, bit 0 */
-#define AR_PHY_SPECTRAL_SCAN_ENA_S             0  /* Enable spectral scan, reg 68, bit 0 */
-#define AR_PHY_SPECTRAL_SCAN_ACTIVE            0x00000002  /* Activate spectral scan reg 68, bit 1*/
-#define AR_PHY_SPECTRAL_SCAN_ACTIVE_S          1  /* Activate spectral scan reg 68, bit 1*/
-#define AR_PHY_SPECTRAL_SCAN_FFT_PERIOD                0x000000F0  /* Interval for FFT reports, reg 68, bits 4-7*/
-#define AR_PHY_SPECTRAL_SCAN_FFT_PERIOD_S      4
-#define AR_PHY_SPECTRAL_SCAN_PERIOD            0x0000FF00  /* Interval for FFT reports, reg 68, bits 8-15*/
-#define AR_PHY_SPECTRAL_SCAN_PERIOD_S          8
-#define AR_PHY_SPECTRAL_SCAN_COUNT             0x00FF0000  /* Number of reports, reg 68, bits 16-23*/
-#define AR_PHY_SPECTRAL_SCAN_COUNT_S           16
-#define AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT      0x01000000  /* Short repeat, reg 68, bit 24*/
-#define AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT_S    24  /* Short repeat, reg 68, bit 24*/
-
-#define AR_PHY_RX_DELAY           0x9914
-#define AR_PHY_SEARCH_START_DELAY 0x9918
-#define AR_PHY_RX_DELAY_DELAY     0x00003FFF
-
-#define AR_PHY_TIMING_CTRL4(_i)     (0x9920 + ((_i) << 12))
-#define AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF 0x01F
-#define AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF_S   0
-#define AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF 0x7E0
-#define AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF_S   5
-#define AR_PHY_TIMING_CTRL4_IQCORR_ENABLE   0x800
-#define AR_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX 0xF000
-#define AR_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX_S   12
-#define AR_PHY_TIMING_CTRL4_DO_CAL    0x10000
-
-#define AR_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI   0x80000000
-#define        AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER  0x40000000
-#define        AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK    0x20000000
-#define        AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK   0x10000000
-
-#define AR_PHY_TIMING5               0x9924
-#define AR_PHY_TIMING5_CYCPWR_THR1   0x000000FE
-#define AR_PHY_TIMING5_CYCPWR_THR1_S 1
-
-#define AR_PHY_POWER_TX_RATE1               0x9934
-#define AR_PHY_POWER_TX_RATE2               0x9938
-#define AR_PHY_POWER_TX_RATE_MAX            0x993c
-#define AR_PHY_POWER_TX_RATE_MAX_TPC_ENABLE 0x00000040
-
-#define AR_PHY_FRAME_CTL            0x9944
-#define AR_PHY_FRAME_CTL_TX_CLIP    0x00000038
-#define AR_PHY_FRAME_CTL_TX_CLIP_S  3
-
-#define AR_PHY_TXPWRADJ                   0x994C
-#define AR_PHY_TXPWRADJ_CCK_GAIN_DELTA    0x00000FC0
-#define AR_PHY_TXPWRADJ_CCK_GAIN_DELTA_S  6
-#define AR_PHY_TXPWRADJ_CCK_PCDAC_INDEX   0x00FC0000
-#define AR_PHY_TXPWRADJ_CCK_PCDAC_INDEX_S 18
-
-#define AR_PHY_RADAR_EXT      0x9940
-#define AR_PHY_RADAR_EXT_ENA  0x00004000
-
-#define AR_PHY_RADAR_0          0x9954
-#define AR_PHY_RADAR_0_ENA      0x00000001
-#define AR_PHY_RADAR_0_FFT_ENA  0x80000000
-#define AR_PHY_RADAR_0_INBAND   0x0000003e
-#define AR_PHY_RADAR_0_INBAND_S 1
-#define AR_PHY_RADAR_0_PRSSI    0x00000FC0
-#define AR_PHY_RADAR_0_PRSSI_S  6
-#define AR_PHY_RADAR_0_HEIGHT   0x0003F000
-#define AR_PHY_RADAR_0_HEIGHT_S 12
-#define AR_PHY_RADAR_0_RRSSI    0x00FC0000
-#define AR_PHY_RADAR_0_RRSSI_S  18
-#define AR_PHY_RADAR_0_FIRPWR   0x7F000000
-#define AR_PHY_RADAR_0_FIRPWR_S 24
-
-#define AR_PHY_RADAR_1                  0x9958
-#define AR_PHY_RADAR_1_RELPWR_ENA       0x00800000
-#define AR_PHY_RADAR_1_USE_FIR128       0x00400000
-#define AR_PHY_RADAR_1_RELPWR_THRESH    0x003F0000
-#define AR_PHY_RADAR_1_RELPWR_THRESH_S  16
-#define AR_PHY_RADAR_1_BLOCK_CHECK      0x00008000
-#define AR_PHY_RADAR_1_MAX_RRSSI        0x00004000
-#define AR_PHY_RADAR_1_RELSTEP_CHECK    0x00002000
-#define AR_PHY_RADAR_1_RELSTEP_THRESH   0x00001F00
-#define AR_PHY_RADAR_1_RELSTEP_THRESH_S 8
-#define AR_PHY_RADAR_1_MAXLEN           0x000000FF
-#define AR_PHY_RADAR_1_MAXLEN_S         0
-
-#define AR_PHY_SWITCH_CHAIN_0     0x9960
-#define AR_PHY_SWITCH_COM         0x9964
-
-#define AR_PHY_SIGMA_DELTA            0x996C
-#define AR_PHY_SIGMA_DELTA_ADC_SEL    0x00000003
-#define AR_PHY_SIGMA_DELTA_ADC_SEL_S  0
-#define AR_PHY_SIGMA_DELTA_FILT2      0x000000F8
-#define AR_PHY_SIGMA_DELTA_FILT2_S    3
-#define AR_PHY_SIGMA_DELTA_FILT1      0x00001F00
-#define AR_PHY_SIGMA_DELTA_FILT1_S    8
-#define AR_PHY_SIGMA_DELTA_ADC_CLIP   0x01FFE000
-#define AR_PHY_SIGMA_DELTA_ADC_CLIP_S 13
-
-#define AR_PHY_RESTART          0x9970
-#define AR_PHY_RESTART_DIV_GC   0x001C0000
-#define AR_PHY_RESTART_DIV_GC_S 18
-
-#define AR_PHY_RFBUS_REQ        0x997C
-#define AR_PHY_RFBUS_REQ_EN     0x00000001
-
-#define        AR_PHY_TIMING7                  0x9980
-#define        AR_PHY_TIMING8                  0x9984
-#define        AR_PHY_TIMING8_PILOT_MASK_2     0x000FFFFF
-#define        AR_PHY_TIMING8_PILOT_MASK_2_S   0
-
-#define        AR_PHY_BIN_MASK2_1      0x9988
-#define        AR_PHY_BIN_MASK2_2      0x998c
-#define        AR_PHY_BIN_MASK2_3      0x9990
-#define        AR_PHY_BIN_MASK2_4      0x9994
-
-#define        AR_PHY_BIN_MASK_1       0x9900
-#define        AR_PHY_BIN_MASK_2       0x9904
-#define        AR_PHY_BIN_MASK_3       0x9908
-
-#define        AR_PHY_MASK_CTL         0x990c
-
-#define        AR_PHY_BIN_MASK2_4_MASK_4       0x00003FFF
-#define        AR_PHY_BIN_MASK2_4_MASK_4_S     0
-
-#define        AR_PHY_TIMING9                  0x9998
-#define        AR_PHY_TIMING10                 0x999c
-#define        AR_PHY_TIMING10_PILOT_MASK_2    0x000FFFFF
-#define        AR_PHY_TIMING10_PILOT_MASK_2_S  0
-
-#define        AR_PHY_TIMING11                         0x99a0
-#define        AR_PHY_TIMING11_SPUR_DELTA_PHASE        0x000FFFFF
-#define        AR_PHY_TIMING11_SPUR_DELTA_PHASE_S      0
-#define        AR_PHY_TIMING11_SPUR_FREQ_SD            0x3FF00000
-#define        AR_PHY_TIMING11_SPUR_FREQ_SD_S          20
-#define AR_PHY_TIMING11_USE_SPUR_IN_AGC                0x40000000
-#define AR_PHY_TIMING11_USE_SPUR_IN_SELFCOR    0x80000000
-
-#define AR_PHY_RX_CHAINMASK     0x99a4
-#define AR_PHY_NEW_ADC_DC_GAIN_CORR(_i) (0x99b4 + ((_i) << 12))
-#define AR_PHY_NEW_ADC_GAIN_CORR_ENABLE 0x40000000
-#define AR_PHY_NEW_ADC_DC_OFFSET_CORR_ENABLE 0x80000000
-
-#define AR_PHY_MULTICHAIN_GAIN_CTL          0x99ac
-#define AR_PHY_9285_ANT_DIV_CTL_ALL         0x7f000000
-#define AR_PHY_9285_ANT_DIV_CTL             0x01000000
-#define AR_PHY_9285_ANT_DIV_CTL_S           24
-#define AR_PHY_9285_ANT_DIV_ALT_LNACONF     0x06000000
-#define AR_PHY_9285_ANT_DIV_ALT_LNACONF_S   25
-#define AR_PHY_9285_ANT_DIV_MAIN_LNACONF    0x18000000
-#define AR_PHY_9285_ANT_DIV_MAIN_LNACONF_S  27
-#define AR_PHY_9285_ANT_DIV_ALT_GAINTB      0x20000000
-#define AR_PHY_9285_ANT_DIV_ALT_GAINTB_S    29
-#define AR_PHY_9285_ANT_DIV_MAIN_GAINTB     0x40000000
-#define AR_PHY_9285_ANT_DIV_MAIN_GAINTB_S   30
-#define AR_PHY_9285_ANT_DIV_LNA1            2
-#define AR_PHY_9285_ANT_DIV_LNA2            1
-#define AR_PHY_9285_ANT_DIV_LNA1_PLUS_LNA2  3
-#define AR_PHY_9285_ANT_DIV_LNA1_MINUS_LNA2 0
-#define AR_PHY_9285_ANT_DIV_GAINTB_0        0
-#define AR_PHY_9285_ANT_DIV_GAINTB_1        1
-
-#define AR_PHY_EXT_CCA0             0x99b8
-#define AR_PHY_EXT_CCA0_THRESH62    0x000000FF
-#define AR_PHY_EXT_CCA0_THRESH62_S  0
-
-#define AR_PHY_EXT_CCA                  0x99bc
-#define AR_PHY_EXT_CCA_CYCPWR_THR1      0x0000FE00
-#define AR_PHY_EXT_CCA_CYCPWR_THR1_S    9
-#define AR_PHY_EXT_CCA_THRESH62         0x007F0000
-#define AR_PHY_EXT_CCA_THRESH62_S       16
-#define AR_PHY_EXT_MINCCA_PWR           0xFF800000
-#define AR_PHY_EXT_MINCCA_PWR_S         23
-#define AR9280_PHY_EXT_MINCCA_PWR       0x01FF0000
-#define AR9280_PHY_EXT_MINCCA_PWR_S     16
-
-#define AR_PHY_SFCORR_EXT                 0x99c0
-#define AR_PHY_SFCORR_EXT_M1_THRESH       0x0000007F
-#define AR_PHY_SFCORR_EXT_M1_THRESH_S     0
-#define AR_PHY_SFCORR_EXT_M2_THRESH       0x00003F80
-#define AR_PHY_SFCORR_EXT_M2_THRESH_S     7
-#define AR_PHY_SFCORR_EXT_M1_THRESH_LOW   0x001FC000
-#define AR_PHY_SFCORR_EXT_M1_THRESH_LOW_S 14
-#define AR_PHY_SFCORR_EXT_M2_THRESH_LOW   0x0FE00000
-#define AR_PHY_SFCORR_EXT_M2_THRESH_LOW_S 21
-#define AR_PHY_SFCORR_SPUR_SUBCHNL_SD_S   28
-
-#define AR_PHY_HALFGI           0x99D0
-#define AR_PHY_HALFGI_DSC_MAN   0x0007FFF0
-#define AR_PHY_HALFGI_DSC_MAN_S 4
-#define AR_PHY_HALFGI_DSC_EXP   0x0000000F
-#define AR_PHY_HALFGI_DSC_EXP_S 0
-
-#define AR_PHY_CHAN_INFO_MEMORY               0x99DC
-#define AR_PHY_CHAN_INFO_MEMORY_CAPTURE_MASK  0x0001
-
-#define AR_PHY_HEAVY_CLIP_ENABLE         0x99E0
-
-#define AR_PHY_HEAVY_CLIP_FACTOR_RIFS    0x99EC
-#define AR_PHY_RIFS_INIT_DELAY         0x03ff0000
-
-#define AR_PHY_M_SLEEP      0x99f0
-#define AR_PHY_REFCLKDLY    0x99f4
-#define AR_PHY_REFCLKPD     0x99f8
-
-#define AR_PHY_CALMODE      0x99f0
-
-#define AR_PHY_CALMODE_IQ           0x00000000
-#define AR_PHY_CALMODE_ADC_GAIN     0x00000001
-#define AR_PHY_CALMODE_ADC_DC_PER   0x00000002
-#define AR_PHY_CALMODE_ADC_DC_INIT  0x00000003
-
-#define AR_PHY_CAL_MEAS_0(_i)     (0x9c10 + ((_i) << 12))
-#define AR_PHY_CAL_MEAS_1(_i)     (0x9c14 + ((_i) << 12))
-#define AR_PHY_CAL_MEAS_2(_i)     (0x9c18 + ((_i) << 12))
-#define AR_PHY_CAL_MEAS_3(_i)     (0x9c1c + ((_i) << 12))
-
-#define AR_PHY_CURRENT_RSSI 0x9c1c
-#define AR9280_PHY_CURRENT_RSSI 0x9c3c
-
-#define AR_PHY_RFBUS_GRANT       0x9C20
-#define AR_PHY_RFBUS_GRANT_EN    0x00000001
-
-#define AR_PHY_CHAN_INFO_GAIN_DIFF             0x9CF4
-#define AR_PHY_CHAN_INFO_GAIN_DIFF_UPPER_LIMIT 320
-
-#define AR_PHY_CHAN_INFO_GAIN          0x9CFC
-
-#define AR_PHY_MODE         0xA200
-#define AR_PHY_MODE_ASYNCFIFO 0x80
-#define AR_PHY_MODE_AR2133  0x08
-#define AR_PHY_MODE_AR5111  0x00
-#define AR_PHY_MODE_AR5112  0x08
-#define AR_PHY_MODE_DYNAMIC 0x04
-#define AR_PHY_MODE_RF2GHZ  0x02
-#define AR_PHY_MODE_RF5GHZ  0x00
-#define AR_PHY_MODE_CCK     0x01
-#define AR_PHY_MODE_OFDM    0x00
-#define AR_PHY_MODE_DYN_CCK_DISABLE 0x100
-
-#define AR_PHY_CCK_TX_CTRL       0xA204
-#define AR_PHY_CCK_TX_CTRL_JAPAN 0x00000010
-#define AR_PHY_CCK_TX_CTRL_TX_DAC_SCALE_CCK         0x0000000C
-#define AR_PHY_CCK_TX_CTRL_TX_DAC_SCALE_CCK_S       2
-
-#define AR_PHY_CCK_DETECT                           0xA208
-#define AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK          0x0000003F
-#define AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK_S        0
-/* [12:6] settling time for antenna switch */
-#define AR_PHY_CCK_DETECT_ANT_SWITCH_TIME           0x00001FC0
-#define AR_PHY_CCK_DETECT_ANT_SWITCH_TIME_S         6
-#define AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV    0x2000
-#define AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV_S  13
-
-#define AR_PHY_GAIN_2GHZ                0xA20C
-#define AR_PHY_GAIN_2GHZ_RXTX_MARGIN    0x00FC0000
-#define AR_PHY_GAIN_2GHZ_RXTX_MARGIN_S  18
-#define AR_PHY_GAIN_2GHZ_BSW_MARGIN     0x00003C00
-#define AR_PHY_GAIN_2GHZ_BSW_MARGIN_S   10
-#define AR_PHY_GAIN_2GHZ_BSW_ATTEN      0x0000001F
-#define AR_PHY_GAIN_2GHZ_BSW_ATTEN_S    0
-
-#define AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN     0x003E0000
-#define AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN_S   17
-#define AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN     0x0001F000
-#define AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN_S   12
-#define AR_PHY_GAIN_2GHZ_XATTEN2_DB         0x00000FC0
-#define AR_PHY_GAIN_2GHZ_XATTEN2_DB_S       6
-#define AR_PHY_GAIN_2GHZ_XATTEN1_DB         0x0000003F
-#define AR_PHY_GAIN_2GHZ_XATTEN1_DB_S       0
-
-#define AR_PHY_CCK_RXCTRL4  0xA21C
-#define AR_PHY_CCK_RXCTRL4_FREQ_EST_SHORT   0x01F80000
-#define AR_PHY_CCK_RXCTRL4_FREQ_EST_SHORT_S 19
-
-#define AR_PHY_DAG_CTRLCCK  0xA228
-#define AR_PHY_DAG_CTRLCCK_EN_RSSI_THR  0x00000200
-#define AR_PHY_DAG_CTRLCCK_RSSI_THR     0x0001FC00
-#define AR_PHY_DAG_CTRLCCK_RSSI_THR_S   10
-
-#define AR_PHY_FORCE_CLKEN_CCK              0xA22C
-#define AR_PHY_FORCE_CLKEN_CCK_MRC_MUX      0x00000040
-
-#define AR_PHY_POWER_TX_RATE3   0xA234
-#define AR_PHY_POWER_TX_RATE4   0xA238
-
-#define AR_PHY_SCRM_SEQ_XR       0xA23C
-#define AR_PHY_HEADER_DETECT_XR  0xA240
-#define AR_PHY_CHIRP_DETECTED_XR 0xA244
-#define AR_PHY_BLUETOOTH         0xA254
-
-#define AR_PHY_TPCRG1   0xA258
-#define AR_PHY_TPCRG1_NUM_PD_GAIN   0x0000c000
-#define AR_PHY_TPCRG1_NUM_PD_GAIN_S 14
-
-#define AR_PHY_TPCRG1_PD_GAIN_1    0x00030000
-#define AR_PHY_TPCRG1_PD_GAIN_1_S  16
-#define AR_PHY_TPCRG1_PD_GAIN_2    0x000C0000
-#define AR_PHY_TPCRG1_PD_GAIN_2_S  18
-#define AR_PHY_TPCRG1_PD_GAIN_3    0x00300000
-#define AR_PHY_TPCRG1_PD_GAIN_3_S  20
-
-#define AR_PHY_TPCRG1_PD_CAL_ENABLE   0x00400000
-#define AR_PHY_TPCRG1_PD_CAL_ENABLE_S 22
-
-#define AR_PHY_TX_PWRCTRL4       0xa264
-#define AR_PHY_TX_PWRCTRL_PD_AVG_VALID     0x00000001
-#define AR_PHY_TX_PWRCTRL_PD_AVG_VALID_S   0
-#define AR_PHY_TX_PWRCTRL_PD_AVG_OUT       0x000001FE
-#define AR_PHY_TX_PWRCTRL_PD_AVG_OUT_S     1
-
-#define AR_PHY_TX_PWRCTRL6_0     0xa270
-#define AR_PHY_TX_PWRCTRL6_1     0xb270
-#define AR_PHY_TX_PWRCTRL_ERR_EST_MODE     0x03000000
-#define AR_PHY_TX_PWRCTRL_ERR_EST_MODE_S   24
-
-#define AR_PHY_TX_PWRCTRL7       0xa274
 #define AR_PHY_TX_PWRCTRL_TX_GAIN_TAB_MAX   0x0007E000
 #define AR_PHY_TX_PWRCTRL_TX_GAIN_TAB_MAX_S 13
-#define AR_PHY_TX_PWRCTRL_INIT_TX_GAIN     0x01F80000
-#define AR_PHY_TX_PWRCTRL_INIT_TX_GAIN_S   19
-
-#define AR_PHY_TX_PWRCTRL9       0xa27C
-#define AR_PHY_TX_DESIRED_SCALE_CCK        0x00007C00
-#define AR_PHY_TX_DESIRED_SCALE_CCK_S      10
-#define AR_PHY_TX_PWRCTRL9_RES_DC_REMOVAL  0x80000000
-#define AR_PHY_TX_PWRCTRL9_RES_DC_REMOVAL_S 31
-
-#define AR_PHY_TX_GAIN_TBL1      0xa300
 #define AR_PHY_TX_GAIN_CLC       0x0000001E
 #define AR_PHY_TX_GAIN_CLC_S     1
 #define AR_PHY_TX_GAIN           0x0007F000
@@ -526,91 +37,6 @@ bool ath9k_hw_set_rf_regs(struct ath_hw *ah,
 #define AR_PHY_CLC_Q0        0x0000ffd0
 #define AR_PHY_CLC_Q0_S      5
 
-#define AR_PHY_CH0_TX_PWRCTRL11  0xa398
-#define AR_PHY_CH1_TX_PWRCTRL11  0xb398
-#define AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP   0x0000FC00
-#define AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP_S 10
-
-#define AR_PHY_VIT_MASK2_M_46_61 0xa3a0
-#define AR_PHY_MASK2_M_31_45     0xa3a4
-#define AR_PHY_MASK2_M_16_30     0xa3a8
-#define AR_PHY_MASK2_M_00_15     0xa3ac
-#define AR_PHY_MASK2_P_15_01     0xa3b8
-#define AR_PHY_MASK2_P_30_16     0xa3bc
-#define AR_PHY_MASK2_P_45_31     0xa3c0
-#define AR_PHY_MASK2_P_61_45     0xa3c4
-#define AR_PHY_SPUR_REG          0x994c
-
-#define AR_PHY_SPUR_REG_MASK_RATE_CNTL       (0xFF << 18)
-#define AR_PHY_SPUR_REG_MASK_RATE_CNTL_S     18
-
-#define AR_PHY_SPUR_REG_ENABLE_MASK_PPM      0x20000
-#define AR_PHY_SPUR_REG_MASK_RATE_SELECT     (0xFF << 9)
-#define AR_PHY_SPUR_REG_MASK_RATE_SELECT_S   9
-#define AR_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI 0x100
-#define AR_PHY_SPUR_REG_SPUR_RSSI_THRESH     0x7F
-#define AR_PHY_SPUR_REG_SPUR_RSSI_THRESH_S   0
-
-#define AR_PHY_PILOT_MASK_01_30   0xa3b0
-#define AR_PHY_PILOT_MASK_31_60   0xa3b4
-
-#define AR_PHY_CHANNEL_MASK_01_30 0x99d4
-#define AR_PHY_CHANNEL_MASK_31_60 0x99d8
-
-#define AR_PHY_ANALOG_SWAP      0xa268
-#define AR_PHY_SWAP_ALT_CHAIN   0x00000040
-
-#define AR_PHY_TPCRG5   0xA26C
-#define AR_PHY_TPCRG5_PD_GAIN_OVERLAP       0x0000000F
-#define AR_PHY_TPCRG5_PD_GAIN_OVERLAP_S     0
-#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1    0x000003F0
-#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1_S  4
-#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2    0x0000FC00
-#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2_S  10
-#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3    0x003F0000
-#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3_S  16
-#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4    0x0FC00000
-#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4_S  22
-
-/* Carrier leak calibration control, do it after AGC calibration */
-#define AR_PHY_CL_CAL_CTL       0xA358
-#define AR_PHY_CL_CAL_ENABLE    0x00000002
-#define AR_PHY_PARALLEL_CAL_ENABLE    0x00000001
-
-#define AR_PHY_POWER_TX_RATE5   0xA38C
-#define AR_PHY_POWER_TX_RATE6   0xA390
-
-#define AR_PHY_CAL_CHAINMASK    0xA39C
-
-#define AR_PHY_POWER_TX_SUB     0xA3C8
-#define AR_PHY_POWER_TX_RATE7   0xA3CC
-#define AR_PHY_POWER_TX_RATE8   0xA3D0
-#define AR_PHY_POWER_TX_RATE9   0xA3D4
-
-#define AR_PHY_XPA_CFG         0xA3D8
-#define AR_PHY_FORCE_XPA_CFG   0x000000001
-#define AR_PHY_FORCE_XPA_CFG_S 0
-
-#define AR_PHY_CH1_CCA          0xa864
-#define AR_PHY_CH1_MINCCA_PWR   0x0FF80000
-#define AR_PHY_CH1_MINCCA_PWR_S 19
-#define AR9280_PHY_CH1_MINCCA_PWR   0x1FF00000
-#define AR9280_PHY_CH1_MINCCA_PWR_S 20
-
-#define AR_PHY_CH2_CCA          0xb864
-#define AR_PHY_CH2_MINCCA_PWR   0x0FF80000
-#define AR_PHY_CH2_MINCCA_PWR_S 19
-
-#define AR_PHY_CH1_EXT_CCA          0xa9bc
-#define AR_PHY_CH1_EXT_MINCCA_PWR   0xFF800000
-#define AR_PHY_CH1_EXT_MINCCA_PWR_S 23
-#define AR9280_PHY_CH1_EXT_MINCCA_PWR   0x01FF0000
-#define AR9280_PHY_CH1_EXT_MINCCA_PWR_S 16
-
-#define AR_PHY_CH2_EXT_CCA          0xb9bc
-#define AR_PHY_CH2_EXT_MINCCA_PWR   0xFF800000
-#define AR_PHY_CH2_EXT_MINCCA_PWR_S 23
-
 #define REG_WRITE_RF_ARRAY(iniarray, regData, regWr) do {               \
                int r;                                                  \
                for (r = 0; r < ((iniarray)->ia_rows); r++) {           \
@@ -625,6 +51,7 @@ bool ath9k_hw_set_rf_regs(struct ath_hw *ah,
 #define ANTSWAP_AB 0x0001
 #define REDUCE_CHAIN_0 0x00000050
 #define REDUCE_CHAIN_1 0x00000051
+#define AR_PHY_CHIP_ID 0x9818
 
 #define RF_BANK_SETUP(_bank, _iniarray, _col) do {                     \
                int i;                                                  \
@@ -632,4 +59,7 @@ bool ath9k_hw_set_rf_regs(struct ath_hw *ah,
                        (_bank)[i] = INI_RA((_iniarray), i, _col);;     \
        } while (0)
 
+#define        AR_PHY_TIMING11_SPUR_FREQ_SD            0x3FF00000
+#define        AR_PHY_TIMING11_SPUR_FREQ_SD_S          20
+
 #endif
index ee81291f2fbad29e844ba734746578b18ea3f0a4..8519452c95f1b1024b3584a49a33af14a0501350 100644 (file)
@@ -691,6 +691,19 @@ static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
        rate_table = sc->cur_rate_table;
        rix = ath_rc_get_highest_rix(sc, ath_rc_priv, rate_table, &is_probe);
 
+       /*
+        * If we're in HT mode and both us and our peer supports LDPC.
+        * We don't need to check our own device's capabilities as our own
+        * ht capabilities would have already been intersected with our peer's.
+        */
+       if (conf_is_ht(&sc->hw->conf) &&
+           (sta->ht_cap.cap & IEEE80211_HT_CAP_LDPC_CODING))
+               tx_info->flags |= IEEE80211_TX_CTL_LDPC;
+
+       if (conf_is_ht(&sc->hw->conf) &&
+           (sta->ht_cap.cap & IEEE80211_HT_CAP_TX_STBC))
+               tx_info->flags |= (1 << IEEE80211_TX_CTL_STBC_SHIFT);
+
        if (is_probe) {
                /* set one try for probe rates. For the
                 * probes don't enable rts */
index 94560e2fe3765ae11209b7b2e135ff0ac8fd04f3..ac60c4ee62d3fb7c41858d6b78da17f86a62701d 100644 (file)
@@ -15,6 +15,9 @@
  */
 
 #include "ath9k.h"
+#include "ar9003_mac.h"
+
+#define SKB_CB_ATHBUF(__skb)   (*((struct ath_buf **)__skb->cb))
 
 static struct ieee80211_hw * ath_get_virt_hw(struct ath_softc *sc,
                                             struct ieee80211_hdr *hdr)
@@ -115,56 +118,246 @@ static void ath_opmode_init(struct ath_softc *sc)
        ath9k_hw_setmcastfilter(ah, mfilt[0], mfilt[1]);
 }
 
-int ath_rx_init(struct ath_softc *sc, int nbufs)
+static bool ath_rx_edma_buf_link(struct ath_softc *sc,
+                                enum ath9k_rx_qtype qtype)
 {
-       struct ath_common *common = ath9k_hw_common(sc->sc_ah);
+       struct ath_hw *ah = sc->sc_ah;
+       struct ath_rx_edma *rx_edma;
        struct sk_buff *skb;
        struct ath_buf *bf;
-       int error = 0;
 
-       spin_lock_init(&sc->rx.rxflushlock);
-       sc->sc_flags &= ~SC_OP_RXFLUSH;
-       spin_lock_init(&sc->rx.rxbuflock);
+       rx_edma = &sc->rx.rx_edma[qtype];
+       if (skb_queue_len(&rx_edma->rx_fifo) >= rx_edma->rx_fifo_hwsize)
+               return false;
 
-       common->rx_bufsize = roundup(IEEE80211_MAX_MPDU_LEN,
-                                    min(common->cachelsz, (u16)64));
+       bf = list_first_entry(&sc->rx.rxbuf, struct ath_buf, list);
+       list_del_init(&bf->list);
 
-       ath_print(common, ATH_DBG_CONFIG, "cachelsz %u rxbufsize %u\n",
-                 common->cachelsz, common->rx_bufsize);
+       skb = bf->bf_mpdu;
+
+       ATH_RXBUF_RESET(bf);
+       memset(skb->data, 0, ah->caps.rx_status_len);
+       dma_sync_single_for_device(sc->dev, bf->bf_buf_addr,
+                               ah->caps.rx_status_len, DMA_TO_DEVICE);
 
-       /* Initialize rx descriptors */
+       SKB_CB_ATHBUF(skb) = bf;
+       ath9k_hw_addrxbuf_edma(ah, bf->bf_buf_addr, qtype);
+       skb_queue_tail(&rx_edma->rx_fifo, skb);
 
-       error = ath_descdma_setup(sc, &sc->rx.rxdma, &sc->rx.rxbuf,
-                                 "rx", nbufs, 1);
-       if (error != 0) {
-               ath_print(common, ATH_DBG_FATAL,
-                         "failed to allocate rx descriptors: %d\n", error);
-               goto err;
+       return true;
+}
+
+static void ath_rx_addbuffer_edma(struct ath_softc *sc,
+                                 enum ath9k_rx_qtype qtype, int size)
+{
+       struct ath_rx_edma *rx_edma;
+       struct ath_common *common = ath9k_hw_common(sc->sc_ah);
+       u32 nbuf = 0;
+
+       rx_edma = &sc->rx.rx_edma[qtype];
+       if (list_empty(&sc->rx.rxbuf)) {
+               ath_print(common, ATH_DBG_QUEUE, "No free rx buf available\n");
+               return;
        }
 
+       while (!list_empty(&sc->rx.rxbuf)) {
+               nbuf++;
+
+               if (!ath_rx_edma_buf_link(sc, qtype))
+                       break;
+
+               if (nbuf >= size)
+                       break;
+       }
+}
+
+static void ath_rx_remove_buffer(struct ath_softc *sc,
+                                enum ath9k_rx_qtype qtype)
+{
+       struct ath_buf *bf;
+       struct ath_rx_edma *rx_edma;
+       struct sk_buff *skb;
+
+       rx_edma = &sc->rx.rx_edma[qtype];
+
+       while ((skb = skb_dequeue(&rx_edma->rx_fifo)) != NULL) {
+               bf = SKB_CB_ATHBUF(skb);
+               BUG_ON(!bf);
+               list_add_tail(&bf->list, &sc->rx.rxbuf);
+       }
+}
+
+static void ath_rx_edma_cleanup(struct ath_softc *sc)
+{
+       struct ath_buf *bf;
+
+       ath_rx_remove_buffer(sc, ATH9K_RX_QUEUE_LP);
+       ath_rx_remove_buffer(sc, ATH9K_RX_QUEUE_HP);
+
        list_for_each_entry(bf, &sc->rx.rxbuf, list) {
+               if (bf->bf_mpdu)
+                       dev_kfree_skb_any(bf->bf_mpdu);
+       }
+
+       INIT_LIST_HEAD(&sc->rx.rxbuf);
+
+       kfree(sc->rx.rx_bufptr);
+       sc->rx.rx_bufptr = NULL;
+}
+
+static void ath_rx_edma_init_queue(struct ath_rx_edma *rx_edma, int size)
+{
+       skb_queue_head_init(&rx_edma->rx_fifo);
+       skb_queue_head_init(&rx_edma->rx_buffers);
+       rx_edma->rx_fifo_hwsize = size;
+}
+
+static int ath_rx_edma_init(struct ath_softc *sc, int nbufs)
+{
+       struct ath_common *common = ath9k_hw_common(sc->sc_ah);
+       struct ath_hw *ah = sc->sc_ah;
+       struct sk_buff *skb;
+       struct ath_buf *bf;
+       int error = 0, i;
+       u32 size;
+
+
+       common->rx_bufsize = roundup(IEEE80211_MAX_MPDU_LEN +
+                                    ah->caps.rx_status_len,
+                                    min(common->cachelsz, (u16)64));
+
+       ath9k_hw_set_rx_bufsize(ah, common->rx_bufsize -
+                                   ah->caps.rx_status_len);
+
+       ath_rx_edma_init_queue(&sc->rx.rx_edma[ATH9K_RX_QUEUE_LP],
+                              ah->caps.rx_lp_qdepth);
+       ath_rx_edma_init_queue(&sc->rx.rx_edma[ATH9K_RX_QUEUE_HP],
+                              ah->caps.rx_hp_qdepth);
+
+       size = sizeof(struct ath_buf) * nbufs;
+       bf = kzalloc(size, GFP_KERNEL);
+       if (!bf)
+               return -ENOMEM;
+
+       INIT_LIST_HEAD(&sc->rx.rxbuf);
+       sc->rx.rx_bufptr = bf;
+
+       for (i = 0; i < nbufs; i++, bf++) {
                skb = ath_rxbuf_alloc(common, common->rx_bufsize, GFP_KERNEL);
-               if (skb == NULL) {
+               if (!skb) {
                        error = -ENOMEM;
-                       goto err;
+                       goto rx_init_fail;
                }
 
+               memset(skb->data, 0, common->rx_bufsize);
                bf->bf_mpdu = skb;
+
                bf->bf_buf_addr = dma_map_single(sc->dev, skb->data,
                                                 common->rx_bufsize,
-                                                DMA_FROM_DEVICE);
+                                                DMA_BIDIRECTIONAL);
                if (unlikely(dma_mapping_error(sc->dev,
-                                              bf->bf_buf_addr))) {
-                       dev_kfree_skb_any(skb);
-                       bf->bf_mpdu = NULL;
+                                               bf->bf_buf_addr))) {
+                               dev_kfree_skb_any(skb);
+                               bf->bf_mpdu = NULL;
+                               ath_print(common, ATH_DBG_FATAL,
+                                       "dma_mapping_error() on RX init\n");
+                               error = -ENOMEM;
+                               goto rx_init_fail;
+               }
+
+               list_add_tail(&bf->list, &sc->rx.rxbuf);
+       }
+
+       return 0;
+
+rx_init_fail:
+       ath_rx_edma_cleanup(sc);
+       return error;
+}
+
+static void ath_edma_start_recv(struct ath_softc *sc)
+{
+       spin_lock_bh(&sc->rx.rxbuflock);
+
+       ath9k_hw_rxena(sc->sc_ah);
+
+       ath_rx_addbuffer_edma(sc, ATH9K_RX_QUEUE_HP,
+                             sc->rx.rx_edma[ATH9K_RX_QUEUE_HP].rx_fifo_hwsize);
+
+       ath_rx_addbuffer_edma(sc, ATH9K_RX_QUEUE_LP,
+                             sc->rx.rx_edma[ATH9K_RX_QUEUE_LP].rx_fifo_hwsize);
+
+       spin_unlock_bh(&sc->rx.rxbuflock);
+
+       ath_opmode_init(sc);
+
+       ath9k_hw_startpcureceive(sc->sc_ah);
+}
+
+static void ath_edma_stop_recv(struct ath_softc *sc)
+{
+       spin_lock_bh(&sc->rx.rxbuflock);
+       ath_rx_remove_buffer(sc, ATH9K_RX_QUEUE_HP);
+       ath_rx_remove_buffer(sc, ATH9K_RX_QUEUE_LP);
+       spin_unlock_bh(&sc->rx.rxbuflock);
+}
+
+int ath_rx_init(struct ath_softc *sc, int nbufs)
+{
+       struct ath_common *common = ath9k_hw_common(sc->sc_ah);
+       struct sk_buff *skb;
+       struct ath_buf *bf;
+       int error = 0;
+
+       spin_lock_init(&sc->rx.rxflushlock);
+       sc->sc_flags &= ~SC_OP_RXFLUSH;
+       spin_lock_init(&sc->rx.rxbuflock);
+
+       if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
+               return ath_rx_edma_init(sc, nbufs);
+       } else {
+               common->rx_bufsize = roundup(IEEE80211_MAX_MPDU_LEN,
+                               min(common->cachelsz, (u16)64));
+
+               ath_print(common, ATH_DBG_CONFIG, "cachelsz %u rxbufsize %u\n",
+                               common->cachelsz, common->rx_bufsize);
+
+               /* Initialize rx descriptors */
+
+               error = ath_descdma_setup(sc, &sc->rx.rxdma, &sc->rx.rxbuf,
+                               "rx", nbufs, 1, 0);
+               if (error != 0) {
                        ath_print(common, ATH_DBG_FATAL,
-                                 "dma_mapping_error() on RX init\n");
-                       error = -ENOMEM;
+                                 "failed to allocate rx descriptors: %d\n",
+                                 error);
                        goto err;
                }
-               bf->bf_dmacontext = bf->bf_buf_addr;
+
+               list_for_each_entry(bf, &sc->rx.rxbuf, list) {
+                       skb = ath_rxbuf_alloc(common, common->rx_bufsize,
+                                             GFP_KERNEL);
+                       if (skb == NULL) {
+                               error = -ENOMEM;
+                               goto err;
+                       }
+
+                       bf->bf_mpdu = skb;
+                       bf->bf_buf_addr = dma_map_single(sc->dev, skb->data,
+                                       common->rx_bufsize,
+                                       DMA_FROM_DEVICE);
+                       if (unlikely(dma_mapping_error(sc->dev,
+                                                       bf->bf_buf_addr))) {
+                               dev_kfree_skb_any(skb);
+                               bf->bf_mpdu = NULL;
+                               ath_print(common, ATH_DBG_FATAL,
+                                         "dma_mapping_error() on RX init\n");
+                               error = -ENOMEM;
+                               goto err;
+                       }
+                       bf->bf_dmacontext = bf->bf_buf_addr;
+               }
+               sc->rx.rxlink = NULL;
        }
-       sc->rx.rxlink = NULL;
 
 err:
        if (error)
@@ -180,17 +373,23 @@ void ath_rx_cleanup(struct ath_softc *sc)
        struct sk_buff *skb;
        struct ath_buf *bf;
 
-       list_for_each_entry(bf, &sc->rx.rxbuf, list) {
-               skb = bf->bf_mpdu;
-               if (skb) {
-                       dma_unmap_single(sc->dev, bf->bf_buf_addr,
-                                        common->rx_bufsize, DMA_FROM_DEVICE);
-                       dev_kfree_skb(skb);
+       if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
+               ath_rx_edma_cleanup(sc);
+               return;
+       } else {
+               list_for_each_entry(bf, &sc->rx.rxbuf, list) {
+                       skb = bf->bf_mpdu;
+                       if (skb) {
+                               dma_unmap_single(sc->dev, bf->bf_buf_addr,
+                                               common->rx_bufsize,
+                                               DMA_FROM_DEVICE);
+                               dev_kfree_skb(skb);
+                       }
                }
-       }
 
-       if (sc->rx.rxdma.dd_desc_len != 0)
-               ath_descdma_cleanup(sc, &sc->rx.rxdma, &sc->rx.rxbuf);
+               if (sc->rx.rxdma.dd_desc_len != 0)
+                       ath_descdma_cleanup(sc, &sc->rx.rxdma, &sc->rx.rxbuf);
+       }
 }
 
 /*
@@ -273,6 +472,11 @@ int ath_startrecv(struct ath_softc *sc)
        struct ath_hw *ah = sc->sc_ah;
        struct ath_buf *bf, *tbf;
 
+       if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
+               ath_edma_start_recv(sc);
+               return 0;
+       }
+
        spin_lock_bh(&sc->rx.rxbuflock);
        if (list_empty(&sc->rx.rxbuf))
                goto start_recv;
@@ -306,7 +510,11 @@ bool ath_stoprecv(struct ath_softc *sc)
        ath9k_hw_stoppcurecv(ah);
        ath9k_hw_setrxfilter(ah, 0);
        stopped = ath9k_hw_stopdmarecv(ah);
-       sc->rx.rxlink = NULL;
+
+       if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
+               ath_edma_stop_recv(sc);
+       else
+               sc->rx.rxlink = NULL;
 
        return stopped;
 }
@@ -315,7 +523,9 @@ void ath_flushrecv(struct ath_softc *sc)
 {
        spin_lock_bh(&sc->rx.rxflushlock);
        sc->sc_flags |= SC_OP_RXFLUSH;
-       ath_rx_tasklet(sc, 1);
+       if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
+               ath_rx_tasklet(sc, 1, true);
+       ath_rx_tasklet(sc, 1, false);
        sc->sc_flags &= ~SC_OP_RXFLUSH;
        spin_unlock_bh(&sc->rx.rxflushlock);
 }
@@ -469,14 +679,147 @@ static void ath_rx_send_to_mac80211(struct ieee80211_hw *hw,
                ieee80211_rx(hw, skb);
 }
 
-int ath_rx_tasklet(struct ath_softc *sc, int flush)
+static bool ath_edma_get_buffers(struct ath_softc *sc,
+                                enum ath9k_rx_qtype qtype)
 {
-#define PA2DESC(_sc, _pa)                                               \
-       ((struct ath_desc *)((caddr_t)(_sc)->rx.rxdma.dd_desc +         \
-                            ((_pa) - (_sc)->rx.rxdma.dd_desc_paddr)))
+       struct ath_rx_edma *rx_edma = &sc->rx.rx_edma[qtype];
+       struct ath_hw *ah = sc->sc_ah;
+       struct ath_common *common = ath9k_hw_common(ah);
+       struct sk_buff *skb;
+       struct ath_buf *bf;
+       int ret;
+
+       skb = skb_peek(&rx_edma->rx_fifo);
+       if (!skb)
+               return false;
+
+       bf = SKB_CB_ATHBUF(skb);
+       BUG_ON(!bf);
+
+       dma_sync_single_for_device(sc->dev, bf->bf_buf_addr,
+                               common->rx_bufsize, DMA_FROM_DEVICE);
+
+       ret = ath9k_hw_process_rxdesc_edma(ah, NULL, skb->data);
+       if (ret == -EINPROGRESS)
+               return false;
+
+       __skb_unlink(skb, &rx_edma->rx_fifo);
+       if (ret == -EINVAL) {
+               /* corrupt descriptor, skip this one and the following one */
+               list_add_tail(&bf->list, &sc->rx.rxbuf);
+               ath_rx_edma_buf_link(sc, qtype);
+               skb = skb_peek(&rx_edma->rx_fifo);
+               if (!skb)
+                       return true;
+
+               bf = SKB_CB_ATHBUF(skb);
+               BUG_ON(!bf);
+
+               __skb_unlink(skb, &rx_edma->rx_fifo);
+               list_add_tail(&bf->list, &sc->rx.rxbuf);
+               ath_rx_edma_buf_link(sc, qtype);
+       }
+       skb_queue_tail(&rx_edma->rx_buffers, skb);
+
+       return true;
+}
 
+static struct ath_buf *ath_edma_get_next_rx_buf(struct ath_softc *sc,
+                                               struct ath_rx_status *rs,
+                                               enum ath9k_rx_qtype qtype)
+{
+       struct ath_rx_edma *rx_edma = &sc->rx.rx_edma[qtype];
+       struct sk_buff *skb;
        struct ath_buf *bf;
+
+       while (ath_edma_get_buffers(sc, qtype));
+       skb = __skb_dequeue(&rx_edma->rx_buffers);
+       if (!skb)
+               return NULL;
+
+       bf = SKB_CB_ATHBUF(skb);
+       ath9k_hw_process_rxdesc_edma(sc->sc_ah, rs, skb->data);
+       return bf;
+}
+
+static struct ath_buf *ath_get_next_rx_buf(struct ath_softc *sc,
+                                          struct ath_rx_status *rs)
+{
+       struct ath_hw *ah = sc->sc_ah;
+       struct ath_common *common = ath9k_hw_common(ah);
        struct ath_desc *ds;
+       struct ath_buf *bf;
+       int ret;
+
+       if (list_empty(&sc->rx.rxbuf)) {
+               sc->rx.rxlink = NULL;
+               return NULL;
+       }
+
+       bf = list_first_entry(&sc->rx.rxbuf, struct ath_buf, list);
+       ds = bf->bf_desc;
+
+       /*
+        * Must provide the virtual address of the current
+        * descriptor, the physical address, and the virtual
+        * address of the next descriptor in the h/w chain.
+        * This allows the HAL to look ahead to see if the
+        * hardware is done with a descriptor by checking the
+        * done bit in the following descriptor and the address
+        * of the current descriptor the DMA engine is working
+        * on.  All this is necessary because of our use of
+        * a self-linked list to avoid rx overruns.
+        */
+       ret = ath9k_hw_rxprocdesc(ah, ds, rs, 0);
+       if (ret == -EINPROGRESS) {
+               struct ath_rx_status trs;
+               struct ath_buf *tbf;
+               struct ath_desc *tds;
+
+               memset(&trs, 0, sizeof(trs));
+               if (list_is_last(&bf->list, &sc->rx.rxbuf)) {
+                       sc->rx.rxlink = NULL;
+                       return NULL;
+               }
+
+               tbf = list_entry(bf->list.next, struct ath_buf, list);
+
+               /*
+                * On some hardware the descriptor status words could
+                * get corrupted, including the done bit. Because of
+                * this, check if the next descriptor's done bit is
+                * set or not.
+                *
+                * If the next descriptor's done bit is set, the current
+                * descriptor has been corrupted. Force s/w to discard
+                * this descriptor and continue...
+                */
+
+               tds = tbf->bf_desc;
+               ret = ath9k_hw_rxprocdesc(ah, tds, &trs, 0);
+               if (ret == -EINPROGRESS)
+                       return NULL;
+       }
+
+       if (!bf->bf_mpdu)
+               return bf;
+
+       /*
+        * Synchronize the DMA transfer with CPU before
+        * 1. accessing the frame
+        * 2. requeueing the same buffer to h/w
+        */
+       dma_sync_single_for_device(sc->dev, bf->bf_buf_addr,
+                       common->rx_bufsize,
+                       DMA_FROM_DEVICE);
+
+       return bf;
+}
+
+
+int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
+{
+       struct ath_buf *bf;
        struct sk_buff *skb = NULL, *requeue_skb;
        struct ieee80211_rx_status *rxs;
        struct ath_hw *ah = sc->sc_ah;
@@ -491,7 +834,16 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
        int retval;
        bool decrypt_error = false;
        struct ath_rx_status rs;
+       enum ath9k_rx_qtype qtype;
+       bool edma = !!(ah->caps.hw_caps & ATH9K_HW_CAP_EDMA);
+       int dma_type;
 
+       if (edma)
+               dma_type = DMA_FROM_DEVICE;
+       else
+               dma_type = DMA_BIDIRECTIONAL;
+
+       qtype = hp ? ATH9K_RX_QUEUE_HP : ATH9K_RX_QUEUE_LP;
        spin_lock_bh(&sc->rx.rxbuflock);
 
        do {
@@ -499,71 +851,19 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
                if ((sc->sc_flags & SC_OP_RXFLUSH) && (flush == 0))
                        break;
 
-               if (list_empty(&sc->rx.rxbuf)) {
-                       sc->rx.rxlink = NULL;
-                       break;
-               }
-
-               bf = list_first_entry(&sc->rx.rxbuf, struct ath_buf, list);
-               ds = bf->bf_desc;
-
-               /*
-                * Must provide the virtual address of the current
-                * descriptor, the physical address, and the virtual
-                * address of the next descriptor in the h/w chain.
-                * This allows the HAL to look ahead to see if the
-                * hardware is done with a descriptor by checking the
-                * done bit in the following descriptor and the address
-                * of the current descriptor the DMA engine is working
-                * on.  All this is necessary because of our use of
-                * a self-linked list to avoid rx overruns.
-                */
                memset(&rs, 0, sizeof(rs));
-               retval = ath9k_hw_rxprocdesc(ah, ds, &rs, 0);
-               if (retval == -EINPROGRESS) {
-                       struct ath_rx_status trs;
-                       struct ath_buf *tbf;
-                       struct ath_desc *tds;
-
-                       memset(&trs, 0, sizeof(trs));
-                       if (list_is_last(&bf->list, &sc->rx.rxbuf)) {
-                               sc->rx.rxlink = NULL;
-                               break;
-                       }
+               if (edma)
+                       bf = ath_edma_get_next_rx_buf(sc, &rs, qtype);
+               else
+                       bf = ath_get_next_rx_buf(sc, &rs);
 
-                       tbf = list_entry(bf->list.next, struct ath_buf, list);
-
-                       /*
-                        * On some hardware the descriptor status words could
-                        * get corrupted, including the done bit. Because of
-                        * this, check if the next descriptor's done bit is
-                        * set or not.
-                        *
-                        * If the next descriptor's done bit is set, the current
-                        * descriptor has been corrupted. Force s/w to discard
-                        * this descriptor and continue...
-                        */
-
-                       tds = tbf->bf_desc;
-                       retval = ath9k_hw_rxprocdesc(ah, tds, &trs, 0);
-                       if (retval == -EINPROGRESS) {
-                               break;
-                       }
-               }
+               if (!bf)
+                       break;
 
                skb = bf->bf_mpdu;
                if (!skb)
                        continue;
 
-               /*
-                * Synchronize the DMA transfer with CPU before
-                * 1. accessing the frame
-                * 2. requeueing the same buffer to h/w
-                */
-               dma_sync_single_for_cpu(sc->dev, bf->bf_buf_addr,
-                               common->rx_bufsize,
-                               DMA_FROM_DEVICE);
-
                hdr = (struct ieee80211_hdr *) skb->data;
                rxs =  IEEE80211_SKB_RXCB(skb);
 
@@ -597,9 +897,11 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
                /* Unmap the frame */
                dma_unmap_single(sc->dev, bf->bf_buf_addr,
                                 common->rx_bufsize,
-                                DMA_FROM_DEVICE);
+                                dma_type);
 
-               skb_put(skb, rs.rs_datalen);
+               skb_put(skb, rs.rs_datalen + ah->caps.rx_status_len);
+               if (ah->caps.rx_status_len)
+                       skb_pull(skb, ah->caps.rx_status_len);
 
                ath9k_cmn_rx_skb_postprocess(common, skb, &rs,
                                             rxs, decrypt_error);
@@ -608,7 +910,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
                bf->bf_mpdu = requeue_skb;
                bf->bf_buf_addr = dma_map_single(sc->dev, requeue_skb->data,
                                                 common->rx_bufsize,
-                                                DMA_FROM_DEVICE);
+                                                dma_type);
                if (unlikely(dma_mapping_error(sc->dev,
                          bf->bf_buf_addr))) {
                        dev_kfree_skb_any(requeue_skb);
@@ -639,12 +941,16 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
                ath_rx_send_to_mac80211(hw, sc, skb, rxs);
 
 requeue:
-               list_move_tail(&bf->list, &sc->rx.rxbuf);
-               ath_rx_buf_link(sc, bf);
+               if (edma) {
+                       list_add_tail(&bf->list, &sc->rx.rxbuf);
+                       ath_rx_edma_buf_link(sc, qtype);
+               } else {
+                       list_move_tail(&bf->list, &sc->rx.rxbuf);
+                       ath_rx_buf_link(sc, bf);
+               }
        } while (1);
 
        spin_unlock_bh(&sc->rx.rxbuflock);
 
        return 0;
-#undef PA2DESC
 }
index 7e36ad7421b77f6464c8bc810c9b1276209fe329..d4371a43bdaac35a6073a55fccf319c3bbe46043 100644 (file)
@@ -20,7 +20,7 @@
 #include "../reg.h"
 
 #define AR_CR                0x0008
-#define AR_CR_RXE            0x00000004
+#define AR_CR_RXE            (AR_SREV_9300_20_OR_LATER(ah) ? 0x0000000c : 0x00000004)
 #define AR_CR_RXD            0x00000020
 #define AR_CR_SWI            0x00000040
 
 #define AR_CFG_PCI_MASTER_REQ_Q_THRESH         0x00060000
 #define AR_CFG_PCI_MASTER_REQ_Q_THRESH_S       17
 
+#define AR_RXBP_THRESH       0x0018
+#define AR_RXBP_THRESH_HP    0x0000000f
+#define AR_RXBP_THRESH_HP_S  0
+#define AR_RXBP_THRESH_LP    0x00003f00
+#define AR_RXBP_THRESH_LP_S  8
+
 #define AR_MIRT              0x0020
 #define AR_MIRT_VAL          0x0000ffff
 #define AR_MIRT_VAL_S        16
 #define AR_MACMISC_MISC_OBS_BUS_MSB_S   15
 #define AR_MACMISC_MISC_OBS_BUS_1       1
 
+#define AR_DATABUF_SIZE                0x0060
+#define AR_DATABUF_SIZE_MASK   0x00000FFF
+
 #define AR_GTXTO    0x0064
 #define AR_GTXTO_TIMEOUT_COUNTER    0x0000FFFF
 #define AR_GTXTO_TIMEOUT_LIMIT      0xFFFF0000
 #define AR_CST_TIMEOUT_LIMIT      0xFFFF0000
 #define AR_CST_TIMEOUT_LIMIT_S    16
 
+#define AR_HP_RXDP 0x0074
+#define AR_LP_RXDP 0x0078
+
 #define AR_ISR               0x0080
 #define AR_ISR_RXOK          0x00000001
 #define AR_ISR_RXDESC        0x00000002
+#define AR_ISR_HP_RXOK      0x00000001
+#define AR_ISR_LP_RXOK      0x00000002
 #define AR_ISR_RXERR         0x00000004
 #define AR_ISR_RXNOPKT       0x00000008
 #define AR_ISR_RXEOL         0x00000010
 #define AR_ISR_S5_TIMER_THRESH      0x0007FE00
 #define AR_ISR_S5_TIM_TIMER         0x00000010
 #define AR_ISR_S5_DTIM_TIMER        0x00000020
-#define AR_ISR_S5_S                 0x00d8
 #define AR_IMR_S5                   0x00b8
 #define AR_IMR_S5_TIM_TIMER         0x00000010
 #define AR_IMR_S5_DTIM_TIMER        0x00000020
 #define AR_ISR_S5_GENTIMER_TRIG_S   0
 #define AR_ISR_S5_GENTIMER_THRESH   0xFF800000
 #define AR_ISR_S5_GENTIMER_THRESH_S 16
-#define AR_ISR_S5_S                 0x00d8
 #define AR_IMR_S5_GENTIMER_TRIG     0x0000FF80
 #define AR_IMR_S5_GENTIMER_TRIG_S   0
 #define AR_IMR_S5_GENTIMER_THRESH   0xFF800000
 #define AR_IMR               0x00a0
 #define AR_IMR_RXOK          0x00000001
 #define AR_IMR_RXDESC        0x00000002
+#define AR_IMR_RXOK_HP      0x00000001
+#define AR_IMR_RXOK_LP      0x00000002
 #define AR_IMR_RXERR         0x00000004
 #define AR_IMR_RXNOPKT       0x00000008
 #define AR_IMR_RXEOL         0x00000010
 #define AR_ISR_S1_QCU_TXEOL    0x03FF0000
 #define AR_ISR_S1_QCU_TXEOL_S  16
 
-#define AR_ISR_S2_S           0x00cc
-#define AR_ISR_S3_S           0x00d0
-#define AR_ISR_S4_S           0x00d4
-#define AR_ISR_S5_S           0x00d8
+#define AR_ISR_S2_S           (AR_SREV_9300_20_OR_LATER(ah) ? 0x00d0 : 0x00cc)
+#define AR_ISR_S3_S           (AR_SREV_9300_20_OR_LATER(ah) ? 0x00d4 : 0x00d0)
+#define AR_ISR_S4_S           (AR_SREV_9300_20_OR_LATER(ah) ? 0x00d8 : 0x00d4)
+#define AR_ISR_S5_S           (AR_SREV_9300_20_OR_LATER(ah) ? 0x00dc : 0x00d8)
 #define AR_DMADBG_0           0x00e0
 #define AR_DMADBG_1           0x00e4
 #define AR_DMADBG_2           0x00e8
 #define AR_Q9_TXDP           0x0824
 #define AR_QTXDP(_i)    (AR_Q0_TXDP + ((_i)<<2))
 
+#define AR_Q_STATUS_RING_START 0x830
+#define AR_Q_STATUS_RING_END   0x834
+
 #define AR_Q_TXE             0x0840
 #define AR_Q_TXE_M           0x000003FF
 
 #define AR_Q_RDYTIMESHDN    0x0a40
 #define AR_Q_RDYTIMESHDN_M  0x000003FF
 
+/* MAC Descriptor CRC check */
+#define AR_Q_DESC_CRCCHK    0xa44
+/* Enable CRC check on the descriptor fetched from host */
+#define AR_Q_DESC_CRCCHK_EN 1
 
 #define AR_NUM_DCU      10
 #define AR_DCU_0        0x0001
 #define AR_SREV_VERSION_9271                   0x140
 #define AR_SREV_REVISION_9271_10               0
 #define AR_SREV_REVISION_9271_11               1
+#define AR_SREV_VERSION_9300                  0x1c0
+#define AR_SREV_REVISION_9300_20              2 /* 2.0 and 2.1 */
 
 #define AR_SREV_5416(_ah) \
        (((_ah)->hw_version.macVersion == AR_SREV_VERSION_5416_PCI) || \
 #define AR_SREV_9271_11(_ah) \
     (AR_SREV_9271(_ah) && \
      ((_ah)->hw_version.macRev == AR_SREV_REVISION_9271_11))
+#define AR_SREV_9300(_ah) \
+       (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9300))
+#define AR_SREV_9300_20(_ah) \
+       (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9300) && \
+        ((_ah)->hw_version.macRev == AR_SREV_REVISION_9300_20))
+#define AR_SREV_9300_20_OR_LATER(_ah) \
+       (((_ah)->hw_version.macVersion > AR_SREV_VERSION_9300) || \
+        (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9300) && \
+         ((_ah)->hw_version.macRev >= AR_SREV_REVISION_9300_20)))
 
 #define AR_SREV_9285E_20(_ah) \
     (AR_SREV_9285_12_OR_LATER(_ah) && \
@@ -945,6 +977,7 @@ enum {
 #define AR9285_NUM_GPIO                          12
 #define AR9287_NUM_GPIO                          11
 #define AR9271_NUM_GPIO                          16
+#define AR9300_NUM_GPIO                          17
 
 #define AR_GPIO_IN_OUT                           0x4048
 #define AR_GPIO_IN_VAL                           0x0FFFC000
@@ -957,19 +990,21 @@ enum {
 #define AR9287_GPIO_IN_VAL_S                     11
 #define AR9271_GPIO_IN_VAL                       0xFFFF0000
 #define AR9271_GPIO_IN_VAL_S                     16
+#define AR9300_GPIO_IN_VAL                       0x0001FFFF
+#define AR9300_GPIO_IN_VAL_S                     0
 
-#define AR_GPIO_OE_OUT                           0x404c
+#define AR_GPIO_OE_OUT                           (AR_SREV_9300_20_OR_LATER(ah) ? 0x4050 : 0x404c)
 #define AR_GPIO_OE_OUT_DRV                       0x3
 #define AR_GPIO_OE_OUT_DRV_NO                    0x0
 #define AR_GPIO_OE_OUT_DRV_LOW                   0x1
 #define AR_GPIO_OE_OUT_DRV_HI                    0x2
 #define AR_GPIO_OE_OUT_DRV_ALL                   0x3
 
-#define AR_GPIO_INTR_POL                         0x4050
-#define AR_GPIO_INTR_POL_VAL                     0x00001FFF
+#define AR_GPIO_INTR_POL                         (AR_SREV_9300_20_OR_LATER(ah) ? 0x4058 : 0x4050)
+#define AR_GPIO_INTR_POL_VAL                     0x0001FFFF
 #define AR_GPIO_INTR_POL_VAL_S                   0
 
-#define AR_GPIO_INPUT_EN_VAL                     0x4054
+#define AR_GPIO_INPUT_EN_VAL                     (AR_SREV_9300_20_OR_LATER(ah) ? 0x405c : 0x4054)
 #define AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_DEF     0x00000004
 #define AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_S       2
 #define AR_GPIO_INPUT_EN_VAL_BT_FREQUENCY_DEF    0x00000008
@@ -987,13 +1022,13 @@ enum {
 #define AR_GPIO_RTC_RESET_OVERRIDE_ENABLE        0x00010000
 #define AR_GPIO_JTAG_DISABLE                     0x00020000
 
-#define AR_GPIO_INPUT_MUX1                       0x4058
+#define AR_GPIO_INPUT_MUX1                       (AR_SREV_9300_20_OR_LATER(ah) ? 0x4060 : 0x4058)
 #define AR_GPIO_INPUT_MUX1_BT_ACTIVE             0x000f0000
 #define AR_GPIO_INPUT_MUX1_BT_ACTIVE_S           16
 #define AR_GPIO_INPUT_MUX1_BT_PRIORITY           0x00000f00
 #define AR_GPIO_INPUT_MUX1_BT_PRIORITY_S         8
 
-#define AR_GPIO_INPUT_MUX2                       0x405c
+#define AR_GPIO_INPUT_MUX2                       (AR_SREV_9300_20_OR_LATER(ah) ? 0x4064 : 0x405c)
 #define AR_GPIO_INPUT_MUX2_CLK25                 0x0000000f
 #define AR_GPIO_INPUT_MUX2_CLK25_S               0
 #define AR_GPIO_INPUT_MUX2_RFSILENT              0x000000f0
@@ -1001,13 +1036,13 @@ enum {
 #define AR_GPIO_INPUT_MUX2_RTC_RESET             0x00000f00
 #define AR_GPIO_INPUT_MUX2_RTC_RESET_S           8
 
-#define AR_GPIO_OUTPUT_MUX1                      0x4060
-#define AR_GPIO_OUTPUT_MUX2                      0x4064
-#define AR_GPIO_OUTPUT_MUX3                      0x4068
+#define AR_GPIO_OUTPUT_MUX1                      (AR_SREV_9300_20_OR_LATER(ah) ? 0x4068 : 0x4060)
+#define AR_GPIO_OUTPUT_MUX2                      (AR_SREV_9300_20_OR_LATER(ah) ? 0x406c : 0x4064)
+#define AR_GPIO_OUTPUT_MUX3                      (AR_SREV_9300_20_OR_LATER(ah) ? 0x4070 : 0x4068)
 
-#define AR_INPUT_STATE                           0x406c
+#define AR_INPUT_STATE                           (AR_SREV_9300_20_OR_LATER(ah) ? 0x4074 : 0x406c)
 
-#define AR_EEPROM_STATUS_DATA                    0x407c
+#define AR_EEPROM_STATUS_DATA                    (AR_SREV_9300_20_OR_LATER(ah) ? 0x4084 : 0x407c)
 #define AR_EEPROM_STATUS_DATA_VAL                0x0000ffff
 #define AR_EEPROM_STATUS_DATA_VAL_S              0
 #define AR_EEPROM_STATUS_DATA_BUSY               0x00010000
@@ -1015,13 +1050,24 @@ enum {
 #define AR_EEPROM_STATUS_DATA_PROT_ACCESS        0x00040000
 #define AR_EEPROM_STATUS_DATA_ABSENT_ACCESS      0x00080000
 
-#define AR_OBS                  0x4080
+#define AR_OBS                  (AR_SREV_9300_20_OR_LATER(ah) ? 0x4088 : 0x4080)
 
-#define AR_GPIO_PDPU                             0x4088
+#define AR_GPIO_PDPU                             (AR_SREV_9300_20_OR_LATER(ah) ? 0x4090 : 0x4088)
 
-#define AR_PCIE_MSI                              0x4094
+#define AR_PCIE_MSI                              (AR_SREV_9300_20_OR_LATER(ah) ? 0x40a4 : 0x4094)
 #define AR_PCIE_MSI_ENABLE                       0x00000001
 
+#define AR_INTR_PRIO_SYNC_ENABLE  0x40c4
+#define AR_INTR_PRIO_ASYNC_MASK   0x40c8
+#define AR_INTR_PRIO_SYNC_MASK    0x40cc
+#define AR_INTR_PRIO_ASYNC_ENABLE 0x40d4
+
+#define AR_RTC_9300_PLL_DIV          0x000003ff
+#define AR_RTC_9300_PLL_DIV_S        0
+#define AR_RTC_9300_PLL_REFDIV       0x00003C00
+#define AR_RTC_9300_PLL_REFDIV_S     10
+#define AR_RTC_9300_PLL_CLKSEL       0x0000C000
+#define AR_RTC_9300_PLL_CLKSEL_S     14
 
 #define AR_RTC_9160_PLL_DIV    0x000003ff
 #define AR_RTC_9160_PLL_DIV_S   0
@@ -1039,6 +1085,16 @@ enum {
 #define AR_RTC_RC_COLD_RESET    0x00000004
 #define AR_RTC_RC_WARM_RESET    0x00000008
 
+/* Crystal Control */
+#define AR_RTC_XTAL_CONTROL     0x7004
+
+/* Reg Control 0 */
+#define AR_RTC_REG_CONTROL0     0x7008
+
+/* Reg Control 1 */
+#define AR_RTC_REG_CONTROL1     0x700c
+#define AR_RTC_REG_CONTROL1_SWREG_PROGRAM       0x00000001
+
 #define AR_RTC_PLL_CONTROL \
        ((AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x0014) : 0x7014)
 
@@ -1069,6 +1125,7 @@ enum {
 #define AR_RTC_SLEEP_CLK \
        ((AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x0048) : 0x7048)
 #define AR_RTC_FORCE_DERIVED_CLK    0x2
+#define AR_RTC_FORCE_SWREG_PRD      0x00000004
 
 #define AR_RTC_FORCE_WAKE \
        ((AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x004c) : 0x704c)
@@ -1533,7 +1590,7 @@ enum {
 #define AR_TSFOOR_THRESHOLD       0x813c
 #define AR_TSFOOR_THRESHOLD_VAL   0x0000FFFF
 
-#define AR_PHY_ERR_EIFS_MASK   8144
+#define AR_PHY_ERR_EIFS_MASK   0x8144
 
 #define AR_PHY_ERR_3           0x8168
 #define AR_PHY_ERR_3_COUNT     0x00FFFFFF
@@ -1599,24 +1656,26 @@ enum {
 #define AR_FIRST_NDP_TIMER                  7
 #define AR_NDP2_PERIOD                      0x81a0
 #define AR_NDP2_TIMER_MODE                  0x81c0
-#define AR_NEXT_TBTT_TIMER                  0x8200
-#define AR_NEXT_DMA_BEACON_ALERT            0x8204
-#define AR_NEXT_SWBA                        0x8208
-#define AR_NEXT_CFP                         0x8208
-#define AR_NEXT_HCF                         0x820C
-#define AR_NEXT_TIM                         0x8210
-#define AR_NEXT_DTIM                        0x8214
-#define AR_NEXT_QUIET_TIMER                 0x8218
-#define AR_NEXT_NDP_TIMER                   0x821C
-
-#define AR_BEACON_PERIOD                    0x8220
-#define AR_DMA_BEACON_PERIOD                0x8224
-#define AR_SWBA_PERIOD                      0x8228
-#define AR_HCF_PERIOD                       0x822C
-#define AR_TIM_PERIOD                       0x8230
-#define AR_DTIM_PERIOD                      0x8234
-#define AR_QUIET_PERIOD                     0x8238
-#define AR_NDP_PERIOD                       0x823C
+
+#define AR_GEN_TIMERS(_i)                   (0x8200 + ((_i) << 2))
+#define AR_NEXT_TBTT_TIMER                  AR_GEN_TIMERS(0)
+#define AR_NEXT_DMA_BEACON_ALERT            AR_GEN_TIMERS(1)
+#define AR_NEXT_SWBA                        AR_GEN_TIMERS(2)
+#define AR_NEXT_CFP                         AR_GEN_TIMERS(2)
+#define AR_NEXT_HCF                         AR_GEN_TIMERS(3)
+#define AR_NEXT_TIM                         AR_GEN_TIMERS(4)
+#define AR_NEXT_DTIM                        AR_GEN_TIMERS(5)
+#define AR_NEXT_QUIET_TIMER                 AR_GEN_TIMERS(6)
+#define AR_NEXT_NDP_TIMER                   AR_GEN_TIMERS(7)
+
+#define AR_BEACON_PERIOD                    AR_GEN_TIMERS(8)
+#define AR_DMA_BEACON_PERIOD                AR_GEN_TIMERS(9)
+#define AR_SWBA_PERIOD                      AR_GEN_TIMERS(10)
+#define AR_HCF_PERIOD                       AR_GEN_TIMERS(11)
+#define AR_TIM_PERIOD                       AR_GEN_TIMERS(12)
+#define AR_DTIM_PERIOD                      AR_GEN_TIMERS(13)
+#define AR_QUIET_PERIOD                     AR_GEN_TIMERS(14)
+#define AR_NDP_PERIOD                       AR_GEN_TIMERS(15)
 
 #define AR_TIMER_MODE                       0x8240
 #define AR_TBTT_TIMER_EN                    0x00000001
@@ -1730,4 +1789,32 @@ enum {
 #define AR9271_CORE_CLOCK      117   /* clock to 117Mhz */
 #define AR9271_TARGET_BAUD_RATE        19200 /* 115200 */
 
+#define AR_AGG_WEP_ENABLE_FIX          0x00000008  /* This allows the use of AR_AGG_WEP_ENABLE */
+#define AR_ADHOC_MCAST_KEYID_ENABLE     0x00000040  /* This bit enables the Multicast search
+                                                    * based on both MAC Address and Key ID.
+                                                    * If bit is 0, then Multicast search is
+                                                    * based on MAC address only.
+                                                    * For Merlin and above only.
+                                                    */
+#define AR_AGG_WEP_ENABLE               0x00020000  /* This field enables AGG_WEP feature,
+                                                    * when it is enable, AGG_WEP would takes
+                                                    * charge of the encryption interface of
+                                                    * pcu_txsm.
+                                                    */
+
+#define AR9300_SM_BASE                         0xa200
+#define AR9002_PHY_AGC_CONTROL                 0x9860
+#define AR9003_PHY_AGC_CONTROL                 AR9300_SM_BASE + 0xc4
+#define AR_PHY_AGC_CONTROL                     (AR_SREV_9300_20_OR_LATER(ah) ? AR9003_PHY_AGC_CONTROL : AR9002_PHY_AGC_CONTROL)
+#define AR_PHY_AGC_CONTROL_CAL                 0x00000001  /* do internal calibration */
+#define AR_PHY_AGC_CONTROL_NF                  0x00000002  /* do noise-floor calibration */
+#define AR_PHY_AGC_CONTROL_OFFSET_CAL          0x00000800  /* allow offset calibration */
+#define AR_PHY_AGC_CONTROL_ENABLE_NF           0x00008000  /* enable noise floor calibration to happen */
+#define AR_PHY_AGC_CONTROL_FLTR_CAL            0x00010000  /* allow tx filter calibration */
+#define AR_PHY_AGC_CONTROL_NO_UPDATE_NF                0x00020000  /* don't update noise floor automatically */
+#define AR_PHY_AGC_CONTROL_EXT_NF_PWR_MEAS     0x00040000  /* extend noise floor power measurement */
+#define AR_PHY_AGC_CONTROL_CLC_SUCCESS         0x00080000  /* carrier leak calibration done */
+#define AR_PHY_AGC_CONTROL_YCOK_MAX            0x000003c0
+#define AR_PHY_AGC_CONTROL_YCOK_MAX_S          6
+
 #endif
index f2ff18cf3e60074b1c26c7b10f9792f2d08f9fe0..dc6c6fc2e095bcdf8d01a3eaaf55b5957ecb5e97 100644 (file)
@@ -101,6 +101,7 @@ struct wmi *ath9k_init_wmi(struct ath9k_htc_priv *priv)
        wmi->drv_priv = priv;
        wmi->stopped = false;
        mutex_init(&wmi->op_mutex);
+       mutex_init(&wmi->multi_write_mutex);
        init_completion(&wmi->cmd_wait);
 
        return wmi;
@@ -128,7 +129,7 @@ void ath9k_wmi_tasklet(unsigned long data)
        void *wmi_event;
        unsigned long flags;
 #ifdef CONFIG_ATH9K_HTC_DEBUGFS
-       u32 txrate;
+       __be32 txrate;
 #endif
 
        spin_lock_irqsave(&priv->wmi->wmi_lock, flags);
@@ -203,6 +204,14 @@ static void ath9k_wmi_ctrl_rx(void *priv, struct sk_buff *skb,
                return;
        }
 
+       /* Check if there has been a timeout. */
+       spin_lock(&wmi->wmi_lock);
+       if (cmd_id != wmi->last_cmd_id) {
+               spin_unlock(&wmi->wmi_lock);
+               goto free_skb;
+       }
+       spin_unlock(&wmi->wmi_lock);
+
        /* WMI command response */
        ath9k_wmi_rsp_callback(wmi, skb);
 
@@ -265,6 +274,7 @@ int ath9k_wmi_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id,
        struct sk_buff *skb;
        u8 *data;
        int time_left, ret = 0;
+       unsigned long flags;
 
        if (!wmi)
                return -EINVAL;
@@ -296,6 +306,10 @@ int ath9k_wmi_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id,
        if (ret)
                goto out;
 
+       spin_lock_irqsave(&wmi->wmi_lock, flags);
+       wmi->last_cmd_id = cmd_id;
+       spin_unlock_irqrestore(&wmi->wmi_lock, flags);
+
        time_left = wait_for_completion_timeout(&wmi->cmd_wait, timeout);
        if (!time_left) {
                ath_print(common, ATH_DBG_WMI,
index 39ef926f27c2382cf995473e91a92c712a635ead..167e15c500627426ff46d21752c9dae8e30a2104 100644 (file)
@@ -19,7 +19,7 @@
 
 
 struct wmi_event_txrate {
-       u32 txrate;
+       __be32 txrate;
        struct {
                u8 rssi_thresh;
                u8 per;
@@ -27,8 +27,8 @@ struct wmi_event_txrate {
 } __packed;
 
 struct wmi_cmd_hdr {
-       u16 command_id;
-       u16 seq_no;
+       __be16 command_id;
+       __be16 seq_no;
 } __packed;
 
 struct wmi_swba {
@@ -84,12 +84,20 @@ enum wmi_event_id {
        WMI_TXRATE_EVENTID,
 };
 
+#define MAX_CMD_NUMBER 62
+
+struct register_write {
+       __be32 reg;
+       __be32 val;
+};
+
 struct wmi {
        struct ath9k_htc_priv *drv_priv;
        struct htc_target *htc;
        enum htc_endpoint_id ctrl_epid;
        struct mutex op_mutex;
        struct completion cmd_wait;
+       enum wmi_cmd_id last_cmd_id;
        u16 tx_seq_id;
        u8 *cmd_rsp_buf;
        u32 cmd_rsp_len;
@@ -97,6 +105,11 @@ struct wmi {
 
        struct sk_buff *wmi_skb;
        spinlock_t wmi_lock;
+
+       atomic_t mwrite_cnt;
+       struct register_write multi_write[MAX_CMD_NUMBER];
+       u32 multi_write_idx;
+       struct mutex multi_write_mutex;
 };
 
 struct wmi *ath9k_init_wmi(struct ath9k_htc_priv *priv);
index 02df4cbf179f4ab1ebdb3cf93c66cc2be7273df4..b0d345a675fe6f23f5e150c6c97f85e767197ba9 100644 (file)
  */
 
 #include "ath9k.h"
+#include "ar9003_mac.h"
 
 #define BITS_PER_BYTE           8
 #define OFDM_PLCP_BITS          22
-#define HT_RC_2_MCS(_rc)        ((_rc) & 0x0f)
+#define HT_RC_2_MCS(_rc)        ((_rc) & 0x1f)
 #define HT_RC_2_STREAMS(_rc)    ((((_rc) & 0x78) >> 3) + 1)
 #define L_STF                   8
 #define L_LTF                   8
@@ -33,7 +34,7 @@
 
 #define OFDM_SIFS_TIME             16
 
-static u32 bits_per_symbol[][2] = {
+static u16 bits_per_symbol[][2] = {
        /* 20MHz 40MHz */
        {    26,   54 },     /*  0: BPSK */
        {    52,  108 },     /*  1: QPSK 1/2 */
@@ -43,14 +44,6 @@ static u32 bits_per_symbol[][2] = {
        {   208,  432 },     /*  5: 64-QAM 2/3 */
        {   234,  486 },     /*  6: 64-QAM 3/4 */
        {   260,  540 },     /*  7: 64-QAM 5/6 */
-       {    52,  108 },     /*  8: BPSK */
-       {   104,  216 },     /*  9: QPSK 1/2 */
-       {   156,  324 },     /* 10: QPSK 3/4 */
-       {   208,  432 },     /* 11: 16-QAM 1/2 */
-       {   312,  648 },     /* 12: 16-QAM 3/4 */
-       {   416,  864 },     /* 13: 64-QAM 2/3 */
-       {   468,  972 },     /* 14: 64-QAM 3/4 */
-       {   520, 1080 },     /* 15: 64-QAM 5/6 */
 };
 
 #define IS_HT_RATE(_rate)     ((_rate) & 0x80)
@@ -70,28 +63,39 @@ static void ath_tx_rc_status(struct ath_buf *bf, struct ath_tx_status *ts,
                             int nbad, int txok, bool update_rc);
 
 enum {
-       MCS_DEFAULT,
+       MCS_HT20,
+       MCS_HT20_SGI,
        MCS_HT40,
        MCS_HT40_SGI,
 };
 
-static int ath_max_4ms_framelen[3][16] = {
-       [MCS_DEFAULT] = {
-               3216,  6434,  9650,  12868, 19304, 25740,  28956,  32180,
-               6430,  12860, 19300, 25736, 38600, 51472,  57890,  64320,
+static int ath_max_4ms_framelen[4][32] = {
+       [MCS_HT20] = {
+               3212,  6432,  9648,  12864,  19300,  25736,  28952,  32172,
+               6424,  12852, 19280, 25708,  38568,  51424,  57852,  64280,
+               9628,  19260, 28896, 38528,  57792,  65532,  65532,  65532,
+               12828, 25656, 38488, 51320,  65532,  65532,  65532,  65532,
+       },
+       [MCS_HT20_SGI] = {
+               3572,  7144,  10720,  14296,  21444,  28596,  32172,  35744,
+               7140,  14284, 21428,  28568,  42856,  57144,  64288,  65532,
+               10700, 21408, 32112,  42816,  64228,  65532,  65532,  65532,
+               14256, 28516, 42780,  57040,  65532,  65532,  65532,  65532,
        },
        [MCS_HT40] = {
-               6684,  13368, 20052, 26738, 40104, 53476,  60156,  66840,
-               13360, 26720, 40080, 53440, 80160, 106880, 120240, 133600,
+               6680,  13360,  20044,  26724,  40092,  53456,  60140,  65532,
+               13348, 26700,  40052,  53400,  65532,  65532,  65532,  65532,
+               20004, 40008,  60016,  65532,  65532,  65532,  65532,  65532,
+               26644, 53292,  65532,  65532,  65532,  65532,  65532,  65532,
        },
        [MCS_HT40_SGI] = {
-               /* TODO: Only MCS 7 and 15 updated, recalculate the rest */
-               6684,  13368, 20052, 26738, 40104, 53476,  60156,  74200,
-               13360, 26720, 40080, 53440, 80160, 106880, 120240, 148400,
+               7420,  14844,  22272,  29696,  44544,  59396,  65532,  65532,
+               14832, 29668,  44504,  59340,  65532,  65532,  65532,  65532,
+               22232, 44464,  65532,  65532,  65532,  65532,  65532,  65532,
+               29616, 59232,  65532,  65532,  65532,  65532,  65532,  65532,
        }
 };
 
-
 /*********************/
 /* Aggregation logic */
 /*********************/
@@ -261,25 +265,46 @@ static void ath_tx_set_retry(struct ath_softc *sc, struct ath_txq *txq,
        hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_RETRY);
 }
 
-static struct ath_buf* ath_clone_txbuf(struct ath_softc *sc, struct ath_buf *bf)
+static struct ath_buf *ath_tx_get_buffer(struct ath_softc *sc)
 {
-       struct ath_buf *tbf;
+       struct ath_buf *bf = NULL;
 
        spin_lock_bh(&sc->tx.txbuflock);
-       if (WARN_ON(list_empty(&sc->tx.txbuf))) {
+
+       if (unlikely(list_empty(&sc->tx.txbuf))) {
                spin_unlock_bh(&sc->tx.txbuflock);
                return NULL;
        }
-       tbf = list_first_entry(&sc->tx.txbuf, struct ath_buf, list);
-       list_del(&tbf->list);
+
+       bf = list_first_entry(&sc->tx.txbuf, struct ath_buf, list);
+       list_del(&bf->list);
+
        spin_unlock_bh(&sc->tx.txbuflock);
 
+       return bf;
+}
+
+static void ath_tx_return_buffer(struct ath_softc *sc, struct ath_buf *bf)
+{
+       spin_lock_bh(&sc->tx.txbuflock);
+       list_add_tail(&bf->list, &sc->tx.txbuf);
+       spin_unlock_bh(&sc->tx.txbuflock);
+}
+
+static struct ath_buf* ath_clone_txbuf(struct ath_softc *sc, struct ath_buf *bf)
+{
+       struct ath_buf *tbf;
+
+       tbf = ath_tx_get_buffer(sc);
+       if (WARN_ON(!tbf))
+               return NULL;
+
        ATH_TXBUF_RESET(tbf);
 
        tbf->aphy = bf->aphy;
        tbf->bf_mpdu = bf->bf_mpdu;
        tbf->bf_buf_addr = bf->bf_buf_addr;
-       *(tbf->bf_desc) = *(bf->bf_desc);
+       memcpy(tbf->bf_desc, bf->bf_desc, sc->sc_ah->caps.tx_desc_len);
        tbf->bf_state = bf->bf_state;
        tbf->bf_dmacontext = bf->bf_dmacontext;
 
@@ -359,7 +384,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
                        acked_cnt++;
                } else {
                        if (!(tid->state & AGGR_CLEANUP) &&
-                           ts->ts_flags != ATH9K_TX_SW_ABORTED) {
+                           !bf_last->bf_tx_aborted) {
                                if (bf->bf_retries < ATH_MAX_SW_RETRIES) {
                                        ath_tx_set_retry(sc, txq, bf);
                                        txpending = 1;
@@ -378,7 +403,8 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
                        }
                }
 
-               if (bf_next == NULL) {
+               if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) &&
+                   bf_next == NULL) {
                        /*
                         * Make sure the last desc is reclaimed if it
                         * not a holding desc.
@@ -412,36 +438,43 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
                                !txfail, sendbar);
                } else {
                        /* retry the un-acked ones */
-                       if (bf->bf_next == NULL && bf_last->bf_stale) {
-                               struct ath_buf *tbf;
-
-                               tbf = ath_clone_txbuf(sc, bf_last);
-                               /*
-                                * Update tx baw and complete the frame with
-                                * failed status if we run out of tx buf
-                                */
-                               if (!tbf) {
-                                       spin_lock_bh(&txq->axq_lock);
-                                       ath_tx_update_baw(sc, tid,
-                                                         bf->bf_seqno);
-                                       spin_unlock_bh(&txq->axq_lock);
-
-                                       bf->bf_state.bf_type |= BUF_XRETRY;
-                                       ath_tx_rc_status(bf, ts, nbad,
-                                                        0, false);
-                                       ath_tx_complete_buf(sc, bf, txq,
-                                                           &bf_head, ts, 0, 0);
-                                       break;
+                       if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)) {
+                               if (bf->bf_next == NULL && bf_last->bf_stale) {
+                                       struct ath_buf *tbf;
+
+                                       tbf = ath_clone_txbuf(sc, bf_last);
+                                       /*
+                                        * Update tx baw and complete the
+                                        * frame with failed status if we
+                                        * run out of tx buf.
+                                        */
+                                       if (!tbf) {
+                                               spin_lock_bh(&txq->axq_lock);
+                                               ath_tx_update_baw(sc, tid,
+                                                               bf->bf_seqno);
+                                               spin_unlock_bh(&txq->axq_lock);
+
+                                               bf->bf_state.bf_type |=
+                                                       BUF_XRETRY;
+                                               ath_tx_rc_status(bf, ts, nbad,
+                                                               0, false);
+                                               ath_tx_complete_buf(sc, bf, txq,
+                                                                   &bf_head,
+                                                                   ts, 0, 0);
+                                               break;
+                                       }
+
+                                       ath9k_hw_cleartxdesc(sc->sc_ah,
+                                                            tbf->bf_desc);
+                                       list_add_tail(&tbf->list, &bf_head);
+                               } else {
+                                       /*
+                                        * Clear descriptor status words for
+                                        * software retry
+                                        */
+                                       ath9k_hw_cleartxdesc(sc->sc_ah,
+                                                            bf->bf_desc);
                                }
-
-                               ath9k_hw_cleartxdesc(sc->sc_ah, tbf->bf_desc);
-                               list_add_tail(&tbf->list, &bf_head);
-                       } else {
-                               /*
-                                * Clear descriptor status words for
-                                * software retry
-                                */
-                               ath9k_hw_cleartxdesc(sc->sc_ah, bf->bf_desc);
                        }
 
                        /*
@@ -509,12 +542,13 @@ static u32 ath_lookup_rate(struct ath_softc *sc, struct ath_buf *bf,
                                break;
                        }
 
-                       if (rates[i].flags & IEEE80211_TX_RC_SHORT_GI)
-                               modeidx = MCS_HT40_SGI;
-                       else if (rates[i].flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
+                       if (rates[i].flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
                                modeidx = MCS_HT40;
                        else
-                               modeidx = MCS_DEFAULT;
+                               modeidx = MCS_HT20;
+
+                       if (rates[i].flags & IEEE80211_TX_RC_SHORT_GI)
+                               modeidx++;
 
                        frmlen = ath_max_4ms_framelen[modeidx][rates[i].idx];
                        max_4ms_framelen = min(max_4ms_framelen, frmlen);
@@ -559,7 +593,7 @@ static int ath_compute_num_delims(struct ath_softc *sc, struct ath_atx_tid *tid,
        u32 nsymbits, nsymbols;
        u16 minlen;
        u8 flags, rix;
-       int width, half_gi, ndelim, mindelim;
+       int width, streams, half_gi, ndelim, mindelim;
 
        /* Select standard number of delimiters based on frame length alone */
        ndelim = ATH_AGGR_GET_NDELIM(frmlen);
@@ -599,7 +633,8 @@ static int ath_compute_num_delims(struct ath_softc *sc, struct ath_atx_tid *tid,
        if (nsymbols == 0)
                nsymbols = 1;
 
-       nsymbits = bits_per_symbol[rix][width];
+       streams = HT_RC_2_STREAMS(rix);
+       nsymbits = bits_per_symbol[rix % 8][width] * streams;
        minlen = (nsymbols * nsymbits) / BITS_PER_BYTE;
 
        if (frmlen < minlen) {
@@ -665,7 +700,7 @@ static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc,
                bpad = PADBYTES(al_delta) + (ndelim << 2);
 
                bf->bf_next = NULL;
-               bf->bf_desc->ds_link = 0;
+               ath9k_hw_set_desc_link(sc->sc_ah, bf->bf_desc, 0);
 
                /* link buffers of this frame to the aggregate */
                ath_tx_addto_baw(sc, tid, bf);
@@ -673,7 +708,8 @@ static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc,
                list_move_tail(&bf->list, bf_q);
                if (bf_prev) {
                        bf_prev->bf_next = bf;
-                       bf_prev->bf_desc->ds_link = bf->bf_daddr;
+                       ath9k_hw_set_desc_link(sc->sc_ah, bf_prev->bf_desc,
+                                              bf->bf_daddr);
                }
                bf_prev = bf;
 
@@ -853,7 +889,7 @@ struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype)
        struct ath_hw *ah = sc->sc_ah;
        struct ath_common *common = ath9k_hw_common(ah);
        struct ath9k_tx_queue_info qi;
-       int qnum;
+       int qnum, i;
 
        memset(&qi, 0, sizeof(qi));
        qi.tqi_subtype = subtype;
@@ -877,11 +913,16 @@ struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype)
         * The UAPSD queue is an exception, since we take a desc-
         * based intr on the EOSP frames.
         */
-       if (qtype == ATH9K_TX_QUEUE_UAPSD)
-               qi.tqi_qflags = TXQ_FLAG_TXDESCINT_ENABLE;
-       else
-               qi.tqi_qflags = TXQ_FLAG_TXEOLINT_ENABLE |
-                       TXQ_FLAG_TXDESCINT_ENABLE;
+       if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
+               qi.tqi_qflags = TXQ_FLAG_TXOKINT_ENABLE |
+                               TXQ_FLAG_TXERRINT_ENABLE;
+       } else {
+               if (qtype == ATH9K_TX_QUEUE_UAPSD)
+                       qi.tqi_qflags = TXQ_FLAG_TXDESCINT_ENABLE;
+               else
+                       qi.tqi_qflags = TXQ_FLAG_TXEOLINT_ENABLE |
+                                       TXQ_FLAG_TXDESCINT_ENABLE;
+       }
        qnum = ath9k_hw_setuptxqueue(ah, qtype, &qi);
        if (qnum == -1) {
                /*
@@ -908,6 +949,11 @@ struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype)
                txq->axq_depth = 0;
                txq->axq_tx_inprogress = false;
                sc->tx.txqsetup |= 1<<qnum;
+
+               txq->txq_headidx = txq->txq_tailidx = 0;
+               for (i = 0; i < ATH_TXFIFO_DEPTH; i++)
+                       INIT_LIST_HEAD(&txq->txq_fifo[i]);
+               INIT_LIST_HEAD(&txq->txq_fifo_pending);
        }
        return &sc->tx.txq[qnum];
 }
@@ -1035,36 +1081,52 @@ void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx)
        struct ath_tx_status ts;
 
        memset(&ts, 0, sizeof(ts));
-       if (!retry_tx)
-               ts.ts_flags = ATH9K_TX_SW_ABORTED;
-
        INIT_LIST_HEAD(&bf_head);
 
        for (;;) {
                spin_lock_bh(&txq->axq_lock);
 
-               if (list_empty(&txq->axq_q)) {
-                       txq->axq_link = NULL;
-                       spin_unlock_bh(&txq->axq_lock);
-                       break;
-               }
-
-               bf = list_first_entry(&txq->axq_q, struct ath_buf, list);
+               if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
+                       if (list_empty(&txq->txq_fifo[txq->txq_tailidx])) {
+                               txq->txq_headidx = txq->txq_tailidx = 0;
+                               spin_unlock_bh(&txq->axq_lock);
+                               break;
+                       } else {
+                               bf = list_first_entry(&txq->txq_fifo[txq->txq_tailidx],
+                                                     struct ath_buf, list);
+                       }
+               } else {
+                       if (list_empty(&txq->axq_q)) {
+                               txq->axq_link = NULL;
+                               spin_unlock_bh(&txq->axq_lock);
+                               break;
+                       }
+                       bf = list_first_entry(&txq->axq_q, struct ath_buf,
+                                             list);
 
-               if (bf->bf_stale) {
-                       list_del(&bf->list);
-                       spin_unlock_bh(&txq->axq_lock);
+                       if (bf->bf_stale) {
+                               list_del(&bf->list);
+                               spin_unlock_bh(&txq->axq_lock);
 
-                       spin_lock_bh(&sc->tx.txbuflock);
-                       list_add_tail(&bf->list, &sc->tx.txbuf);
-                       spin_unlock_bh(&sc->tx.txbuflock);
-                       continue;
+                               ath_tx_return_buffer(sc, bf);
+                               continue;
+                       }
                }
 
                lastbf = bf->bf_lastbf;
+               if (!retry_tx)
+                       lastbf->bf_tx_aborted = true;
+
+               if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
+                       list_cut_position(&bf_head,
+                                         &txq->txq_fifo[txq->txq_tailidx],
+                                         &lastbf->list);
+                       INCR(txq->txq_tailidx, ATH_TXFIFO_DEPTH);
+               } else {
+                       /* remove ath_buf's of the same mpdu from txq */
+                       list_cut_position(&bf_head, &txq->axq_q, &lastbf->list);
+               }
 
-               /* remove ath_buf's of the same mpdu from txq */
-               list_cut_position(&bf_head, &txq->axq_q, &lastbf->list);
                txq->axq_depth--;
 
                spin_unlock_bh(&txq->axq_lock);
@@ -1087,6 +1149,27 @@ void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx)
                        spin_unlock_bh(&txq->axq_lock);
                }
        }
+
+       if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
+               spin_lock_bh(&txq->axq_lock);
+               while (!list_empty(&txq->txq_fifo_pending)) {
+                       bf = list_first_entry(&txq->txq_fifo_pending,
+                                             struct ath_buf, list);
+                       list_cut_position(&bf_head,
+                                         &txq->txq_fifo_pending,
+                                         &bf->bf_lastbf->list);
+                       spin_unlock_bh(&txq->axq_lock);
+
+                       if (bf_isampdu(bf))
+                               ath_tx_complete_aggr(sc, txq, bf, &bf_head,
+                                                    &ts, 0);
+                       else
+                               ath_tx_complete_buf(sc, bf, txq, &bf_head,
+                                                   &ts, 0, 0);
+                       spin_lock_bh(&txq->axq_lock);
+               }
+               spin_unlock_bh(&txq->axq_lock);
+       }
 }
 
 void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx)
@@ -1224,44 +1307,47 @@ static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq,
 
        bf = list_first_entry(head, struct ath_buf, list);
 
-       list_splice_tail_init(head, &txq->axq_q);
-       txq->axq_depth++;
-
        ath_print(common, ATH_DBG_QUEUE,
                  "qnum: %d, txq depth: %d\n", txq->axq_qnum, txq->axq_depth);
 
-       if (txq->axq_link == NULL) {
+       if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
+               if (txq->axq_depth >= ATH_TXFIFO_DEPTH) {
+                       list_splice_tail_init(head, &txq->txq_fifo_pending);
+                       return;
+               }
+               if (!list_empty(&txq->txq_fifo[txq->txq_headidx]))
+                       ath_print(common, ATH_DBG_XMIT,
+                                 "Initializing tx fifo %d which "
+                                 "is non-empty\n",
+                                 txq->txq_headidx);
+               INIT_LIST_HEAD(&txq->txq_fifo[txq->txq_headidx]);
+               list_splice_init(head, &txq->txq_fifo[txq->txq_headidx]);
+               INCR(txq->txq_headidx, ATH_TXFIFO_DEPTH);
                ath9k_hw_puttxbuf(ah, txq->axq_qnum, bf->bf_daddr);
                ath_print(common, ATH_DBG_XMIT,
                          "TXDP[%u] = %llx (%p)\n",
                          txq->axq_qnum, ito64(bf->bf_daddr), bf->bf_desc);
        } else {
-               *txq->axq_link = bf->bf_daddr;
-               ath_print(common, ATH_DBG_XMIT, "link[%u] (%p)=%llx (%p)\n",
-                         txq->axq_qnum, txq->axq_link,
-                         ito64(bf->bf_daddr), bf->bf_desc);
-       }
-       txq->axq_link = &(bf->bf_lastbf->bf_desc->ds_link);
-       ath9k_hw_txstart(ah, txq->axq_qnum);
-}
+               list_splice_tail_init(head, &txq->axq_q);
 
-static struct ath_buf *ath_tx_get_buffer(struct ath_softc *sc)
-{
-       struct ath_buf *bf = NULL;
-
-       spin_lock_bh(&sc->tx.txbuflock);
-
-       if (unlikely(list_empty(&sc->tx.txbuf))) {
-               spin_unlock_bh(&sc->tx.txbuflock);
-               return NULL;
+               if (txq->axq_link == NULL) {
+                       ath9k_hw_puttxbuf(ah, txq->axq_qnum, bf->bf_daddr);
+                       ath_print(common, ATH_DBG_XMIT,
+                                       "TXDP[%u] = %llx (%p)\n",
+                                       txq->axq_qnum, ito64(bf->bf_daddr),
+                                       bf->bf_desc);
+               } else {
+                       *txq->axq_link = bf->bf_daddr;
+                       ath_print(common, ATH_DBG_XMIT,
+                                       "link[%u] (%p)=%llx (%p)\n",
+                                       txq->axq_qnum, txq->axq_link,
+                                       ito64(bf->bf_daddr), bf->bf_desc);
+               }
+               ath9k_hw_get_desc_link(ah, bf->bf_lastbf->bf_desc,
+                                      &txq->axq_link);
+               ath9k_hw_txstart(ah, txq->axq_qnum);
        }
-
-       bf = list_first_entry(&sc->tx.txbuf, struct ath_buf, list);
-       list_del(&bf->list);
-
-       spin_unlock_bh(&sc->tx.txbuflock);
-
-       return bf;
+       txq->axq_depth++;
 }
 
 static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid,
@@ -1408,8 +1494,7 @@ static void assign_aggr_tid_seqno(struct sk_buff *skb,
        INCR(tid->seq_next, IEEE80211_SEQ_MAX);
 }
 
-static int setup_tx_flags(struct ath_softc *sc, struct sk_buff *skb,
-                         struct ath_txq *txq)
+static int setup_tx_flags(struct sk_buff *skb, bool use_ldpc)
 {
        struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
        int flags = 0;
@@ -1420,6 +1505,9 @@ static int setup_tx_flags(struct ath_softc *sc, struct sk_buff *skb,
        if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK)
                flags |= ATH9K_TXDESC_NOACK;
 
+       if (use_ldpc)
+               flags |= ATH9K_TXDESC_LDPC;
+
        return flags;
 }
 
@@ -1438,8 +1526,9 @@ static u32 ath_pkt_duration(struct ath_softc *sc, u8 rix, struct ath_buf *bf,
        pktlen = bf_isaggr(bf) ? bf->bf_al : bf->bf_frmlen;
 
        /* find number of symbols: PLCP + data */
+       streams = HT_RC_2_STREAMS(rix);
        nbits = (pktlen << 3) + OFDM_PLCP_BITS;
-       nsymbits = bits_per_symbol[rix][width];
+       nsymbits = bits_per_symbol[rix % 8][width] * streams;
        nsymbols = (nbits + nsymbits - 1) / nsymbits;
 
        if (!half_gi)
@@ -1448,7 +1537,6 @@ static u32 ath_pkt_duration(struct ath_softc *sc, u8 rix, struct ath_buf *bf,
                duration = SYMBOL_TIME_HALFGI(nsymbols);
 
        /* addup duration for legacy/ht training and signal fields */
-       streams = HT_RC_2_STREAMS(rix);
        duration += L_STF + L_LTF + L_SIG + HT_SIG + HT_STF + HT_LTF(streams);
 
        return duration;
@@ -1519,6 +1607,8 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf)
                        series[i].Rate = rix | 0x80;
                        series[i].PktDuration = ath_pkt_duration(sc, rix, bf,
                                 is_40, is_sgi, is_sp);
+                       if (rix < 8 && (tx_info->flags & IEEE80211_TX_CTL_STBC))
+                               series[i].RateFlags |= ATH9K_RATESERIES_STBC;
                        continue;
                }
 
@@ -1571,6 +1661,7 @@ static int ath_tx_setup_buffer(struct ieee80211_hw *hw, struct ath_buf *bf,
        int hdrlen;
        __le16 fc;
        int padpos, padsize;
+       bool use_ldpc = false;
 
        tx_info->pad[0] = 0;
        switch (txctl->frame_type) {
@@ -1597,10 +1688,13 @@ static int ath_tx_setup_buffer(struct ieee80211_hw *hw, struct ath_buf *bf,
                bf->bf_frmlen -= padsize;
        }
 
-       if (conf_is_ht(&hw->conf))
+       if (conf_is_ht(&hw->conf)) {
                bf->bf_state.bf_type |= BUF_HT;
+               if (tx_info->flags & IEEE80211_TX_CTL_LDPC)
+                       use_ldpc = true;
+       }
 
-       bf->bf_flags = setup_tx_flags(sc, skb, txctl->txq);
+       bf->bf_flags = setup_tx_flags(skb, use_ldpc);
 
        bf->bf_keytype = get_hw_crypto_keytype(skb);
        if (bf->bf_keytype != ATH9K_KEY_TYPE_CLEAR) {
@@ -1659,8 +1753,7 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf,
        list_add_tail(&bf->list, &bf_head);
 
        ds = bf->bf_desc;
-       ds->ds_link = 0;
-       ds->ds_data = bf->bf_buf_addr;
+       ath9k_hw_set_desc_link(ah, ds, 0);
 
        ath9k_hw_set11n_txdesc(ah, ds, bf->bf_frmlen, frm_type, MAX_RATE_POWER,
                               bf->bf_keyix, bf->bf_keytype, bf->bf_flags);
@@ -1669,7 +1762,9 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf,
                            skb->len,   /* segment length */
                            true,       /* first segment */
                            true,       /* last segment */
-                           ds);        /* first descriptor */
+                           ds,         /* first descriptor */
+                           bf->bf_buf_addr,
+                           txctl->txq->axq_qnum);
 
        spin_lock_bh(&txctl->txq->axq_lock);
 
@@ -1738,9 +1833,7 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
                }
                spin_unlock_bh(&txq->axq_lock);
 
-               spin_lock_bh(&sc->tx.txbuflock);
-               list_add_tail(&bf->list, &sc->tx.txbuf);
-               spin_unlock_bh(&sc->tx.txbuflock);
+               ath_tx_return_buffer(sc, bf);
 
                return r;
        }
@@ -1896,7 +1989,7 @@ static int ath_tx_num_badfrms(struct ath_softc *sc, struct ath_buf *bf,
        int nbad = 0;
        int isaggr = 0;
 
-       if (ts->ts_flags == ATH9K_TX_SW_ABORTED)
+       if (bf->bf_tx_aborted)
                return 0;
 
        isaggr = bf_isaggr(bf);
@@ -2054,13 +2147,12 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
                txq->axq_depth--;
                txok = !(ts.ts_status & ATH9K_TXERR_MASK);
                txq->axq_tx_inprogress = false;
+               if (bf_held)
+                       list_del(&bf_held->list);
                spin_unlock_bh(&txq->axq_lock);
 
-               if (bf_held) {
-                       spin_lock_bh(&sc->tx.txbuflock);
-                       list_move_tail(&bf_held->list, &sc->tx.txbuf);
-                       spin_unlock_bh(&sc->tx.txbuflock);
-               }
+               if (bf_held)
+                       ath_tx_return_buffer(sc, bf_held);
 
                if (!bf_isampdu(bf)) {
                        /*
@@ -2138,10 +2230,119 @@ void ath_tx_tasklet(struct ath_softc *sc)
        }
 }
 
+void ath_tx_edma_tasklet(struct ath_softc *sc)
+{
+       struct ath_tx_status txs;
+       struct ath_common *common = ath9k_hw_common(sc->sc_ah);
+       struct ath_hw *ah = sc->sc_ah;
+       struct ath_txq *txq;
+       struct ath_buf *bf, *lastbf;
+       struct list_head bf_head;
+       int status;
+       int txok;
+
+       for (;;) {
+               status = ath9k_hw_txprocdesc(ah, NULL, (void *)&txs);
+               if (status == -EINPROGRESS)
+                       break;
+               if (status == -EIO) {
+                       ath_print(common, ATH_DBG_XMIT,
+                                 "Error processing tx status\n");
+                       break;
+               }
+
+               /* Skip beacon completions */
+               if (txs.qid == sc->beacon.beaconq)
+                       continue;
+
+               txq = &sc->tx.txq[txs.qid];
+
+               spin_lock_bh(&txq->axq_lock);
+               if (list_empty(&txq->txq_fifo[txq->txq_tailidx])) {
+                       spin_unlock_bh(&txq->axq_lock);
+                       return;
+               }
+
+               bf = list_first_entry(&txq->txq_fifo[txq->txq_tailidx],
+                                     struct ath_buf, list);
+               lastbf = bf->bf_lastbf;
+
+               INIT_LIST_HEAD(&bf_head);
+               list_cut_position(&bf_head, &txq->txq_fifo[txq->txq_tailidx],
+                                 &lastbf->list);
+               INCR(txq->txq_tailidx, ATH_TXFIFO_DEPTH);
+               txq->axq_depth--;
+               txq->axq_tx_inprogress = false;
+               spin_unlock_bh(&txq->axq_lock);
+
+               txok = !(txs.ts_status & ATH9K_TXERR_MASK);
+
+               if (!bf_isampdu(bf)) {
+                       bf->bf_retries = txs.ts_longretry;
+                       if (txs.ts_status & ATH9K_TXERR_XRETRY)
+                               bf->bf_state.bf_type |= BUF_XRETRY;
+                       ath_tx_rc_status(bf, &txs, 0, txok, true);
+               }
+
+               if (bf_isampdu(bf))
+                       ath_tx_complete_aggr(sc, txq, bf, &bf_head, &txs, txok);
+               else
+                       ath_tx_complete_buf(sc, bf, txq, &bf_head,
+                                           &txs, txok, 0);
+
+               spin_lock_bh(&txq->axq_lock);
+               if (!list_empty(&txq->txq_fifo_pending)) {
+                       INIT_LIST_HEAD(&bf_head);
+                       bf = list_first_entry(&txq->txq_fifo_pending,
+                               struct ath_buf, list);
+                       list_cut_position(&bf_head, &txq->txq_fifo_pending,
+                               &bf->bf_lastbf->list);
+                       ath_tx_txqaddbuf(sc, txq, &bf_head);
+               } else if (sc->sc_flags & SC_OP_TXAGGR)
+                       ath_txq_schedule(sc, txq);
+               spin_unlock_bh(&txq->axq_lock);
+       }
+}
+
 /*****************/
 /* Init, Cleanup */
 /*****************/
 
+static int ath_txstatus_setup(struct ath_softc *sc, int size)
+{
+       struct ath_descdma *dd = &sc->txsdma;
+       u8 txs_len = sc->sc_ah->caps.txs_len;
+
+       dd->dd_desc_len = size * txs_len;
+       dd->dd_desc = dma_alloc_coherent(sc->dev, dd->dd_desc_len,
+                                        &dd->dd_desc_paddr, GFP_KERNEL);
+       if (!dd->dd_desc)
+               return -ENOMEM;
+
+       return 0;
+}
+
+static int ath_tx_edma_init(struct ath_softc *sc)
+{
+       int err;
+
+       err = ath_txstatus_setup(sc, ATH_TXSTATUS_RING_SIZE);
+       if (!err)
+               ath9k_hw_setup_statusring(sc->sc_ah, sc->txsdma.dd_desc,
+                                         sc->txsdma.dd_desc_paddr,
+                                         ATH_TXSTATUS_RING_SIZE);
+
+       return err;
+}
+
+static void ath_tx_edma_cleanup(struct ath_softc *sc)
+{
+       struct ath_descdma *dd = &sc->txsdma;
+
+       dma_free_coherent(sc->dev, dd->dd_desc_len, dd->dd_desc,
+                         dd->dd_desc_paddr);
+}
+
 int ath_tx_init(struct ath_softc *sc, int nbufs)
 {
        struct ath_common *common = ath9k_hw_common(sc->sc_ah);
@@ -2150,7 +2351,7 @@ int ath_tx_init(struct ath_softc *sc, int nbufs)
        spin_lock_init(&sc->tx.txbuflock);
 
        error = ath_descdma_setup(sc, &sc->tx.txdma, &sc->tx.txbuf,
-                                 "tx", nbufs, 1);
+                                 "tx", nbufs, 1, 1);
        if (error != 0) {
                ath_print(common, ATH_DBG_FATAL,
                          "Failed to allocate tx descriptors: %d\n", error);
@@ -2158,7 +2359,7 @@ int ath_tx_init(struct ath_softc *sc, int nbufs)
        }
 
        error = ath_descdma_setup(sc, &sc->beacon.bdma, &sc->beacon.bbuf,
-                                 "beacon", ATH_BCBUF, 1);
+                                 "beacon", ATH_BCBUF, 1, 1);
        if (error != 0) {
                ath_print(common, ATH_DBG_FATAL,
                          "Failed to allocate beacon descriptors: %d\n", error);
@@ -2167,6 +2368,12 @@ int ath_tx_init(struct ath_softc *sc, int nbufs)
 
        INIT_DELAYED_WORK(&sc->tx_complete_work, ath_tx_complete_poll_work);
 
+       if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
+               error = ath_tx_edma_init(sc);
+               if (error)
+                       goto err;
+       }
+
 err:
        if (error != 0)
                ath_tx_cleanup(sc);
@@ -2181,6 +2388,9 @@ void ath_tx_cleanup(struct ath_softc *sc)
 
        if (sc->tx.txdma.dd_desc_len != 0)
                ath_descdma_cleanup(sc, &sc->tx.txdma, &sc->tx.txbuf);
+
+       if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
+               ath_tx_edma_cleanup(sc);
 }
 
 void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an)
index a684a72eb6e980caa78a89f5cf0b7f62d2aea882..5ed2dcbe6d01bbb0dc4c87b9d34a04b185dddf4f 100644 (file)
@@ -12,6 +12,7 @@ obj-$(CONFIG_IWLAGN)  += iwlagn.o
 iwlagn-objs            := iwl-agn.o iwl-agn-rs.o iwl-agn-led.o iwl-agn-ict.o
 iwlagn-objs            += iwl-agn-ucode.o iwl-agn-hcmd.o iwl-agn-tx.o
 iwlagn-objs            += iwl-agn-lib.o
+iwlagn-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-agn-debugfs.o
 
 iwlagn-$(CONFIG_IWL4965) += iwl-4965.o
 iwlagn-$(CONFIG_IWL5000) += iwl-5000.o
index 9a0191a5ea35761e5e412aaeaeb5e6e23d950d8e..8431ffce37d3e8cea51bf24df3aeeb4e0d56f324 100644 (file)
@@ -46,6 +46,7 @@
 #include "iwl-helpers.h"
 #include "iwl-agn-hw.h"
 #include "iwl-agn-led.h"
+#include "iwl-agn-debugfs.h"
 
 /* Highest firmware API version supported */
 #define IWL1000_UCODE_API_MAX 3
@@ -212,6 +213,11 @@ static struct iwl_lib_ops iwl1000_lib = {
                .set_ct_kill = iwl1000_set_ct_threshold,
         },
        .add_bcast_station = iwl_add_bcast_station,
+       .debugfs_ops = {
+               .rx_stats_read = iwl_ucode_rx_stats_read,
+               .tx_stats_read = iwl_ucode_tx_stats_read,
+               .general_stats_read = iwl_ucode_general_stats_read,
+       },
        .recover_from_tx_stall = iwl_bg_monitor_recover,
        .check_plcp_health = iwl_good_plcp_health,
        .check_ack_health = iwl_good_ack_health,
index bde3b4cbab9d6519d76d287e62cffb53616449b9..59af2594c9c5a5e1842643c26a838e0b17beba4a 100644 (file)
@@ -2688,6 +2688,7 @@ IWL3945_UCODE_GET(boot_size);
 static struct iwl_hcmd_ops iwl3945_hcmd = {
        .rxon_assoc = iwl3945_send_rxon_assoc,
        .commit_rxon = iwl3945_commit_rxon,
+       .send_bt_config = iwl_send_bt_config,
 };
 
 static struct iwl_ucode_ops iwl3945_ucode = {
@@ -2741,6 +2742,7 @@ static struct iwl_hcmd_utils_ops iwl3945_hcmd_utils = {
        .get_hcmd_size = iwl3945_get_hcmd_size,
        .build_addsta_hcmd = iwl3945_build_addsta_hcmd,
        .rts_tx_cmd_flag = iwlcore_rts_tx_cmd_flag,
+       .request_scan = iwl3945_request_scan,
 };
 
 static const struct iwl_ops iwl3945_ops = {
index b89219573b916158b90a4334b725911375f82192..e9674f0a1e949c379b043d4ee5da6c31ee2ccd2e 100644 (file)
@@ -294,6 +294,9 @@ extern const struct iwl_channel_info *iwl3945_get_channel_info(
 
 extern int iwl3945_rs_next_rate(struct iwl_priv *priv, int rate);
 
+/* scanning */
+void iwl3945_request_scan(struct iwl_priv *priv);
+
 /* Requires full declaration of iwl_priv before including */
 #include "iwl-io.h"
 
index 2e3cda75f3ad3a56f7c7091b7ae37cab3ab6284f..136c29067489ebbadbe9ec25593285cd973ea20a 100644 (file)
@@ -47,6 +47,7 @@
 #include "iwl-sta.h"
 #include "iwl-agn-led.h"
 #include "iwl-agn.h"
+#include "iwl-agn-debugfs.h"
 
 static int iwl4965_send_tx_power(struct iwl_priv *priv);
 static int iwl4965_hw_get_temperature(struct iwl_priv *priv);
@@ -2143,6 +2144,7 @@ static struct iwl_hcmd_ops iwl4965_hcmd = {
        .rxon_assoc = iwl4965_send_rxon_assoc,
        .commit_rxon = iwl_commit_rxon,
        .set_rxon_chain = iwl_set_rxon_chain,
+       .send_bt_config = iwl_send_bt_config,
 };
 
 static struct iwl_ucode_ops iwl4965_ucode = {
@@ -2162,6 +2164,7 @@ static struct iwl_hcmd_utils_ops iwl4965_hcmd_utils = {
        .gain_computation = iwl4965_gain_computation,
        .rts_tx_cmd_flag = iwlcore_rts_tx_cmd_flag,
        .calc_rssi = iwl4965_calc_rssi,
+       .request_scan = iwlagn_request_scan,
 };
 
 static struct iwl_lib_ops iwl4965_lib = {
@@ -2216,6 +2219,11 @@ static struct iwl_lib_ops iwl4965_lib = {
                .set_ct_kill = iwl4965_set_ct_threshold,
        },
        .add_bcast_station = iwl_add_bcast_station,
+       .debugfs_ops = {
+               .rx_stats_read = iwl_ucode_rx_stats_read,
+               .tx_stats_read = iwl_ucode_tx_stats_read,
+               .general_stats_read = iwl_ucode_general_stats_read,
+       },
        .check_plcp_health = iwl_good_plcp_health,
 };
 
@@ -2253,8 +2261,13 @@ struct iwl_cfg iwl4965_agn_cfg = {
        .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
        .monitor_recover_period = IWL_MONITORING_PERIOD,
        .temperature_kelvin = true,
-       .off_channel_workaround = true,
        .max_event_log_size = 512,
+
+       /*
+        * Force use of chains B and C for scan RX on 5 GHz band
+        * because the device has off-channel reception on chain A.
+        */
+       .scan_antennas[IEEE80211_BAND_5GHZ] = ANT_BC,
 };
 
 /* Module firmware */
index e967cfcac2249adfb9493e058df2d3abbd97f0c3..e434936852714599d9eee6c67fb082cc5ad97d06 100644 (file)
@@ -48,6 +48,7 @@
 #include "iwl-agn-led.h"
 #include "iwl-agn-hw.h"
 #include "iwl-5000-hw.h"
+#include "iwl-agn-debugfs.h"
 
 /* Highest firmware API version supported */
 #define IWL5000_UCODE_API_MAX 2
@@ -320,6 +321,11 @@ static struct iwl_lib_ops iwl5000_lib = {
                .set_ct_kill = iwl5000_set_ct_threshold,
         },
        .add_bcast_station = iwl_add_bcast_station,
+       .debugfs_ops = {
+               .rx_stats_read = iwl_ucode_rx_stats_read,
+               .tx_stats_read = iwl_ucode_tx_stats_read,
+               .general_stats_read = iwl_ucode_general_stats_read,
+       },
        .recover_from_tx_stall = iwl_bg_monitor_recover,
        .check_plcp_health = iwl_good_plcp_health,
        .check_ack_health = iwl_good_ack_health,
@@ -377,6 +383,11 @@ static struct iwl_lib_ops iwl5150_lib = {
                .set_ct_kill = iwl5150_set_ct_threshold,
         },
        .add_bcast_station = iwl_add_bcast_station,
+       .debugfs_ops = {
+               .rx_stats_read = iwl_ucode_rx_stats_read,
+               .tx_stats_read = iwl_ucode_tx_stats_read,
+               .general_stats_read = iwl_ucode_general_stats_read,
+       },
        .recover_from_tx_stall = iwl_bg_monitor_recover,
        .check_plcp_health = iwl_good_plcp_health,
        .check_ack_health = iwl_good_ack_health,
index 3e32693d1c2f024247d2305b76b73a0f52c2408a..7da23d3ff7b65efbf6e4b6563f1fc60a3e5b4959 100644 (file)
 #include "iwl-agn-hw.h"
 #include "iwl-6000-hw.h"
 #include "iwl-agn-led.h"
+#include "iwl-agn-debugfs.h"
 
 /* Highest firmware API version supported */
 #define IWL6000_UCODE_API_MAX 4
 #define IWL6050_UCODE_API_MAX 4
+#define IWL6000G2_UCODE_API_MAX 4
 
 /* Lowest firmware API version supported */
 #define IWL6000_UCODE_API_MIN 4
 #define IWL6050_UCODE_API_MIN 4
+#define IWL6000G2_UCODE_API_MIN 4
 
 #define IWL6000_FW_PRE "iwlwifi-6000-"
-#define IWL6000_G2_FW_PRE "iwlwifi-6005-"
 #define _IWL6000_MODULE_FIRMWARE(api) IWL6000_FW_PRE #api ".ucode"
 #define IWL6000_MODULE_FIRMWARE(api) _IWL6000_MODULE_FIRMWARE(api)
 
 #define _IWL6050_MODULE_FIRMWARE(api) IWL6050_FW_PRE #api ".ucode"
 #define IWL6050_MODULE_FIRMWARE(api) _IWL6050_MODULE_FIRMWARE(api)
 
+#define IWL6000G2_FW_PRE "iwlwifi-6005-"
+#define _IWL6000G2_MODULE_FIRMWARE(api) IWL6000G2_FW_PRE #api ".ucode"
+#define IWL6000G2_MODULE_FIRMWARE(api) _IWL6000G2_MODULE_FIRMWARE(api)
+
 static void iwl6000_set_ct_threshold(struct iwl_priv *priv)
 {
        /* want Celsius */
@@ -261,7 +267,6 @@ static struct iwl_lib_ops iwl6000_lib = {
                        EEPROM_REG_BAND_3_CHANNELS,
                        EEPROM_REG_BAND_4_CHANNELS,
                        EEPROM_REG_BAND_5_CHANNELS,
-                       EEPROM_REG_BAND_24_HT40_CHANNELS,
                        EEPROM_6000_REG_BAND_24_HT40_CHANNELS,
                        EEPROM_REG_BAND_52_HT40_CHANNELS
                },
@@ -280,6 +285,11 @@ static struct iwl_lib_ops iwl6000_lib = {
                .set_ct_kill = iwl6000_set_ct_threshold,
         },
        .add_bcast_station = iwl_add_bcast_station,
+       .debugfs_ops = {
+               .rx_stats_read = iwl_ucode_rx_stats_read,
+               .tx_stats_read = iwl_ucode_tx_stats_read,
+               .general_stats_read = iwl_ucode_general_stats_read,
+       },
        .recover_from_tx_stall = iwl_bg_monitor_recover,
        .check_plcp_health = iwl_good_plcp_health,
        .check_ack_health = iwl_good_ack_health,
@@ -348,6 +358,11 @@ static struct iwl_lib_ops iwl6050_lib = {
                .set_calib_version = iwl6050_set_calib_version,
         },
        .add_bcast_station = iwl_add_bcast_station,
+       .debugfs_ops = {
+               .rx_stats_read = iwl_ucode_rx_stats_read,
+               .tx_stats_read = iwl_ucode_tx_stats_read,
+               .general_stats_read = iwl_ucode_general_stats_read,
+       },
        .recover_from_tx_stall = iwl_bg_monitor_recover,
        .check_plcp_health = iwl_good_plcp_health,
        .check_ack_health = iwl_good_ack_health,
@@ -364,16 +379,16 @@ static const struct iwl_ops iwl6050_ops = {
 /*
  * "i": Internal configuration, use internal Power Amplifier
  */
-struct iwl_cfg iwl6000i_g2_2agn_cfg = {
+struct iwl_cfg iwl6000g2_2agn_cfg = {
        .name = "6000 Series 2x2 AGN Gen2",
-       .fw_name_pre = IWL6000_G2_FW_PRE,
-       .ucode_api_max = IWL6000_UCODE_API_MAX,
-       .ucode_api_min = IWL6000_UCODE_API_MIN,
+       .fw_name_pre = IWL6000G2_FW_PRE,
+       .ucode_api_max = IWL6000G2_UCODE_API_MAX,
+       .ucode_api_min = IWL6000G2_UCODE_API_MIN,
        .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
        .ops = &iwl6000_ops,
        .eeprom_size = OTP_LOW_IMAGE_SIZE,
-       .eeprom_ver = EEPROM_6000_EEPROM_VERSION,
-       .eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION,
+       .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
+       .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
        .num_of_queues = IWLAGN_NUM_QUEUES,
        .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
        .mod_params = &iwlagn_mod_params,
@@ -382,7 +397,7 @@ struct iwl_cfg iwl6000i_g2_2agn_cfg = {
        .pll_cfg_val = 0,
        .set_l0s = true,
        .use_bsm = false,
-       .pa_type = IWL_PA_INTERNAL,
+       .pa_type = IWL_PA_SYSTEM,
        .max_ll_items = OTP_MAX_LL_ITEMS_6x00,
        .shadow_ram_support = true,
        .ht_greenfield_support = true,
@@ -601,3 +616,4 @@ struct iwl_cfg iwl6000_3agn_cfg = {
 
 MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX));
 MODULE_FIRMWARE(IWL6050_MODULE_FIRMWARE(IWL6050_UCODE_API_MAX));
+MODULE_FIRMWARE(IWL6000G2_MODULE_FIRMWARE(IWL6000G2_UCODE_API_MAX));
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c
new file mode 100644 (file)
index 0000000..f249b70
--- /dev/null
@@ -0,0 +1,834 @@
+/******************************************************************************
+*
+* GPL LICENSE SUMMARY
+*
+* Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of version 2 of the GNU General Public License as
+* published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful, but
+* WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
+* USA
+*
+* The full GNU General Public License is included in this distribution
+* in the file called LICENSE.GPL.
+*
+* Contact Information:
+*  Intel Linux Wireless <ilw@linux.intel.com>
+* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+*****************************************************************************/
+
+#include "iwl-agn-debugfs.h"
+
+ssize_t iwl_ucode_rx_stats_read(struct file *file, char __user *user_buf,
+                               size_t count, loff_t *ppos)
+  {
+       struct iwl_priv *priv = file->private_data;
+       int pos = 0;
+       char *buf;
+       int bufsz = sizeof(struct statistics_rx_phy) * 40 +
+                   sizeof(struct statistics_rx_non_phy) * 40 +
+                   sizeof(struct statistics_rx_ht_phy) * 40 + 400;
+       ssize_t ret;
+       struct statistics_rx_phy *ofdm, *accum_ofdm, *delta_ofdm, *max_ofdm;
+       struct statistics_rx_phy *cck, *accum_cck, *delta_cck, *max_cck;
+       struct statistics_rx_non_phy *general, *accum_general;
+       struct statistics_rx_non_phy *delta_general, *max_general;
+       struct statistics_rx_ht_phy *ht, *accum_ht, *delta_ht, *max_ht;
+
+       if (!iwl_is_alive(priv))
+               return -EAGAIN;
+
+       buf = kzalloc(bufsz, GFP_KERNEL);
+       if (!buf) {
+               IWL_ERR(priv, "Can not allocate Buffer\n");
+               return -ENOMEM;
+       }
+
+       /*
+        * the statistic information display here is based on
+        * the last statistics notification from uCode
+        * might not reflect the current uCode activity
+        */
+       ofdm = &priv->statistics.rx.ofdm;
+       cck = &priv->statistics.rx.cck;
+       general = &priv->statistics.rx.general;
+       ht = &priv->statistics.rx.ofdm_ht;
+       accum_ofdm = &priv->accum_statistics.rx.ofdm;
+       accum_cck = &priv->accum_statistics.rx.cck;
+       accum_general = &priv->accum_statistics.rx.general;
+       accum_ht = &priv->accum_statistics.rx.ofdm_ht;
+       delta_ofdm = &priv->delta_statistics.rx.ofdm;
+       delta_cck = &priv->delta_statistics.rx.cck;
+       delta_general = &priv->delta_statistics.rx.general;
+       delta_ht = &priv->delta_statistics.rx.ofdm_ht;
+       max_ofdm = &priv->max_delta.rx.ofdm;
+       max_cck = &priv->max_delta.rx.cck;
+       max_general = &priv->max_delta.rx.general;
+       max_ht = &priv->max_delta.rx.ofdm_ht;
+
+       pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz);
+       pos += scnprintf(buf + pos, bufsz - pos, "%-32s     current"
+                        "acumulative       delta         max\n",
+                        "Statistics_Rx - OFDM:");
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "  %-30s %10u  %10u  %10u  %10u\n",
+                        "ina_cnt:", le32_to_cpu(ofdm->ina_cnt),
+                        accum_ofdm->ina_cnt,
+                        delta_ofdm->ina_cnt, max_ofdm->ina_cnt);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "  %-30s %10u  %10u  %10u  %10u\n",
+                        "fina_cnt:",
+                        le32_to_cpu(ofdm->fina_cnt), accum_ofdm->fina_cnt,
+                        delta_ofdm->fina_cnt, max_ofdm->fina_cnt);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "  %-30s %10u  %10u  %10u  %10u\n",
+                        "plcp_err:",
+                        le32_to_cpu(ofdm->plcp_err), accum_ofdm->plcp_err,
+                        delta_ofdm->plcp_err, max_ofdm->plcp_err);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "  %-30s %10u  %10u  %10u  %10u\n", "crc32_err:",
+                        le32_to_cpu(ofdm->crc32_err), accum_ofdm->crc32_err,
+                        delta_ofdm->crc32_err, max_ofdm->crc32_err);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "  %-30s %10u  %10u  %10u  %10u\n", "overrun_err:",
+                        le32_to_cpu(ofdm->overrun_err),
+                        accum_ofdm->overrun_err, delta_ofdm->overrun_err,
+                        max_ofdm->overrun_err);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "  %-30s %10u  %10u  %10u  %10u\n",
+                        "early_overrun_err:",
+                        le32_to_cpu(ofdm->early_overrun_err),
+                        accum_ofdm->early_overrun_err,
+                        delta_ofdm->early_overrun_err,
+                        max_ofdm->early_overrun_err);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "  %-30s %10u  %10u  %10u  %10u\n",
+                        "crc32_good:", le32_to_cpu(ofdm->crc32_good),
+                        accum_ofdm->crc32_good, delta_ofdm->crc32_good,
+                        max_ofdm->crc32_good);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "  %-30s %10u  %10u  %10u  %10u\n", "false_alarm_cnt:",
+                        le32_to_cpu(ofdm->false_alarm_cnt),
+                        accum_ofdm->false_alarm_cnt,
+                        delta_ofdm->false_alarm_cnt,
+                        max_ofdm->false_alarm_cnt);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "  %-30s %10u  %10u  %10u  %10u\n",
+                        "fina_sync_err_cnt:",
+                        le32_to_cpu(ofdm->fina_sync_err_cnt),
+                        accum_ofdm->fina_sync_err_cnt,
+                        delta_ofdm->fina_sync_err_cnt,
+                        max_ofdm->fina_sync_err_cnt);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "  %-30s %10u  %10u  %10u  %10u\n", "sfd_timeout:",
+                        le32_to_cpu(ofdm->sfd_timeout),
+                        accum_ofdm->sfd_timeout, delta_ofdm->sfd_timeout,
+                        max_ofdm->sfd_timeout);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "  %-30s %10u  %10u  %10u  %10u\n", "fina_timeout:",
+                        le32_to_cpu(ofdm->fina_timeout),
+                        accum_ofdm->fina_timeout, delta_ofdm->fina_timeout,
+                        max_ofdm->fina_timeout);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "  %-30s %10u  %10u  %10u  %10u\n",
+                        "unresponded_rts:",
+                        le32_to_cpu(ofdm->unresponded_rts),
+                        accum_ofdm->unresponded_rts,
+                        delta_ofdm->unresponded_rts,
+                        max_ofdm->unresponded_rts);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "  %-30s %10u  %10u  %10u  %10u\n",
+                        "rxe_frame_lmt_ovrun:",
+                        le32_to_cpu(ofdm->rxe_frame_limit_overrun),
+                        accum_ofdm->rxe_frame_limit_overrun,
+                        delta_ofdm->rxe_frame_limit_overrun,
+                        max_ofdm->rxe_frame_limit_overrun);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "  %-30s %10u  %10u  %10u  %10u\n", "sent_ack_cnt:",
+                        le32_to_cpu(ofdm->sent_ack_cnt),
+                        accum_ofdm->sent_ack_cnt, delta_ofdm->sent_ack_cnt,
+                        max_ofdm->sent_ack_cnt);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "  %-30s %10u  %10u  %10u  %10u\n", "sent_cts_cnt:",
+                        le32_to_cpu(ofdm->sent_cts_cnt),
+                        accum_ofdm->sent_cts_cnt, delta_ofdm->sent_cts_cnt,
+                        max_ofdm->sent_cts_cnt);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "  %-30s %10u  %10u  %10u  %10u\n",
+                        "sent_ba_rsp_cnt:",
+                        le32_to_cpu(ofdm->sent_ba_rsp_cnt),
+                        accum_ofdm->sent_ba_rsp_cnt,
+                        delta_ofdm->sent_ba_rsp_cnt,
+                        max_ofdm->sent_ba_rsp_cnt);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "  %-30s %10u  %10u  %10u  %10u\n", "dsp_self_kill:",
+                        le32_to_cpu(ofdm->dsp_self_kill),
+                        accum_ofdm->dsp_self_kill,
+                        delta_ofdm->dsp_self_kill,
+                        max_ofdm->dsp_self_kill);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "  %-30s %10u  %10u  %10u  %10u\n",
+                        "mh_format_err:",
+                        le32_to_cpu(ofdm->mh_format_err),
+                        accum_ofdm->mh_format_err,
+                        delta_ofdm->mh_format_err,
+                        max_ofdm->mh_format_err);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "  %-30s %10u  %10u  %10u  %10u\n",
+                        "re_acq_main_rssi_sum:",
+                        le32_to_cpu(ofdm->re_acq_main_rssi_sum),
+                        accum_ofdm->re_acq_main_rssi_sum,
+                        delta_ofdm->re_acq_main_rssi_sum,
+                        max_ofdm->re_acq_main_rssi_sum);
+
+       pos += scnprintf(buf + pos, bufsz - pos, "%-32s     current"
+                        "acumulative       delta         max\n",
+                        "Statistics_Rx - CCK:");
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "  %-30s %10u  %10u  %10u  %10u\n",
+                        "ina_cnt:",
+                        le32_to_cpu(cck->ina_cnt), accum_cck->ina_cnt,
+                        delta_cck->ina_cnt, max_cck->ina_cnt);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "  %-30s %10u  %10u  %10u  %10u\n",
+                        "fina_cnt:",
+                        le32_to_cpu(cck->fina_cnt), accum_cck->fina_cnt,
+                        delta_cck->fina_cnt, max_cck->fina_cnt);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "  %-30s %10u  %10u  %10u  %10u\n",
+                        "plcp_err:",
+                        le32_to_cpu(cck->plcp_err), accum_cck->plcp_err,
+                        delta_cck->plcp_err, max_cck->plcp_err);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "  %-30s %10u  %10u  %10u  %10u\n",
+                        "crc32_err:",
+                        le32_to_cpu(cck->crc32_err), accum_cck->crc32_err,
+                        delta_cck->crc32_err, max_cck->crc32_err);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "  %-30s %10u  %10u  %10u  %10u\n",
+                        "overrun_err:",
+                        le32_to_cpu(cck->overrun_err),
+                        accum_cck->overrun_err, delta_cck->overrun_err,
+                        max_cck->overrun_err);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "  %-30s %10u  %10u  %10u  %10u\n",
+                        "early_overrun_err:",
+                        le32_to_cpu(cck->early_overrun_err),
+                        accum_cck->early_overrun_err,
+                        delta_cck->early_overrun_err,
+                        max_cck->early_overrun_err);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "  %-30s %10u  %10u  %10u  %10u\n",
+                        "crc32_good:",
+                        le32_to_cpu(cck->crc32_good), accum_cck->crc32_good,
+                        delta_cck->crc32_good, max_cck->crc32_good);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "  %-30s %10u  %10u  %10u  %10u\n",
+                        "false_alarm_cnt:",
+                        le32_to_cpu(cck->false_alarm_cnt),
+                        accum_cck->false_alarm_cnt,
+                        delta_cck->false_alarm_cnt, max_cck->false_alarm_cnt);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "  %-30s %10u  %10u  %10u  %10u\n",
+                        "fina_sync_err_cnt:",
+                        le32_to_cpu(cck->fina_sync_err_cnt),
+                        accum_cck->fina_sync_err_cnt,
+                        delta_cck->fina_sync_err_cnt,
+                        max_cck->fina_sync_err_cnt);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "  %-30s %10u  %10u  %10u  %10u\n",
+                        "sfd_timeout:",
+                        le32_to_cpu(cck->sfd_timeout),
+                        accum_cck->sfd_timeout, delta_cck->sfd_timeout,
+                        max_cck->sfd_timeout);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "  %-30s %10u  %10u  %10u  %10u\n", "fina_timeout:",
+                        le32_to_cpu(cck->fina_timeout),
+                        accum_cck->fina_timeout, delta_cck->fina_timeout,
+                        max_cck->fina_timeout);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "  %-30s %10u  %10u  %10u  %10u\n",
+                        "unresponded_rts:",
+                        le32_to_cpu(cck->unresponded_rts),
+                        accum_cck->unresponded_rts, delta_cck->unresponded_rts,
+                        max_cck->unresponded_rts);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "  %-30s %10u  %10u  %10u  %10u\n",
+                        "rxe_frame_lmt_ovrun:",
+                        le32_to_cpu(cck->rxe_frame_limit_overrun),
+                        accum_cck->rxe_frame_limit_overrun,
+                        delta_cck->rxe_frame_limit_overrun,
+                        max_cck->rxe_frame_limit_overrun);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "  %-30s %10u  %10u  %10u  %10u\n", "sent_ack_cnt:",
+                        le32_to_cpu(cck->sent_ack_cnt),
+                        accum_cck->sent_ack_cnt, delta_cck->sent_ack_cnt,
+                        max_cck->sent_ack_cnt);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "  %-30s %10u  %10u  %10u  %10u\n", "sent_cts_cnt:",
+                        le32_to_cpu(cck->sent_cts_cnt),
+                        accum_cck->sent_cts_cnt, delta_cck->sent_cts_cnt,
+                        max_cck->sent_cts_cnt);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "  %-30s %10u  %10u  %10u  %10u\n", "sent_ba_rsp_cnt:",
+                        le32_to_cpu(cck->sent_ba_rsp_cnt),
+                        accum_cck->sent_ba_rsp_cnt,
+                        delta_cck->sent_ba_rsp_cnt,
+                        max_cck->sent_ba_rsp_cnt);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "  %-30s %10u  %10u  %10u  %10u\n", "dsp_self_kill:",
+                        le32_to_cpu(cck->dsp_self_kill),
+                        accum_cck->dsp_self_kill, delta_cck->dsp_self_kill,
+                        max_cck->dsp_self_kill);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "  %-30s %10u  %10u  %10u  %10u\n", "mh_format_err:",
+                        le32_to_cpu(cck->mh_format_err),
+                        accum_cck->mh_format_err, delta_cck->mh_format_err,
+                        max_cck->mh_format_err);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "  %-30s %10u  %10u  %10u  %10u\n",
+                        "re_acq_main_rssi_sum:",
+                        le32_to_cpu(cck->re_acq_main_rssi_sum),
+                        accum_cck->re_acq_main_rssi_sum,
+                        delta_cck->re_acq_main_rssi_sum,
+                        max_cck->re_acq_main_rssi_sum);
+
+       pos += scnprintf(buf + pos, bufsz - pos, "%-32s     current"
+                        "acumulative       delta         max\n",
+                        "Statistics_Rx - GENERAL:");
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "  %-30s %10u  %10u  %10u  %10u\n", "bogus_cts:",
+                        le32_to_cpu(general->bogus_cts),
+                        accum_general->bogus_cts, delta_general->bogus_cts,
+                        max_general->bogus_cts);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "  %-30s %10u  %10u  %10u  %10u\n", "bogus_ack:",
+                        le32_to_cpu(general->bogus_ack),
+                        accum_general->bogus_ack, delta_general->bogus_ack,
+                        max_general->bogus_ack);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "  %-30s %10u  %10u  %10u  %10u\n",
+                        "non_bssid_frames:",
+                        le32_to_cpu(general->non_bssid_frames),
+                        accum_general->non_bssid_frames,
+                        delta_general->non_bssid_frames,
+                        max_general->non_bssid_frames);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "  %-30s %10u  %10u  %10u  %10u\n",
+                        "filtered_frames:",
+                        le32_to_cpu(general->filtered_frames),
+                        accum_general->filtered_frames,
+                        delta_general->filtered_frames,
+                        max_general->filtered_frames);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "  %-30s %10u  %10u  %10u  %10u\n",
+                        "non_channel_beacons:",
+                        le32_to_cpu(general->non_channel_beacons),
+                        accum_general->non_channel_beacons,
+                        delta_general->non_channel_beacons,
+                        max_general->non_channel_beacons);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "  %-30s %10u  %10u  %10u  %10u\n",
+                        "channel_beacons:",
+                        le32_to_cpu(general->channel_beacons),
+                        accum_general->channel_beacons,
+                        delta_general->channel_beacons,
+                        max_general->channel_beacons);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "  %-30s %10u  %10u  %10u  %10u\n",
+                        "num_missed_bcon:",
+                        le32_to_cpu(general->num_missed_bcon),
+                        accum_general->num_missed_bcon,
+                        delta_general->num_missed_bcon,
+                        max_general->num_missed_bcon);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "  %-30s %10u  %10u  %10u  %10u\n",
+                        "adc_rx_saturation_time:",
+                        le32_to_cpu(general->adc_rx_saturation_time),
+                        accum_general->adc_rx_saturation_time,
+                        delta_general->adc_rx_saturation_time,
+                        max_general->adc_rx_saturation_time);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "  %-30s %10u  %10u  %10u  %10u\n",
+                        "ina_detect_search_tm:",
+                        le32_to_cpu(general->ina_detection_search_time),
+                        accum_general->ina_detection_search_time,
+                        delta_general->ina_detection_search_time,
+                        max_general->ina_detection_search_time);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "  %-30s %10u  %10u  %10u  %10u\n",
+                        "beacon_silence_rssi_a:",
+                        le32_to_cpu(general->beacon_silence_rssi_a),
+                        accum_general->beacon_silence_rssi_a,
+                        delta_general->beacon_silence_rssi_a,
+                        max_general->beacon_silence_rssi_a);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "  %-30s %10u  %10u  %10u  %10u\n",
+                        "beacon_silence_rssi_b:",
+                        le32_to_cpu(general->beacon_silence_rssi_b),
+                        accum_general->beacon_silence_rssi_b,
+                        delta_general->beacon_silence_rssi_b,
+                        max_general->beacon_silence_rssi_b);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "  %-30s %10u  %10u  %10u  %10u\n",
+                        "beacon_silence_rssi_c:",
+                        le32_to_cpu(general->beacon_silence_rssi_c),
+                        accum_general->beacon_silence_rssi_c,
+                        delta_general->beacon_silence_rssi_c,
+                        max_general->beacon_silence_rssi_c);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "  %-30s %10u  %10u  %10u  %10u\n",
+                        "interference_data_flag:",
+                        le32_to_cpu(general->interference_data_flag),
+                        accum_general->interference_data_flag,
+                        delta_general->interference_data_flag,
+                        max_general->interference_data_flag);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "  %-30s %10u  %10u  %10u  %10u\n",
+                        "channel_load:",
+                        le32_to_cpu(general->channel_load),
+                        accum_general->channel_load,
+                        delta_general->channel_load,
+                        max_general->channel_load);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "  %-30s %10u  %10u  %10u  %10u\n",
+                        "dsp_false_alarms:",
+                        le32_to_cpu(general->dsp_false_alarms),
+                        accum_general->dsp_false_alarms,
+                        delta_general->dsp_false_alarms,
+                        max_general->dsp_false_alarms);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "  %-30s %10u  %10u  %10u  %10u\n",
+                        "beacon_rssi_a:",
+                        le32_to_cpu(general->beacon_rssi_a),
+                        accum_general->beacon_rssi_a,
+                        delta_general->beacon_rssi_a,
+                        max_general->beacon_rssi_a);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "  %-30s %10u  %10u  %10u  %10u\n",
+                        "beacon_rssi_b:",
+                        le32_to_cpu(general->beacon_rssi_b),
+                        accum_general->beacon_rssi_b,
+                        delta_general->beacon_rssi_b,
+                        max_general->beacon_rssi_b);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "  %-30s %10u  %10u  %10u  %10u\n",
+                        "beacon_rssi_c:",
+                        le32_to_cpu(general->beacon_rssi_c),
+                        accum_general->beacon_rssi_c,
+                        delta_general->beacon_rssi_c,
+                        max_general->beacon_rssi_c);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "  %-30s %10u  %10u  %10u  %10u\n",
+                        "beacon_energy_a:",
+                        le32_to_cpu(general->beacon_energy_a),
+                        accum_general->beacon_energy_a,
+                        delta_general->beacon_energy_a,
+                        max_general->beacon_energy_a);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "  %-30s %10u  %10u  %10u  %10u\n",
+                        "beacon_energy_b:",
+                        le32_to_cpu(general->beacon_energy_b),
+                        accum_general->beacon_energy_b,
+                        delta_general->beacon_energy_b,
+                        max_general->beacon_energy_b);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "  %-30s %10u  %10u  %10u  %10u\n",
+                        "beacon_energy_c:",
+                        le32_to_cpu(general->beacon_energy_c),
+                        accum_general->beacon_energy_c,
+                        delta_general->beacon_energy_c,
+                        max_general->beacon_energy_c);
+
+       pos += scnprintf(buf + pos, bufsz - pos, "Statistics_Rx - OFDM_HT:\n");
+       pos += scnprintf(buf + pos, bufsz - pos, "%-32s     current"
+                        "acumulative       delta         max\n",
+                        "Statistics_Rx - OFDM_HT:");
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "  %-30s %10u  %10u  %10u  %10u\n",
+                        "plcp_err:",
+                        le32_to_cpu(ht->plcp_err), accum_ht->plcp_err,
+                        delta_ht->plcp_err, max_ht->plcp_err);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "  %-30s %10u  %10u  %10u  %10u\n",
+                        "overrun_err:",
+                        le32_to_cpu(ht->overrun_err), accum_ht->overrun_err,
+                        delta_ht->overrun_err, max_ht->overrun_err);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "  %-30s %10u  %10u  %10u  %10u\n",
+                        "early_overrun_err:",
+                        le32_to_cpu(ht->early_overrun_err),
+                        accum_ht->early_overrun_err,
+                        delta_ht->early_overrun_err,
+                        max_ht->early_overrun_err);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "  %-30s %10u  %10u  %10u  %10u\n",
+                        "crc32_good:",
+                        le32_to_cpu(ht->crc32_good), accum_ht->crc32_good,
+                        delta_ht->crc32_good, max_ht->crc32_good);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "  %-30s %10u  %10u  %10u  %10u\n",
+                        "crc32_err:",
+                        le32_to_cpu(ht->crc32_err), accum_ht->crc32_err,
+                        delta_ht->crc32_err, max_ht->crc32_err);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "  %-30s %10u  %10u  %10u  %10u\n",
+                        "mh_format_err:",
+                        le32_to_cpu(ht->mh_format_err),
+                        accum_ht->mh_format_err,
+                        delta_ht->mh_format_err, max_ht->mh_format_err);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "  %-30s %10u  %10u  %10u  %10u\n",
+                        "agg_crc32_good:",
+                        le32_to_cpu(ht->agg_crc32_good),
+                        accum_ht->agg_crc32_good,
+                        delta_ht->agg_crc32_good, max_ht->agg_crc32_good);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "  %-30s %10u  %10u  %10u  %10u\n",
+                        "agg_mpdu_cnt:",
+                        le32_to_cpu(ht->agg_mpdu_cnt),
+                        accum_ht->agg_mpdu_cnt,
+                        delta_ht->agg_mpdu_cnt, max_ht->agg_mpdu_cnt);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "  %-30s %10u  %10u  %10u  %10u\n",
+                        "agg_cnt:",
+                        le32_to_cpu(ht->agg_cnt), accum_ht->agg_cnt,
+                        delta_ht->agg_cnt, max_ht->agg_cnt);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "  %-30s %10u  %10u  %10u  %10u\n",
+                        "unsupport_mcs:",
+                        le32_to_cpu(ht->unsupport_mcs),
+                        accum_ht->unsupport_mcs,
+                        delta_ht->unsupport_mcs, max_ht->unsupport_mcs);
+
+       ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
+       kfree(buf);
+       return ret;
+}
+
+ssize_t iwl_ucode_tx_stats_read(struct file *file,
+                               char __user *user_buf,
+                               size_t count, loff_t *ppos)
+{
+       struct iwl_priv *priv = file->private_data;
+       int pos = 0;
+       char *buf;
+       int bufsz = (sizeof(struct statistics_tx) * 48) + 250;
+       ssize_t ret;
+       struct statistics_tx *tx, *accum_tx, *delta_tx, *max_tx;
+
+       if (!iwl_is_alive(priv))
+               return -EAGAIN;
+
+       buf = kzalloc(bufsz, GFP_KERNEL);
+       if (!buf) {
+               IWL_ERR(priv, "Can not allocate Buffer\n");
+               return -ENOMEM;
+       }
+
+       /* the statistic information display here is based on
+         * the last statistics notification from uCode
+         * might not reflect the current uCode activity
+         */
+       tx = &priv->statistics.tx;
+       accum_tx = &priv->accum_statistics.tx;
+       delta_tx = &priv->delta_statistics.tx;
+       max_tx = &priv->max_delta.tx;
+       pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz);
+       pos += scnprintf(buf + pos, bufsz - pos,  "%-32s     current"
+                        "acumulative       delta         max\n",
+                        "Statistics_Tx:");
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "  %-30s %10u  %10u  %10u  %10u\n",
+                        "preamble:",
+                        le32_to_cpu(tx->preamble_cnt),
+                        accum_tx->preamble_cnt,
+                        delta_tx->preamble_cnt, max_tx->preamble_cnt);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "  %-30s %10u  %10u  %10u  %10u\n",
+                        "rx_detected_cnt:",
+                        le32_to_cpu(tx->rx_detected_cnt),
+                        accum_tx->rx_detected_cnt,
+                        delta_tx->rx_detected_cnt, max_tx->rx_detected_cnt);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "  %-30s %10u  %10u  %10u  %10u\n",
+                        "bt_prio_defer_cnt:",
+                        le32_to_cpu(tx->bt_prio_defer_cnt),
+                        accum_tx->bt_prio_defer_cnt,
+                        delta_tx->bt_prio_defer_cnt,
+                        max_tx->bt_prio_defer_cnt);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "  %-30s %10u  %10u  %10u  %10u\n",
+                        "bt_prio_kill_cnt:",
+                        le32_to_cpu(tx->bt_prio_kill_cnt),
+                        accum_tx->bt_prio_kill_cnt,
+                        delta_tx->bt_prio_kill_cnt,
+                        max_tx->bt_prio_kill_cnt);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "  %-30s %10u  %10u  %10u  %10u\n",
+                        "few_bytes_cnt:",
+                        le32_to_cpu(tx->few_bytes_cnt),
+                        accum_tx->few_bytes_cnt,
+                        delta_tx->few_bytes_cnt, max_tx->few_bytes_cnt);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "  %-30s %10u  %10u  %10u  %10u\n",
+                        "cts_timeout:",
+                        le32_to_cpu(tx->cts_timeout), accum_tx->cts_timeout,
+                        delta_tx->cts_timeout, max_tx->cts_timeout);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "  %-30s %10u  %10u  %10u  %10u\n",
+                        "ack_timeout:",
+                        le32_to_cpu(tx->ack_timeout),
+                        accum_tx->ack_timeout,
+                        delta_tx->ack_timeout, max_tx->ack_timeout);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "  %-30s %10u  %10u  %10u  %10u\n",
+                        "expected_ack_cnt:",
+                        le32_to_cpu(tx->expected_ack_cnt),
+                        accum_tx->expected_ack_cnt,
+                        delta_tx->expected_ack_cnt,
+                        max_tx->expected_ack_cnt);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "  %-30s %10u  %10u  %10u  %10u\n",
+                        "actual_ack_cnt:",
+                        le32_to_cpu(tx->actual_ack_cnt),
+                        accum_tx->actual_ack_cnt,
+                        delta_tx->actual_ack_cnt,
+                        max_tx->actual_ack_cnt);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "  %-30s %10u  %10u  %10u  %10u\n",
+                        "dump_msdu_cnt:",
+                        le32_to_cpu(tx->dump_msdu_cnt),
+                        accum_tx->dump_msdu_cnt,
+                        delta_tx->dump_msdu_cnt,
+                        max_tx->dump_msdu_cnt);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "  %-30s %10u  %10u  %10u  %10u\n",
+                        "abort_nxt_frame_mismatch:",
+                        le32_to_cpu(tx->burst_abort_next_frame_mismatch_cnt),
+                        accum_tx->burst_abort_next_frame_mismatch_cnt,
+                        delta_tx->burst_abort_next_frame_mismatch_cnt,
+                        max_tx->burst_abort_next_frame_mismatch_cnt);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "  %-30s %10u  %10u  %10u  %10u\n",
+                        "abort_missing_nxt_frame:",
+                        le32_to_cpu(tx->burst_abort_missing_next_frame_cnt),
+                        accum_tx->burst_abort_missing_next_frame_cnt,
+                        delta_tx->burst_abort_missing_next_frame_cnt,
+                        max_tx->burst_abort_missing_next_frame_cnt);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "  %-30s %10u  %10u  %10u  %10u\n",
+                        "cts_timeout_collision:",
+                        le32_to_cpu(tx->cts_timeout_collision),
+                        accum_tx->cts_timeout_collision,
+                        delta_tx->cts_timeout_collision,
+                        max_tx->cts_timeout_collision);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "  %-30s %10u  %10u  %10u  %10u\n",
+                        "ack_ba_timeout_collision:",
+                        le32_to_cpu(tx->ack_or_ba_timeout_collision),
+                        accum_tx->ack_or_ba_timeout_collision,
+                        delta_tx->ack_or_ba_timeout_collision,
+                        max_tx->ack_or_ba_timeout_collision);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "  %-30s %10u  %10u  %10u  %10u\n",
+                        "agg ba_timeout:",
+                        le32_to_cpu(tx->agg.ba_timeout),
+                        accum_tx->agg.ba_timeout,
+                        delta_tx->agg.ba_timeout,
+                        max_tx->agg.ba_timeout);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "  %-30s %10u  %10u  %10u  %10u\n",
+                        "agg ba_resched_frames:",
+                        le32_to_cpu(tx->agg.ba_reschedule_frames),
+                        accum_tx->agg.ba_reschedule_frames,
+                        delta_tx->agg.ba_reschedule_frames,
+                        max_tx->agg.ba_reschedule_frames);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "  %-30s %10u  %10u  %10u  %10u\n",
+                        "agg scd_query_agg_frame:",
+                        le32_to_cpu(tx->agg.scd_query_agg_frame_cnt),
+                        accum_tx->agg.scd_query_agg_frame_cnt,
+                        delta_tx->agg.scd_query_agg_frame_cnt,
+                        max_tx->agg.scd_query_agg_frame_cnt);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "  %-30s %10u  %10u  %10u  %10u\n",
+                        "agg scd_query_no_agg:",
+                        le32_to_cpu(tx->agg.scd_query_no_agg),
+                        accum_tx->agg.scd_query_no_agg,
+                        delta_tx->agg.scd_query_no_agg,
+                        max_tx->agg.scd_query_no_agg);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "  %-30s %10u  %10u  %10u  %10u\n",
+                        "agg scd_query_agg:",
+                        le32_to_cpu(tx->agg.scd_query_agg),
+                        accum_tx->agg.scd_query_agg,
+                        delta_tx->agg.scd_query_agg,
+                        max_tx->agg.scd_query_agg);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "  %-30s %10u  %10u  %10u  %10u\n",
+                        "agg scd_query_mismatch:",
+                        le32_to_cpu(tx->agg.scd_query_mismatch),
+                        accum_tx->agg.scd_query_mismatch,
+                        delta_tx->agg.scd_query_mismatch,
+                        max_tx->agg.scd_query_mismatch);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "  %-30s %10u  %10u  %10u  %10u\n",
+                        "agg frame_not_ready:",
+                        le32_to_cpu(tx->agg.frame_not_ready),
+                        accum_tx->agg.frame_not_ready,
+                        delta_tx->agg.frame_not_ready,
+                        max_tx->agg.frame_not_ready);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "  %-30s %10u  %10u  %10u  %10u\n",
+                        "agg underrun:",
+                        le32_to_cpu(tx->agg.underrun),
+                        accum_tx->agg.underrun,
+                        delta_tx->agg.underrun, max_tx->agg.underrun);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "  %-30s %10u  %10u  %10u  %10u\n",
+                        "agg bt_prio_kill:",
+                        le32_to_cpu(tx->agg.bt_prio_kill),
+                        accum_tx->agg.bt_prio_kill,
+                        delta_tx->agg.bt_prio_kill,
+                        max_tx->agg.bt_prio_kill);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "  %-30s %10u  %10u  %10u  %10u\n",
+                        "agg rx_ba_rsp_cnt:",
+                        le32_to_cpu(tx->agg.rx_ba_rsp_cnt),
+                        accum_tx->agg.rx_ba_rsp_cnt,
+                        delta_tx->agg.rx_ba_rsp_cnt,
+                        max_tx->agg.rx_ba_rsp_cnt);
+
+       ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
+       kfree(buf);
+       return ret;
+}
+
+ssize_t iwl_ucode_general_stats_read(struct file *file, char __user *user_buf,
+                                    size_t count, loff_t *ppos)
+{
+       struct iwl_priv *priv = file->private_data;
+       int pos = 0;
+       char *buf;
+       int bufsz = sizeof(struct statistics_general) * 10 + 300;
+       ssize_t ret;
+       struct statistics_general *general, *accum_general;
+       struct statistics_general *delta_general, *max_general;
+       struct statistics_dbg *dbg, *accum_dbg, *delta_dbg, *max_dbg;
+       struct statistics_div *div, *accum_div, *delta_div, *max_div;
+
+       if (!iwl_is_alive(priv))
+               return -EAGAIN;
+
+       buf = kzalloc(bufsz, GFP_KERNEL);
+       if (!buf) {
+               IWL_ERR(priv, "Can not allocate Buffer\n");
+               return -ENOMEM;
+       }
+
+       /* the statistic information display here is based on
+         * the last statistics notification from uCode
+         * might not reflect the current uCode activity
+         */
+       general = &priv->statistics.general;
+       dbg = &priv->statistics.general.dbg;
+       div = &priv->statistics.general.div;
+       accum_general = &priv->accum_statistics.general;
+       delta_general = &priv->delta_statistics.general;
+       max_general = &priv->max_delta.general;
+       accum_dbg = &priv->accum_statistics.general.dbg;
+       delta_dbg = &priv->delta_statistics.general.dbg;
+       max_dbg = &priv->max_delta.general.dbg;
+       accum_div = &priv->accum_statistics.general.div;
+       delta_div = &priv->delta_statistics.general.div;
+       max_div = &priv->max_delta.general.div;
+       pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz);
+       pos += scnprintf(buf + pos, bufsz - pos, "%-32s     current"
+                        "acumulative       delta         max\n",
+                        "Statistics_General:");
+       pos += scnprintf(buf + pos, bufsz - pos, "  %-30s %10u\n",
+                        "temperature:",
+                        le32_to_cpu(general->temperature));
+       pos += scnprintf(buf + pos, bufsz - pos, "  %-30s %10u\n",
+                        "temperature_m:",
+                        le32_to_cpu(general->temperature_m));
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "  %-30s %10u  %10u  %10u  %10u\n",
+                        "burst_check:",
+                        le32_to_cpu(dbg->burst_check),
+                        accum_dbg->burst_check,
+                        delta_dbg->burst_check, max_dbg->burst_check);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "  %-30s %10u  %10u  %10u  %10u\n",
+                        "burst_count:",
+                        le32_to_cpu(dbg->burst_count),
+                        accum_dbg->burst_count,
+                        delta_dbg->burst_count, max_dbg->burst_count);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "  %-30s %10u  %10u  %10u  %10u\n",
+                        "sleep_time:",
+                        le32_to_cpu(general->sleep_time),
+                        accum_general->sleep_time,
+                        delta_general->sleep_time, max_general->sleep_time);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "  %-30s %10u  %10u  %10u  %10u\n",
+                        "slots_out:",
+                        le32_to_cpu(general->slots_out),
+                        accum_general->slots_out,
+                        delta_general->slots_out, max_general->slots_out);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "  %-30s %10u  %10u  %10u  %10u\n",
+                        "slots_idle:",
+                        le32_to_cpu(general->slots_idle),
+                        accum_general->slots_idle,
+                        delta_general->slots_idle, max_general->slots_idle);
+       pos += scnprintf(buf + pos, bufsz - pos, "ttl_timestamp:\t\t\t%u\n",
+                        le32_to_cpu(general->ttl_timestamp));
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "  %-30s %10u  %10u  %10u  %10u\n",
+                        "tx_on_a:",
+                        le32_to_cpu(div->tx_on_a), accum_div->tx_on_a,
+                        delta_div->tx_on_a, max_div->tx_on_a);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "  %-30s %10u  %10u  %10u  %10u\n",
+                        "tx_on_b:",
+                        le32_to_cpu(div->tx_on_b), accum_div->tx_on_b,
+                        delta_div->tx_on_b, max_div->tx_on_b);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "  %-30s %10u  %10u  %10u  %10u\n",
+                        "exec_time:",
+                        le32_to_cpu(div->exec_time), accum_div->exec_time,
+                        delta_div->exec_time, max_div->exec_time);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "  %-30s %10u  %10u  %10u  %10u\n",
+                        "probe_time:",
+                        le32_to_cpu(div->probe_time), accum_div->probe_time,
+                        delta_div->probe_time, max_div->probe_time);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "  %-30s %10u  %10u  %10u  %10u\n",
+                        "rx_enable_counter:",
+                        le32_to_cpu(general->rx_enable_counter),
+                        accum_general->rx_enable_counter,
+                        delta_general->rx_enable_counter,
+                        max_general->rx_enable_counter);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "  %-30s %10u  %10u  %10u  %10u\n",
+                        "num_of_sos_states:",
+                        le32_to_cpu(general->num_of_sos_states),
+                        accum_general->num_of_sos_states,
+                        delta_general->num_of_sos_states,
+                        max_general->num_of_sos_states);
+       ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
+       kfree(buf);
+       return ret;
+}
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.h b/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.h
new file mode 100644 (file)
index 0000000..59b1f25
--- /dev/null
@@ -0,0 +1,56 @@
+/******************************************************************************
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
+ * USA
+ *
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * Contact Information:
+ *  Intel Linux Wireless <ilw@linux.intel.com>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *****************************************************************************/
+
+#include "iwl-dev.h"
+#include "iwl-core.h"
+#include "iwl-debug.h"
+
+#ifdef CONFIG_IWLWIFI_DEBUGFS
+ssize_t iwl_ucode_rx_stats_read(struct file *file, char __user *user_buf,
+                               size_t count, loff_t *ppos);
+ssize_t iwl_ucode_tx_stats_read(struct file *file, char __user *user_buf,
+                               size_t count, loff_t *ppos);
+ssize_t iwl_ucode_general_stats_read(struct file *file, char __user *user_buf,
+                                    size_t count, loff_t *ppos);
+#else
+static ssize_t iwl_ucode_rx_stats_read(struct file *file, char __user *user_buf,
+                                      size_t count, loff_t *ppos)
+{
+       return 0;
+}
+static ssize_t iwl_ucode_tx_stats_read(struct file *file, char __user *user_buf,
+                                      size_t count, loff_t *ppos)
+{
+       return 0;
+}
+static ssize_t iwl_ucode_general_stats_read(struct file *file, char __user *user_buf,
+                                           size_t count, loff_t *ppos)
+{
+       return 0;
+}
+#endif
index 28bc8f8ba981591408f581100db8a69ce6efbac2..44ef5d93befcda26e6bec109c4b5ae66994da549 100644 (file)
@@ -262,6 +262,7 @@ struct iwl_hcmd_ops iwlagn_hcmd = {
        .commit_rxon = iwl_commit_rxon,
        .set_rxon_chain = iwl_set_rxon_chain,
        .set_tx_ant = iwlagn_send_tx_ant_config,
+       .send_bt_config = iwl_send_bt_config,
 };
 
 struct iwl_hcmd_utils_ops iwlagn_hcmd_utils = {
@@ -271,4 +272,5 @@ struct iwl_hcmd_utils_ops iwlagn_hcmd_utils = {
        .chain_noise_reset = iwlagn_chain_noise_reset,
        .rts_tx_cmd_flag = iwlagn_rts_tx_cmd_flag,
        .calc_rssi = iwlagn_calc_rssi,
+       .request_scan = iwlagn_request_scan,
 };
index c465c85908332fb651ff53435a6a1de75cd2ce79..4bd0aecc7713164656db82044df1804323c67666 100644 (file)
@@ -331,7 +331,7 @@ u16 iwlagn_eeprom_calib_version(struct iwl_priv *priv)
        } *hdr;
 
        hdr = (struct iwl_eeprom_calib_hdr *)iwl_eeprom_query_addr(priv,
-                                                       EEPROM_5000_CALIB_ALL);
+                                                       EEPROM_CALIB_ALL);
        return hdr->version;
 
 }
@@ -348,22 +348,22 @@ static u32 eeprom_indirect_address(const struct iwl_priv *priv, u32 address)
 
        switch (address & INDIRECT_TYPE_MSK) {
        case INDIRECT_HOST:
-               offset = iwl_eeprom_query16(priv, EEPROM_5000_LINK_HOST);
+               offset = iwl_eeprom_query16(priv, EEPROM_LINK_HOST);
                break;
        case INDIRECT_GENERAL:
-               offset = iwl_eeprom_query16(priv, EEPROM_5000_LINK_GENERAL);
+               offset = iwl_eeprom_query16(priv, EEPROM_LINK_GENERAL);
                break;
        case INDIRECT_REGULATORY:
-               offset = iwl_eeprom_query16(priv, EEPROM_5000_LINK_REGULATORY);
+               offset = iwl_eeprom_query16(priv, EEPROM_LINK_REGULATORY);
                break;
        case INDIRECT_CALIBRATION:
-               offset = iwl_eeprom_query16(priv, EEPROM_5000_LINK_CALIBRATION);
+               offset = iwl_eeprom_query16(priv, EEPROM_LINK_CALIBRATION);
                break;
        case INDIRECT_PROCESS_ADJST:
-               offset = iwl_eeprom_query16(priv, EEPROM_5000_LINK_PROCESS_ADJST);
+               offset = iwl_eeprom_query16(priv, EEPROM_LINK_PROCESS_ADJST);
                break;
        case INDIRECT_OTHERS:
-               offset = iwl_eeprom_query16(priv, EEPROM_5000_LINK_OTHERS);
+               offset = iwl_eeprom_query16(priv, EEPROM_LINK_OTHERS);
                break;
        default:
                IWL_ERR(priv, "illegal indirect type: 0x%X\n",
@@ -1111,3 +1111,392 @@ void iwlagn_rx_reply_rx_phy(struct iwl_priv *priv,
        memcpy(&priv->_agn.last_phy_res, pkt->u.raw,
               sizeof(struct iwl_rx_phy_res));
 }
+
+static int iwl_get_single_channel_for_scan(struct iwl_priv *priv,
+                                    enum ieee80211_band band,
+                                    struct iwl_scan_channel *scan_ch)
+{
+       const struct ieee80211_supported_band *sband;
+       const struct iwl_channel_info *ch_info;
+       u16 passive_dwell = 0;
+       u16 active_dwell = 0;
+       int i, added = 0;
+       u16 channel = 0;
+
+       sband = iwl_get_hw_mode(priv, band);
+       if (!sband) {
+               IWL_ERR(priv, "invalid band\n");
+               return added;
+       }
+
+       active_dwell = iwl_get_active_dwell_time(priv, band, 0);
+       passive_dwell = iwl_get_passive_dwell_time(priv, band);
+
+       if (passive_dwell <= active_dwell)
+               passive_dwell = active_dwell + 1;
+
+       /* only scan single channel, good enough to reset the RF */
+       /* pick the first valid not in-use channel */
+       if (band == IEEE80211_BAND_5GHZ) {
+               for (i = 14; i < priv->channel_count; i++) {
+                       if (priv->channel_info[i].channel !=
+                           le16_to_cpu(priv->staging_rxon.channel)) {
+                               channel = priv->channel_info[i].channel;
+                               ch_info = iwl_get_channel_info(priv,
+                                       band, channel);
+                               if (is_channel_valid(ch_info))
+                                       break;
+                       }
+               }
+       } else {
+               for (i = 0; i < 14; i++) {
+                       if (priv->channel_info[i].channel !=
+                           le16_to_cpu(priv->staging_rxon.channel)) {
+                                       channel =
+                                               priv->channel_info[i].channel;
+                                       ch_info = iwl_get_channel_info(priv,
+                                               band, channel);
+                                       if (is_channel_valid(ch_info))
+                                               break;
+                       }
+               }
+       }
+       if (channel) {
+               scan_ch->channel = cpu_to_le16(channel);
+               scan_ch->type = SCAN_CHANNEL_TYPE_PASSIVE;
+               scan_ch->active_dwell = cpu_to_le16(active_dwell);
+               scan_ch->passive_dwell = cpu_to_le16(passive_dwell);
+               /* Set txpower levels to defaults */
+               scan_ch->dsp_atten = 110;
+               if (band == IEEE80211_BAND_5GHZ)
+                       scan_ch->tx_gain = ((1 << 5) | (3 << 3)) | 3;
+               else
+                       scan_ch->tx_gain = ((1 << 5) | (5 << 3));
+               added++;
+       } else
+               IWL_ERR(priv, "no valid channel found\n");
+       return added;
+}
+
+static int iwl_get_channels_for_scan(struct iwl_priv *priv,
+                                    enum ieee80211_band band,
+                                    u8 is_active, u8 n_probes,
+                                    struct iwl_scan_channel *scan_ch)
+{
+       struct ieee80211_channel *chan;
+       const struct ieee80211_supported_band *sband;
+       const struct iwl_channel_info *ch_info;
+       u16 passive_dwell = 0;
+       u16 active_dwell = 0;
+       int added, i;
+       u16 channel;
+
+       sband = iwl_get_hw_mode(priv, band);
+       if (!sband)
+               return 0;
+
+       active_dwell = iwl_get_active_dwell_time(priv, band, n_probes);
+       passive_dwell = iwl_get_passive_dwell_time(priv, band);
+
+       if (passive_dwell <= active_dwell)
+               passive_dwell = active_dwell + 1;
+
+       for (i = 0, added = 0; i < priv->scan_request->n_channels; i++) {
+               chan = priv->scan_request->channels[i];
+
+               if (chan->band != band)
+                       continue;
+
+               channel = ieee80211_frequency_to_channel(chan->center_freq);
+               scan_ch->channel = cpu_to_le16(channel);
+
+               ch_info = iwl_get_channel_info(priv, band, channel);
+               if (!is_channel_valid(ch_info)) {
+                       IWL_DEBUG_SCAN(priv, "Channel %d is INVALID for this band.\n",
+                                       channel);
+                       continue;
+               }
+
+               if (!is_active || is_channel_passive(ch_info) ||
+                   (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN))
+                       scan_ch->type = SCAN_CHANNEL_TYPE_PASSIVE;
+               else
+                       scan_ch->type = SCAN_CHANNEL_TYPE_ACTIVE;
+
+               if (n_probes)
+                       scan_ch->type |= IWL_SCAN_PROBE_MASK(n_probes);
+
+               scan_ch->active_dwell = cpu_to_le16(active_dwell);
+               scan_ch->passive_dwell = cpu_to_le16(passive_dwell);
+
+               /* Set txpower levels to defaults */
+               scan_ch->dsp_atten = 110;
+
+               /* NOTE: if we were doing 6Mb OFDM for scans we'd use
+                * power level:
+                * scan_ch->tx_gain = ((1 << 5) | (2 << 3)) | 3;
+                */
+               if (band == IEEE80211_BAND_5GHZ)
+                       scan_ch->tx_gain = ((1 << 5) | (3 << 3)) | 3;
+               else
+                       scan_ch->tx_gain = ((1 << 5) | (5 << 3));
+
+               IWL_DEBUG_SCAN(priv, "Scanning ch=%d prob=0x%X [%s %d]\n",
+                              channel, le32_to_cpu(scan_ch->type),
+                              (scan_ch->type & SCAN_CHANNEL_TYPE_ACTIVE) ?
+                               "ACTIVE" : "PASSIVE",
+                              (scan_ch->type & SCAN_CHANNEL_TYPE_ACTIVE) ?
+                              active_dwell : passive_dwell);
+
+               scan_ch++;
+               added++;
+       }
+
+       IWL_DEBUG_SCAN(priv, "total channels to scan %d\n", added);
+       return added;
+}
+
+void iwlagn_request_scan(struct iwl_priv *priv)
+{
+       struct iwl_host_cmd cmd = {
+               .id = REPLY_SCAN_CMD,
+               .len = sizeof(struct iwl_scan_cmd),
+               .flags = CMD_SIZE_HUGE,
+       };
+       struct iwl_scan_cmd *scan;
+       struct ieee80211_conf *conf = NULL;
+       u32 rate_flags = 0;
+       u16 cmd_len;
+       u16 rx_chain = 0;
+       enum ieee80211_band band;
+       u8 n_probes = 0;
+       u8 rx_ant = priv->hw_params.valid_rx_ant;
+       u8 rate;
+       bool is_active = false;
+       int  chan_mod;
+       u8 active_chains;
+
+       conf = ieee80211_get_hw_conf(priv->hw);
+
+       cancel_delayed_work(&priv->scan_check);
+
+       if (!iwl_is_ready(priv)) {
+               IWL_WARN(priv, "request scan called when driver not ready.\n");
+               goto done;
+       }
+
+       /* Make sure the scan wasn't canceled before this queued work
+        * was given the chance to run... */
+       if (!test_bit(STATUS_SCANNING, &priv->status))
+               goto done;
+
+       /* This should never be called or scheduled if there is currently
+        * a scan active in the hardware. */
+       if (test_bit(STATUS_SCAN_HW, &priv->status)) {
+               IWL_DEBUG_INFO(priv, "Multiple concurrent scan requests in parallel. "
+                              "Ignoring second request.\n");
+               goto done;
+       }
+
+       if (test_bit(STATUS_EXIT_PENDING, &priv->status)) {
+               IWL_DEBUG_SCAN(priv, "Aborting scan due to device shutdown\n");
+               goto done;
+       }
+
+       if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
+               IWL_DEBUG_HC(priv, "Scan request while abort pending.  Queuing.\n");
+               goto done;
+       }
+
+       if (iwl_is_rfkill(priv)) {
+               IWL_DEBUG_HC(priv, "Aborting scan due to RF Kill activation\n");
+               goto done;
+       }
+
+       if (!test_bit(STATUS_READY, &priv->status)) {
+               IWL_DEBUG_HC(priv, "Scan request while uninitialized.  Queuing.\n");
+               goto done;
+       }
+
+       if (!priv->scan_cmd) {
+               priv->scan_cmd = kmalloc(sizeof(struct iwl_scan_cmd) +
+                                        IWL_MAX_SCAN_SIZE, GFP_KERNEL);
+               if (!priv->scan_cmd) {
+                       IWL_DEBUG_SCAN(priv,
+                                      "fail to allocate memory for scan\n");
+                       goto done;
+               }
+       }
+       scan = priv->scan_cmd;
+       memset(scan, 0, sizeof(struct iwl_scan_cmd) + IWL_MAX_SCAN_SIZE);
+
+       scan->quiet_plcp_th = IWL_PLCP_QUIET_THRESH;
+       scan->quiet_time = IWL_ACTIVE_QUIET_TIME;
+
+       if (iwl_is_associated(priv)) {
+               u16 interval = 0;
+               u32 extra;
+               u32 suspend_time = 100;
+               u32 scan_suspend_time = 100;
+               unsigned long flags;
+
+               IWL_DEBUG_INFO(priv, "Scanning while associated...\n");
+               spin_lock_irqsave(&priv->lock, flags);
+               interval = priv->beacon_int;
+               spin_unlock_irqrestore(&priv->lock, flags);
+
+               scan->suspend_time = 0;
+               scan->max_out_time = cpu_to_le32(200 * 1024);
+               if (!interval)
+                       interval = suspend_time;
+
+               extra = (suspend_time / interval) << 22;
+               scan_suspend_time = (extra |
+                   ((suspend_time % interval) * 1024));
+               scan->suspend_time = cpu_to_le32(scan_suspend_time);
+               IWL_DEBUG_SCAN(priv, "suspend_time 0x%X beacon interval %d\n",
+                              scan_suspend_time, interval);
+       }
+
+       if (priv->is_internal_short_scan) {
+               IWL_DEBUG_SCAN(priv, "Start internal passive scan.\n");
+       } else if (priv->scan_request->n_ssids) {
+               int i, p = 0;
+               IWL_DEBUG_SCAN(priv, "Kicking off active scan\n");
+               for (i = 0; i < priv->scan_request->n_ssids; i++) {
+                       /* always does wildcard anyway */
+                       if (!priv->scan_request->ssids[i].ssid_len)
+                               continue;
+                       scan->direct_scan[p].id = WLAN_EID_SSID;
+                       scan->direct_scan[p].len =
+                               priv->scan_request->ssids[i].ssid_len;
+                       memcpy(scan->direct_scan[p].ssid,
+                              priv->scan_request->ssids[i].ssid,
+                              priv->scan_request->ssids[i].ssid_len);
+                       n_probes++;
+                       p++;
+               }
+               is_active = true;
+       } else
+               IWL_DEBUG_SCAN(priv, "Start passive scan.\n");
+
+       scan->tx_cmd.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK;
+       scan->tx_cmd.sta_id = priv->hw_params.bcast_sta_id;
+       scan->tx_cmd.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
+
+       switch (priv->scan_band) {
+       case IEEE80211_BAND_2GHZ:
+               scan->flags = RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK;
+               chan_mod = le32_to_cpu(priv->active_rxon.flags & RXON_FLG_CHANNEL_MODE_MSK)
+                                      >> RXON_FLG_CHANNEL_MODE_POS;
+               if (chan_mod == CHANNEL_MODE_PURE_40) {
+                       rate = IWL_RATE_6M_PLCP;
+               } else {
+                       rate = IWL_RATE_1M_PLCP;
+                       rate_flags = RATE_MCS_CCK_MSK;
+               }
+               scan->good_CRC_th = 0;
+               break;
+       case IEEE80211_BAND_5GHZ:
+               rate = IWL_RATE_6M_PLCP;
+               /*
+                * If active scaning is requested but a certain channel
+                * is marked passive, we can do active scanning if we
+                * detect transmissions.
+                */
+               scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH : 0;
+               break;
+       default:
+               IWL_WARN(priv, "Invalid scan band count\n");
+               goto done;
+       }
+
+       band = priv->scan_band;
+
+       if (priv->cfg->scan_antennas[band])
+               rx_ant = priv->cfg->scan_antennas[band];
+
+       priv->scan_tx_ant[band] =
+                       iwl_toggle_tx_ant(priv, priv->scan_tx_ant[band]);
+       rate_flags |= iwl_ant_idx_to_flags(priv->scan_tx_ant[band]);
+       scan->tx_cmd.rate_n_flags = iwl_hw_set_rate_n_flags(rate, rate_flags);
+
+       /* In power save mode use one chain, otherwise use all chains */
+       if (test_bit(STATUS_POWER_PMI, &priv->status)) {
+               /* rx_ant has been set to all valid chains previously */
+               active_chains = rx_ant &
+                               ((u8)(priv->chain_noise_data.active_chains));
+               if (!active_chains)
+                       active_chains = rx_ant;
+
+               IWL_DEBUG_SCAN(priv, "chain_noise_data.active_chains: %u\n",
+                               priv->chain_noise_data.active_chains);
+
+               rx_ant = first_antenna(active_chains);
+       }
+       /* MIMO is not used here, but value is required */
+       rx_chain |= priv->hw_params.valid_rx_ant << RXON_RX_CHAIN_VALID_POS;
+       rx_chain |= rx_ant << RXON_RX_CHAIN_FORCE_MIMO_SEL_POS;
+       rx_chain |= rx_ant << RXON_RX_CHAIN_FORCE_SEL_POS;
+       rx_chain |= 0x1 << RXON_RX_CHAIN_DRIVER_FORCE_POS;
+       scan->rx_chain = cpu_to_le16(rx_chain);
+       if (!priv->is_internal_short_scan) {
+               cmd_len = iwl_fill_probe_req(priv,
+                                       (struct ieee80211_mgmt *)scan->data,
+                                       priv->scan_request->ie,
+                                       priv->scan_request->ie_len,
+                                       IWL_MAX_SCAN_SIZE - sizeof(*scan));
+       } else {
+               cmd_len = iwl_fill_probe_req(priv,
+                                       (struct ieee80211_mgmt *)scan->data,
+                                       NULL, 0,
+                                       IWL_MAX_SCAN_SIZE - sizeof(*scan));
+
+       }
+       scan->tx_cmd.len = cpu_to_le16(cmd_len);
+
+       scan->filter_flags |= (RXON_FILTER_ACCEPT_GRP_MSK |
+                              RXON_FILTER_BCON_AWARE_MSK);
+
+       if (priv->is_internal_short_scan) {
+               scan->channel_count =
+                       iwl_get_single_channel_for_scan(priv, band,
+                               (void *)&scan->data[le16_to_cpu(
+                               scan->tx_cmd.len)]);
+       } else {
+               scan->channel_count =
+                       iwl_get_channels_for_scan(priv, band,
+                               is_active, n_probes,
+                               (void *)&scan->data[le16_to_cpu(
+                               scan->tx_cmd.len)]);
+       }
+       if (scan->channel_count == 0) {
+               IWL_DEBUG_SCAN(priv, "channel count %d\n", scan->channel_count);
+               goto done;
+       }
+
+       cmd.len += le16_to_cpu(scan->tx_cmd.len) +
+           scan->channel_count * sizeof(struct iwl_scan_channel);
+       cmd.data = scan;
+       scan->len = cpu_to_le16(cmd.len);
+
+       set_bit(STATUS_SCAN_HW, &priv->status);
+       if (iwl_send_cmd_sync(priv, &cmd))
+               goto done;
+
+       queue_delayed_work(priv->workqueue, &priv->scan_check,
+                          IWL_SCAN_CHECK_WATCHDOG);
+
+       return;
+
+ done:
+       /* Cannot perform scan. Make sure we clear scanning
+       * bits from status so next scan request can be performed.
+       * If we don't clear scanning status bit here all next scan
+       * will fail
+       */
+       clear_bit(STATUS_SCAN_HW, &priv->status);
+       clear_bit(STATUS_SCANNING, &priv->status);
+       /* inform mac80211 scan aborted */
+       queue_work(priv->workqueue, &priv->scan_completed);
+}
index f7d85a2173c8cdda6433eb470e965b81ef2f760b..0e6161d7c764e470a8a2cea287c6fb97db0b57a7 100644 (file)
@@ -295,11 +295,11 @@ static u32 rs_tl_get_load(struct iwl_lq_sta *lq_data, u8 tid)
        return tl->total;
 }
 
-static void rs_tl_turn_on_agg_for_tid(struct iwl_priv *priv,
+static int rs_tl_turn_on_agg_for_tid(struct iwl_priv *priv,
                                      struct iwl_lq_sta *lq_data, u8 tid,
                                      struct ieee80211_sta *sta)
 {
-       int ret;
+       int ret = -EAGAIN;
 
        if (rs_tl_get_load(lq_data, tid) > IWL_AGG_LOAD_THRESHOLD) {
                IWL_DEBUG_HT(priv, "Starting Tx agg: STA: %pM tid: %d\n",
@@ -313,29 +313,29 @@ static void rs_tl_turn_on_agg_for_tid(struct iwl_priv *priv,
                         */
                        IWL_DEBUG_HT(priv, "Fail start Tx agg on tid: %d\n",
                                tid);
-                       ret = ieee80211_stop_tx_ba_session(sta, tid,
+                       ieee80211_stop_tx_ba_session(sta, tid,
                                                WLAN_BACK_INITIATOR);
                }
-       }
+       } else
+               IWL_ERR(priv, "Fail finding valid aggregation tid: %d\n", tid);
+       return ret;
 }
 
 static void rs_tl_turn_on_agg(struct iwl_priv *priv, u8 tid,
                              struct iwl_lq_sta *lq_data,
                              struct ieee80211_sta *sta)
 {
-       if ((tid < TID_MAX_LOAD_COUNT))
-               rs_tl_turn_on_agg_for_tid(priv, lq_data, tid, sta);
-       else if (tid == IWL_AGG_ALL_TID)
-               for (tid = 0; tid < TID_MAX_LOAD_COUNT; tid++)
-                       rs_tl_turn_on_agg_for_tid(priv, lq_data, tid, sta);
-       if (priv->cfg->use_rts_for_ht) {
-               /*
-                * switch to RTS/CTS if it is the prefer protection method
-                * for HT traffic
-                */
-               IWL_DEBUG_HT(priv, "use RTS/CTS protection for HT\n");
-               priv->staging_rxon.flags &= ~RXON_FLG_SELF_CTS_EN;
-               iwlcore_commit_rxon(priv);
+       if ((tid < TID_MAX_LOAD_COUNT) &&
+           !rs_tl_turn_on_agg_for_tid(priv, lq_data, tid, sta)) {
+               if (priv->cfg->use_rts_for_ht) {
+                       /*
+                        * switch to RTS/CTS if it is the prefer protection
+                        * method for HT traffic
+                        */
+                       IWL_DEBUG_HT(priv, "use RTS/CTS protection for HT\n");
+                       priv->staging_rxon.flags &= ~RXON_FLG_SELF_CTS_EN;
+                       iwlcore_commit_rxon(priv);
+               }
        }
 }
 
@@ -2558,8 +2558,17 @@ void iwl_rs_rate_init(struct iwl_priv *priv, struct ieee80211_sta *sta, u8 sta_i
                     lq_sta->active_mimo3_rate);
 
        /* These values will be overridden later */
-       lq_sta->lq.general_params.single_stream_ant_msk = ANT_A;
-       lq_sta->lq.general_params.dual_stream_ant_msk = ANT_AB;
+       lq_sta->lq.general_params.single_stream_ant_msk =
+               first_antenna(priv->hw_params.valid_tx_ant);
+       lq_sta->lq.general_params.dual_stream_ant_msk =
+               priv->hw_params.valid_tx_ant &
+               ~first_antenna(priv->hw_params.valid_tx_ant);
+       if (!lq_sta->lq.general_params.dual_stream_ant_msk) {
+               lq_sta->lq.general_params.dual_stream_ant_msk = ANT_AB;
+       } else if (num_of_ant(priv->hw_params.valid_tx_ant) == 2) {
+               lq_sta->lq.general_params.dual_stream_ant_msk =
+                       priv->hw_params.valid_tx_ant;
+       }
 
        /* as default allow aggregation for all tids */
        lq_sta->tx_agg_tid_en = IWL_AGG_ALL_TID;
index 3077eac58880c02291478dcf296564e7366e2248..11661fa28f219be6ab34422fbe9dbaafef2a9cac 100644 (file)
@@ -167,7 +167,7 @@ static int iwlagn_tx_queue_set_q2ratid(struct iwl_priv *priv, u16 ra_tid,
        scd_q2ratid = ra_tid & IWL_SCD_QUEUE_RA_TID_MAP_RATID_MSK;
 
        tbl_dw_addr = priv->scd_base_addr +
-                       IWL50_SCD_TRANSLATE_TBL_OFFSET_QUEUE(txq_id);
+                       IWLAGN_SCD_TRANSLATE_TBL_OFFSET_QUEUE(txq_id);
 
        tbl_dw = iwl_read_targ_mem(priv, tbl_dw_addr);
 
@@ -186,9 +186,9 @@ static void iwlagn_tx_queue_stop_scheduler(struct iwl_priv *priv, u16 txq_id)
        /* Simply stop the queue, but don't change any configuration;
         * the SCD_ACT_EN bit is the write-enable mask for the ACTIVE bit. */
        iwl_write_prph(priv,
-               IWL50_SCD_QUEUE_STATUS_BITS(txq_id),
-               (0 << IWL50_SCD_QUEUE_STTS_REG_POS_ACTIVE)|
-               (1 << IWL50_SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN));
+               IWLAGN_SCD_QUEUE_STATUS_BITS(txq_id),
+               (0 << IWLAGN_SCD_QUEUE_STTS_REG_POS_ACTIVE)|
+               (1 << IWLAGN_SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN));
 }
 
 void iwlagn_set_wr_ptrs(struct iwl_priv *priv,
@@ -196,7 +196,7 @@ void iwlagn_set_wr_ptrs(struct iwl_priv *priv,
 {
        iwl_write_direct32(priv, HBUS_TARG_WRPTR,
                        (index & 0xff) | (txq_id << 8));
-       iwl_write_prph(priv, IWL50_SCD_QUEUE_RDPTR(txq_id), index);
+       iwl_write_prph(priv, IWLAGN_SCD_QUEUE_RDPTR(txq_id), index);
 }
 
 void iwlagn_tx_queue_set_status(struct iwl_priv *priv,
@@ -206,11 +206,11 @@ void iwlagn_tx_queue_set_status(struct iwl_priv *priv,
        int txq_id = txq->q.id;
        int active = test_bit(txq_id, &priv->txq_ctx_active_msk) ? 1 : 0;
 
-       iwl_write_prph(priv, IWL50_SCD_QUEUE_STATUS_BITS(txq_id),
-                       (active << IWL50_SCD_QUEUE_STTS_REG_POS_ACTIVE) |
-                       (tx_fifo_id << IWL50_SCD_QUEUE_STTS_REG_POS_TXF) |
-                       (1 << IWL50_SCD_QUEUE_STTS_REG_POS_WSL) |
-                       IWL50_SCD_QUEUE_STTS_REG_MSK);
+       iwl_write_prph(priv, IWLAGN_SCD_QUEUE_STATUS_BITS(txq_id),
+                       (active << IWLAGN_SCD_QUEUE_STTS_REG_POS_ACTIVE) |
+                       (tx_fifo_id << IWLAGN_SCD_QUEUE_STTS_REG_POS_TXF) |
+                       (1 << IWLAGN_SCD_QUEUE_STTS_REG_POS_WSL) |
+                       IWLAGN_SCD_QUEUE_STTS_REG_MSK);
 
        txq->sched_retry = scd_retry;
 
@@ -250,10 +250,10 @@ int iwlagn_txq_agg_enable(struct iwl_priv *priv, int txq_id,
        iwlagn_tx_queue_set_q2ratid(priv, ra_tid, txq_id);
 
        /* Set this queue as a chain-building queue */
-       iwl_set_bits_prph(priv, IWL50_SCD_QUEUECHAIN_SEL, (1<<txq_id));
+       iwl_set_bits_prph(priv, IWLAGN_SCD_QUEUECHAIN_SEL, (1<<txq_id));
 
        /* enable aggregations for the queue */
-       iwl_set_bits_prph(priv, IWL50_SCD_AGGR_SEL, (1<<txq_id));
+       iwl_set_bits_prph(priv, IWLAGN_SCD_AGGR_SEL, (1<<txq_id));
 
        /* Place first TFD at index corresponding to start sequence number.
         * Assumes that ssn_idx is valid (!= 0xFFF) */
@@ -263,16 +263,16 @@ int iwlagn_txq_agg_enable(struct iwl_priv *priv, int txq_id,
 
        /* Set up Tx window size and frame limit for this queue */
        iwl_write_targ_mem(priv, priv->scd_base_addr +
-                       IWL50_SCD_CONTEXT_QUEUE_OFFSET(txq_id) +
+                       IWLAGN_SCD_CONTEXT_QUEUE_OFFSET(txq_id) +
                        sizeof(u32),
                        ((SCD_WIN_SIZE <<
-                       IWL50_SCD_QUEUE_CTX_REG2_WIN_SIZE_POS) &
-                       IWL50_SCD_QUEUE_CTX_REG2_WIN_SIZE_MSK) |
+                       IWLAGN_SCD_QUEUE_CTX_REG2_WIN_SIZE_POS) &
+                       IWLAGN_SCD_QUEUE_CTX_REG2_WIN_SIZE_MSK) |
                        ((SCD_FRAME_LIMIT <<
-                       IWL50_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS) &
-                       IWL50_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK));
+                       IWLAGN_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS) &
+                       IWLAGN_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK));
 
-       iwl_set_bits_prph(priv, IWL50_SCD_INTERRUPT_MASK, (1 << txq_id));
+       iwl_set_bits_prph(priv, IWLAGN_SCD_INTERRUPT_MASK, (1 << txq_id));
 
        /* Set up Status area in SRAM, map to Tx DMA/FIFO, activate the queue */
        iwlagn_tx_queue_set_status(priv, &priv->txq[txq_id], tx_fifo, 1);
@@ -298,14 +298,14 @@ int iwlagn_txq_agg_disable(struct iwl_priv *priv, u16 txq_id,
 
        iwlagn_tx_queue_stop_scheduler(priv, txq_id);
 
-       iwl_clear_bits_prph(priv, IWL50_SCD_AGGR_SEL, (1 << txq_id));
+       iwl_clear_bits_prph(priv, IWLAGN_SCD_AGGR_SEL, (1 << txq_id));
 
        priv->txq[txq_id].q.read_ptr = (ssn_idx & 0xff);
        priv->txq[txq_id].q.write_ptr = (ssn_idx & 0xff);
        /* supposes that ssn_idx is valid (!= 0xFFF) */
        iwlagn_set_wr_ptrs(priv, txq_id, ssn_idx);
 
-       iwl_clear_bits_prph(priv, IWL50_SCD_INTERRUPT_MASK, (1 << txq_id));
+       iwl_clear_bits_prph(priv, IWLAGN_SCD_INTERRUPT_MASK, (1 << txq_id));
        iwl_txq_ctx_deactivate(priv, txq_id);
        iwlagn_tx_queue_set_status(priv, &priv->txq[txq_id], tx_fifo, 0);
 
@@ -318,7 +318,7 @@ int iwlagn_txq_agg_disable(struct iwl_priv *priv, u16 txq_id,
  */
 void iwlagn_txq_set_sched(struct iwl_priv *priv, u32 mask)
 {
-       iwl_write_prph(priv, IWL50_SCD_TXFACT, mask);
+       iwl_write_prph(priv, IWLAGN_SCD_TXFACT, mask);
 }
 
 static inline int get_queue_from_ac(u16 ac)
index 52ae157968b2242533d8d7fed4effdb98eef20fa..ae476c234a7c49d3f9722fd0941af08960a32691 100644 (file)
@@ -207,7 +207,7 @@ static int iwlagn_set_Xtal_calib(struct iwl_priv *priv)
 {
        struct iwl_calib_xtal_freq_cmd cmd;
        __le16 *xtal_calib =
-               (__le16 *)iwl_eeprom_query_addr(priv, EEPROM_5000_XTAL);
+               (__le16 *)iwl_eeprom_query_addr(priv, EEPROM_XTAL);
 
        cmd.hdr.op_code = IWL_PHY_CALIBRATE_CRYSTAL_FRQ_CMD;
        cmd.hdr.first_group = 0;
@@ -329,19 +329,19 @@ int iwlagn_alive_notify(struct iwl_priv *priv)
 
        spin_lock_irqsave(&priv->lock, flags);
 
-       priv->scd_base_addr = iwl_read_prph(priv, IWL50_SCD_SRAM_BASE_ADDR);
-       a = priv->scd_base_addr + IWL50_SCD_CONTEXT_DATA_OFFSET;
-       for (; a < priv->scd_base_addr + IWL50_SCD_TX_STTS_BITMAP_OFFSET;
+       priv->scd_base_addr = iwl_read_prph(priv, IWLAGN_SCD_SRAM_BASE_ADDR);
+       a = priv->scd_base_addr + IWLAGN_SCD_CONTEXT_DATA_OFFSET;
+       for (; a < priv->scd_base_addr + IWLAGN_SCD_TX_STTS_BITMAP_OFFSET;
                a += 4)
                iwl_write_targ_mem(priv, a, 0);
-       for (; a < priv->scd_base_addr + IWL50_SCD_TRANSLATE_TBL_OFFSET;
+       for (; a < priv->scd_base_addr + IWLAGN_SCD_TRANSLATE_TBL_OFFSET;
                a += 4)
                iwl_write_targ_mem(priv, a, 0);
        for (; a < priv->scd_base_addr +
-              IWL50_SCD_TRANSLATE_TBL_OFFSET_QUEUE(priv->hw_params.max_txq_num); a += 4)
+              IWLAGN_SCD_TRANSLATE_TBL_OFFSET_QUEUE(priv->hw_params.max_txq_num); a += 4)
                iwl_write_targ_mem(priv, a, 0);
 
-       iwl_write_prph(priv, IWL50_SCD_DRAM_BASE_ADDR,
+       iwl_write_prph(priv, IWLAGN_SCD_DRAM_BASE_ADDR,
                       priv->scd_bc_tbls.dma >> 10);
 
        /* Enable DMA channel */
@@ -355,28 +355,28 @@ int iwlagn_alive_notify(struct iwl_priv *priv)
        iwl_write_direct32(priv, FH_TX_CHICKEN_BITS_REG,
                           reg_val | FH_TX_CHICKEN_BITS_SCD_AUTO_RETRY_EN);
 
-       iwl_write_prph(priv, IWL50_SCD_QUEUECHAIN_SEL,
-               IWL50_SCD_QUEUECHAIN_SEL_ALL(priv->hw_params.max_txq_num));
-       iwl_write_prph(priv, IWL50_SCD_AGGR_SEL, 0);
+       iwl_write_prph(priv, IWLAGN_SCD_QUEUECHAIN_SEL,
+               IWLAGN_SCD_QUEUECHAIN_SEL_ALL(priv->hw_params.max_txq_num));
+       iwl_write_prph(priv, IWLAGN_SCD_AGGR_SEL, 0);
 
        /* initiate the queues */
        for (i = 0; i < priv->hw_params.max_txq_num; i++) {
-               iwl_write_prph(priv, IWL50_SCD_QUEUE_RDPTR(i), 0);
+               iwl_write_prph(priv, IWLAGN_SCD_QUEUE_RDPTR(i), 0);
                iwl_write_direct32(priv, HBUS_TARG_WRPTR, 0 | (i << 8));
                iwl_write_targ_mem(priv, priv->scd_base_addr +
-                               IWL50_SCD_CONTEXT_QUEUE_OFFSET(i), 0);
+                               IWLAGN_SCD_CONTEXT_QUEUE_OFFSET(i), 0);
                iwl_write_targ_mem(priv, priv->scd_base_addr +
-                               IWL50_SCD_CONTEXT_QUEUE_OFFSET(i) +
+                               IWLAGN_SCD_CONTEXT_QUEUE_OFFSET(i) +
                                sizeof(u32),
                                ((SCD_WIN_SIZE <<
-                               IWL50_SCD_QUEUE_CTX_REG2_WIN_SIZE_POS) &
-                               IWL50_SCD_QUEUE_CTX_REG2_WIN_SIZE_MSK) |
+                               IWLAGN_SCD_QUEUE_CTX_REG2_WIN_SIZE_POS) &
+                               IWLAGN_SCD_QUEUE_CTX_REG2_WIN_SIZE_MSK) |
                                ((SCD_FRAME_LIMIT <<
-                               IWL50_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS) &
-                               IWL50_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK));
+                               IWLAGN_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS) &
+                               IWLAGN_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK));
        }
 
-       iwl_write_prph(priv, IWL50_SCD_INTERRUPT_MASK,
+       iwl_write_prph(priv, IWLAGN_SCD_INTERRUPT_MASK,
                        IWL_MASK(0, priv->hw_params.max_txq_num));
 
        /* Activate all Tx DMA/FIFO channels */
index 310bc6aeb99be4ca73ad636e5bf140193328b770..00344d64635c580146762ba25f179fe323106cf1 100644 (file)
@@ -2174,7 +2174,7 @@ static void iwl_alive_start(struct iwl_priv *priv)
        }
 
        /* Configure Bluetooth device coexistence support */
-       iwl_send_bt_config(priv);
+       priv->cfg->ops->hcmd->send_bt_config(priv);
 
        iwl_reset_run_time_calib(priv);
 
@@ -3178,44 +3178,6 @@ static ssize_t store_tx_power(struct device *d,
 
 static DEVICE_ATTR(tx_power, S_IWUSR | S_IRUGO, show_tx_power, store_tx_power);
 
-static ssize_t show_statistics(struct device *d,
-                              struct device_attribute *attr, char *buf)
-{
-       struct iwl_priv *priv = dev_get_drvdata(d);
-       u32 size = sizeof(struct iwl_notif_statistics);
-       u32 len = 0, ofs = 0;
-       u8 *data = (u8 *)&priv->statistics;
-       int rc = 0;
-
-       if (!iwl_is_alive(priv))
-               return -EAGAIN;
-
-       mutex_lock(&priv->mutex);
-       rc = iwl_send_statistics_request(priv, CMD_SYNC, false);
-       mutex_unlock(&priv->mutex);
-
-       if (rc) {
-               len = sprintf(buf,
-                             "Error sending statistics request: 0x%08X\n", rc);
-               return len;
-       }
-
-       while (size && (PAGE_SIZE - len)) {
-               hex_dump_to_buffer(data + ofs, size, 16, 1, buf + len,
-                                  PAGE_SIZE - len, 1);
-               len = strlen(buf);
-               if (PAGE_SIZE - len)
-                       buf[len++] = '\n';
-
-               ofs += 16;
-               size -= min(size, 16U);
-       }
-
-       return len;
-}
-
-static DEVICE_ATTR(statistics, S_IRUGO, show_statistics, NULL);
-
 static ssize_t show_rts_ht_protection(struct device *d,
                             struct device_attribute *attr, char *buf)
 {
@@ -3401,11 +3363,10 @@ static void iwl_uninit_drv(struct iwl_priv *priv)
        iwl_calib_free_results(priv);
        iwlcore_free_geos(priv);
        iwl_free_channel_map(priv);
-       kfree(priv->scan);
+       kfree(priv->scan_cmd);
 }
 
 static struct attribute *iwl_sysfs_entries[] = {
-       &dev_attr_statistics.attr,
        &dev_attr_temperature.attr,
        &dev_attr_tx_power.attr,
        &dev_attr_rts_ht_protection.attr,
@@ -3836,7 +3797,12 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = {
        {IWL_PCI_DEVICE(0x4238, 0x1111, iwl6000_3agn_cfg)},
        {IWL_PCI_DEVICE(0x4239, 0x1311, iwl6000i_2agn_cfg)},
        {IWL_PCI_DEVICE(0x4239, 0x1316, iwl6000i_2abg_cfg)},
-       {IWL_PCI_DEVICE(0x0082, 0x1201, iwl6000i_g2_2agn_cfg)},
+
+/* 6x00 Series Gen2 */
+       {IWL_PCI_DEVICE(0x0082, 0x1201, iwl6000g2_2agn_cfg)},
+       {IWL_PCI_DEVICE(0x0082, 0x1301, iwl6000g2_2agn_cfg)},
+       {IWL_PCI_DEVICE(0x0082, 0x1321, iwl6000g2_2agn_cfg)},
+       {IWL_PCI_DEVICE(0x0085, 0x1311, iwl6000g2_2agn_cfg)},
 
 /* 6x50 WiFi/WiMax Series */
        {IWL_PCI_DEVICE(0x0087, 0x1301, iwl6050_2agn_cfg)},
index 5d3142287e14f7ed4e7bd609c410f5015ec2ff11..cfee9994383e787f13680b912ff3178b820e0a60 100644 (file)
@@ -171,4 +171,7 @@ static inline bool iwl_is_tx_success(u32 status)
               (status == TX_STATUS_DIRECT_DONE);
 }
 
+/* scan */
+void iwlagn_request_scan(struct iwl_priv *priv);
+
 #endif /* __iwl_agn_h__ */
index d830086ca195e31cd7c08304f6e752e4e1d5a932..67c723cc32d276b1b310f701d98adfc4c3274241 100644 (file)
@@ -1443,7 +1443,7 @@ struct iwl4965_rx_mpdu_res_start {
 
 /* 1: Ignore Bluetooth priority for this frame.
  * 0: Delay Tx until Bluetooth device is done (normal usage). */
-#define TX_CMD_FLG_BT_DIS_MSK cpu_to_le32(1 << 12)
+#define TX_CMD_FLG_IGNORE_BT cpu_to_le32(1 << 12)
 
 /* 1: uCode overrides sequence control field in MAC header.
  * 0: Driver provides sequence control field in MAC header.
index b75808aad1ef523fbafbe303fcdb5bc9b94a7b78..56a9f1741419b581bbcb23bbf083319bdb05b16c 100644 (file)
@@ -828,19 +828,6 @@ static u8 iwl_count_chain_bitmap(u32 chain_bitmap)
        return res;
 }
 
-/**
- * iwl_is_monitor_mode - Determine if interface in monitor mode
- *
- * priv->iw_mode is set in add_interface, but add_interface is
- * never called for monitor mode. The only way mac80211 informs us about
- * monitor mode is through configuring filters (call to configure_filter).
- */
-bool iwl_is_monitor_mode(struct iwl_priv *priv)
-{
-       return !!(priv->staging_rxon.filter_flags & RXON_FILTER_PROMISC_MSK);
-}
-EXPORT_SYMBOL(iwl_is_monitor_mode);
-
 /**
  * iwl_set_rxon_chain - Set up Rx chain usage in "staging" RXON image
  *
@@ -884,19 +871,6 @@ void iwl_set_rxon_chain(struct iwl_priv *priv)
        rx_chain |= active_rx_cnt << RXON_RX_CHAIN_MIMO_CNT_POS;
        rx_chain |= idle_rx_cnt  << RXON_RX_CHAIN_CNT_POS;
 
-       /* copied from 'iwl_bg_request_scan()' */
-       /* Force use of chains B and C (0x6) for Rx
-        * Avoid A (0x1) for the device has off-channel reception on A-band.
-        * MIMO is not used here, but value is required */
-       if (iwl_is_monitor_mode(priv) &&
-           !(priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) &&
-           priv->cfg->off_channel_workaround) {
-               rx_chain = ANT_ABC << RXON_RX_CHAIN_VALID_POS;
-               rx_chain |= ANT_BC << RXON_RX_CHAIN_FORCE_SEL_POS;
-               rx_chain |= ANT_ABC << RXON_RX_CHAIN_FORCE_MIMO_SEL_POS;
-               rx_chain |= 0x1 << RXON_RX_CHAIN_DRIVER_FORCE_POS;
-       }
-
        priv->staging_rxon.rx_chain = cpu_to_le16(rx_chain);
 
        if (!is_single && (active_rx_cnt >= IWL_NUM_RX_CHAINS_SINGLE) && is_cam)
@@ -1480,7 +1454,7 @@ irqreturn_t iwl_isr_legacy(int irq, void *data)
 }
 EXPORT_SYMBOL(iwl_isr_legacy);
 
-int iwl_send_bt_config(struct iwl_priv *priv)
+void iwl_send_bt_config(struct iwl_priv *priv)
 {
        struct iwl_bt_cmd bt_cmd = {
                .lead_time = BT_LEAD_TIME_DEF,
@@ -1497,8 +1471,9 @@ int iwl_send_bt_config(struct iwl_priv *priv)
        IWL_DEBUG_INFO(priv, "BT coex %s\n",
                (bt_cmd.flags == BT_COEX_DISABLE) ? "disable" : "active");
 
-       return iwl_send_cmd_pdu(priv, REPLY_BT_CONFIG,
-                               sizeof(struct iwl_bt_cmd), &bt_cmd);
+       if (iwl_send_cmd_pdu(priv, REPLY_BT_CONFIG,
+                            sizeof(struct iwl_bt_cmd), &bt_cmd))
+               IWL_ERR(priv, "failed to send BT Coex Config\n");
 }
 EXPORT_SYMBOL(iwl_send_bt_config);
 
@@ -1868,7 +1843,6 @@ static inline void iwl_set_no_assoc(struct iwl_priv *priv)
        iwlcore_commit_rxon(priv);
 }
 
-#define IWL_DELAY_NEXT_SCAN_AFTER_ASSOC (HZ*6)
 void iwl_bss_info_changed(struct ieee80211_hw *hw,
                          struct ieee80211_vif *vif,
                          struct ieee80211_bss_conf *bss_conf,
@@ -1989,14 +1963,6 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw,
 
                        iwl_led_associate(priv);
 
-                       /*
-                        * We have just associated, don't start scan too early
-                        * leave time for EAPOL exchange to complete.
-                        *
-                        * XXX: do this in mac80211
-                        */
-                       priv->next_scan_jiffies = jiffies +
-                                       IWL_DELAY_NEXT_SCAN_AFTER_ASSOC;
                        if (!iwl_is_rfkill(priv))
                                priv->cfg->ops->lib->post_associate(priv);
                } else
@@ -2383,11 +2349,11 @@ EXPORT_SYMBOL(iwl_free_txq_mem);
 
 int iwl_send_wimax_coex(struct iwl_priv *priv)
 {
-       struct iwl_wimax_coex_cmd uninitialized_var(coex_cmd);
+       struct iwl_wimax_coex_cmd coex_cmd;
 
        if (priv->cfg->support_wimax_coexist) {
                /* UnMask wake up src at associated sleep */
-               coex_cmd.flags |= COEX_FLAGS_ASSOC_WA_UNMASK_MSK;
+               coex_cmd.flags = COEX_FLAGS_ASSOC_WA_UNMASK_MSK;
 
                /* UnMask wake up src at unassociated sleep */
                coex_cmd.flags |= COEX_FLAGS_UNASSOC_WA_UNMASK_MSK;
index 6c3f0127f7432a4aa5abc9359f4985d30b8cb2ea..a0cc11ecbe939322450a00072e65403d6ff308c9 100644 (file)
@@ -90,6 +90,7 @@ struct iwl_hcmd_ops {
        int (*commit_rxon)(struct iwl_priv *priv);
        void (*set_rxon_chain)(struct iwl_priv *priv);
        int (*set_tx_ant)(struct iwl_priv *priv, u8 valid_tx_ant);
+       void (*send_bt_config)(struct iwl_priv *priv);
 };
 
 struct iwl_hcmd_utils_ops {
@@ -105,6 +106,7 @@ struct iwl_hcmd_utils_ops {
                        __le32 *tx_flags);
        int  (*calc_rssi)(struct iwl_priv *priv,
                          struct iwl_rx_phy_res *rx_resp);
+       void (*request_scan)(struct iwl_priv *priv);
 };
 
 struct iwl_apm_ops {
@@ -114,6 +116,15 @@ struct iwl_apm_ops {
        int (*set_pwr_src)(struct iwl_priv *priv, enum iwl_pwr_src src);
 };
 
+struct iwl_debugfs_ops {
+       ssize_t (*rx_stats_read)(struct file *file, char __user *user_buf,
+                                size_t count, loff_t *ppos);
+       ssize_t (*tx_stats_read)(struct file *file, char __user *user_buf,
+                                size_t count, loff_t *ppos);
+       ssize_t (*general_stats_read)(struct file *file, char __user *user_buf,
+                                     size_t count, loff_t *ppos);
+};
+
 struct iwl_temp_ops {
        void (*temperature)(struct iwl_priv *priv);
        void (*set_ct_kill)(struct iwl_priv *priv);
@@ -199,6 +210,7 @@ struct iwl_lib_ops {
        /* check for ack health */
        bool (*check_ack_health)(struct iwl_priv *priv,
                                        struct iwl_rx_packet *pkt);
+       struct iwl_debugfs_ops debugfs_ops;
 };
 
 struct iwl_led_ops {
@@ -306,8 +318,8 @@ struct iwl_cfg {
        /* timer period for monitor the driver queues */
        u32 monitor_recover_period;
        bool temperature_kelvin;
-       bool off_channel_workaround;
        u32 max_event_log_size;
+       u8 scan_antennas[IEEE80211_NUM_BANDS];
 };
 
 /***************************
@@ -339,7 +351,6 @@ void iwl_configure_filter(struct ieee80211_hw *hw,
                          unsigned int changed_flags,
                          unsigned int *total_flags, u64 multicast);
 int iwl_set_hw_params(struct iwl_priv *priv);
-bool iwl_is_monitor_mode(struct iwl_priv *priv);
 void iwl_post_associate(struct iwl_priv *priv);
 void iwl_bss_info_changed(struct ieee80211_hw *hw,
                                     struct ieee80211_vif *vif,
@@ -526,6 +537,7 @@ void iwl_setup_scan_deferred_work(struct iwl_priv *priv);
 #define IWL_ACTIVE_QUIET_TIME       cpu_to_le16(10)  /* msec */
 #define IWL_PLCP_QUIET_THRESH       cpu_to_le16(1)  /* packets */
 
+#define IWL_SCAN_CHECK_WATCHDOG                (HZ * 7)
 
 /*******************************************************************************
  * Calibrations - implemented in iwl-calib.c
@@ -665,7 +677,7 @@ static inline int iwl_is_ready_rf(struct iwl_priv *priv)
 }
 
 extern void iwl_rf_kill_ct_config(struct iwl_priv *priv);
-extern int iwl_send_bt_config(struct iwl_priv *priv);
+extern void iwl_send_bt_config(struct iwl_priv *priv);
 extern int iwl_send_statistics_request(struct iwl_priv *priv,
                                       u8 flags, bool clear);
 extern int iwl_verify_ucode(struct iwl_priv *priv);
index 808b7146bead98d1cfc15e83051450d561261a37..254c35ae8b38b583472df5254a3b50c36e83825c 100644 (file)
 #define CSR_HW_REV_TYPE_1000           (0x0000060)
 #define CSR_HW_REV_TYPE_6x00           (0x0000070)
 #define CSR_HW_REV_TYPE_6x50           (0x0000080)
+#define CSR_HW_REV_TYPE_6x00g2         (0x00000B0)
 #define CSR_HW_REV_TYPE_NONE           (0x00000F0)
 
 /* EEPROM REG */
index 1c7b53d511c7eefe9bec3fca6fc143ab8d994f46..5c2bcef5df0cdca8a328f2fc35b38b7c6aa71f2b 100644 (file)
@@ -78,6 +78,8 @@ static inline void iwl_print_hex_dump(struct iwl_priv *priv, int level,
 #ifdef CONFIG_IWLWIFI_DEBUGFS
 int iwl_dbgfs_register(struct iwl_priv *priv, const char *name);
 void iwl_dbgfs_unregister(struct iwl_priv *priv);
+extern int iwl_dbgfs_statistics_flag(struct iwl_priv *priv, char *buf,
+                                    int bufsz);
 #else
 static inline int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
 {
index 607a91f3eb6b475511afa603281ae7866678b1da..61faf2dd7fbe95df7571919ff8b008f6dde68c32 100644 (file)
@@ -106,6 +106,26 @@ static const struct file_operations iwl_dbgfs_##name##_ops = {          \
        .open = iwl_dbgfs_open_file_generic,                            \
 };
 
+int iwl_dbgfs_statistics_flag(struct iwl_priv *priv, char *buf, int bufsz)
+{
+       int p = 0;
+
+       p += scnprintf(buf + p, bufsz - p, "Statistics Flag(0x%X):\n",
+                      le32_to_cpu(priv->statistics.flag));
+       if (le32_to_cpu(priv->statistics.flag) & UCODE_STATISTICS_CLEAR_MSK)
+               p += scnprintf(buf + p, bufsz - p,
+                              "\tStatistics have been cleared\n");
+       p += scnprintf(buf + p, bufsz - p, "\tOperational Frequency: %s\n",
+                      (le32_to_cpu(priv->statistics.flag) &
+                       UCODE_STATISTICS_FREQUENCY_MSK)
+                       ? "2.4 GHz" : "5.2 GHz");
+       p += scnprintf(buf + p, bufsz - p, "\tTGj Narrow Band: %s\n",
+                      (le32_to_cpu(priv->statistics.flag) &
+                       UCODE_STATISTICS_NARROW_BAND_MSK)
+                       ? "enabled" : "disabled");
+       return p;
+}
+EXPORT_SYMBOL(iwl_dbgfs_statistics_flag);
 
 static ssize_t iwl_dbgfs_tx_statistics_read(struct file *file,
                                                char __user *user_buf,
@@ -1034,474 +1054,15 @@ static ssize_t iwl_dbgfs_rx_queue_read(struct file *file,
        return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
 }
 
-static int iwl_dbgfs_statistics_flag(struct iwl_priv *priv, char *buf,
-                                    int bufsz)
-{
-       int p = 0;
-
-       p += scnprintf(buf + p, bufsz - p,
-               "Statistics Flag(0x%X):\n",
-               le32_to_cpu(priv->statistics.flag));
-       if (le32_to_cpu(priv->statistics.flag) & UCODE_STATISTICS_CLEAR_MSK)
-               p += scnprintf(buf + p, bufsz - p,
-               "\tStatistics have been cleared\n");
-       p += scnprintf(buf + p, bufsz - p,
-               "\tOperational Frequency: %s\n",
-               (le32_to_cpu(priv->statistics.flag) &
-               UCODE_STATISTICS_FREQUENCY_MSK)
-                ? "2.4 GHz" : "5.2 GHz");
-       p += scnprintf(buf + p, bufsz - p,
-               "\tTGj Narrow Band: %s\n",
-               (le32_to_cpu(priv->statistics.flag) &
-               UCODE_STATISTICS_NARROW_BAND_MSK)
-                ? "enabled" : "disabled");
-       return p;
-}
-
-static const char ucode_stats_header[] =
-       "%-32s     current  acumulative       delta         max\n";
-static const char ucode_stats_short_format[] =
-       "  %-30s %10u\n";
-static const char ucode_stats_format[] =
-       "  %-30s %10u  %10u  %10u  %10u\n";
-
 static ssize_t iwl_dbgfs_ucode_rx_stats_read(struct file *file,
                                        char __user *user_buf,
                                        size_t count, loff_t *ppos)
 {
        struct iwl_priv *priv = file->private_data;
-       int pos = 0;
-       char *buf;
-       int bufsz = sizeof(struct statistics_rx_phy) * 40 +
-               sizeof(struct statistics_rx_non_phy) * 40 +
-               sizeof(struct statistics_rx_ht_phy) * 40 + 400;
-       ssize_t ret;
-       struct statistics_rx_phy *ofdm, *accum_ofdm, *delta_ofdm, *max_ofdm;
-       struct statistics_rx_phy *cck, *accum_cck, *delta_cck, *max_cck;
-       struct statistics_rx_non_phy *general, *accum_general;
-       struct statistics_rx_non_phy *delta_general, *max_general;
-       struct statistics_rx_ht_phy *ht, *accum_ht, *delta_ht, *max_ht;
-
-       if (!iwl_is_alive(priv))
-               return -EAGAIN;
-
-       buf = kzalloc(bufsz, GFP_KERNEL);
-       if (!buf) {
-               IWL_ERR(priv, "Can not allocate Buffer\n");
-               return -ENOMEM;
-       }
-
-       /* the statistic information display here is based on
-        * the last statistics notification from uCode
-        * might not reflect the current uCode activity
-        */
-       ofdm = &priv->statistics.rx.ofdm;
-       cck = &priv->statistics.rx.cck;
-       general = &priv->statistics.rx.general;
-       ht = &priv->statistics.rx.ofdm_ht;
-       accum_ofdm = &priv->accum_statistics.rx.ofdm;
-       accum_cck = &priv->accum_statistics.rx.cck;
-       accum_general = &priv->accum_statistics.rx.general;
-       accum_ht = &priv->accum_statistics.rx.ofdm_ht;
-       delta_ofdm = &priv->delta_statistics.rx.ofdm;
-       delta_cck = &priv->delta_statistics.rx.cck;
-       delta_general = &priv->delta_statistics.rx.general;
-       delta_ht = &priv->delta_statistics.rx.ofdm_ht;
-       max_ofdm = &priv->max_delta.rx.ofdm;
-       max_cck = &priv->max_delta.rx.cck;
-       max_general = &priv->max_delta.rx.general;
-       max_ht = &priv->max_delta.rx.ofdm_ht;
-
-       pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz);
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_header,
-                        "Statistics_Rx - OFDM:");
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
-                        "ina_cnt:", le32_to_cpu(ofdm->ina_cnt),
-                        accum_ofdm->ina_cnt,
-                        delta_ofdm->ina_cnt, max_ofdm->ina_cnt);
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
-                        "fina_cnt:",
-                        le32_to_cpu(ofdm->fina_cnt), accum_ofdm->fina_cnt,
-                        delta_ofdm->fina_cnt, max_ofdm->fina_cnt);
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
-                        "plcp_err:",
-                        le32_to_cpu(ofdm->plcp_err), accum_ofdm->plcp_err,
-                        delta_ofdm->plcp_err, max_ofdm->plcp_err);
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
-                        "crc32_err:",
-                        le32_to_cpu(ofdm->crc32_err), accum_ofdm->crc32_err,
-                        delta_ofdm->crc32_err, max_ofdm->crc32_err);
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
-                        "overrun_err:",
-                        le32_to_cpu(ofdm->overrun_err),
-                        accum_ofdm->overrun_err,
-                        delta_ofdm->overrun_err, max_ofdm->overrun_err);
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
-                        "early_overrun_err:",
-                        le32_to_cpu(ofdm->early_overrun_err),
-                        accum_ofdm->early_overrun_err,
-                        delta_ofdm->early_overrun_err,
-                        max_ofdm->early_overrun_err);
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
-                        "crc32_good:",
-                        le32_to_cpu(ofdm->crc32_good),
-                        accum_ofdm->crc32_good,
-                        delta_ofdm->crc32_good, max_ofdm->crc32_good);
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
-                        "false_alarm_cnt:",
-                        le32_to_cpu(ofdm->false_alarm_cnt),
-                        accum_ofdm->false_alarm_cnt,
-                        delta_ofdm->false_alarm_cnt,
-                        max_ofdm->false_alarm_cnt);
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
-                        "fina_sync_err_cnt:",
-                        le32_to_cpu(ofdm->fina_sync_err_cnt),
-                        accum_ofdm->fina_sync_err_cnt,
-                        delta_ofdm->fina_sync_err_cnt,
-                        max_ofdm->fina_sync_err_cnt);
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
-                        "sfd_timeout:",
-                        le32_to_cpu(ofdm->sfd_timeout),
-                        accum_ofdm->sfd_timeout,
-                        delta_ofdm->sfd_timeout,
-                        max_ofdm->sfd_timeout);
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
-                        "fina_timeout:",
-                        le32_to_cpu(ofdm->fina_timeout),
-                        accum_ofdm->fina_timeout,
-                        delta_ofdm->fina_timeout,
-                        max_ofdm->fina_timeout);
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
-                        "unresponded_rts:",
-                        le32_to_cpu(ofdm->unresponded_rts),
-                        accum_ofdm->unresponded_rts,
-                        delta_ofdm->unresponded_rts,
-                        max_ofdm->unresponded_rts);
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
-                       "rxe_frame_lmt_ovrun:",
-                        le32_to_cpu(ofdm->rxe_frame_limit_overrun),
-                        accum_ofdm->rxe_frame_limit_overrun,
-                        delta_ofdm->rxe_frame_limit_overrun,
-                        max_ofdm->rxe_frame_limit_overrun);
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
-                        "sent_ack_cnt:",
-                        le32_to_cpu(ofdm->sent_ack_cnt),
-                        accum_ofdm->sent_ack_cnt,
-                        delta_ofdm->sent_ack_cnt,
-                        max_ofdm->sent_ack_cnt);
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
-                        "sent_cts_cnt:",
-                        le32_to_cpu(ofdm->sent_cts_cnt),
-                        accum_ofdm->sent_cts_cnt,
-                        delta_ofdm->sent_cts_cnt, max_ofdm->sent_cts_cnt);
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
-                        "sent_ba_rsp_cnt:",
-                        le32_to_cpu(ofdm->sent_ba_rsp_cnt),
-                        accum_ofdm->sent_ba_rsp_cnt,
-                        delta_ofdm->sent_ba_rsp_cnt,
-                        max_ofdm->sent_ba_rsp_cnt);
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
-                        "dsp_self_kill:",
-                        le32_to_cpu(ofdm->dsp_self_kill),
-                        accum_ofdm->dsp_self_kill,
-                        delta_ofdm->dsp_self_kill,
-                        max_ofdm->dsp_self_kill);
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
-                        "mh_format_err:",
-                        le32_to_cpu(ofdm->mh_format_err),
-                        accum_ofdm->mh_format_err,
-                        delta_ofdm->mh_format_err,
-                        max_ofdm->mh_format_err);
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
-                        "re_acq_main_rssi_sum:",
-                        le32_to_cpu(ofdm->re_acq_main_rssi_sum),
-                        accum_ofdm->re_acq_main_rssi_sum,
-                        delta_ofdm->re_acq_main_rssi_sum,
-                       max_ofdm->re_acq_main_rssi_sum);
-
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_header,
-                        "Statistics_Rx - CCK:");
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
-                        "ina_cnt:",
-                        le32_to_cpu(cck->ina_cnt), accum_cck->ina_cnt,
-                        delta_cck->ina_cnt, max_cck->ina_cnt);
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
-                        "fina_cnt:",
-                        le32_to_cpu(cck->fina_cnt), accum_cck->fina_cnt,
-                        delta_cck->fina_cnt, max_cck->fina_cnt);
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
-                        "plcp_err:",
-                        le32_to_cpu(cck->plcp_err), accum_cck->plcp_err,
-                        delta_cck->plcp_err, max_cck->plcp_err);
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
-                        "crc32_err:",
-                        le32_to_cpu(cck->crc32_err), accum_cck->crc32_err,
-                        delta_cck->crc32_err, max_cck->crc32_err);
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
-                        "overrun_err:",
-                        le32_to_cpu(cck->overrun_err),
-                        accum_cck->overrun_err,
-                        delta_cck->overrun_err, max_cck->overrun_err);
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
-                        "early_overrun_err:",
-                        le32_to_cpu(cck->early_overrun_err),
-                        accum_cck->early_overrun_err,
-                        delta_cck->early_overrun_err,
-                        max_cck->early_overrun_err);
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
-                        "crc32_good:",
-                        le32_to_cpu(cck->crc32_good), accum_cck->crc32_good,
-                        delta_cck->crc32_good,
-                        max_cck->crc32_good);
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
-                        "false_alarm_cnt:",
-                        le32_to_cpu(cck->false_alarm_cnt),
-                        accum_cck->false_alarm_cnt,
-                        delta_cck->false_alarm_cnt, max_cck->false_alarm_cnt);
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
-                        "fina_sync_err_cnt:",
-                        le32_to_cpu(cck->fina_sync_err_cnt),
-                        accum_cck->fina_sync_err_cnt,
-                        delta_cck->fina_sync_err_cnt,
-                        max_cck->fina_sync_err_cnt);
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
-                        "sfd_timeout:",
-                        le32_to_cpu(cck->sfd_timeout),
-                        accum_cck->sfd_timeout,
-                        delta_cck->sfd_timeout, max_cck->sfd_timeout);
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
-                        "fina_timeout:",
-                        le32_to_cpu(cck->fina_timeout),
-                        accum_cck->fina_timeout,
-                        delta_cck->fina_timeout, max_cck->fina_timeout);
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
-                        "unresponded_rts:",
-                        le32_to_cpu(cck->unresponded_rts),
-                        accum_cck->unresponded_rts,
-                        delta_cck->unresponded_rts,
-                        max_cck->unresponded_rts);
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
-                       "rxe_frame_lmt_ovrun:",
-                        le32_to_cpu(cck->rxe_frame_limit_overrun),
-                        accum_cck->rxe_frame_limit_overrun,
-                        delta_cck->rxe_frame_limit_overrun,
-                        max_cck->rxe_frame_limit_overrun);
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
-                        "sent_ack_cnt:",
-                        le32_to_cpu(cck->sent_ack_cnt),
-                        accum_cck->sent_ack_cnt,
-                        delta_cck->sent_ack_cnt,
-                        max_cck->sent_ack_cnt);
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
-                        "sent_cts_cnt:",
-                        le32_to_cpu(cck->sent_cts_cnt),
-                        accum_cck->sent_cts_cnt,
-                        delta_cck->sent_cts_cnt,
-                        max_cck->sent_cts_cnt);
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
-                        "sent_ba_rsp_cnt:",
-                        le32_to_cpu(cck->sent_ba_rsp_cnt),
-                        accum_cck->sent_ba_rsp_cnt,
-                        delta_cck->sent_ba_rsp_cnt,
-                        max_cck->sent_ba_rsp_cnt);
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
-                        "dsp_self_kill:",
-                        le32_to_cpu(cck->dsp_self_kill),
-                        accum_cck->dsp_self_kill,
-                        delta_cck->dsp_self_kill,
-                        max_cck->dsp_self_kill);
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
-                        "mh_format_err:",
-                        le32_to_cpu(cck->mh_format_err),
-                        accum_cck->mh_format_err,
-                        delta_cck->mh_format_err, max_cck->mh_format_err);
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
-                        "re_acq_main_rssi_sum:",
-                        le32_to_cpu(cck->re_acq_main_rssi_sum),
-                        accum_cck->re_acq_main_rssi_sum,
-                        delta_cck->re_acq_main_rssi_sum,
-                        max_cck->re_acq_main_rssi_sum);
-
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_header,
-                       "Statistics_Rx - GENERAL:");
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
-                        "bogus_cts:",
-                        le32_to_cpu(general->bogus_cts),
-                        accum_general->bogus_cts,
-                        delta_general->bogus_cts, max_general->bogus_cts);
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
-                        "bogus_ack:",
-                        le32_to_cpu(general->bogus_ack),
-                        accum_general->bogus_ack,
-                        delta_general->bogus_ack, max_general->bogus_ack);
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
-                        "non_bssid_frames:",
-                        le32_to_cpu(general->non_bssid_frames),
-                        accum_general->non_bssid_frames,
-                        delta_general->non_bssid_frames,
-                        max_general->non_bssid_frames);
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
-                        "filtered_frames:",
-                        le32_to_cpu(general->filtered_frames),
-                        accum_general->filtered_frames,
-                        delta_general->filtered_frames,
-                        max_general->filtered_frames);
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
-                        "non_channel_beacons:",
-                        le32_to_cpu(general->non_channel_beacons),
-                        accum_general->non_channel_beacons,
-                        delta_general->non_channel_beacons,
-                        max_general->non_channel_beacons);
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
-                        "channel_beacons:",
-                        le32_to_cpu(general->channel_beacons),
-                        accum_general->channel_beacons,
-                        delta_general->channel_beacons,
-                        max_general->channel_beacons);
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
-                        "num_missed_bcon:",
-                        le32_to_cpu(general->num_missed_bcon),
-                        accum_general->num_missed_bcon,
-                        delta_general->num_missed_bcon,
-                        max_general->num_missed_bcon);
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
-                       "adc_rx_saturation_time:",
-                        le32_to_cpu(general->adc_rx_saturation_time),
-                        accum_general->adc_rx_saturation_time,
-                        delta_general->adc_rx_saturation_time,
-                        max_general->adc_rx_saturation_time);
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
-                       "ina_detect_search_tm:",
-                        le32_to_cpu(general->ina_detection_search_time),
-                        accum_general->ina_detection_search_time,
-                        delta_general->ina_detection_search_time,
-                        max_general->ina_detection_search_time);
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
-                        "beacon_silence_rssi_a:",
-                        le32_to_cpu(general->beacon_silence_rssi_a),
-                        accum_general->beacon_silence_rssi_a,
-                        delta_general->beacon_silence_rssi_a,
-                        max_general->beacon_silence_rssi_a);
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
-                        "beacon_silence_rssi_b:",
-                        le32_to_cpu(general->beacon_silence_rssi_b),
-                        accum_general->beacon_silence_rssi_b,
-                        delta_general->beacon_silence_rssi_b,
-                        max_general->beacon_silence_rssi_b);
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
-                        "beacon_silence_rssi_c:",
-                        le32_to_cpu(general->beacon_silence_rssi_c),
-                        accum_general->beacon_silence_rssi_c,
-                        delta_general->beacon_silence_rssi_c,
-                        max_general->beacon_silence_rssi_c);
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
-                       "interference_data_flag:",
-                        le32_to_cpu(general->interference_data_flag),
-                        accum_general->interference_data_flag,
-                        delta_general->interference_data_flag,
-                        max_general->interference_data_flag);
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
-                        "channel_load:",
-                        le32_to_cpu(general->channel_load),
-                        accum_general->channel_load,
-                        delta_general->channel_load,
-                        max_general->channel_load);
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
-                        "dsp_false_alarms:",
-                        le32_to_cpu(general->dsp_false_alarms),
-                        accum_general->dsp_false_alarms,
-                        delta_general->dsp_false_alarms,
-                        max_general->dsp_false_alarms);
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
-                        "beacon_rssi_a:",
-                        le32_to_cpu(general->beacon_rssi_a),
-                        accum_general->beacon_rssi_a,
-                        delta_general->beacon_rssi_a,
-                        max_general->beacon_rssi_a);
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
-                        "beacon_rssi_b:",
-                        le32_to_cpu(general->beacon_rssi_b),
-                        accum_general->beacon_rssi_b,
-                        delta_general->beacon_rssi_b,
-                        max_general->beacon_rssi_b);
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
-                        "beacon_rssi_c:",
-                        le32_to_cpu(general->beacon_rssi_c),
-                        accum_general->beacon_rssi_c,
-                        delta_general->beacon_rssi_c,
-                        max_general->beacon_rssi_c);
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
-                        "beacon_energy_a:",
-                        le32_to_cpu(general->beacon_energy_a),
-                        accum_general->beacon_energy_a,
-                        delta_general->beacon_energy_a,
-                        max_general->beacon_energy_a);
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
-                        "beacon_energy_b:",
-                        le32_to_cpu(general->beacon_energy_b),
-                        accum_general->beacon_energy_b,
-                        delta_general->beacon_energy_b,
-                        max_general->beacon_energy_b);
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
-                        "beacon_energy_c:",
-                        le32_to_cpu(general->beacon_energy_c),
-                        accum_general->beacon_energy_c,
-                        delta_general->beacon_energy_c,
-                        max_general->beacon_energy_c);
-
-       pos += scnprintf(buf + pos, bufsz - pos, "Statistics_Rx - OFDM_HT:\n");
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_header,
-                       "Statistics_Rx - OFDM_HT:");
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
-                        "plcp_err:",
-                        le32_to_cpu(ht->plcp_err), accum_ht->plcp_err,
-                        delta_ht->plcp_err, max_ht->plcp_err);
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
-                        "overrun_err:",
-                        le32_to_cpu(ht->overrun_err), accum_ht->overrun_err,
-                        delta_ht->overrun_err, max_ht->overrun_err);
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
-                        "early_overrun_err:",
-                        le32_to_cpu(ht->early_overrun_err),
-                        accum_ht->early_overrun_err,
-                        delta_ht->early_overrun_err,
-                        max_ht->early_overrun_err);
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
-                        "crc32_good:",
-                        le32_to_cpu(ht->crc32_good), accum_ht->crc32_good,
-                        delta_ht->crc32_good, max_ht->crc32_good);
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
-                        "crc32_err:",
-                        le32_to_cpu(ht->crc32_err), accum_ht->crc32_err,
-                        delta_ht->crc32_err, max_ht->crc32_err);
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
-                        "mh_format_err:",
-                        le32_to_cpu(ht->mh_format_err),
-                        accum_ht->mh_format_err,
-                        delta_ht->mh_format_err, max_ht->mh_format_err);
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
-                        "agg_crc32_good:",
-                        le32_to_cpu(ht->agg_crc32_good),
-                        accum_ht->agg_crc32_good,
-                        delta_ht->agg_crc32_good, max_ht->agg_crc32_good);
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
-                        "agg_mpdu_cnt:",
-                        le32_to_cpu(ht->agg_mpdu_cnt),
-                        accum_ht->agg_mpdu_cnt,
-                        delta_ht->agg_mpdu_cnt, max_ht->agg_mpdu_cnt);
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
-                        "agg_cnt:",
-                        le32_to_cpu(ht->agg_cnt), accum_ht->agg_cnt,
-                        delta_ht->agg_cnt, max_ht->agg_cnt);
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
-                        "unsupport_mcs:",
-                        le32_to_cpu(ht->unsupport_mcs),
-                        accum_ht->unsupport_mcs,
-                        delta_ht->unsupport_mcs, max_ht->unsupport_mcs);
-
-       ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
-       kfree(buf);
-       return ret;
+       if (priv->cfg->ops->lib->debugfs_ops.rx_stats_read)
+               return priv->cfg->ops->lib->debugfs_ops.rx_stats_read(file,
+                                               user_buf, count, ppos);
+       return 0;
 }
 
 static ssize_t iwl_dbgfs_ucode_tx_stats_read(struct file *file,
@@ -1509,173 +1070,10 @@ static ssize_t iwl_dbgfs_ucode_tx_stats_read(struct file *file,
                                        size_t count, loff_t *ppos)
 {
        struct iwl_priv *priv = file->private_data;
-       int pos = 0;
-       char *buf;
-       int bufsz = (sizeof(struct statistics_tx) * 48) + 250;
-       ssize_t ret;
-       struct statistics_tx *tx, *accum_tx, *delta_tx, *max_tx;
-
-       if (!iwl_is_alive(priv))
-               return -EAGAIN;
-
-       buf = kzalloc(bufsz, GFP_KERNEL);
-       if (!buf) {
-               IWL_ERR(priv, "Can not allocate Buffer\n");
-               return -ENOMEM;
-       }
-
-       /* the statistic information display here is based on
-        * the last statistics notification from uCode
-        * might not reflect the current uCode activity
-        */
-       tx = &priv->statistics.tx;
-       accum_tx = &priv->accum_statistics.tx;
-       delta_tx = &priv->delta_statistics.tx;
-       max_tx = &priv->max_delta.tx;
-       pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz);
-       pos += scnprintf(buf + pos, bufsz - pos,  ucode_stats_header,
-                       "Statistics_Tx:");
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
-                        "preamble:",
-                        le32_to_cpu(tx->preamble_cnt),
-                        accum_tx->preamble_cnt,
-                        delta_tx->preamble_cnt, max_tx->preamble_cnt);
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
-                        "rx_detected_cnt:",
-                        le32_to_cpu(tx->rx_detected_cnt),
-                        accum_tx->rx_detected_cnt,
-                        delta_tx->rx_detected_cnt, max_tx->rx_detected_cnt);
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
-                        "bt_prio_defer_cnt:",
-                        le32_to_cpu(tx->bt_prio_defer_cnt),
-                        accum_tx->bt_prio_defer_cnt,
-                        delta_tx->bt_prio_defer_cnt,
-                        max_tx->bt_prio_defer_cnt);
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
-                        "bt_prio_kill_cnt:",
-                        le32_to_cpu(tx->bt_prio_kill_cnt),
-                        accum_tx->bt_prio_kill_cnt,
-                        delta_tx->bt_prio_kill_cnt,
-                        max_tx->bt_prio_kill_cnt);
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
-                        "few_bytes_cnt:",
-                        le32_to_cpu(tx->few_bytes_cnt),
-                        accum_tx->few_bytes_cnt,
-                        delta_tx->few_bytes_cnt, max_tx->few_bytes_cnt);
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
-                        "cts_timeout:",
-                        le32_to_cpu(tx->cts_timeout), accum_tx->cts_timeout,
-                        delta_tx->cts_timeout, max_tx->cts_timeout);
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
-                        "ack_timeout:",
-                        le32_to_cpu(tx->ack_timeout),
-                        accum_tx->ack_timeout,
-                        delta_tx->ack_timeout, max_tx->ack_timeout);
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
-                        "expected_ack_cnt:",
-                        le32_to_cpu(tx->expected_ack_cnt),
-                        accum_tx->expected_ack_cnt,
-                        delta_tx->expected_ack_cnt,
-                        max_tx->expected_ack_cnt);
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
-                        "actual_ack_cnt:",
-                        le32_to_cpu(tx->actual_ack_cnt),
-                        accum_tx->actual_ack_cnt,
-                        delta_tx->actual_ack_cnt,
-                        max_tx->actual_ack_cnt);
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
-                        "dump_msdu_cnt:",
-                        le32_to_cpu(tx->dump_msdu_cnt),
-                        accum_tx->dump_msdu_cnt,
-                        delta_tx->dump_msdu_cnt,
-                        max_tx->dump_msdu_cnt);
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
-                        "abort_nxt_frame_mismatch:",
-                        le32_to_cpu(tx->burst_abort_next_frame_mismatch_cnt),
-                        accum_tx->burst_abort_next_frame_mismatch_cnt,
-                        delta_tx->burst_abort_next_frame_mismatch_cnt,
-                        max_tx->burst_abort_next_frame_mismatch_cnt);
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
-                        "abort_missing_nxt_frame:",
-                        le32_to_cpu(tx->burst_abort_missing_next_frame_cnt),
-                        accum_tx->burst_abort_missing_next_frame_cnt,
-                        delta_tx->burst_abort_missing_next_frame_cnt,
-                        max_tx->burst_abort_missing_next_frame_cnt);
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
-                        "cts_timeout_collision:",
-                        le32_to_cpu(tx->cts_timeout_collision),
-                        accum_tx->cts_timeout_collision,
-                        delta_tx->cts_timeout_collision,
-                        max_tx->cts_timeout_collision);
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
-                       "ack_ba_timeout_collision:",
-                        le32_to_cpu(tx->ack_or_ba_timeout_collision),
-                        accum_tx->ack_or_ba_timeout_collision,
-                        delta_tx->ack_or_ba_timeout_collision,
-                        max_tx->ack_or_ba_timeout_collision);
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
-                        "agg ba_timeout:",
-                        le32_to_cpu(tx->agg.ba_timeout),
-                        accum_tx->agg.ba_timeout,
-                        delta_tx->agg.ba_timeout,
-                        max_tx->agg.ba_timeout);
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
-                       "agg ba_resched_frames:",
-                        le32_to_cpu(tx->agg.ba_reschedule_frames),
-                        accum_tx->agg.ba_reschedule_frames,
-                        delta_tx->agg.ba_reschedule_frames,
-                        max_tx->agg.ba_reschedule_frames);
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
-                       "agg scd_query_agg_frame:",
-                        le32_to_cpu(tx->agg.scd_query_agg_frame_cnt),
-                        accum_tx->agg.scd_query_agg_frame_cnt,
-                        delta_tx->agg.scd_query_agg_frame_cnt,
-                        max_tx->agg.scd_query_agg_frame_cnt);
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
-                        "agg scd_query_no_agg:",
-                        le32_to_cpu(tx->agg.scd_query_no_agg),
-                        accum_tx->agg.scd_query_no_agg,
-                        delta_tx->agg.scd_query_no_agg,
-                        max_tx->agg.scd_query_no_agg);
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
-                        "agg scd_query_agg:",
-                        le32_to_cpu(tx->agg.scd_query_agg),
-                        accum_tx->agg.scd_query_agg,
-                        delta_tx->agg.scd_query_agg,
-                        max_tx->agg.scd_query_agg);
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
-                       "agg scd_query_mismatch:",
-                        le32_to_cpu(tx->agg.scd_query_mismatch),
-                        accum_tx->agg.scd_query_mismatch,
-                        delta_tx->agg.scd_query_mismatch,
-                        max_tx->agg.scd_query_mismatch);
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
-                        "agg frame_not_ready:",
-                        le32_to_cpu(tx->agg.frame_not_ready),
-                        accum_tx->agg.frame_not_ready,
-                        delta_tx->agg.frame_not_ready,
-                        max_tx->agg.frame_not_ready);
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
-                        "agg underrun:",
-                        le32_to_cpu(tx->agg.underrun),
-                        accum_tx->agg.underrun,
-                        delta_tx->agg.underrun, max_tx->agg.underrun);
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
-                        "agg bt_prio_kill:",
-                        le32_to_cpu(tx->agg.bt_prio_kill),
-                        accum_tx->agg.bt_prio_kill,
-                        delta_tx->agg.bt_prio_kill,
-                        max_tx->agg.bt_prio_kill);
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
-                        "agg rx_ba_rsp_cnt:",
-                        le32_to_cpu(tx->agg.rx_ba_rsp_cnt),
-                        accum_tx->agg.rx_ba_rsp_cnt,
-                        delta_tx->agg.rx_ba_rsp_cnt,
-                        max_tx->agg.rx_ba_rsp_cnt);
-
-       ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
-       kfree(buf);
-       return ret;
+       if (priv->cfg->ops->lib->debugfs_ops.tx_stats_read)
+               return priv->cfg->ops->lib->debugfs_ops.tx_stats_read(file,
+                                               user_buf, count, ppos);
+       return 0;
 }
 
 static ssize_t iwl_dbgfs_ucode_general_stats_read(struct file *file,
@@ -1683,107 +1081,10 @@ static ssize_t iwl_dbgfs_ucode_general_stats_read(struct file *file,
                                        size_t count, loff_t *ppos)
 {
        struct iwl_priv *priv = file->private_data;
-       int pos = 0;
-       char *buf;
-       int bufsz = sizeof(struct statistics_general) * 10 + 300;
-       ssize_t ret;
-       struct statistics_general *general, *accum_general;
-       struct statistics_general *delta_general, *max_general;
-       struct statistics_dbg *dbg, *accum_dbg, *delta_dbg, *max_dbg;
-       struct statistics_div *div, *accum_div, *delta_div, *max_div;
-
-       if (!iwl_is_alive(priv))
-               return -EAGAIN;
-
-       buf = kzalloc(bufsz, GFP_KERNEL);
-       if (!buf) {
-               IWL_ERR(priv, "Can not allocate Buffer\n");
-               return -ENOMEM;
-       }
-
-       /* the statistic information display here is based on
-        * the last statistics notification from uCode
-        * might not reflect the current uCode activity
-        */
-       general = &priv->statistics.general;
-       dbg = &priv->statistics.general.dbg;
-       div = &priv->statistics.general.div;
-       accum_general = &priv->accum_statistics.general;
-       delta_general = &priv->delta_statistics.general;
-       max_general = &priv->max_delta.general;
-       accum_dbg = &priv->accum_statistics.general.dbg;
-       delta_dbg = &priv->delta_statistics.general.dbg;
-       max_dbg = &priv->max_delta.general.dbg;
-       accum_div = &priv->accum_statistics.general.div;
-       delta_div = &priv->delta_statistics.general.div;
-       max_div = &priv->max_delta.general.div;
-       pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz);
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_header,
-                       "Statistics_General:");
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_short_format,
-                        "temperature:",
-                        le32_to_cpu(general->temperature));
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_short_format,
-                        "temperature_m:",
-                        le32_to_cpu(general->temperature_m));
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
-                        "burst_check:",
-                        le32_to_cpu(dbg->burst_check),
-                        accum_dbg->burst_check,
-                        delta_dbg->burst_check, max_dbg->burst_check);
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
-                        "burst_count:",
-                        le32_to_cpu(dbg->burst_count),
-                        accum_dbg->burst_count,
-                        delta_dbg->burst_count, max_dbg->burst_count);
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
-                        "sleep_time:",
-                        le32_to_cpu(general->sleep_time),
-                        accum_general->sleep_time,
-                        delta_general->sleep_time, max_general->sleep_time);
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
-                        "slots_out:",
-                        le32_to_cpu(general->slots_out),
-                        accum_general->slots_out,
-                        delta_general->slots_out, max_general->slots_out);
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
-                        "slots_idle:",
-                        le32_to_cpu(general->slots_idle),
-                        accum_general->slots_idle,
-                        delta_general->slots_idle, max_general->slots_idle);
-       pos += scnprintf(buf + pos, bufsz - pos, "ttl_timestamp:\t\t\t%u\n",
-                        le32_to_cpu(general->ttl_timestamp));
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
-                        "tx_on_a:",
-                        le32_to_cpu(div->tx_on_a), accum_div->tx_on_a,
-                        delta_div->tx_on_a, max_div->tx_on_a);
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
-                        "tx_on_b:",
-                        le32_to_cpu(div->tx_on_b), accum_div->tx_on_b,
-                        delta_div->tx_on_b, max_div->tx_on_b);
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
-                        "exec_time:",
-                        le32_to_cpu(div->exec_time), accum_div->exec_time,
-                        delta_div->exec_time, max_div->exec_time);
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
-                        "probe_time:",
-                        le32_to_cpu(div->probe_time), accum_div->probe_time,
-                        delta_div->probe_time, max_div->probe_time);
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
-                        "rx_enable_counter:",
-                        le32_to_cpu(general->rx_enable_counter),
-                        accum_general->rx_enable_counter,
-                        delta_general->rx_enable_counter,
-                        max_general->rx_enable_counter);
-       pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
-                        "num_of_sos_states:",
-                        le32_to_cpu(general->num_of_sos_states),
-                        accum_general->num_of_sos_states,
-                        delta_general->num_of_sos_states,
-                        max_general->num_of_sos_states);
-       ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
-       kfree(buf);
-       return ret;
+       if (priv->cfg->ops->lib->debugfs_ops.general_stats_read)
+               return priv->cfg->ops->lib->debugfs_ops.general_stats_read(file,
+                                               user_buf, count, ppos);
+       return 0;
 }
 
 static ssize_t iwl_dbgfs_sensitivity_read(struct file *file,
@@ -2341,10 +1642,11 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
        DEBUGFS_ADD_FILE(missed_beacon, dir_debug, S_IWUSR);
        DEBUGFS_ADD_FILE(plcp_delta, dir_debug, S_IWUSR | S_IRUSR);
        DEBUGFS_ADD_FILE(force_reset, dir_debug, S_IWUSR | S_IRUSR);
+       DEBUGFS_ADD_FILE(ucode_rx_stats, dir_debug, S_IRUSR);
+       DEBUGFS_ADD_FILE(ucode_tx_stats, dir_debug, S_IRUSR);
+       DEBUGFS_ADD_FILE(ucode_general_stats, dir_debug, S_IRUSR);
+
        if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) != CSR_HW_REV_TYPE_3945) {
-               DEBUGFS_ADD_FILE(ucode_rx_stats, dir_debug, S_IRUSR);
-               DEBUGFS_ADD_FILE(ucode_tx_stats, dir_debug, S_IRUSR);
-               DEBUGFS_ADD_FILE(ucode_general_stats, dir_debug, S_IRUSR);
                DEBUGFS_ADD_FILE(sensitivity, dir_debug, S_IRUSR);
                DEBUGFS_ADD_FILE(chain_noise, dir_debug, S_IRUSR);
                DEBUGFS_ADD_FILE(ucode_tracing, dir_debug, S_IWUSR | S_IRUSR);
index b2d94c7c64570b632330fa6a0871faadd9831de2..bdc60aae75ec6862c9ec70471a563b001629fc93 100644 (file)
@@ -58,7 +58,7 @@ extern struct iwl_cfg iwl5100_abg_cfg;
 extern struct iwl_cfg iwl5150_agn_cfg;
 extern struct iwl_cfg iwl5150_abg_cfg;
 extern struct iwl_cfg iwl6000i_2agn_cfg;
-extern struct iwl_cfg iwl6000i_g2_2agn_cfg;
+extern struct iwl_cfg iwl6000g2_2agn_cfg;
 extern struct iwl_cfg iwl6000i_2abg_cfg;
 extern struct iwl_cfg iwl6000i_2bg_cfg;
 extern struct iwl_cfg iwl6000_3agn_cfg;
@@ -1049,12 +1049,10 @@ struct iwl_priv {
        struct iwl_calib_result calib_results[IWL_CALIB_MAX];
 
        /* Scan related variables */
-       unsigned long next_scan_jiffies;
        unsigned long scan_start;
-       unsigned long scan_pass_start;
        unsigned long scan_start_tsf;
-       void *scan;
-       int scan_bands;
+       void *scan_cmd;
+       enum ieee80211_band scan_band;
        struct cfg80211_scan_request *scan_request;
        bool is_internal_short_scan;
        u8 scan_tx_ant[IEEE80211_NUM_BANDS];
@@ -1259,7 +1257,6 @@ struct iwl_priv {
        struct work_struct scan_completed;
        struct work_struct rx_replenish;
        struct work_struct abort_scan;
-       struct work_struct request_scan;
        struct work_struct beacon_update;
        struct work_struct tt_work;
        struct work_struct ct_enter;
index ef0e3256eec2da85163f6d1f28dd921c88758775..95aa202c85e315a1737301863ebb880c40150c88 100644 (file)
@@ -172,22 +172,22 @@ struct iwl_eeprom_enhanced_txpwr {
 #define EEPROM_5000_TX_POWER_VERSION    (4)
 #define EEPROM_5000_EEPROM_VERSION     (0x11A)
 
-/*5000 calibrations */
-#define EEPROM_5000_CALIB_ALL  (INDIRECT_ADDRESS | INDIRECT_CALIBRATION)
-#define EEPROM_5000_XTAL       ((2*0x128) | EEPROM_5000_CALIB_ALL)
-#define EEPROM_5000_TEMPERATURE ((2*0x12A) | EEPROM_5000_CALIB_ALL)
-
-/* 5000 links */
-#define EEPROM_5000_LINK_HOST             (2*0x64)
-#define EEPROM_5000_LINK_GENERAL          (2*0x65)
-#define EEPROM_5000_LINK_REGULATORY       (2*0x66)
-#define EEPROM_5000_LINK_CALIBRATION      (2*0x67)
-#define EEPROM_5000_LINK_PROCESS_ADJST    (2*0x68)
-#define EEPROM_5000_LINK_OTHERS           (2*0x69)
-
-/* 5000 regulatory - indirect access */
-#define EEPROM_5000_REG_SKU_ID ((0x02)\
-               | INDIRECT_ADDRESS | INDIRECT_REGULATORY)   /* 4  bytes */
+/* 5000 and up calibration */
+#define EEPROM_CALIB_ALL       (INDIRECT_ADDRESS | INDIRECT_CALIBRATION)
+#define EEPROM_XTAL            ((2*0x128) | EEPROM_CALIB_ALL)
+
+/* 5000 temperature */
+#define EEPROM_5000_TEMPERATURE ((2*0x12A) | EEPROM_CALIB_ALL)
+
+/* agn links */
+#define EEPROM_LINK_HOST             (2*0x64)
+#define EEPROM_LINK_GENERAL          (2*0x65)
+#define EEPROM_LINK_REGULATORY       (2*0x66)
+#define EEPROM_LINK_CALIBRATION      (2*0x67)
+#define EEPROM_LINK_PROCESS_ADJST    (2*0x68)
+#define EEPROM_LINK_OTHERS           (2*0x69)
+
+/* agn regulatory - indirect access */
 #define EEPROM_REG_BAND_1_CHANNELS       ((0x08)\
                | INDIRECT_ADDRESS | INDIRECT_REGULATORY)   /* 28 bytes */
 #define EEPROM_REG_BAND_2_CHANNELS       ((0x26)\
@@ -276,6 +276,10 @@ struct iwl_eeprom_enhanced_txpwr {
 #define EEPROM_6050_TX_POWER_VERSION    (4)
 #define EEPROM_6050_EEPROM_VERSION     (0x532)
 
+/* 6x00g2 Specific */
+#define EEPROM_6000G2_TX_POWER_VERSION    (6)
+#define EEPROM_6000G2_EEPROM_VERSION   (0x709)
+
 /* OTP */
 /* lower blocks contain EEPROM image and calibration data */
 #define OTP_LOW_IMAGE_SIZE             (2 * 512 * sizeof(u16)) /* 2 KB */
index 5944de7a98a222e4cd9e82d55ae340ce43419b09..b1f101caf19d2f063386453c7cd1f8e045e7b10d 100644 (file)
 #define IWL_SCD_TXFIFO_POS_RA                  (4)
 #define IWL_SCD_QUEUE_RA_TID_MAP_RATID_MSK     (0x01FF)
 
-/* 5000 SCD */
-#define IWL50_SCD_QUEUE_STTS_REG_POS_TXF       (0)
-#define IWL50_SCD_QUEUE_STTS_REG_POS_ACTIVE    (3)
-#define IWL50_SCD_QUEUE_STTS_REG_POS_WSL       (4)
-#define IWL50_SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN (19)
-#define IWL50_SCD_QUEUE_STTS_REG_MSK           (0x00FF0000)
-
-#define IWL50_SCD_QUEUE_CTX_REG1_CREDIT_POS            (8)
-#define IWL50_SCD_QUEUE_CTX_REG1_CREDIT_MSK            (0x00FFFF00)
-#define IWL50_SCD_QUEUE_CTX_REG1_SUPER_CREDIT_POS      (24)
-#define IWL50_SCD_QUEUE_CTX_REG1_SUPER_CREDIT_MSK      (0xFF000000)
-#define IWL50_SCD_QUEUE_CTX_REG2_WIN_SIZE_POS          (0)
-#define IWL50_SCD_QUEUE_CTX_REG2_WIN_SIZE_MSK          (0x0000007F)
-#define IWL50_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS       (16)
-#define IWL50_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK       (0x007F0000)
-
-#define IWL50_SCD_CONTEXT_DATA_OFFSET          (0x600)
-#define IWL50_SCD_TX_STTS_BITMAP_OFFSET                (0x7B1)
-#define IWL50_SCD_TRANSLATE_TBL_OFFSET         (0x7E0)
-
-#define IWL50_SCD_CONTEXT_QUEUE_OFFSET(x)\
-       (IWL50_SCD_CONTEXT_DATA_OFFSET + ((x) * 8))
-
-#define IWL50_SCD_TRANSLATE_TBL_OFFSET_QUEUE(x) \
-       ((IWL50_SCD_TRANSLATE_TBL_OFFSET + ((x) * 2)) & 0xfffc)
-
-#define IWL50_SCD_QUEUECHAIN_SEL_ALL(x)                (((1<<(x)) - 1) &\
+/* agn SCD */
+#define IWLAGN_SCD_QUEUE_STTS_REG_POS_TXF      (0)
+#define IWLAGN_SCD_QUEUE_STTS_REG_POS_ACTIVE   (3)
+#define IWLAGN_SCD_QUEUE_STTS_REG_POS_WSL      (4)
+#define IWLAGN_SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN (19)
+#define IWLAGN_SCD_QUEUE_STTS_REG_MSK          (0x00FF0000)
+
+#define IWLAGN_SCD_QUEUE_CTX_REG1_CREDIT_POS           (8)
+#define IWLAGN_SCD_QUEUE_CTX_REG1_CREDIT_MSK           (0x00FFFF00)
+#define IWLAGN_SCD_QUEUE_CTX_REG1_SUPER_CREDIT_POS     (24)
+#define IWLAGN_SCD_QUEUE_CTX_REG1_SUPER_CREDIT_MSK     (0xFF000000)
+#define IWLAGN_SCD_QUEUE_CTX_REG2_WIN_SIZE_POS         (0)
+#define IWLAGN_SCD_QUEUE_CTX_REG2_WIN_SIZE_MSK         (0x0000007F)
+#define IWLAGN_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS      (16)
+#define IWLAGN_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK      (0x007F0000)
+
+#define IWLAGN_SCD_CONTEXT_DATA_OFFSET         (0x600)
+#define IWLAGN_SCD_TX_STTS_BITMAP_OFFSET               (0x7B1)
+#define IWLAGN_SCD_TRANSLATE_TBL_OFFSET                (0x7E0)
+
+#define IWLAGN_SCD_CONTEXT_QUEUE_OFFSET(x)\
+       (IWLAGN_SCD_CONTEXT_DATA_OFFSET + ((x) * 8))
+
+#define IWLAGN_SCD_TRANSLATE_TBL_OFFSET_QUEUE(x) \
+       ((IWLAGN_SCD_TRANSLATE_TBL_OFFSET + ((x) * 2)) & 0xfffc)
+
+#define IWLAGN_SCD_QUEUECHAIN_SEL_ALL(x)               (((1<<(x)) - 1) &\
        (~(1<<IWL_CMD_QUEUE_NUM)))
 
-#define IWL50_SCD_BASE                 (PRPH_BASE + 0xa02c00)
-
-#define IWL50_SCD_SRAM_BASE_ADDR         (IWL50_SCD_BASE + 0x0)
-#define IWL50_SCD_DRAM_BASE_ADDR        (IWL50_SCD_BASE + 0x8)
-#define IWL50_SCD_AIT                    (IWL50_SCD_BASE + 0x0c)
-#define IWL50_SCD_TXFACT                 (IWL50_SCD_BASE + 0x10)
-#define IWL50_SCD_ACTIVE                (IWL50_SCD_BASE + 0x14)
-#define IWL50_SCD_QUEUE_WRPTR(x)         (IWL50_SCD_BASE + 0x18 + (x) * 4)
-#define IWL50_SCD_QUEUE_RDPTR(x)         (IWL50_SCD_BASE + 0x68 + (x) * 4)
-#define IWL50_SCD_QUEUECHAIN_SEL         (IWL50_SCD_BASE + 0xe8)
-#define IWL50_SCD_AGGR_SEL              (IWL50_SCD_BASE + 0x248)
-#define IWL50_SCD_INTERRUPT_MASK         (IWL50_SCD_BASE + 0x108)
-#define IWL50_SCD_QUEUE_STATUS_BITS(x)   (IWL50_SCD_BASE + 0x10c + (x) * 4)
+#define IWLAGN_SCD_BASE                        (PRPH_BASE + 0xa02c00)
+
+#define IWLAGN_SCD_SRAM_BASE_ADDR      (IWLAGN_SCD_BASE + 0x0)
+#define IWLAGN_SCD_DRAM_BASE_ADDR      (IWLAGN_SCD_BASE + 0x8)
+#define IWLAGN_SCD_AIT                 (IWLAGN_SCD_BASE + 0x0c)
+#define IWLAGN_SCD_TXFACT              (IWLAGN_SCD_BASE + 0x10)
+#define IWLAGN_SCD_ACTIVE              (IWLAGN_SCD_BASE + 0x14)
+#define IWLAGN_SCD_QUEUE_WRPTR(x)      (IWLAGN_SCD_BASE + 0x18 + (x) * 4)
+#define IWLAGN_SCD_QUEUE_RDPTR(x)      (IWLAGN_SCD_BASE + 0x68 + (x) * 4)
+#define IWLAGN_SCD_QUEUECHAIN_SEL      (IWLAGN_SCD_BASE + 0xe8)
+#define IWLAGN_SCD_AGGR_SEL            (IWLAGN_SCD_BASE + 0x248)
+#define IWLAGN_SCD_INTERRUPT_MASK      (IWLAGN_SCD_BASE + 0x108)
+#define IWLAGN_SCD_QUEUE_STATUS_BITS(x)        (IWLAGN_SCD_BASE + 0x10c + (x) * 4)
 
 /*********************** END TX SCHEDULER *************************************/
 
index de0446d4bfe985c1ff636d172ff8c23e770542aa..f4b897804a8072bc8b3b8e5e8e462b594a49c2d4 100644 (file)
@@ -69,9 +69,8 @@ int iwl_scan_cancel(struct iwl_priv *priv)
        }
 
        if (test_bit(STATUS_SCANNING, &priv->status)) {
-               if (!test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
+               if (!test_and_set_bit(STATUS_SCAN_ABORTING, &priv->status)) {
                        IWL_DEBUG_SCAN(priv, "Queuing scan abort.\n");
-                       set_bit(STATUS_SCAN_ABORTING, &priv->status);
                        queue_work(priv->workqueue, &priv->abort_scan);
 
                } else
@@ -201,9 +200,6 @@ static void iwl_rx_scan_results_notif(struct iwl_priv *priv,
                       le32_to_cpu(notif->statistics[0]),
                       le32_to_cpu(notif->tsf_low) - priv->scan_start_tsf);
 #endif
-
-       if (!priv->is_internal_short_scan)
-               priv->next_scan_jiffies = 0;
 }
 
 /* Service SCAN_COMPLETE_NOTIFICATION (0x84) */
@@ -223,49 +219,24 @@ static void iwl_rx_scan_complete_notif(struct iwl_priv *priv,
        /* The HW is no longer scanning */
        clear_bit(STATUS_SCAN_HW, &priv->status);
 
-       IWL_DEBUG_INFO(priv, "Scan pass on %sGHz took %dms\n",
-                      (priv->scan_bands & BIT(IEEE80211_BAND_2GHZ)) ?
-                                               "2.4" : "5.2",
+       IWL_DEBUG_INFO(priv, "Scan on %sGHz took %dms\n",
+                      (priv->scan_band == IEEE80211_BAND_2GHZ) ? "2.4" : "5.2",
                       jiffies_to_msecs(elapsed_jiffies
-                                       (priv->scan_pass_start, jiffies)));
-
-       /* Remove this scanned band from the list of pending
-        * bands to scan, band G precedes A in order of scanning
-        * as seen in iwl_bg_request_scan */
-       if (priv->scan_bands & BIT(IEEE80211_BAND_2GHZ))
-               priv->scan_bands &= ~BIT(IEEE80211_BAND_2GHZ);
-       else if (priv->scan_bands &  BIT(IEEE80211_BAND_5GHZ))
-               priv->scan_bands &= ~BIT(IEEE80211_BAND_5GHZ);
+                                       (priv->scan_start, jiffies)));
 
-       /* If a request to abort was given, or the scan did not succeed
+       /*
+        * If a request to abort was given, or the scan did not succeed
         * then we reset the scan state machine and terminate,
-        * re-queuing another scan if one has been requested */
-       if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
+        * re-queuing another scan if one has been requested
+        */
+       if (test_and_clear_bit(STATUS_SCAN_ABORTING, &priv->status))
                IWL_DEBUG_INFO(priv, "Aborted scan completed.\n");
-               clear_bit(STATUS_SCAN_ABORTING, &priv->status);
-       } else {
-               /* If there are more bands on this scan pass reschedule */
-               if (priv->scan_bands)
-                       goto reschedule;
-       }
-
-       if (!priv->is_internal_short_scan)
-               priv->next_scan_jiffies = 0;
 
        IWL_DEBUG_INFO(priv, "Setting scan to off\n");
 
        clear_bit(STATUS_SCANNING, &priv->status);
 
-       IWL_DEBUG_INFO(priv, "Scan took %dms\n",
-               jiffies_to_msecs(elapsed_jiffies(priv->scan_start, jiffies)));
-
        queue_work(priv->workqueue, &priv->scan_completed);
-
-       return;
-
-reschedule:
-       priv->scan_pass_start = jiffies;
-       queue_work(priv->workqueue, &priv->request_scan);
 }
 
 void iwl_setup_rx_scan_handlers(struct iwl_priv *priv)
@@ -314,150 +285,6 @@ u16 iwl_get_passive_dwell_time(struct iwl_priv *priv,
 }
 EXPORT_SYMBOL(iwl_get_passive_dwell_time);
 
-static int iwl_get_single_channel_for_scan(struct iwl_priv *priv,
-                                    enum ieee80211_band band,
-                                    struct iwl_scan_channel *scan_ch)
-{
-       const struct ieee80211_supported_band *sband;
-       const struct iwl_channel_info *ch_info;
-       u16 passive_dwell = 0;
-       u16 active_dwell = 0;
-       int i, added = 0;
-       u16 channel = 0;
-
-       sband = iwl_get_hw_mode(priv, band);
-       if (!sband) {
-               IWL_ERR(priv, "invalid band\n");
-               return added;
-       }
-
-       active_dwell = iwl_get_active_dwell_time(priv, band, 0);
-       passive_dwell = iwl_get_passive_dwell_time(priv, band);
-
-       if (passive_dwell <= active_dwell)
-               passive_dwell = active_dwell + 1;
-
-       /* only scan single channel, good enough to reset the RF */
-       /* pick the first valid not in-use channel */
-       if (band == IEEE80211_BAND_5GHZ) {
-               for (i = 14; i < priv->channel_count; i++) {
-                       if (priv->channel_info[i].channel !=
-                           le16_to_cpu(priv->staging_rxon.channel)) {
-                               channel = priv->channel_info[i].channel;
-                               ch_info = iwl_get_channel_info(priv,
-                                       band, channel);
-                               if (is_channel_valid(ch_info))
-                                       break;
-                       }
-               }
-       } else {
-               for (i = 0; i < 14; i++) {
-                       if (priv->channel_info[i].channel !=
-                           le16_to_cpu(priv->staging_rxon.channel)) {
-                                       channel =
-                                               priv->channel_info[i].channel;
-                                       ch_info = iwl_get_channel_info(priv,
-                                               band, channel);
-                                       if (is_channel_valid(ch_info))
-                                               break;
-                       }
-               }
-       }
-       if (channel) {
-               scan_ch->channel = cpu_to_le16(channel);
-               scan_ch->type = SCAN_CHANNEL_TYPE_PASSIVE;
-               scan_ch->active_dwell = cpu_to_le16(active_dwell);
-               scan_ch->passive_dwell = cpu_to_le16(passive_dwell);
-               /* Set txpower levels to defaults */
-               scan_ch->dsp_atten = 110;
-               if (band == IEEE80211_BAND_5GHZ)
-                       scan_ch->tx_gain = ((1 << 5) | (3 << 3)) | 3;
-               else
-                       scan_ch->tx_gain = ((1 << 5) | (5 << 3));
-               added++;
-       } else
-               IWL_ERR(priv, "no valid channel found\n");
-       return added;
-}
-
-static int iwl_get_channels_for_scan(struct iwl_priv *priv,
-                                    enum ieee80211_band band,
-                                    u8 is_active, u8 n_probes,
-                                    struct iwl_scan_channel *scan_ch)
-{
-       struct ieee80211_channel *chan;
-       const struct ieee80211_supported_band *sband;
-       const struct iwl_channel_info *ch_info;
-       u16 passive_dwell = 0;
-       u16 active_dwell = 0;
-       int added, i;
-       u16 channel;
-
-       sband = iwl_get_hw_mode(priv, band);
-       if (!sband)
-               return 0;
-
-       active_dwell = iwl_get_active_dwell_time(priv, band, n_probes);
-       passive_dwell = iwl_get_passive_dwell_time(priv, band);
-
-       if (passive_dwell <= active_dwell)
-               passive_dwell = active_dwell + 1;
-
-       for (i = 0, added = 0; i < priv->scan_request->n_channels; i++) {
-               chan = priv->scan_request->channels[i];
-
-               if (chan->band != band)
-                       continue;
-
-               channel = ieee80211_frequency_to_channel(chan->center_freq);
-               scan_ch->channel = cpu_to_le16(channel);
-
-               ch_info = iwl_get_channel_info(priv, band, channel);
-               if (!is_channel_valid(ch_info)) {
-                       IWL_DEBUG_SCAN(priv, "Channel %d is INVALID for this band.\n",
-                                       channel);
-                       continue;
-               }
-
-               if (!is_active || is_channel_passive(ch_info) ||
-                   (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN))
-                       scan_ch->type = SCAN_CHANNEL_TYPE_PASSIVE;
-               else
-                       scan_ch->type = SCAN_CHANNEL_TYPE_ACTIVE;
-
-               if (n_probes)
-                       scan_ch->type |= IWL_SCAN_PROBE_MASK(n_probes);
-
-               scan_ch->active_dwell = cpu_to_le16(active_dwell);
-               scan_ch->passive_dwell = cpu_to_le16(passive_dwell);
-
-               /* Set txpower levels to defaults */
-               scan_ch->dsp_atten = 110;
-
-               /* NOTE: if we were doing 6Mb OFDM for scans we'd use
-                * power level:
-                * scan_ch->tx_gain = ((1 << 5) | (2 << 3)) | 3;
-                */
-               if (band == IEEE80211_BAND_5GHZ)
-                       scan_ch->tx_gain = ((1 << 5) | (3 << 3)) | 3;
-               else
-                       scan_ch->tx_gain = ((1 << 5) | (5 << 3));
-
-               IWL_DEBUG_SCAN(priv, "Scanning ch=%d prob=0x%X [%s %d]\n",
-                              channel, le32_to_cpu(scan_ch->type),
-                              (scan_ch->type & SCAN_CHANNEL_TYPE_ACTIVE) ?
-                               "ACTIVE" : "PASSIVE",
-                              (scan_ch->type & SCAN_CHANNEL_TYPE_ACTIVE) ?
-                              active_dwell : passive_dwell);
-
-               scan_ch++;
-               added++;
-       }
-
-       IWL_DEBUG_SCAN(priv, "total channels to scan %d\n", added);
-       return added;
-}
-
 void iwl_init_scan_params(struct iwl_priv *priv)
 {
        u8 ant_idx = fls(priv->hw_params.valid_tx_ant) - 1;
@@ -476,26 +303,27 @@ static int iwl_scan_initiate(struct iwl_priv *priv)
        set_bit(STATUS_SCANNING, &priv->status);
        priv->is_internal_short_scan = false;
        priv->scan_start = jiffies;
-       priv->scan_pass_start = priv->scan_start;
 
-       queue_work(priv->workqueue, &priv->request_scan);
+       if (WARN_ON(!priv->cfg->ops->utils->request_scan))
+               return -EOPNOTSUPP;
+
+       priv->cfg->ops->utils->request_scan(priv);
 
        return 0;
 }
 
-#define IWL_DELAY_NEXT_SCAN (HZ*2)
-
 int iwl_mac_hw_scan(struct ieee80211_hw *hw,
                     struct cfg80211_scan_request *req)
 {
-       unsigned long flags;
        struct iwl_priv *priv = hw->priv;
-       int ret, i;
+       int ret;
 
        IWL_DEBUG_MAC80211(priv, "enter\n");
 
+       if (req->n_channels == 0)
+               return -EINVAL;
+
        mutex_lock(&priv->mutex);
-       spin_lock_irqsave(&priv->lock, flags);
 
        if (!iwl_is_ready_rf(priv)) {
                ret = -EIO;
@@ -515,22 +343,8 @@ int iwl_mac_hw_scan(struct ieee80211_hw *hw,
                goto out_unlock;
        }
 
-       /* We don't schedule scan within next_scan_jiffies period.
-        * Avoid scanning during possible EAPOL exchange, return
-        * success immediately.
-        */
-       if (priv->next_scan_jiffies &&
-           time_after(priv->next_scan_jiffies, jiffies)) {
-               IWL_DEBUG_SCAN(priv, "scan rejected: within next scan period\n");
-               queue_work(priv->workqueue, &priv->scan_completed);
-               ret = 0;
-               goto out_unlock;
-       }
-
-       priv->scan_bands = 0;
-       for (i = 0; i < req->n_channels; i++)
-               priv->scan_bands |= BIT(req->channels[i]->band);
-
+       /* mac80211 will only ask for one band at a time */
+       priv->scan_band = req->channels[0]->band;
        priv->scan_request = req;
 
        ret = iwl_scan_initiate(priv);
@@ -538,7 +352,6 @@ int iwl_mac_hw_scan(struct ieee80211_hw *hw,
        IWL_DEBUG_MAC80211(priv, "leave\n");
 
 out_unlock:
-       spin_unlock_irqrestore(&priv->lock, flags);
        mutex_unlock(&priv->mutex);
 
        return ret;
@@ -576,22 +389,20 @@ static void iwl_bg_start_internal_scan(struct work_struct *work)
                goto unlock;
        }
 
-       priv->scan_bands = 0;
-       if (priv->band == IEEE80211_BAND_5GHZ)
-               priv->scan_bands |= BIT(IEEE80211_BAND_5GHZ);
-       else
-               priv->scan_bands |= BIT(IEEE80211_BAND_2GHZ);
+       priv->scan_band = priv->band;
 
        IWL_DEBUG_SCAN(priv, "Start internal short scan...\n");
        set_bit(STATUS_SCANNING, &priv->status);
        priv->is_internal_short_scan = true;
-       queue_work(priv->workqueue, &priv->request_scan);
+
+       if (WARN_ON(!priv->cfg->ops->utils->request_scan))
+               goto unlock;
+
+       priv->cfg->ops->utils->request_scan(priv);
  unlock:
        mutex_unlock(&priv->mutex);
 }
 
-#define IWL_SCAN_CHECK_WATCHDOG (7 * HZ)
-
 void iwl_bg_scan_check(struct work_struct *data)
 {
        struct iwl_priv *priv =
@@ -653,275 +464,15 @@ u16 iwl_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame,
        if (WARN_ON(left < ie_len))
                return len;
 
-       if (ies)
+       if (ies && ie_len) {
                memcpy(pos, ies, ie_len);
-       len += ie_len;
-       left -= ie_len;
+               len += ie_len;
+       }
 
        return (u16)len;
 }
 EXPORT_SYMBOL(iwl_fill_probe_req);
 
-static void iwl_bg_request_scan(struct work_struct *data)
-{
-       struct iwl_priv *priv =
-           container_of(data, struct iwl_priv, request_scan);
-       struct iwl_host_cmd cmd = {
-               .id = REPLY_SCAN_CMD,
-               .len = sizeof(struct iwl_scan_cmd),
-               .flags = CMD_SIZE_HUGE,
-       };
-       struct iwl_scan_cmd *scan;
-       struct ieee80211_conf *conf = NULL;
-       u32 rate_flags = 0;
-       u16 cmd_len;
-       u16 rx_chain = 0;
-       enum ieee80211_band band;
-       u8 n_probes = 0;
-       u8 rx_ant = priv->hw_params.valid_rx_ant;
-       u8 rate;
-       bool is_active = false;
-       int  chan_mod;
-       u8 active_chains;
-
-       conf = ieee80211_get_hw_conf(priv->hw);
-
-       mutex_lock(&priv->mutex);
-
-       cancel_delayed_work(&priv->scan_check);
-
-       if (!iwl_is_ready(priv)) {
-               IWL_WARN(priv, "request scan called when driver not ready.\n");
-               goto done;
-       }
-
-       /* Make sure the scan wasn't canceled before this queued work
-        * was given the chance to run... */
-       if (!test_bit(STATUS_SCANNING, &priv->status))
-               goto done;
-
-       /* This should never be called or scheduled if there is currently
-        * a scan active in the hardware. */
-       if (test_bit(STATUS_SCAN_HW, &priv->status)) {
-               IWL_DEBUG_INFO(priv, "Multiple concurrent scan requests in parallel. "
-                              "Ignoring second request.\n");
-               goto done;
-       }
-
-       if (test_bit(STATUS_EXIT_PENDING, &priv->status)) {
-               IWL_DEBUG_SCAN(priv, "Aborting scan due to device shutdown\n");
-               goto done;
-       }
-
-       if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
-               IWL_DEBUG_HC(priv, "Scan request while abort pending.  Queuing.\n");
-               goto done;
-       }
-
-       if (iwl_is_rfkill(priv)) {
-               IWL_DEBUG_HC(priv, "Aborting scan due to RF Kill activation\n");
-               goto done;
-       }
-
-       if (!test_bit(STATUS_READY, &priv->status)) {
-               IWL_DEBUG_HC(priv, "Scan request while uninitialized.  Queuing.\n");
-               goto done;
-       }
-
-       if (!priv->scan_bands) {
-               IWL_DEBUG_HC(priv, "Aborting scan due to no requested bands\n");
-               goto done;
-       }
-
-       if (!priv->scan) {
-               priv->scan = kmalloc(sizeof(struct iwl_scan_cmd) +
-                                    IWL_MAX_SCAN_SIZE, GFP_KERNEL);
-               if (!priv->scan) {
-                       IWL_DEBUG_SCAN(priv,
-                                      "fail to allocate memory for scan\n");
-                       goto done;
-               }
-       }
-       scan = priv->scan;
-       memset(scan, 0, sizeof(struct iwl_scan_cmd) + IWL_MAX_SCAN_SIZE);
-
-       scan->quiet_plcp_th = IWL_PLCP_QUIET_THRESH;
-       scan->quiet_time = IWL_ACTIVE_QUIET_TIME;
-
-       if (iwl_is_associated(priv)) {
-               u16 interval = 0;
-               u32 extra;
-               u32 suspend_time = 100;
-               u32 scan_suspend_time = 100;
-               unsigned long flags;
-
-               IWL_DEBUG_INFO(priv, "Scanning while associated...\n");
-               spin_lock_irqsave(&priv->lock, flags);
-               interval = priv->beacon_int;
-               spin_unlock_irqrestore(&priv->lock, flags);
-
-               scan->suspend_time = 0;
-               scan->max_out_time = cpu_to_le32(200 * 1024);
-               if (!interval)
-                       interval = suspend_time;
-
-               extra = (suspend_time / interval) << 22;
-               scan_suspend_time = (extra |
-                   ((suspend_time % interval) * 1024));
-               scan->suspend_time = cpu_to_le32(scan_suspend_time);
-               IWL_DEBUG_SCAN(priv, "suspend_time 0x%X beacon interval %d\n",
-                              scan_suspend_time, interval);
-       }
-
-       if (priv->is_internal_short_scan) {
-               IWL_DEBUG_SCAN(priv, "Start internal passive scan.\n");
-       } else if (priv->scan_request->n_ssids) {
-               int i, p = 0;
-               IWL_DEBUG_SCAN(priv, "Kicking off active scan\n");
-               for (i = 0; i < priv->scan_request->n_ssids; i++) {
-                       /* always does wildcard anyway */
-                       if (!priv->scan_request->ssids[i].ssid_len)
-                               continue;
-                       scan->direct_scan[p].id = WLAN_EID_SSID;
-                       scan->direct_scan[p].len =
-                               priv->scan_request->ssids[i].ssid_len;
-                       memcpy(scan->direct_scan[p].ssid,
-                              priv->scan_request->ssids[i].ssid,
-                              priv->scan_request->ssids[i].ssid_len);
-                       n_probes++;
-                       p++;
-               }
-               is_active = true;
-       } else
-               IWL_DEBUG_SCAN(priv, "Start passive scan.\n");
-
-       scan->tx_cmd.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK;
-       scan->tx_cmd.sta_id = priv->hw_params.bcast_sta_id;
-       scan->tx_cmd.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
-
-
-       if (priv->scan_bands & BIT(IEEE80211_BAND_2GHZ)) {
-               band = IEEE80211_BAND_2GHZ;
-               scan->flags = RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK;
-               chan_mod = le32_to_cpu(priv->active_rxon.flags & RXON_FLG_CHANNEL_MODE_MSK)
-                                      >> RXON_FLG_CHANNEL_MODE_POS;
-               if (chan_mod == CHANNEL_MODE_PURE_40) {
-                       rate = IWL_RATE_6M_PLCP;
-               } else {
-                       rate = IWL_RATE_1M_PLCP;
-                       rate_flags = RATE_MCS_CCK_MSK;
-               }
-               scan->good_CRC_th = 0;
-       } else if (priv->scan_bands & BIT(IEEE80211_BAND_5GHZ)) {
-               band = IEEE80211_BAND_5GHZ;
-               rate = IWL_RATE_6M_PLCP;
-               /*
-                * If active scaning is requested but a certain channel
-                * is marked passive, we can do active scanning if we
-                * detect transmissions.
-                */
-               scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH : 0;
-
-               /* Force use of chains B and C (0x6) for scan Rx
-                * Avoid A (0x1) for the device has off-channel reception
-                * on A-band.
-                */
-               if (priv->cfg->off_channel_workaround)
-                       rx_ant = ANT_BC;
-       } else {
-               IWL_WARN(priv, "Invalid scan band count\n");
-               goto done;
-       }
-
-       priv->scan_tx_ant[band] =
-                        iwl_toggle_tx_ant(priv, priv->scan_tx_ant[band]);
-       rate_flags |= iwl_ant_idx_to_flags(priv->scan_tx_ant[band]);
-       scan->tx_cmd.rate_n_flags = iwl_hw_set_rate_n_flags(rate, rate_flags);
-
-       /* In power save mode use one chain, otherwise use all chains */
-       if (test_bit(STATUS_POWER_PMI, &priv->status)) {
-               /* rx_ant has been set to all valid chains previously */
-               active_chains = rx_ant &
-                               ((u8)(priv->chain_noise_data.active_chains));
-               if (!active_chains)
-                       active_chains = rx_ant;
-
-               IWL_DEBUG_SCAN(priv, "chain_noise_data.active_chains: %u\n",
-                               priv->chain_noise_data.active_chains);
-
-               rx_ant = first_antenna(active_chains);
-       }
-       /* MIMO is not used here, but value is required */
-       rx_chain |= priv->hw_params.valid_rx_ant << RXON_RX_CHAIN_VALID_POS;
-       rx_chain |= rx_ant << RXON_RX_CHAIN_FORCE_MIMO_SEL_POS;
-       rx_chain |= rx_ant << RXON_RX_CHAIN_FORCE_SEL_POS;
-       rx_chain |= 0x1 << RXON_RX_CHAIN_DRIVER_FORCE_POS;
-       scan->rx_chain = cpu_to_le16(rx_chain);
-       if (!priv->is_internal_short_scan) {
-               cmd_len = iwl_fill_probe_req(priv,
-                                       (struct ieee80211_mgmt *)scan->data,
-                                       priv->scan_request->ie,
-                                       priv->scan_request->ie_len,
-                                       IWL_MAX_SCAN_SIZE - sizeof(*scan));
-       } else {
-               cmd_len = iwl_fill_probe_req(priv,
-                                       (struct ieee80211_mgmt *)scan->data,
-                                       NULL, 0,
-                                       IWL_MAX_SCAN_SIZE - sizeof(*scan));
-
-       }
-       scan->tx_cmd.len = cpu_to_le16(cmd_len);
-       if (iwl_is_monitor_mode(priv))
-               scan->filter_flags = RXON_FILTER_PROMISC_MSK;
-
-       scan->filter_flags |= (RXON_FILTER_ACCEPT_GRP_MSK |
-                              RXON_FILTER_BCON_AWARE_MSK);
-
-       if (priv->is_internal_short_scan) {
-               scan->channel_count =
-                       iwl_get_single_channel_for_scan(priv, band,
-                               (void *)&scan->data[le16_to_cpu(
-                               scan->tx_cmd.len)]);
-       } else {
-               scan->channel_count =
-                       iwl_get_channels_for_scan(priv, band,
-                               is_active, n_probes,
-                               (void *)&scan->data[le16_to_cpu(
-                               scan->tx_cmd.len)]);
-       }
-       if (scan->channel_count == 0) {
-               IWL_DEBUG_SCAN(priv, "channel count %d\n", scan->channel_count);
-               goto done;
-       }
-
-       cmd.len += le16_to_cpu(scan->tx_cmd.len) +
-           scan->channel_count * sizeof(struct iwl_scan_channel);
-       cmd.data = scan;
-       scan->len = cpu_to_le16(cmd.len);
-
-       set_bit(STATUS_SCAN_HW, &priv->status);
-       if (iwl_send_cmd_sync(priv, &cmd))
-               goto done;
-
-       queue_delayed_work(priv->workqueue, &priv->scan_check,
-                          IWL_SCAN_CHECK_WATCHDOG);
-
-       mutex_unlock(&priv->mutex);
-       return;
-
- done:
-       /* Cannot perform scan. Make sure we clear scanning
-       * bits from status so next scan request can be performed.
-       * If we don't clear scanning status bit here all next scan
-       * will fail
-       */
-       clear_bit(STATUS_SCAN_HW, &priv->status);
-       clear_bit(STATUS_SCANNING, &priv->status);
-       /* inform mac80211 scan aborted */
-       queue_work(priv->workqueue, &priv->scan_completed);
-       mutex_unlock(&priv->mutex);
-}
-
 void iwl_bg_abort_scan(struct work_struct *work)
 {
        struct iwl_priv *priv = container_of(work, struct iwl_priv, abort_scan);
@@ -969,7 +520,6 @@ EXPORT_SYMBOL(iwl_bg_scan_completed);
 void iwl_setup_scan_deferred_work(struct iwl_priv *priv)
 {
        INIT_WORK(&priv->scan_completed, iwl_bg_scan_completed);
-       INIT_WORK(&priv->request_scan, iwl_bg_request_scan);
        INIT_WORK(&priv->abort_scan, iwl_bg_abort_scan);
        INIT_WORK(&priv->start_internal_scan, iwl_bg_start_internal_scan);
        INIT_DELAYED_WORK(&priv->scan_check, iwl_bg_scan_check);
index d86ecd2f9ec2ff96bbb3d2d1dd6a1983cd780642..db934476b5e9e81572ff9b58585acec653ff5176 100644 (file)
@@ -451,7 +451,17 @@ static void iwl_sta_init_lq(struct iwl_priv *priv, const u8 *addr, bool is_ap)
 
        link_cmd.general_params.single_stream_ant_msk =
                                first_antenna(priv->hw_params.valid_tx_ant);
-       link_cmd.general_params.dual_stream_ant_msk = 3;
+
+       link_cmd.general_params.dual_stream_ant_msk =
+               priv->hw_params.valid_tx_ant &
+               ~first_antenna(priv->hw_params.valid_tx_ant);
+       if (!link_cmd.general_params.dual_stream_ant_msk) {
+               link_cmd.general_params.dual_stream_ant_msk = ANT_AB;
+       } else if (num_of_ant(priv->hw_params.valid_tx_ant) == 2) {
+               link_cmd.general_params.dual_stream_ant_msk =
+                       priv->hw_params.valid_tx_ant;
+       }
+
        link_cmd.agg_params.agg_dis_start_th = LINK_QUAL_AGG_DISABLE_START_DEF;
        link_cmd.agg_params.agg_time_limit =
                cpu_to_le16(LINK_QUAL_AGG_TIME_LIMIT_DEF);
@@ -1196,7 +1206,6 @@ int iwl_send_lq_cmd(struct iwl_priv *priv,
        iwl_dump_lq_cmd(priv, lq);
        BUG_ON(init && (cmd.flags & CMD_ASYNC));
 
-       iwl_dump_lq_cmd(priv, lq);
        ret = iwl_send_cmd(priv, &cmd);
        if (ret || (cmd.flags & CMD_ASYNC))
                return ret;
index 9f362024a29c1e336b7064a638e0578422817223..a41ba72ceb007da8a283df9c60ed84425badc3a4 100644 (file)
@@ -2527,7 +2527,7 @@ static void iwl3945_alive_start(struct iwl_priv *priv)
        }
 
        /* Configure Bluetooth device coexistence support */
-       iwl_send_bt_config(priv);
+       priv->cfg->ops->hcmd->send_bt_config(priv);
 
        /* Configure the adapter for unassociated operation */
        iwlcore_commit_rxon(priv);
@@ -2791,11 +2791,8 @@ static void iwl3945_rfkill_poll(struct work_struct *data)
 
 }
 
-#define IWL_SCAN_CHECK_WATCHDOG (7 * HZ)
-static void iwl3945_bg_request_scan(struct work_struct *data)
+void iwl3945_request_scan(struct iwl_priv *priv)
 {
-       struct iwl_priv *priv =
-           container_of(data, struct iwl_priv, request_scan);
        struct iwl_host_cmd cmd = {
                .id = REPLY_SCAN_CMD,
                .len = sizeof(struct iwl3945_scan_cmd),
@@ -2809,8 +2806,6 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
 
        conf = ieee80211_get_hw_conf(priv->hw);
 
-       mutex_lock(&priv->mutex);
-
        cancel_delayed_work(&priv->scan_check);
 
        if (!iwl_is_ready(priv)) {
@@ -2853,20 +2848,15 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
                goto done;
        }
 
-       if (!priv->scan_bands) {
-               IWL_DEBUG_HC(priv, "Aborting scan due to no requested bands\n");
-               goto done;
-       }
-
-       if (!priv->scan) {
-               priv->scan = kmalloc(sizeof(struct iwl3945_scan_cmd) +
-                                    IWL_MAX_SCAN_SIZE, GFP_KERNEL);
-               if (!priv->scan) {
+       if (!priv->scan_cmd) {
+               priv->scan_cmd = kmalloc(sizeof(struct iwl3945_scan_cmd) +
+                                        IWL_MAX_SCAN_SIZE, GFP_KERNEL);
+               if (!priv->scan_cmd) {
                        IWL_DEBUG_SCAN(priv, "Fail to allocate scan memory\n");
                        goto done;
                }
        }
-       scan = priv->scan;
+       scan = priv->scan_cmd;
        memset(scan, 0, sizeof(struct iwl3945_scan_cmd) + IWL_MAX_SCAN_SIZE);
 
        scan->quiet_plcp_th = IWL_PLCP_QUIET_THRESH;
@@ -2935,12 +2925,14 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
 
        /* flags + rate selection */
 
-       if (priv->scan_bands & BIT(IEEE80211_BAND_2GHZ)) {
+       switch (priv->scan_band) {
+       case IEEE80211_BAND_2GHZ:
                scan->flags = RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK;
                scan->tx_cmd.rate = IWL_RATE_1M_PLCP;
                scan->good_CRC_th = 0;
                band = IEEE80211_BAND_2GHZ;
-       } else if (priv->scan_bands & BIT(IEEE80211_BAND_5GHZ)) {
+               break;
+       case IEEE80211_BAND_5GHZ:
                scan->tx_cmd.rate = IWL_RATE_6M_PLCP;
                /*
                 * If active scaning is requested but a certain channel
@@ -2949,8 +2941,9 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
                 */
                scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH : 0;
                band = IEEE80211_BAND_5GHZ;
-       } else {
-               IWL_WARN(priv, "Invalid scan band count\n");
+               break;
+       default:
+               IWL_WARN(priv, "Invalid scan band\n");
                goto done;
        }
 
@@ -2971,9 +2964,6 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
        /* select Rx antennas */
        scan->flags |= iwl3945_get_antenna_flags(priv);
 
-       if (iwl_is_monitor_mode(priv))
-               scan->filter_flags = RXON_FILTER_PROMISC_MSK;
-
        scan->channel_count =
                iwl3945_get_channels_for_scan(priv, band, is_active, n_probes,
                        (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]);
@@ -2995,7 +2985,6 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
        queue_delayed_work(priv->workqueue, &priv->scan_check,
                           IWL_SCAN_CHECK_WATCHDOG);
 
-       mutex_unlock(&priv->mutex);
        return;
 
  done:
@@ -3009,7 +2998,6 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
 
        /* inform mac80211 scan aborted */
        queue_work(priv->workqueue, &priv->scan_completed);
-       mutex_unlock(&priv->mutex);
 }
 
 static void iwl3945_bg_restart(struct work_struct *data)
@@ -3051,8 +3039,6 @@ static void iwl3945_bg_rx_replenish(struct work_struct *data)
        mutex_unlock(&priv->mutex);
 }
 
-#define IWL_DELAY_NEXT_SCAN (HZ*2)
-
 void iwl3945_post_associate(struct iwl_priv *priv)
 {
        int rc = 0;
@@ -3137,9 +3123,6 @@ void iwl3945_post_associate(struct iwl_priv *priv)
                           __func__, priv->iw_mode);
                break;
        }
-
-       /* we have just associated, don't start scan too early */
-       priv->next_scan_jiffies = jiffies + IWL_DELAY_NEXT_SCAN;
 }
 
 /*****************************************************************************
@@ -3672,44 +3655,6 @@ static ssize_t show_channels(struct device *d,
 
 static DEVICE_ATTR(channels, S_IRUSR, show_channels, NULL);
 
-static ssize_t show_statistics(struct device *d,
-                              struct device_attribute *attr, char *buf)
-{
-       struct iwl_priv *priv = dev_get_drvdata(d);
-       u32 size = sizeof(struct iwl3945_notif_statistics);
-       u32 len = 0, ofs = 0;
-       u8 *data = (u8 *)&priv->_3945.statistics;
-       int rc = 0;
-
-       if (!iwl_is_alive(priv))
-               return -EAGAIN;
-
-       mutex_lock(&priv->mutex);
-       rc = iwl_send_statistics_request(priv, CMD_SYNC, false);
-       mutex_unlock(&priv->mutex);
-
-       if (rc) {
-               len = sprintf(buf,
-                             "Error sending statistics request: 0x%08X\n", rc);
-               return len;
-       }
-
-       while (size && (PAGE_SIZE - len)) {
-               hex_dump_to_buffer(data + ofs, size, 16, 1, buf + len,
-                                  PAGE_SIZE - len, 1);
-               len = strlen(buf);
-               if (PAGE_SIZE - len)
-                       buf[len++] = '\n';
-
-               ofs += 16;
-               size -= min(size, 16U);
-       }
-
-       return len;
-}
-
-static DEVICE_ATTR(statistics, S_IRUGO, show_statistics, NULL);
-
 static ssize_t show_antenna(struct device *d,
                            struct device_attribute *attr, char *buf)
 {
@@ -3793,7 +3738,6 @@ static void iwl3945_setup_deferred_work(struct iwl_priv *priv)
        INIT_DELAYED_WORK(&priv->alive_start, iwl3945_bg_alive_start);
        INIT_DELAYED_WORK(&priv->_3945.rfkill_poll, iwl3945_rfkill_poll);
        INIT_WORK(&priv->scan_completed, iwl_bg_scan_completed);
-       INIT_WORK(&priv->request_scan, iwl3945_bg_request_scan);
        INIT_WORK(&priv->abort_scan, iwl_bg_abort_scan);
        INIT_DELAYED_WORK(&priv->scan_check, iwl_bg_scan_check);
 
@@ -3830,7 +3774,6 @@ static struct attribute *iwl3945_sysfs_entries[] = {
        &dev_attr_filter_flags.attr,
        &dev_attr_measurement.attr,
        &dev_attr_retry_rate.attr,
-       &dev_attr_statistics.attr,
        &dev_attr_status.attr,
        &dev_attr_temperature.attr,
        &dev_attr_tx_power.attr,
@@ -4253,7 +4196,7 @@ static void __devexit iwl3945_pci_remove(struct pci_dev *pdev)
 
        iwl_free_channel_map(priv);
        iwlcore_free_geos(priv);
-       kfree(priv->scan);
+       kfree(priv->scan_cmd);
        if (priv->ibss_beacon)
                dev_kfree_skb(priv->ibss_beacon);
 
index aeed5cd808195303acfd361fd84a730fe0051a21..cdc7e07ba113b02b60bb383fcd3bccecbfa9560d 100644 (file)
@@ -6,3 +6,5 @@ iwmc3200wifi-$(CONFIG_IWM_DEBUG) += debugfs.o
 iwmc3200wifi-$(CONFIG_IWM_TRACING) += trace.o
 
 CFLAGS_trace.o := -I$(src)
+
+ccflags-y += -D__CHECK_ENDIAN__
index ad53987792400eb59eb95ff6bcf369e1363b1128..e1184deca55900636257525f1b24e4bf0f20be1c 100644 (file)
@@ -431,7 +431,8 @@ static int iwm_ntf_rx_ticket(struct iwm_priv *iwm, u8 *buf,
                                return PTR_ERR(ticket_node);
 
                        IWM_DBG_RX(iwm, DBG, "TICKET %s(%d)\n",
-                                  ticket->action ==  IWM_RX_TICKET_RELEASE ?
+                                  __le16_to_cpu(ticket->action) ==
+                                                       IWM_RX_TICKET_RELEASE ?
                                   "RELEASE" : "DROP",
                                   ticket->id);
                        spin_lock(&iwm->ticket_lock);
index 320e54fbb38cbdc570d62c4b3b106677a53c061a..abb4805fa8dfe2b82d8aee77ece564524ca7f596 100644 (file)
@@ -76,7 +76,7 @@ TRACE_EVENT(iwm_tx_wifi_cmd,
                IWM_ASSIGN;
                __entry->opcode = hdr->sw_hdr.cmd.cmd;
                __entry->lmac = 0;
-               __entry->seq = hdr->sw_hdr.cmd.seq_num;
+               __entry->seq = __le16_to_cpu(hdr->sw_hdr.cmd.seq_num);
                __entry->resp = GET_VAL8(hdr->sw_hdr.cmd.flags, UMAC_DEV_CMD_FLAGS_RESP_REQ);
                __entry->color = GET_VAL32(hdr->sw_hdr.meta_data, UMAC_FW_CMD_TX_STA_COLOR);
                __entry->eot = GET_VAL32(hdr->hw_hdr.cmd, UMAC_HDI_OUT_CMD_EOT);
@@ -123,7 +123,7 @@ TRACE_EVENT(iwm_tx_packets,
                __entry->ra_tid = GET_VAL32(hdr->hw_hdr.meta_data, UMAC_HDI_OUT_RATID);
                __entry->credit_group = GET_VAL32(hdr->hw_hdr.meta_data, UMAC_HDI_OUT_CREDIT_GRP);
                __entry->color = GET_VAL32(hdr->sw_hdr.meta_data, UMAC_FW_CMD_TX_STA_COLOR);
-               __entry->seq = hdr->sw_hdr.cmd.seq_num;
+               __entry->seq = __le16_to_cpu(hdr->sw_hdr.cmd.seq_num);
                __entry->npkt = 1;
                __entry->bytes = len;
 
index 9537cdb13d3fe65d03c036d8ae37a213e9a50e4f..3216621fc55a020ecd081362d1633a30067a75bb 100644 (file)
@@ -302,8 +302,8 @@ void iwm_tx_credit_init_pools(struct iwm_priv *iwm,
 
 #define IWM_UDMA_HDR_LEN       sizeof(struct iwm_umac_wifi_out_hdr)
 
-static int iwm_tx_build_packet(struct iwm_priv *iwm, struct sk_buff *skb,
-                              int pool_id, u8 *buf)
+static __le16 iwm_tx_build_packet(struct iwm_priv *iwm, struct sk_buff *skb,
+                                 int pool_id, u8 *buf)
 {
        struct iwm_umac_wifi_out_hdr *hdr = (struct iwm_umac_wifi_out_hdr *)buf;
        struct iwm_udma_wifi_cmd udma_cmd;
index cd464a2589b9411bb9e07e8cbd153b8a6a2a2f7a..13dfeda742bcb4a3ffe45a3848d27cf35383530e 100644 (file)
@@ -315,12 +315,28 @@ out:
        return ret;
 }
 
+static int if_sdio_wait_status(struct if_sdio_card *card, const u8 condition)
+{
+       u8 status;
+       unsigned long timeout;
+       int ret = 0;
+
+       timeout = jiffies + HZ;
+       while (1) {
+               status = sdio_readb(card->func, IF_SDIO_STATUS, &ret);
+               if (ret || (status & condition))
+                       break;
+               if (time_after(jiffies, timeout))
+                       return -ETIMEDOUT;
+               mdelay(1);
+       }
+       return ret;
+}
+
 static int if_sdio_card_to_host(struct if_sdio_card *card)
 {
        int ret;
-       u8 status;
        u16 size, type, chunk;
-       unsigned long timeout;
 
        lbs_deb_enter(LBS_DEB_SDIO);
 
@@ -335,19 +351,9 @@ static int if_sdio_card_to_host(struct if_sdio_card *card)
                goto out;
        }
 
-       timeout = jiffies + HZ;
-       while (1) {
-               status = sdio_readb(card->func, IF_SDIO_STATUS, &ret);
-               if (ret)
-                       goto out;
-               if (status & IF_SDIO_IO_RDY)
-                       break;
-               if (time_after(jiffies, timeout)) {
-                       ret = -ETIMEDOUT;
-                       goto out;
-               }
-               mdelay(1);
-       }
+       ret = if_sdio_wait_status(card, IF_SDIO_IO_RDY);
+       if (ret)
+               goto out;
 
        /*
         * The transfer must be in one transaction or the firmware
@@ -414,8 +420,6 @@ static void if_sdio_host_to_card_worker(struct work_struct *work)
 {
        struct if_sdio_card *card;
        struct if_sdio_packet *packet;
-       unsigned long timeout;
-       u8 status;
        int ret;
        unsigned long flags;
 
@@ -435,25 +439,15 @@ static void if_sdio_host_to_card_worker(struct work_struct *work)
 
                sdio_claim_host(card->func);
 
-               timeout = jiffies + HZ;
-               while (1) {
-                       status = sdio_readb(card->func, IF_SDIO_STATUS, &ret);
-                       if (ret)
-                               goto release;
-                       if (status & IF_SDIO_IO_RDY)
-                               break;
-                       if (time_after(jiffies, timeout)) {
-                               ret = -ETIMEDOUT;
-                               goto release;
-                       }
-                       mdelay(1);
+               ret = if_sdio_wait_status(card, IF_SDIO_IO_RDY);
+               if (ret == 0) {
+                       ret = sdio_writesb(card->func, card->ioport,
+                                          packet->buffer, packet->nb);
                }
 
-               ret = sdio_writesb(card->func, card->ioport,
-                               packet->buffer, packet->nb);
                if (ret)
-                       goto release;
-release:
+                       lbs_pr_err("error %d sending packet to firmware\n", ret);
+
                sdio_release_host(card->func);
 
                kfree(packet);
@@ -466,10 +460,11 @@ release:
 /* Firmware                                                         */
 /********************************************************************/
 
+#define FW_DL_READY_STATUS (IF_SDIO_IO_RDY | IF_SDIO_DL_RDY)
+
 static int if_sdio_prog_helper(struct if_sdio_card *card)
 {
        int ret;
-       u8 status;
        const struct firmware *fw;
        unsigned long timeout;
        u8 *chunk_buffer;
@@ -501,20 +496,14 @@ static int if_sdio_prog_helper(struct if_sdio_card *card)
        size = fw->size;
 
        while (size) {
-               timeout = jiffies + HZ;
-               while (1) {
-                       status = sdio_readb(card->func, IF_SDIO_STATUS, &ret);
-                       if (ret)
-                               goto release;
-                       if ((status & IF_SDIO_IO_RDY) &&
-                                       (status & IF_SDIO_DL_RDY))
-                               break;
-                       if (time_after(jiffies, timeout)) {
-                               ret = -ETIMEDOUT;
-                               goto release;
-                       }
-                       mdelay(1);
-               }
+               ret = if_sdio_wait_status(card, FW_DL_READY_STATUS);
+               if (ret)
+                       goto release;
+
+               /* On some platforms (like Davinci) the chip needs more time
+                * between helper blocks.
+                */
+               mdelay(2);
 
                chunk_size = min(size, (size_t)60);
 
@@ -584,7 +573,6 @@ out:
 static int if_sdio_prog_real(struct if_sdio_card *card)
 {
        int ret;
-       u8 status;
        const struct firmware *fw;
        unsigned long timeout;
        u8 *chunk_buffer;
@@ -616,20 +604,9 @@ static int if_sdio_prog_real(struct if_sdio_card *card)
        size = fw->size;
 
        while (size) {
-               timeout = jiffies + HZ;
-               while (1) {
-                       status = sdio_readb(card->func, IF_SDIO_STATUS, &ret);
-                       if (ret)
-                               goto release;
-                       if ((status & IF_SDIO_IO_RDY) &&
-                                       (status & IF_SDIO_DL_RDY))
-                               break;
-                       if (time_after(jiffies, timeout)) {
-                               ret = -ETIMEDOUT;
-                               goto release;
-                       }
-                       mdelay(1);
-               }
+               ret = if_sdio_wait_status(card, FW_DL_READY_STATUS);
+               if (ret)
+                       goto release;
 
                req_size = sdio_readb(card->func, IF_SDIO_RD_BASE, &ret);
                if (ret)
index dfff02f5c86dd1985593add2f3bc202d7ab63c1a..6f0d8c9fa933d4f2e533ea9a08f940a6fd973bc0 100644 (file)
@@ -830,6 +830,33 @@ static int mac80211_hwsim_conf_tx(
        return 0;
 }
 
+static int mac80211_hwsim_get_survey(
+       struct ieee80211_hw *hw, int idx,
+       struct survey_info *survey)
+{
+       struct ieee80211_conf *conf = &hw->conf;
+
+       printk(KERN_DEBUG "%s:%s (idx=%d)\n",
+              wiphy_name(hw->wiphy), __func__, idx);
+
+       if (idx != 0)
+               return -ENOENT;
+
+       /* Current channel */
+       survey->channel = conf->channel;
+
+       /*
+        * Magically conjured noise level --- this is only ok for simulated hardware.
+        *
+        * A real driver which cannot determine the real channel noise MUST NOT
+        * report any noise, especially not a magically conjured one :-)
+        */
+       survey->filled = SURVEY_INFO_NOISE_DBM;
+       survey->noise = -92;
+
+       return 0;
+}
+
 #ifdef CONFIG_NL80211_TESTMODE
 /*
  * This section contains example code for using netlink
@@ -1013,6 +1040,7 @@ static struct ieee80211_ops mac80211_hwsim_ops =
        .sta_notify = mac80211_hwsim_sta_notify,
        .set_tim = mac80211_hwsim_set_tim,
        .conf_tx = mac80211_hwsim_conf_tx,
+       .get_survey = mac80211_hwsim_get_survey,
        CFG80211_TESTMODE_CMD(mac80211_hwsim_testmode_cmd)
        .ampdu_action = mac80211_hwsim_ampdu_action,
        .sw_scan_start = mac80211_hwsim_sw_scan,
index 9abd6329bcbd3548640e50c2653b3e79f2568d5b..e6452698eba9bc6bd150bedb19880e63ecf66176 100644 (file)
@@ -11,3 +11,6 @@ obj-$(CONFIG_PCI_HERMES)      += orinoco_pci.o
 obj-$(CONFIG_TMD_HERMES)       += orinoco_tmd.o
 obj-$(CONFIG_NORTEL_HERMES)    += orinoco_nortel.o
 obj-$(CONFIG_PCMCIA_SPECTRUM)  += spectrum_cs.o
+
+# Orinoco should be endian clean.
+ccflags-y += -D__CHECK_ENDIAN__
index 27f2d334264535944d518ce4cac961e987f23e97..90dd4d0595c33b544894beb0b8eef9f56ed6f574 100644 (file)
@@ -88,7 +88,9 @@ int orinoco_wiphy_register(struct wiphy *wiphy)
 
        wiphy->rts_threshold = priv->rts_thresh;
        if (!priv->has_mwo)
-               wiphy->frag_threshold = priv->frag_thresh;
+               wiphy->frag_threshold = priv->frag_thresh + 1;
+       wiphy->retry_short = priv->short_retry_limit;
+       wiphy->retry_long = priv->long_retry_limit;
 
        return wiphy_register(wiphy);
 }
@@ -196,8 +198,92 @@ static int orinoco_set_channel(struct wiphy *wiphy,
        return err;
 }
 
+static int orinoco_set_wiphy_params(struct wiphy *wiphy, u32 changed)
+{
+       struct orinoco_private *priv = wiphy_priv(wiphy);
+       int frag_value = -1;
+       int rts_value = -1;
+       int err = 0;
+
+       if (changed & WIPHY_PARAM_RETRY_SHORT) {
+               /* Setting short retry not supported */
+               err = -EINVAL;
+       }
+
+       if (changed & WIPHY_PARAM_RETRY_LONG) {
+               /* Setting long retry not supported */
+               err = -EINVAL;
+       }
+
+       if (changed & WIPHY_PARAM_FRAG_THRESHOLD) {
+               /* Set fragmentation */
+               if (priv->has_mwo) {
+                       if (wiphy->frag_threshold < 0)
+                               frag_value = 0;
+                       else {
+                               printk(KERN_WARNING "%s: Fixed fragmentation "
+                                      "is not supported on this firmware. "
+                                      "Using MWO robust instead.\n",
+                                      priv->ndev->name);
+                               frag_value = 1;
+                       }
+               } else {
+                       if (wiphy->frag_threshold < 0)
+                               frag_value = 2346;
+                       else if ((wiphy->frag_threshold < 257) ||
+                                (wiphy->frag_threshold > 2347))
+                               err = -EINVAL;
+                       else
+                               /* cfg80211 value is 257-2347 (odd only)
+                                * orinoco rid has range 256-2346 (even only) */
+                               frag_value = wiphy->frag_threshold & ~0x1;
+               }
+       }
+
+       if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
+               /* Set RTS.
+                *
+                * Prism documentation suggests default of 2432,
+                * and a range of 0-3000.
+                *
+                * Current implementation uses 2347 as the default and
+                * the upper limit.
+                */
+
+               if (wiphy->rts_threshold < 0)
+                       rts_value = 2347;
+               else if (wiphy->rts_threshold > 2347)
+                       err = -EINVAL;
+               else
+                       rts_value = wiphy->rts_threshold;
+       }
+
+       if (!err) {
+               unsigned long flags;
+
+               if (orinoco_lock(priv, &flags) != 0)
+                       return -EBUSY;
+
+               if (frag_value >= 0) {
+                       if (priv->has_mwo)
+                               priv->mwo_robust = frag_value;
+                       else
+                               priv->frag_thresh = frag_value;
+               }
+               if (rts_value >= 0)
+                       priv->rts_thresh = rts_value;
+
+               err = orinoco_commit(priv);
+
+               orinoco_unlock(priv, &flags);
+       }
+
+       return err;
+}
+
 const struct cfg80211_ops orinoco_cfg_ops = {
        .change_virtual_intf = orinoco_change_vif,
        .set_channel = orinoco_set_channel,
        .scan = orinoco_scan,
+       .set_wiphy_params = orinoco_set_wiphy_params,
 };
index 9f657afaa3e5aadbe7aacedbffdbba77eccf6456..741f8cea95b9230f4088167af7ed27822c989ca1 100644 (file)
@@ -374,6 +374,32 @@ int orinoco_hw_read_card_settings(struct orinoco_private *priv, u8 *dev_addr)
                err = hermes_read_wordrec(hw, USER_BAP,
                                          HERMES_RID_CNFPREAMBLE_SYMBOL,
                                          &priv->preamble);
+               if (err) {
+                       dev_err(dev, "Failed to read preamble setup\n");
+                       goto out;
+               }
+       }
+
+       /* Retry settings */
+       err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_SHORTRETRYLIMIT,
+                                 &priv->short_retry_limit);
+       if (err) {
+               dev_err(dev, "Failed to read short retry limit\n");
+               goto out;
+       }
+
+       err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_LONGRETRYLIMIT,
+                                 &priv->long_retry_limit);
+       if (err) {
+               dev_err(dev, "Failed to read long retry limit\n");
+               goto out;
+       }
+
+       err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_MAXTRANSMITLIFETIME,
+                                 &priv->retry_lifetime);
+       if (err) {
+               dev_err(dev, "Failed to read max retry lifetime\n");
+               goto out;
        }
 
 out:
index 21ab36cd76c795b74604df687a15e5a1f8658a86..4dadf9880a974c5820ab915700385b1e9b6d46ab 100644 (file)
@@ -33,18 +33,6 @@ int orinoco_commit(struct orinoco_private *priv);
 void orinoco_reset(struct work_struct *work);
 
 /* Information element helpers - find a home for these... */
-static inline u8 *orinoco_get_ie(u8 *data, size_t len,
-                                enum ieee80211_eid eid)
-{
-       u8 *p = data;
-       while ((p + 2) < (data + len)) {
-               if (p[0] == eid)
-                       return p;
-               p += p[1] + 2;
-       }
-       return NULL;
-}
-
 #define WPA_OUI_TYPE   "\x00\x50\xF2\x01"
 #define WPA_SELECTOR_LEN 4
 static inline u8 *orinoco_get_wpa_ie(u8 *data, size_t len)
index 665ef56f8382cba58ed3bbfcc2d20d230bce57db..ff6b7b1d421d10fe72c758a812e09d1e67ebbfbd 100644 (file)
@@ -131,6 +131,8 @@ struct orinoco_private {
        u16 ap_density, rts_thresh;
        u16 pm_on, pm_mcast, pm_period, pm_timeout;
        u16 preamble;
+       u16 short_retry_limit, long_retry_limit;
+       u16 retry_lifetime;
 #ifdef WIRELESS_SPY
        struct iw_spy_data spy_data; /* iwspy support */
        struct iw_public_data   wireless_data;
index 330d42d453330ddbe7209fe81cff1de7b1f2b608..4300d9db7d8caab2d70442b7cbd37a9da69adef9 100644 (file)
@@ -127,7 +127,7 @@ void orinoco_add_extscan_result(struct orinoco_private *priv,
 {
        struct wiphy *wiphy = priv_to_wiphy(priv);
        struct ieee80211_channel *channel;
-       u8 *ie;
+       const u8 *ie;
        u64 timestamp;
        s32 signal;
        u16 capability;
@@ -136,7 +136,7 @@ void orinoco_add_extscan_result(struct orinoco_private *priv,
        int chan, freq;
 
        ie_len = len - sizeof(*bss);
-       ie = orinoco_get_ie(bss->data, ie_len, WLAN_EID_DS_PARAMS);
+       ie = cfg80211_find_ie(WLAN_EID_DS_PARAMS, bss->data, ie_len);
        chan = ie ? ie[2] : 0;
        freq = ieee80211_dsss_chan_to_freq(chan);
        channel = ieee80211_get_channel(wiphy, freq);
index 57b850ebfeb22d84b817a3a18f1a3ddcdb81fa79..a1006bf430cc661240a710af9a466559e9acb51a 100644 (file)
@@ -538,125 +538,6 @@ static int orinoco_ioctl_setsens(struct net_device *dev,
        return -EINPROGRESS;            /* Call commit handler */
 }
 
-static int orinoco_ioctl_setrts(struct net_device *dev,
-                               struct iw_request_info *info,
-                               struct iw_param *rrq,
-                               char *extra)
-{
-       struct orinoco_private *priv = ndev_priv(dev);
-       int val = rrq->value;
-       unsigned long flags;
-
-       if (rrq->disabled)
-               val = 2347;
-
-       if ((val < 0) || (val > 2347))
-               return -EINVAL;
-
-       if (orinoco_lock(priv, &flags) != 0)
-               return -EBUSY;
-
-       priv->rts_thresh = val;
-       orinoco_unlock(priv, &flags);
-
-       return -EINPROGRESS;            /* Call commit handler */
-}
-
-static int orinoco_ioctl_getrts(struct net_device *dev,
-                               struct iw_request_info *info,
-                               struct iw_param *rrq,
-                               char *extra)
-{
-       struct orinoco_private *priv = ndev_priv(dev);
-
-       rrq->value = priv->rts_thresh;
-       rrq->disabled = (rrq->value == 2347);
-       rrq->fixed = 1;
-
-       return 0;
-}
-
-static int orinoco_ioctl_setfrag(struct net_device *dev,
-                                struct iw_request_info *info,
-                                struct iw_param *frq,
-                                char *extra)
-{
-       struct orinoco_private *priv = ndev_priv(dev);
-       int err = -EINPROGRESS;         /* Call commit handler */
-       unsigned long flags;
-
-       if (orinoco_lock(priv, &flags) != 0)
-               return -EBUSY;
-
-       if (priv->has_mwo) {
-               if (frq->disabled)
-                       priv->mwo_robust = 0;
-               else {
-                       if (frq->fixed)
-                               printk(KERN_WARNING "%s: Fixed fragmentation "
-                                      "is not supported on this firmware. "
-                                      "Using MWO robust instead.\n",
-                                      dev->name);
-                       priv->mwo_robust = 1;
-               }
-       } else {
-               if (frq->disabled)
-                       priv->frag_thresh = 2346;
-               else {
-                       if ((frq->value < 256) || (frq->value > 2346))
-                               err = -EINVAL;
-                       else
-                               /* must be even */
-                               priv->frag_thresh = frq->value & ~0x1;
-               }
-       }
-
-       orinoco_unlock(priv, &flags);
-
-       return err;
-}
-
-static int orinoco_ioctl_getfrag(struct net_device *dev,
-                                struct iw_request_info *info,
-                                struct iw_param *frq,
-                                char *extra)
-{
-       struct orinoco_private *priv = ndev_priv(dev);
-       hermes_t *hw = &priv->hw;
-       int err;
-       u16 val;
-       unsigned long flags;
-
-       if (orinoco_lock(priv, &flags) != 0)
-               return -EBUSY;
-
-       if (priv->has_mwo) {
-               err = hermes_read_wordrec(hw, USER_BAP,
-                                         HERMES_RID_CNFMWOROBUST_AGERE,
-                                         &val);
-               if (err)
-                       val = 0;
-
-               frq->value = val ? 2347 : 0;
-               frq->disabled = !val;
-               frq->fixed = 0;
-       } else {
-               err = hermes_read_wordrec(hw, USER_BAP,
-                                         HERMES_RID_CNFFRAGMENTATIONTHRESHOLD,
-                                         &val);
-               if (err)
-                       val = 0;
-
-               frq->value = val;
-               frq->disabled = (val >= 2346);
-               frq->fixed = 1;
-       }
-
-       orinoco_unlock(priv, &flags);
-
-       return err;
-}
-
 static int orinoco_ioctl_setrate(struct net_device *dev,
                                 struct iw_request_info *info,
                                 struct iw_param *rrq,
@@ -1201,60 +1082,6 @@ static int orinoco_ioctl_set_mlme(struct net_device *dev,
        return ret;
 }
 
-static int orinoco_ioctl_getretry(struct net_device *dev,
-                                 struct iw_request_info *info,
-                                 struct iw_param *rrq,
-                                 char *extra)
-{
-       struct orinoco_private *priv = ndev_priv(dev);
-       hermes_t *hw = &priv->hw;
-       int err = 0;
-       u16 short_limit, long_limit, lifetime;
-       unsigned long flags;
-
-       if (orinoco_lock(priv, &flags) != 0)
-               return -EBUSY;
-
-       err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_SHORTRETRYLIMIT,
-                                 &short_limit);
-       if (err)
-               goto out;
-
-       err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_LONGRETRYLIMIT,
-                                 &long_limit);
-       if (err)
-               goto out;
-
-       err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_MAXTRANSMITLIFETIME,
-                                 &lifetime);
-       if (err)
-               goto out;
-
-       rrq->disabled = 0;              /* Can't be disabled */
-
-       /* Note : by default, display the retry number */
-       if ((rrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) {
-               rrq->flags = IW_RETRY_LIFETIME;
-               rrq->value = lifetime * 1000;   /* ??? */
-       } else {
-               /* By default, display the min number */
-               if ((rrq->flags & IW_RETRY_LONG)) {
-                       rrq->flags = IW_RETRY_LIMIT | IW_RETRY_LONG;
-                       rrq->value = long_limit;
-               } else {
-                       rrq->flags = IW_RETRY_LIMIT;
-                       rrq->value = short_limit;
-                       if (short_limit != long_limit)
-                               rrq->flags |= IW_RETRY_SHORT;
-               }
-       }
-
- out:
-       orinoco_unlock(priv, &flags);
-
-       return err;
-}
-
 static int orinoco_ioctl_reset(struct net_device *dev,
                               struct iw_request_info *info,
                               void *wrqu,
@@ -1528,11 +1355,11 @@ static const iw_handler orinoco_handler[] = {
        IW_HANDLER(SIOCGIWESSID,        (iw_handler)orinoco_ioctl_getessid),
        IW_HANDLER(SIOCSIWRATE,         (iw_handler)orinoco_ioctl_setrate),
        IW_HANDLER(SIOCGIWRATE,         (iw_handler)orinoco_ioctl_getrate),
-       IW_HANDLER(SIOCSIWRTS,          (iw_handler)orinoco_ioctl_setrts),
-       IW_HANDLER(SIOCGIWRTS,          (iw_handler)orinoco_ioctl_getrts),
-       IW_HANDLER(SIOCSIWFRAG,         (iw_handler)orinoco_ioctl_setfrag),
-       IW_HANDLER(SIOCGIWFRAG,         (iw_handler)orinoco_ioctl_getfrag),
-       IW_HANDLER(SIOCGIWRETRY,        (iw_handler)orinoco_ioctl_getretry),
+       IW_HANDLER(SIOCSIWRTS,          (iw_handler)cfg80211_wext_siwrts),
+       IW_HANDLER(SIOCGIWRTS,          (iw_handler)cfg80211_wext_giwrts),
+       IW_HANDLER(SIOCSIWFRAG,         (iw_handler)cfg80211_wext_siwfrag),
+       IW_HANDLER(SIOCGIWFRAG,         (iw_handler)cfg80211_wext_giwfrag),
+       IW_HANDLER(SIOCGIWRETRY,        (iw_handler)cfg80211_wext_giwretry),
        IW_HANDLER(SIOCSIWENCODE,       (iw_handler)orinoco_ioctl_setiwencode),
        IW_HANDLER(SIOCGIWENCODE,       (iw_handler)orinoco_ioctl_getiwencode),
        IW_HANDLER(SIOCSIWPOWER,        (iw_handler)orinoco_ioctl_setpower),
index 86f3e9ac4c7ac2edf5643b4c19767732d5582326..679da7e7522ebe3383e8f014065c4714d9d3aaf7 100644 (file)
@@ -140,7 +140,7 @@ static void p54p_refill_rx_ring(struct ieee80211_hw *dev,
 
        idx = le32_to_cpu(ring_control->host_idx[ring_index]);
        limit = idx;
-       limit -= le32_to_cpu(index);
+       limit -= index;
        limit = ring_limit - limit;
 
        i = idx % ring_limit;
index 2131f8f0c50229aa99a9abdf30d020603b8ee038..0e52f174896c5cdf5805cbcace8f5186e08b7f47 100644 (file)
@@ -613,15 +613,23 @@ static int rt2800pci_set_device_state(struct rt2x00_dev *rt2x00dev,
 /*
  * TX descriptor initialization
  */
-static void rt2800pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
-                                   struct sk_buff *skb,
-                                   struct txentry_desc *txdesc)
+static int rt2800pci_write_tx_data(struct queue_entry* entry,
+                                  struct txentry_desc *txdesc)
 {
-       struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
-       __le32 *txd = skbdesc->desc;
-       __le32 *txwi = (__le32 *)(skb->data - rt2x00dev->ops->extra_tx_headroom);
+       struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
+       struct sk_buff *skb = entry->skb;
+       struct skb_frame_desc *skbdesc;
+       int ret;
+       __le32 *txwi;
        u32 word;
 
+       ret = rt2x00pci_write_tx_data(entry, txdesc);
+       if (ret)
+               return ret;
+
+       skbdesc = get_skb_frame_desc(skb);
+       txwi = (__le32 *)(skb->data - rt2x00dev->ops->extra_tx_headroom);
+
        /*
         * Initialize TX Info descriptor
         */
@@ -670,6 +678,18 @@ static void rt2800pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
        _rt2x00_desc_write(txwi, 2, 0 /* skbdesc->iv[0] */);
        _rt2x00_desc_write(txwi, 3, 0 /* skbdesc->iv[1] */);
 
+       return 0;
+}
+
+
+static void rt2800pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
+                                   struct sk_buff *skb,
+                                   struct txentry_desc *txdesc)
+{
+       struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
+       __le32 *txd = skbdesc->desc;
+       u32 word;
+
        /*
         * The buffers pointed by SD_PTR0/SD_LEN0 and SD_PTR1/SD_LEN1
         * must contains a TXWI structure + 802.11 header + padding + 802.11
@@ -1135,7 +1155,7 @@ static const struct rt2x00lib_ops rt2800pci_rt2x00_ops = {
        .reset_tuner            = rt2800_reset_tuner,
        .link_tuner             = rt2800_link_tuner,
        .write_tx_desc          = rt2800pci_write_tx_desc,
-       .write_tx_data          = rt2x00pci_write_tx_data,
+       .write_tx_data          = rt2800pci_write_tx_data,
        .write_beacon           = rt2800pci_write_beacon,
        .kick_tx_queue          = rt2800pci_kick_tx_queue,
        .kill_tx_queue          = rt2800pci_kill_tx_queue,
index 6b809ab42c618e253a1b12c5baa6471627c06dc8..95c8a6134ff8816911ea9f2cd018e5c955d754ce 100644 (file)
@@ -806,6 +806,10 @@ static struct usb_device_id rt2800usb_device_table[] = {
        { USB_DEVICE(0x07b8, 0x2870), USB_DEVICE_DATA(&rt2800usb_ops) },
        { USB_DEVICE(0x07b8, 0x2770), USB_DEVICE_DATA(&rt2800usb_ops) },
        { USB_DEVICE(0x1482, 0x3c09), USB_DEVICE_DATA(&rt2800usb_ops) },
+       /* Allwin */
+       { USB_DEVICE(0x8516, 0x2070), USB_DEVICE_DATA(&rt2800usb_ops) },
+       { USB_DEVICE(0x8516, 0x2770), USB_DEVICE_DATA(&rt2800usb_ops) },
+       { USB_DEVICE(0x8516, 0x2870), USB_DEVICE_DATA(&rt2800usb_ops) },
        /* Amit */
        { USB_DEVICE(0x15c5, 0x0008), USB_DEVICE_DATA(&rt2800usb_ops) },
        /* Askey */
@@ -848,6 +852,11 @@ static struct usb_device_id rt2800usb_device_table[] = {
        /* Hawking */
        { USB_DEVICE(0x0e66, 0x0001), USB_DEVICE_DATA(&rt2800usb_ops) },
        { USB_DEVICE(0x0e66, 0x0003), USB_DEVICE_DATA(&rt2800usb_ops) },
+       { USB_DEVICE(0x0e66, 0x0009), USB_DEVICE_DATA(&rt2800usb_ops) },
+       { USB_DEVICE(0x0e66, 0x000b), USB_DEVICE_DATA(&rt2800usb_ops) },
+       { USB_DEVICE(0x0e66, 0x0013), USB_DEVICE_DATA(&rt2800usb_ops) },
+       { USB_DEVICE(0x0e66, 0x0017), USB_DEVICE_DATA(&rt2800usb_ops) },
+       { USB_DEVICE(0x0e66, 0x0018), USB_DEVICE_DATA(&rt2800usb_ops) },
        /* Linksys */
        { USB_DEVICE(0x1737, 0x0070), USB_DEVICE_DATA(&rt2800usb_ops) },
        { USB_DEVICE(0x1737, 0x0071), USB_DEVICE_DATA(&rt2800usb_ops) },
@@ -907,6 +916,10 @@ static struct usb_device_id rt2800usb_device_table[] = {
        { USB_DEVICE(0x07b8, 0x3072), USB_DEVICE_DATA(&rt2800usb_ops) },
        /* AirTies */
        { USB_DEVICE(0x1eda, 0x2310), USB_DEVICE_DATA(&rt2800usb_ops) },
+       /* Allwin */
+       { USB_DEVICE(0x8516, 0x3070), USB_DEVICE_DATA(&rt2800usb_ops) },
+       { USB_DEVICE(0x8516, 0x3071), USB_DEVICE_DATA(&rt2800usb_ops) },
+       { USB_DEVICE(0x8516, 0x3072), USB_DEVICE_DATA(&rt2800usb_ops) },
        /* ASUS */
        { USB_DEVICE(0x0b05, 0x1784), USB_DEVICE_DATA(&rt2800usb_ops) },
        /* AzureWave */
@@ -991,6 +1004,8 @@ static struct usb_device_id rt2800usb_device_table[] = {
        { USB_DEVICE(0x5a57, 0x5257), USB_DEVICE_DATA(&rt2800usb_ops) },
 #endif
 #ifdef CONFIG_RT2800USB_RT35XX
+       /* Allwin */
+       { USB_DEVICE(0x8516, 0x3572), USB_DEVICE_DATA(&rt2800usb_ops) },
        /* Askey */
        { USB_DEVICE(0x1690, 0x0744), USB_DEVICE_DATA(&rt2800usb_ops) },
        /* Cisco */
@@ -1014,14 +1029,6 @@ static struct usb_device_id rt2800usb_device_table[] = {
         * Unclear what kind of devices these are (they aren't supported by the
         * vendor driver).
         */
-       /* Allwin */
-       { USB_DEVICE(0x8516, 0x2070), USB_DEVICE_DATA(&rt2800usb_ops) },
-       { USB_DEVICE(0x8516, 0x2770), USB_DEVICE_DATA(&rt2800usb_ops) },
-       { USB_DEVICE(0x8516, 0x2870), USB_DEVICE_DATA(&rt2800usb_ops) },
-       { USB_DEVICE(0x8516, 0x3070), USB_DEVICE_DATA(&rt2800usb_ops) },
-       { USB_DEVICE(0x8516, 0x3071), USB_DEVICE_DATA(&rt2800usb_ops) },
-       { USB_DEVICE(0x8516, 0x3072), USB_DEVICE_DATA(&rt2800usb_ops) },
-       { USB_DEVICE(0x8516, 0x3572), USB_DEVICE_DATA(&rt2800usb_ops) },
        /* Amigo */
        { USB_DEVICE(0x0e0b, 0x9031), USB_DEVICE_DATA(&rt2800usb_ops) },
        { USB_DEVICE(0x0e0b, 0x9041), USB_DEVICE_DATA(&rt2800usb_ops) },
@@ -1057,9 +1064,6 @@ static struct usb_device_id rt2800usb_device_table[] = {
        { USB_DEVICE(0x15a9, 0x0010), USB_DEVICE_DATA(&rt2800usb_ops) },
        /* Gigabyte */
        { USB_DEVICE(0x1044, 0x800c), USB_DEVICE_DATA(&rt2800usb_ops) },
-       /* Hawking */
-       { USB_DEVICE(0x0e66, 0x0009), USB_DEVICE_DATA(&rt2800usb_ops) },
-       { USB_DEVICE(0x0e66, 0x000b), USB_DEVICE_DATA(&rt2800usb_ops) },
        /* LevelOne */
        { USB_DEVICE(0x1740, 0x0605), USB_DEVICE_DATA(&rt2800usb_ops) },
        { USB_DEVICE(0x1740, 0x0615), USB_DEVICE_DATA(&rt2800usb_ops) },
index 4de505b98331fb203ac369c82e039e3f702e4f15..4f9b666f7a7f4e7195169f06062f1e577d5b951d 100644 (file)
@@ -549,7 +549,8 @@ struct rt2x00lib_ops {
        void (*write_tx_desc) (struct rt2x00_dev *rt2x00dev,
                               struct sk_buff *skb,
                               struct txentry_desc *txdesc);
-       int (*write_tx_data) (struct queue_entry *entry);
+       int (*write_tx_data) (struct queue_entry *entry,
+                             struct txentry_desc *txdesc);
        void (*write_beacon) (struct queue_entry *entry);
        int (*get_tx_data_len) (struct queue_entry *entry);
        void (*kick_tx_queue) (struct rt2x00_dev *rt2x00dev,
index cf3f1c0c43822fe70d0390bfd4ff060c306c07c3..4b941e9c794e5dd26b7495ec5ff21d778d295d30 100644 (file)
@@ -63,7 +63,8 @@ EXPORT_SYMBOL_GPL(rt2x00pci_regbusy_read);
 /*
  * TX data handlers.
  */
-int rt2x00pci_write_tx_data(struct queue_entry *entry)
+int rt2x00pci_write_tx_data(struct queue_entry *entry,
+                           struct txentry_desc *txdesc)
 {
        struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
        struct queue_entry_priv_pci *entry_priv = entry->priv_data;
index 8149ff68410a5f3a7bed11c6bf72e7b201bfed48..51bcef3839ce3ae52fe00974de87d0978f43ef4f 100644 (file)
@@ -92,7 +92,8 @@ int rt2x00pci_regbusy_read(struct rt2x00_dev *rt2x00dev,
  * This function will initialize the DMA and skb descriptor
  * to prepare the entry for the actual TX operation.
  */
-int rt2x00pci_write_tx_data(struct queue_entry *entry);
+int rt2x00pci_write_tx_data(struct queue_entry *entry,
+                           struct txentry_desc *txdesc);
 
 /**
  * struct queue_entry_priv_pci: Per entry PCI specific information
index a0bd36fc4d2e928227478f7b7f266978ccb4813b..91b7fb99ceb44067f621bc562c2539274e3981bc 100644 (file)
@@ -526,7 +526,8 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb,
         * call failed. Since we always return NETDEV_TX_OK to mac80211,
         * this frame will simply be dropped.
         */
-       if (unlikely(queue->rt2x00dev->ops->lib->write_tx_data(entry))) {
+       if (unlikely(queue->rt2x00dev->ops->lib->write_tx_data(entry,
+                                                              &txdesc))) {
                clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags);
                entry->skb = NULL;
                return -EIO;
index f9a7f8b1741134e57e840ea01baa0bb4ace149b8..da111c0c292843c2c9628d3cea4980b16ece82ae 100644 (file)
@@ -216,7 +216,8 @@ static void rt2x00usb_interrupt_txdone(struct urb *urb)
        rt2x00lib_txdone(entry, &txdesc);
 }
 
-int rt2x00usb_write_tx_data(struct queue_entry *entry)
+int rt2x00usb_write_tx_data(struct queue_entry *entry,
+                           struct txentry_desc *txdesc)
 {
        struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
        struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev);
index 3da6841b5d4251be61d30bf058c625fc2ede0715..621d0f8292514cf93079dbb6a553d9524bbc8d76 100644 (file)
@@ -376,7 +376,8 @@ void rt2x00usb_disable_radio(struct rt2x00_dev *rt2x00dev);
  * This function will initialize the URB and skb descriptor
  * to prepare the entry for the actual TX operation.
  */
-int rt2x00usb_write_tx_data(struct queue_entry *entry);
+int rt2x00usb_write_tx_data(struct queue_entry *entry,
+                           struct txentry_desc *txdesc);
 
 /**
  * struct queue_entry_priv_usb: Per entry USB specific information
diff --git a/drivers/net/wireless/rtl818x/Kconfig b/drivers/net/wireless/rtl818x/Kconfig
new file mode 100644 (file)
index 0000000..17d80fe
--- /dev/null
@@ -0,0 +1,88 @@
+#
+# RTL818X Wireless LAN device configuration
+#
+config RTL8180
+       tristate "Realtek 8180/8185 PCI support"
+       depends on MAC80211 && PCI && EXPERIMENTAL
+       select EEPROM_93CX6
+       ---help---
+         This is a driver for RTL8180 and RTL8185 based cards.
+         These are PCI based chips found in cards such as:
+
+         (RTL8185 802.11g)
+         A-Link WL54PC
+
+         (RTL8180 802.11b)
+         Belkin F5D6020 v3
+         Belkin F5D6020 v3
+         Dlink DWL-610
+         Dlink DWL-510
+         Netgear MA521
+         Level-One WPC-0101
+         Acer Aspire 1357 LMi
+         VCTnet PC-11B1
+         Ovislink AirLive WL-1120PCM
+         Mentor WL-PCI
+         Linksys WPC11 v4
+         TrendNET TEW-288PI
+         D-Link DWL-520 Rev D
+         Repotec RP-WP7126
+         TP-Link TL-WN250/251
+         Zonet ZEW1000
+         Longshine LCS-8031-R
+         HomeLine HLW-PCC200
+         GigaFast WF721-AEX
+         Planet WL-3553
+         Encore ENLWI-PCI1-NT
+         TrendNET TEW-266PC
+         Gigabyte GN-WLMR101
+         Siemens-fujitsu Amilo D1840W
+         Edimax EW-7126
+         PheeNet WL-11PCIR
+         Tonze PC-2100T
+         Planet WL-8303
+         Dlink DWL-650 v M1
+         Edimax EW-7106
+         Q-Tec 770WC
+         Topcom Skyr@cer 4011b
+         Roper FreeLan 802.11b (edition 2004)
+         Wistron Neweb Corp CB-200B
+         Pentagram HorNET
+         QTec 775WC
+         TwinMOS Booming B Series
+         Micronet SP906BB
+         Sweex LC700010
+         Surecom EP-9428
+         Safecom SWLCR-1100
+
+         Thanks to Realtek for their support!
+
+config RTL8187
+       tristate "Realtek 8187 and 8187B USB support"
+       depends on MAC80211 && USB
+       select EEPROM_93CX6
+       ---help---
+         This is a driver for RTL8187 and RTL8187B based cards.
+         These are USB based chips found in devices such as:
+
+         Netgear WG111v2
+         Level 1 WNC-0301USB
+         Micronet SP907GK V5
+         Encore ENUWI-G2
+         Trendnet TEW-424UB
+         ASUS P5B Deluxe/P5K Premium motherboards
+         Toshiba Satellite Pro series of laptops
+         Asus Wireless Link
+         Linksys WUSB54GC-EU v2
+           (v1 = rt73usb; v3 is rt2070-based,
+            use staging/rt3070 or try rt2800usb)
+
+         Thanks to Realtek for their support!
+
+# If possible, automatically enable LEDs for RTL8187.
+
+config RTL8187_LEDS
+       bool
+       depends on RTL8187 && MAC80211_LEDS && (LEDS_CLASS = y || LEDS_CLASS = RTL8187)
+       default y
+
index 4d479708158da2e43804029b644e9045123032da..51614d181ccb86c64951f7211ee2d6b7967664ed 100644 (file)
@@ -1196,6 +1196,66 @@ static const struct ieee80211_ops wl1251_ops = {
        .conf_tx = wl1251_op_conf_tx,
 };
 
+static int wl1251_read_eeprom_byte(struct wl1251 *wl, off_t offset, u8 *data)
+{
+       unsigned long timeout;
+
+       wl1251_reg_write32(wl, EE_ADDR, offset);
+       wl1251_reg_write32(wl, EE_CTL, EE_CTL_READ);
+
+       /* EE_CTL_READ clears when data is ready */
+       timeout = jiffies + msecs_to_jiffies(100);
+       while (1) {
+               if (!(wl1251_reg_read32(wl, EE_CTL) & EE_CTL_READ))
+                       break;
+
+               if (time_after(jiffies, timeout))
+                       return -ETIMEDOUT;
+
+               msleep(1);
+       }
+
+       *data = wl1251_reg_read32(wl, EE_DATA);
+       return 0;
+}
+
+static int wl1251_read_eeprom(struct wl1251 *wl, off_t offset,
+                             u8 *data, size_t len)
+{
+       size_t i;
+       int ret;
+
+       wl1251_reg_write32(wl, EE_START, 0);
+
+       for (i = 0; i < len; i++) {
+               ret = wl1251_read_eeprom_byte(wl, offset + i, &data[i]);
+               if (ret < 0)
+                       return ret;
+       }
+
+       return 0;
+}
+
+static int wl1251_read_eeprom_mac(struct wl1251 *wl)
+{
+       u8 mac[ETH_ALEN];
+       int i, ret;
+
+       wl1251_set_partition(wl, 0, 0, REGISTERS_BASE, REGISTERS_DOWN_SIZE);
+
+       ret = wl1251_read_eeprom(wl, 0x1c, mac, sizeof(mac));
+       if (ret < 0) {
+               wl1251_warning("failed to read MAC address from EEPROM");
+               return ret;
+       }
+
+       /* MAC is stored in reverse order */
+       for (i = 0; i < ETH_ALEN; i++)
+               wl->mac_addr[i] = mac[ETH_ALEN - i - 1];
+
+       return 0;
+}
+
 static int wl1251_register_hw(struct wl1251 *wl)
 {
        int ret;
@@ -1242,6 +1302,9 @@ int wl1251_init_ieee80211(struct wl1251 *wl)
 
        wl->hw->queues = 4;
 
+       if (wl->use_eeprom)
+               wl1251_read_eeprom_mac(wl);
+
        ret = wl1251_register_hw(wl);
        if (ret)
                goto out;
index 0ca3b4326056896f5c3e970df26afb44a4ffe58e..d16edd9bf06c1bf9e61cb397068ba381f1da22ca 100644 (file)
 #define SOR_CFG                        (REGISTERS_BASE + 0x0800)
 #define ECPU_CTRL                      (REGISTERS_BASE + 0x0804)
 #define HI_CFG                         (REGISTERS_BASE + 0x0808)
+
+/* EEPROM registers */
 #define EE_START                       (REGISTERS_BASE + 0x080C)
+#define EE_CTL                         (REGISTERS_BASE + 0x2000)
+#define EE_DATA                        (REGISTERS_BASE + 0x2004)
+#define EE_ADDR                        (REGISTERS_BASE + 0x2008)
+
+#define EE_CTL_READ                   2
 
 #define CHIP_ID_B                      (REGISTERS_BASE + 0x5674)
 
index 2051ef06e9ecbf3650051495acb4e68c12add062..d234285c2c81186fc096044dcfa309236e7e2d51 100644 (file)
@@ -23,6 +23,9 @@
 #include <linux/mod_devicetable.h>
 #include <linux/mmc/sdio_func.h>
 #include <linux/mmc/sdio_ids.h>
+#include <linux/platform_device.h>
+#include <linux/spi/wl12xx.h>
+#include <linux/irq.h>
 
 #include "wl1251.h"
 
@@ -34,6 +37,8 @@
 #define SDIO_DEVICE_ID_TI_WL1251       0x9066
 #endif
 
+static struct wl12xx_platform_data *wl12xx_board_data;
+
 static struct sdio_func *wl_to_func(struct wl1251 *wl)
 {
        return wl->if_priv;
@@ -130,18 +135,60 @@ static void wl1251_sdio_disable_irq(struct wl1251 *wl)
        sdio_release_host(func);
 }
 
+/* Interrupts when using dedicated WLAN_IRQ pin */
+static irqreturn_t wl1251_line_irq(int irq, void *cookie)
+{
+       struct wl1251 *wl = cookie;
+
+       ieee80211_queue_work(wl->hw, &wl->irq_work);
+
+       return IRQ_HANDLED;
+}
+
+static void wl1251_enable_line_irq(struct wl1251 *wl)
+{
+       return enable_irq(wl->irq);
+}
+
+static void wl1251_disable_line_irq(struct wl1251 *wl)
+{
+       return disable_irq(wl->irq);
+}
+
 static void wl1251_sdio_set_power(bool enable)
 {
 }
 
-static const struct wl1251_if_operations wl1251_sdio_ops = {
+static struct wl1251_if_operations wl1251_sdio_ops = {
        .read = wl1251_sdio_read,
        .write = wl1251_sdio_write,
        .write_elp = wl1251_sdio_write_elp,
        .read_elp = wl1251_sdio_read_elp,
        .reset = wl1251_sdio_reset,
-       .enable_irq = wl1251_sdio_enable_irq,
-       .disable_irq = wl1251_sdio_disable_irq,
+};
+
+static int wl1251_platform_probe(struct platform_device *pdev)
+{
+       if (pdev->id != -1) {
+               wl1251_error("can only handle single device");
+               return -ENODEV;
+       }
+
+       wl12xx_board_data = pdev->dev.platform_data;
+       return 0;
+}
+
+/*
+ * Dummy platform_driver for passing platform_data to this driver,
+ * until we have a way to pass this through SDIO subsystem or
+ * some other way.
+ */
+static struct platform_driver wl1251_platform_driver = {
+       .driver = {
+               .name   = "wl1251_data",
+               .owner  = THIS_MODULE,
+       },
+       .probe  = wl1251_platform_probe,
 };
 
 static int wl1251_sdio_probe(struct sdio_func *func,
@@ -163,20 +210,50 @@ static int wl1251_sdio_probe(struct sdio_func *func,
                goto release;
 
        sdio_set_block_size(func, 512);
+       sdio_release_host(func);
 
        SET_IEEE80211_DEV(hw, &func->dev);
        wl->if_priv = func;
        wl->if_ops = &wl1251_sdio_ops;
        wl->set_power = wl1251_sdio_set_power;
 
-       sdio_release_host(func);
+       if (wl12xx_board_data != NULL) {
+               wl->set_power = wl12xx_board_data->set_power;
+               wl->irq = wl12xx_board_data->irq;
+               wl->use_eeprom = wl12xx_board_data->use_eeprom;
+       }
+
+       if (wl->irq) {
+               ret = request_irq(wl->irq, wl1251_line_irq, 0, "wl1251", wl);
+               if (ret < 0) {
+                       wl1251_error("request_irq() failed: %d", ret);
+                       goto disable;
+               }
+
+               set_irq_type(wl->irq, IRQ_TYPE_EDGE_RISING);
+               disable_irq(wl->irq);
+
+               wl1251_sdio_ops.enable_irq = wl1251_enable_line_irq;
+               wl1251_sdio_ops.disable_irq = wl1251_disable_line_irq;
+
+               wl1251_info("using dedicated interrupt line");
+       } else {
+               wl1251_sdio_ops.enable_irq = wl1251_sdio_enable_irq;
+               wl1251_sdio_ops.disable_irq = wl1251_sdio_disable_irq;
+
+               wl1251_info("using SDIO interrupt");
+       }
+
        ret = wl1251_init_ieee80211(wl);
        if (ret)
-               goto disable;
+               goto out_free_irq;
 
        sdio_set_drvdata(func, wl);
        return ret;
 
+out_free_irq:
+       if (wl->irq)
+               free_irq(wl->irq, wl);
 disable:
        sdio_claim_host(func);
        sdio_disable_func(func);
@@ -189,6 +266,8 @@ static void __devexit wl1251_sdio_remove(struct sdio_func *func)
 {
        struct wl1251 *wl = sdio_get_drvdata(func);
 
+       if (wl->irq)
+               free_irq(wl->irq, wl);
        wl1251_free_hw(wl);
 
        sdio_claim_host(func);
@@ -208,6 +287,12 @@ static int __init wl1251_sdio_init(void)
 {
        int err;
 
+       err = platform_driver_register(&wl1251_platform_driver);
+       if (err) {
+               wl1251_error("failed to register platform driver: %d", err);
+               return err;
+       }
+
        err = sdio_register_driver(&wl1251_sdio_driver);
        if (err)
                wl1251_error("failed to register sdio driver: %d", err);
@@ -217,6 +302,7 @@ static int __init wl1251_sdio_init(void)
 static void __exit wl1251_sdio_exit(void)
 {
        sdio_unregister_driver(&wl1251_sdio_driver);
+       platform_driver_unregister(&wl1251_platform_driver);
        wl1251_notice("unloaded");
 }
 
index 1252ba1fbff535151aaf41aca7a07063264e8d64..97b2eae6a22cfe302d9a5956830a93c8cc37dab0 100644 (file)
@@ -876,6 +876,7 @@ struct ieee80211_ht_cap {
 #define IEEE80211_HT_CAP_SGI_40                        0x0040
 #define IEEE80211_HT_CAP_TX_STBC               0x0080
 #define IEEE80211_HT_CAP_RX_STBC               0x0300
+#define                IEEE80211_HT_CAP_RX_STBC_SHIFT  8
 #define IEEE80211_HT_CAP_DELAY_BA              0x0400
 #define IEEE80211_HT_CAP_MAX_AMSDU             0x0800
 #define IEEE80211_HT_CAP_DSSSCCK40             0x1000
index aed64ed3dc8a4f2d32839c34a442217dea4bc81b..a223ecbc71eff8160c0c0b96921cd4e81e0e9d4f 100644 (file)
@@ -26,6 +26,8 @@
 
 struct wl12xx_platform_data {
        void (*set_power)(bool enable);
+       /* SDIO only: IRQ number if WLAN_IRQ line is used, 0 for SDIO IRQs */
+       int irq;
        bool use_eeprom;
 };
 
index 37cebd3aa0f7d3f57d9a89b4f617e66a406676ee..5a4efe54cffdb0ff047a62f53bd2c5e5dfa9b5db 100644 (file)
@@ -1643,7 +1643,7 @@ struct ieee80211_radiotap_iterator {
        const struct ieee80211_radiotap_namespace *current_namespace;
 
        unsigned char *_arg, *_next_ns_data;
-       uint32_t *_next_bitmap;
+       __le32 *_next_bitmap;
 
        unsigned char *this_arg;
        int this_arg_index;
index 344e5bf72062b98651307e3ba92523a60cd22b90..78908b516f42f25e1aeacdebf9e0874b39fc6b3a 100644 (file)
@@ -274,6 +274,9 @@ struct ieee80211_bss_conf {
  * @IEEE80211_TX_INTFL_NL80211_FRAME_TX: Frame was requested through nl80211
  *     MLME command (internal to mac80211 to figure out whether to send TX
  *     status to user space)
+ * @IEEE80211_TX_CTL_LDPC: tells the driver to use LDPC for this frame
+ * @IEEE80211_TX_CTL_STBC: Enables Space-Time Block Coding (STBC) for this
+ *     frame and selects the maximum number of streams that it can use.
  */
 enum mac80211_tx_control_flags {
        IEEE80211_TX_CTL_REQ_TX_STATUS          = BIT(0),
@@ -297,6 +300,9 @@ enum mac80211_tx_control_flags {
        IEEE80211_TX_INTFL_RETRANSMISSION       = BIT(19),
        IEEE80211_TX_INTFL_HAS_RADIOTAP         = BIT(20),
        IEEE80211_TX_INTFL_NL80211_FRAME_TX     = BIT(21),
+       IEEE80211_TX_CTL_LDPC                   = BIT(22),
+       IEEE80211_TX_CTL_STBC                   = BIT(23) | BIT(24),
+#define IEEE80211_TX_CTL_STBC_SHIFT            23
 };
 
 /**
@@ -395,11 +401,11 @@ struct ieee80211_tx_rate {
  * @status: union for status data
  * @driver_data: array of driver_data pointers
  * @ampdu_ack_len: number of acked aggregated frames.
- *     relevant only if IEEE80211_TX_STATUS_AMPDU was set.
+ *     relevant only if IEEE80211_TX_STAT_AMPDU was set.
  * @ampdu_ack_map: block ack bit map for the aggregation.
- *     relevant only if IEEE80211_TX_STATUS_AMPDU was set.
+ *     relevant only if IEEE80211_TX_STAT_AMPDU was set.
  * @ampdu_len: number of aggregated frames.
- *     relevant only if IEEE80211_TX_STATUS_AMPDU was set.
+ *     relevant only if IEEE80211_TX_STAT_AMPDU was set.
  * @ack_signal: signal strength of the ACK frame
  */
 struct ieee80211_tx_info {
@@ -610,6 +616,7 @@ enum ieee80211_conf_flags {
  * @IEEE80211_CONF_CHANGE_RETRY_LIMITS: retry limits changed
  * @IEEE80211_CONF_CHANGE_IDLE: Idle flag changed
  * @IEEE80211_CONF_CHANGE_SMPS: Spatial multiplexing powersave mode changed
+ * @IEEE80211_CONF_CHANGE_QOS: Quality of service was enabled or disabled
  */
 enum ieee80211_conf_changed {
        IEEE80211_CONF_CHANGE_SMPS              = BIT(1),
@@ -791,6 +798,7 @@ struct ieee80211_key_conf {
        u8 iv_len;
        u8 hw_key_idx;
        u8 flags;
+       u8 *ap_addr;
        s8 keyidx;
        u8 keylen;
        u8 key[0];
@@ -1671,7 +1679,8 @@ struct ieee80211_ops {
                            struct ieee80211_vif *vif,
                            enum ieee80211_ampdu_mlme_action action,
                            struct ieee80211_sta *sta, u16 tid, u16 *ssn);
-
+       int (*get_survey)(struct ieee80211_hw *hw, int idx,
+               struct survey_info *survey);
        void (*rfkill_poll)(struct ieee80211_hw *hw);
        void (*set_coverage_class)(struct ieee80211_hw *hw, u8 coverage_class);
 #ifdef CONFIG_NL80211_TESTMODE
index 9598fdb4ad011c1fb06c6dd84acb3aa3f97efed6..6bb9a9a94960e9214e92f1debf023aa0ebb3b987 100644 (file)
@@ -19,8 +19,9 @@
 #include "ieee80211_i.h"
 #include "driver-ops.h"
 
-void __ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid,
-                                   u16 initiator, u16 reason)
+static void ___ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid,
+                                           u16 initiator, u16 reason,
+                                           bool from_timer)
 {
        struct ieee80211_local *local = sta->local;
        struct tid_ampdu_rx *tid_rx;
@@ -70,10 +71,17 @@ void __ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid,
 
        spin_unlock_bh(&sta->lock);
 
-       del_timer_sync(&tid_rx->session_timer);
+       if (!from_timer)
+               del_timer_sync(&tid_rx->session_timer);
        kfree(tid_rx);
 }
 
+void __ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid,
+                                   u16 initiator, u16 reason)
+{
+       ___ieee80211_stop_rx_ba_session(sta, tid, initiator, reason, false);
+}
+
 /*
  * After accepting the AddBA Request we activated a timer,
  * resetting it after each frame that arrives from the originator.
@@ -92,8 +100,8 @@ static void sta_rx_agg_session_timer_expired(unsigned long data)
 #ifdef CONFIG_MAC80211_HT_DEBUG
        printk(KERN_DEBUG "rx session timer expired on tid %d\n", (u16)*ptid);
 #endif
-       __ieee80211_stop_rx_ba_session(sta, *ptid, WLAN_BACK_RECIPIENT,
-                                      WLAN_REASON_QSTA_TIMEOUT);
+       ___ieee80211_stop_rx_ba_session(sta, *ptid, WLAN_BACK_RECIPIENT,
+                                       WLAN_REASON_QSTA_TIMEOUT, true);
 }
 
 static void ieee80211_send_addba_resp(struct ieee80211_sub_if_data *sdata, u8 *da, u16 tid,
index 555c6a14a6fad84ea783b89317871fed5b2db9d5..c163d0a149f49be05b07fa879562f2d821004beb 100644 (file)
@@ -186,7 +186,7 @@ static void sta_addba_resp_timer_expired(unsigned long data)
                spin_unlock_bh(&sta->lock);
 #ifdef CONFIG_MAC80211_HT_DEBUG
                printk(KERN_DEBUG "timer expired on tid %d but we are not "
-                               "(or no longer) expecting addBA response there",
+                               "(or no longer) expecting addBA response there\n",
                        tid);
 #endif
                return;
index 7dd7cda75cfa986cf7aa83b8d15719638f7d77bf..845a6e6b9d892b21be1d6ce0839b4908ffe10f58 100644 (file)
@@ -411,6 +411,17 @@ static int ieee80211_dump_station(struct wiphy *wiphy, struct net_device *dev,
        return ret;
 }
 
+static int ieee80211_dump_survey(struct wiphy *wiphy, struct net_device *dev,
+                                int idx, struct survey_info *survey)
+{
+       struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
+
+       if (!local->ops->get_survey)
+               return -EOPNOTSUPP;
+
+       return drv_get_survey(local, idx, survey);
+}
+
 static int ieee80211_get_station(struct wiphy *wiphy, struct net_device *dev,
                                 u8 *mac, struct station_info *sinfo)
 {
@@ -1508,6 +1519,7 @@ struct cfg80211_ops mac80211_config_ops = {
        .change_station = ieee80211_change_station,
        .get_station = ieee80211_get_station,
        .dump_station = ieee80211_dump_station,
+       .dump_survey = ieee80211_dump_survey,
 #ifdef CONFIG_MAC80211_MESH
        .add_mpath = ieee80211_add_mpath,
        .del_mpath = ieee80211_del_mpath,
index 9179196da264df16df969ea8c36b9d85187a0336..35e1e581e806cc4510547fd5cbec865ee1724d8a 100644 (file)
@@ -344,6 +344,15 @@ static inline int drv_ampdu_action(struct ieee80211_local *local,
        return ret;
 }
 
+static inline int drv_get_survey(struct ieee80211_local *local, int idx,
+                               struct survey_info *survey)
+{
+       int ret = -EOPNOTSUPP;
+       if (local->ops->conf_tx)
+               ret = local->ops->get_survey(&local->hw, idx, survey);
+       /* trace_drv_get_survey(local, idx, survey, ret); */
+       return ret;
+}
 
 static inline void drv_rfkill_poll(struct ieee80211_local *local)
 {
index e8f6e3b252d8b8ee3ef4210695dfc44283534bc4..8d4b41787dcf5146b94267a4aff7c8025b4a21c0 100644 (file)
@@ -140,6 +140,7 @@ static void ieee80211_key_enable_hw_accel(struct ieee80211_key *key)
                                     struct ieee80211_sub_if_data,
                                     u.ap);
 
+       key->conf.ap_addr = sdata->dev->dev_addr;
        ret = drv_set_key(key->local, SET_KEY, sdata, sta, &key->conf);
 
        if (!ret) {
index 3133681bdaa0b51c99aa62997c0170c3c700e9c5..425f66c7001346f7edae7933a53ace1e82c89076 100644 (file)
@@ -1333,12 +1333,17 @@ static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata,
                mutex_lock(&sdata->local->iflist_mtx);
                ieee80211_recalc_ps(sdata->local, -1);
                mutex_unlock(&sdata->local->iflist_mtx);
+
+               if (sdata->local->hw.flags & IEEE80211_HW_CONNECTION_MONITOR)
+                       return;
+
                /*
                 * We've received a probe response, but are not sure whether
                 * we have or will be receiving any beacons or data, so let's
                 * schedule the timers again, just in case.
                 */
                mod_beacon_timer(sdata);
+
                mod_timer(&ifmgd->conn_mon_timer,
                          round_jiffies_up(jiffies +
                                           IEEE80211_CONNECTION_IDLE_TIME));
index ff0eb948917bf78b3f25c97f4ae568c9b35088ca..3de7a2260d651b33cf28b1591ca864ac6b2e561a 100644 (file)
@@ -575,7 +575,7 @@ static int sta_info_buffer_expired(struct sta_info *sta,
 }
 
 
-static void sta_info_cleanup_expire_buffered(struct ieee80211_local *local,
+static bool sta_info_cleanup_expire_buffered(struct ieee80211_local *local,
                                             struct sta_info *sta)
 {
        unsigned long flags;
@@ -583,7 +583,7 @@ static void sta_info_cleanup_expire_buffered(struct ieee80211_local *local,
        struct ieee80211_sub_if_data *sdata;
 
        if (skb_queue_empty(&sta->ps_tx_buf))
-               return;
+               return false;
 
        for (;;) {
                spin_lock_irqsave(&sta->ps_tx_buf.lock, flags);
@@ -608,6 +608,8 @@ static void sta_info_cleanup_expire_buffered(struct ieee80211_local *local,
                if (skb_queue_empty(&sta->ps_tx_buf))
                        sta_info_clear_tim_bit(sta);
        }
+
+       return true;
 }
 
 static int __must_check __sta_info_destroy(struct sta_info *sta)
@@ -755,15 +757,20 @@ static void sta_info_cleanup(unsigned long data)
 {
        struct ieee80211_local *local = (struct ieee80211_local *) data;
        struct sta_info *sta;
+       bool timer_needed = false;
 
        rcu_read_lock();
        list_for_each_entry_rcu(sta, &local->sta_list, list)
-               sta_info_cleanup_expire_buffered(local, sta);
+               if (sta_info_cleanup_expire_buffered(local, sta))
+                       timer_needed = true;
        rcu_read_unlock();
 
        if (local->quiescing)
                return;
 
+       if (!timer_needed)
+               return;
+
        local->sta_cleanup.expires =
                round_jiffies(jiffies + STA_INFO_CLEANUP_INTERVAL);
        add_timer(&local->sta_cleanup);
index 2cb77267f733182a246653605fe564d93e5db4ba..e2aa972d584fa28556d78a8dc9801acf3042b154 100644 (file)
@@ -429,6 +429,7 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx)
        struct sta_info *sta = tx->sta;
        struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb);
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data;
+       struct ieee80211_local *local = tx->local;
        u32 staflags;
 
        if (unlikely(!sta ||
@@ -476,6 +477,12 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx)
                info->control.vif = &tx->sdata->vif;
                info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING;
                skb_queue_tail(&sta->ps_tx_buf, tx->skb);
+
+               if (!timer_pending(&local->sta_cleanup))
+                       mod_timer(&local->sta_cleanup,
+                                 round_jiffies(jiffies +
+                                               STA_INFO_CLEANUP_INTERVAL));
+
                return TX_QUEUED;
        }
 #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
index c2735775ec19d87e2dbf7872a409d5e9d852c51b..8ddf5ae0dd036442f67f46289414e83682193ef1 100644 (file)
@@ -518,12 +518,16 @@ void cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
        ev->type = EVENT_CONNECT_RESULT;
        if (bssid)
                memcpy(ev->cr.bssid, bssid, ETH_ALEN);
-       ev->cr.req_ie = ((u8 *)ev) + sizeof(*ev);
-       ev->cr.req_ie_len = req_ie_len;
-       memcpy((void *)ev->cr.req_ie, req_ie, req_ie_len);
-       ev->cr.resp_ie = ((u8 *)ev) + sizeof(*ev) + req_ie_len;
-       ev->cr.resp_ie_len = resp_ie_len;
-       memcpy((void *)ev->cr.resp_ie, resp_ie, resp_ie_len);
+       if (req_ie_len) {
+               ev->cr.req_ie = ((u8 *)ev) + sizeof(*ev);
+               ev->cr.req_ie_len = req_ie_len;
+               memcpy((void *)ev->cr.req_ie, req_ie, req_ie_len);
+       }
+       if (resp_ie_len) {
+               ev->cr.resp_ie = ((u8 *)ev) + sizeof(*ev) + req_ie_len;
+               ev->cr.resp_ie_len = resp_ie_len;
+               memcpy((void *)ev->cr.resp_ie, resp_ie, resp_ie_len);
+       }
        ev->cr.status = status;
 
        spin_lock_irqsave(&wdev->event_lock, flags);