]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[ath9k] Add ath9k driver
authorScott K Logan <logans@cottsay.net>
Fri, 14 Oct 2011 14:19:32 +0000 (15:19 +0100)
committerMichael Brown <mcb30@ipxe.org>
Fri, 14 Oct 2011 14:34:52 +0000 (15:34 +0100)
Signed-off-by: Michael Brown <mcb30@ipxe.org>
75 files changed:
src/Makefile
src/drivers/net/ath/ath.h [new file with mode: 0644]
src/drivers/net/ath/ath5k/ath5k.c [moved from src/drivers/net/ath5k/ath5k.c with 100% similarity]
src/drivers/net/ath/ath5k/ath5k.h [moved from src/drivers/net/ath5k/ath5k.h with 100% similarity]
src/drivers/net/ath/ath5k/ath5k_attach.c [moved from src/drivers/net/ath5k/ath5k_attach.c with 100% similarity]
src/drivers/net/ath/ath5k/ath5k_caps.c [moved from src/drivers/net/ath5k/ath5k_caps.c with 100% similarity]
src/drivers/net/ath/ath5k/ath5k_desc.c [moved from src/drivers/net/ath5k/ath5k_desc.c with 100% similarity]
src/drivers/net/ath/ath5k/ath5k_dma.c [moved from src/drivers/net/ath5k/ath5k_dma.c with 100% similarity]
src/drivers/net/ath/ath5k/ath5k_eeprom.c [moved from src/drivers/net/ath5k/ath5k_eeprom.c with 100% similarity]
src/drivers/net/ath/ath5k/ath5k_gpio.c [moved from src/drivers/net/ath5k/ath5k_gpio.c with 100% similarity]
src/drivers/net/ath/ath5k/ath5k_initvals.c [moved from src/drivers/net/ath5k/ath5k_initvals.c with 100% similarity]
src/drivers/net/ath/ath5k/ath5k_pcu.c [moved from src/drivers/net/ath5k/ath5k_pcu.c with 100% similarity]
src/drivers/net/ath/ath5k/ath5k_phy.c [moved from src/drivers/net/ath5k/ath5k_phy.c with 100% similarity]
src/drivers/net/ath/ath5k/ath5k_qcu.c [moved from src/drivers/net/ath5k/ath5k_qcu.c with 100% similarity]
src/drivers/net/ath/ath5k/ath5k_reset.c [moved from src/drivers/net/ath5k/ath5k_reset.c with 100% similarity]
src/drivers/net/ath/ath5k/ath5k_rfkill.c [moved from src/drivers/net/ath5k/ath5k_rfkill.c with 100% similarity]
src/drivers/net/ath/ath5k/base.h [moved from src/drivers/net/ath5k/base.h with 100% similarity]
src/drivers/net/ath/ath5k/desc.h [moved from src/drivers/net/ath5k/desc.h with 100% similarity]
src/drivers/net/ath/ath5k/eeprom.h [moved from src/drivers/net/ath5k/eeprom.h with 100% similarity]
src/drivers/net/ath/ath5k/reg.h [moved from src/drivers/net/ath5k/reg.h with 100% similarity]
src/drivers/net/ath/ath5k/rfbuffer.h [moved from src/drivers/net/ath5k/rfbuffer.h with 100% similarity]
src/drivers/net/ath/ath5k/rfgain.h [moved from src/drivers/net/ath5k/rfgain.h with 100% similarity]
src/drivers/net/ath/ath9k/ani.h [new file with mode: 0644]
src/drivers/net/ath/ath9k/ar5008_initvals.h [new file with mode: 0644]
src/drivers/net/ath/ath9k/ar9001_initvals.h [new file with mode: 0644]
src/drivers/net/ath/ath9k/ar9002_initvals.h [new file with mode: 0644]
src/drivers/net/ath/ath9k/ar9002_phy.h [new file with mode: 0644]
src/drivers/net/ath/ath9k/ar9003_2p2_initvals.h [new file with mode: 0644]
src/drivers/net/ath/ath9k/ar9003_eeprom.h [new file with mode: 0644]
src/drivers/net/ath/ath9k/ar9003_mac.h [new file with mode: 0644]
src/drivers/net/ath/ath9k/ar9003_phy.h [new file with mode: 0644]
src/drivers/net/ath/ath9k/ar9340_initvals.h [new file with mode: 0644]
src/drivers/net/ath/ath9k/ar9485_initvals.h [new file with mode: 0644]
src/drivers/net/ath/ath9k/ath9k.c [new file with mode: 0644]
src/drivers/net/ath/ath9k/ath9k.h [new file with mode: 0644]
src/drivers/net/ath/ath9k/ath9k_ani.c [new file with mode: 0644]
src/drivers/net/ath/ath9k/ath9k_ar5008_phy.c [new file with mode: 0644]
src/drivers/net/ath/ath9k/ath9k_ar9002_calib.c [new file with mode: 0644]
src/drivers/net/ath/ath9k/ath9k_ar9002_hw.c [new file with mode: 0644]
src/drivers/net/ath/ath9k/ath9k_ar9002_mac.c [new file with mode: 0644]
src/drivers/net/ath/ath9k/ath9k_ar9002_phy.c [new file with mode: 0644]
src/drivers/net/ath/ath9k/ath9k_ar9003_calib.c [new file with mode: 0644]
src/drivers/net/ath/ath9k/ath9k_ar9003_eeprom.c [new file with mode: 0644]
src/drivers/net/ath/ath9k/ath9k_ar9003_hw.c [new file with mode: 0644]
src/drivers/net/ath/ath9k/ath9k_ar9003_mac.c [new file with mode: 0644]
src/drivers/net/ath/ath9k/ath9k_ar9003_phy.c [new file with mode: 0644]
src/drivers/net/ath/ath9k/ath9k_calib.c [new file with mode: 0644]
src/drivers/net/ath/ath9k/ath9k_common.c [new file with mode: 0644]
src/drivers/net/ath/ath9k/ath9k_eeprom.c [new file with mode: 0644]
src/drivers/net/ath/ath9k/ath9k_eeprom_4k.c [new file with mode: 0644]
src/drivers/net/ath/ath9k/ath9k_eeprom_9287.c [new file with mode: 0644]
src/drivers/net/ath/ath9k/ath9k_eeprom_def.c [new file with mode: 0644]
src/drivers/net/ath/ath9k/ath9k_hw.c [new file with mode: 0644]
src/drivers/net/ath/ath9k/ath9k_init.c [new file with mode: 0644]
src/drivers/net/ath/ath9k/ath9k_mac.c [new file with mode: 0644]
src/drivers/net/ath/ath9k/ath9k_main.c [new file with mode: 0644]
src/drivers/net/ath/ath9k/ath9k_recv.c [new file with mode: 0644]
src/drivers/net/ath/ath9k/ath9k_xmit.c [new file with mode: 0644]
src/drivers/net/ath/ath9k/calib.h [new file with mode: 0644]
src/drivers/net/ath/ath9k/common.h [new file with mode: 0644]
src/drivers/net/ath/ath9k/eeprom.h [new file with mode: 0644]
src/drivers/net/ath/ath9k/hw-ops.h [new file with mode: 0644]
src/drivers/net/ath/ath9k/hw.h [new file with mode: 0644]
src/drivers/net/ath/ath9k/mac.h [new file with mode: 0644]
src/drivers/net/ath/ath9k/phy.h [new file with mode: 0644]
src/drivers/net/ath/ath9k/reg.h [new file with mode: 0644]
src/drivers/net/ath/ath_hw.c [new file with mode: 0644]
src/drivers/net/ath/ath_key.c [new file with mode: 0644]
src/drivers/net/ath/ath_main.c [new file with mode: 0644]
src/drivers/net/ath/ath_regd.c [new file with mode: 0644]
src/drivers/net/ath/reg.h [new file with mode: 0644]
src/drivers/net/ath/regd.h [new file with mode: 0644]
src/drivers/net/ath/regd_common.h [new file with mode: 0644]
src/include/ipxe/errfile.h
src/include/ipxe/net80211.h

index 8cc976ba09a50c86cdf3bd23677893ba30ba670c..e2425d7637857cb11996001aa453f5518771f24a 100644 (file)
@@ -68,7 +68,9 @@ SRCDIRS               += drivers/net/igb
 SRCDIRS                += drivers/net/igbvf
 SRCDIRS                += drivers/net/phantom
 SRCDIRS                += drivers/net/rtl818x
-SRCDIRS                += drivers/net/ath5k
+SRCDIRS                += drivers/net/ath
+SRCDIRS                += drivers/net/ath/ath5k
+SRCDIRS                += drivers/net/ath/ath9k
 SRCDIRS                += drivers/net/vxge
 SRCDIRS                += drivers/net/efi
 SRCDIRS                += drivers/block
diff --git a/src/drivers/net/ath/ath.h b/src/drivers/net/ath/ath.h
new file mode 100644 (file)
index 0000000..5a19a19
--- /dev/null
@@ -0,0 +1,239 @@
+/*
+ * Copyright (c) 2008-2009 Atheros Communications Inc.
+ *
+ * Modified for iPXE by Scott K Logan <logans@cottsay.net> July 2011
+ * Original from Linux kernel 3.0.1
+ *
+ * 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 ATH_H
+#define ATH_H
+
+#include <unistd.h>
+#include <ipxe/net80211.h>
+
+/* This block of functions are from kernel.h v3.0.1 */
+#define ARRAY_SIZE(arr)                (sizeof(arr) / sizeof((arr)[0]))
+#define DIV_ROUND_UP(n,d)      (((n) + (d) - 1) / (d))
+#define BITS_PER_BYTE          8
+#define BITS_TO_LONGS(nr)      DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long))
+#define BIT(nr)                        (1UL << (nr))
+
+#define min(x, y) ({                                   \
+       typeof(x) _min1 = (x);                          \
+       typeof(y) _min2 = (y);                          \
+       (void) (&_min1 == &_min2);                      \
+       _min1 < _min2 ? _min1 : _min2; })
+#define max(x, y) ({                                   \
+       typeof(x) _max1 = (x);                          \
+       typeof(y) _max2 = (y);                          \
+       (void) (&_max1 == &_max2);                      \
+       _max1 > _max2 ? _max1 : _max2; })
+#define abs(x) ({                                      \
+               long ret;                               \
+               if (sizeof(x) == sizeof(long)) {        \
+                       long __x = (x);                 \
+                       ret = (__x < 0) ? -__x : __x;   \
+               } else {                                \
+                       int __x = (x);                  \
+                       ret = (__x < 0) ? -__x : __x;   \
+               }                                       \
+               ret;                                    \
+       })
+
+#define ___constant_swab16(x) ((uint16_t)(                     \
+       (((uint16_t)(x) & (uint16_t)0x00ffU) << 8) |            \
+       (((uint16_t)(x) & (uint16_t)0xff00U) >> 8)))
+#define ___constant_swab32(x) ((uint32_t)(                     \
+       (((uint32_t)(x) & (uint32_t)0x000000ffUL) << 24) |      \
+       (((uint32_t)(x) & (uint32_t)0x0000ff00UL) <<  8) |      \
+       (((uint32_t)(x) & (uint32_t)0x00ff0000UL) >>  8) |      \
+       (((uint32_t)(x) & (uint32_t)0xff000000UL) >> 24)))
+#define __swab16(x) ___constant_swab16(x)
+#define __swab32(x) ___constant_swab32(x)
+#define swab16 __swab16
+#define swab32 __swab32
+
+static inline int32_t sign_extend32(uint32_t value, int index)
+{
+       uint8_t shift = 31 - index;
+       return (int32_t)(value << shift) >> shift;
+}
+
+static inline u16 __get_unaligned_le16(const u8 *p)
+{
+       return p[0] | p[1] << 8;
+}
+static inline u32 __get_unaligned_le32(const u8 *p)
+{
+       return p[0] | p[1] << 8 | p[2] << 16 | p[3] << 24;
+}
+static inline u16 get_unaligned_le16(const void *p)
+{
+       return __get_unaligned_le16((const u8 *)p);
+}
+static inline u32 get_unaligned_le32(const void *p)
+{
+       return __get_unaligned_le32((const u8 *)p);
+}
+/* End Kernel Block */
+
+/*
+ * The key cache is used for h/w cipher state and also for
+ * tracking station state such as the current tx antenna.
+ * We also setup a mapping table between key cache slot indices
+ * and station state to short-circuit node lookups on rx.
+ * Different parts have different size key caches.  We handle
+ * up to ATH_KEYMAX entries (could dynamically allocate state).
+ */
+#define        ATH_KEYMAX              128     /* max key cache size we handle */
+
+static const u8 ath_bcast_mac[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+
+struct ath_ani {
+       int caldone;
+       unsigned int longcal_timer;
+       unsigned int shortcal_timer;
+       unsigned int resetcal_timer;
+       unsigned int checkani_timer;
+       int timer;
+};
+
+struct ath_cycle_counters {
+       u32 cycles;
+       u32 rx_busy;
+       u32 rx_frame;
+       u32 tx_frame;
+};
+
+enum ath_device_state {
+       ATH_HW_UNAVAILABLE,
+       ATH_HW_INITIALIZED,
+};
+
+enum ath_bus_type {
+       ATH_PCI,
+       ATH_AHB,
+       ATH_USB,
+};
+
+struct reg_dmn_pair_mapping {
+       u16 regDmnEnum;
+       u16 reg_5ghz_ctl;
+       u16 reg_2ghz_ctl;
+};
+
+struct ath_regulatory {
+       char alpha2[2];
+       u16 country_code;
+       u16 max_power_level;
+       u32 tp_scale;
+       u16 current_rd;
+       u16 current_rd_ext;
+       int16_t power_limit;
+       struct reg_dmn_pair_mapping *regpair;
+};
+
+enum ath_crypt_caps {
+       ATH_CRYPT_CAP_CIPHER_AESCCM             = BIT(0),
+       ATH_CRYPT_CAP_MIC_COMBINED              = BIT(1),
+};
+
+struct ath_keyval {
+       u8 kv_type;
+       u8 kv_pad;
+       u16 kv_len;
+       u8 kv_val[16]; /* TK */
+       u8 kv_mic[8]; /* Michael MIC key */
+       u8 kv_txmic[8]; /* Michael MIC TX key (used only if the hardware
+                        * supports both MIC keys in the same key cache entry;
+                        * in that case, kv_mic is the RX key) */
+};
+
+enum ath_cipher {
+       ATH_CIPHER_WEP = 0,
+       ATH_CIPHER_AES_OCB = 1,
+       ATH_CIPHER_AES_CCM = 2,
+       ATH_CIPHER_CKIP = 3,
+       ATH_CIPHER_TKIP = 4,
+       ATH_CIPHER_CLR = 5,
+       ATH_CIPHER_MIC = 127
+};
+
+/**
+ * struct ath_ops - Register read/write operations
+ *
+ * @read: Register read
+ * @multi_read: Multiple register read
+ * @write: Register write
+ * @enable_write_buffer: Enable multiple register writes
+ * @write_flush: flush buffered register writes and disable buffering
+ */
+struct ath_ops {
+       unsigned int (*read)(void *, u32 reg_offset);
+       void (*multi_read)(void *, u32 *addr, u32 *val, u16 count);
+       void (*write)(void *, u32 val, u32 reg_offset);
+       void (*enable_write_buffer)(void *);
+       void (*write_flush) (void *);
+       u32 (*rmw)(void *, u32 reg_offset, u32 set, u32 clr);
+};
+
+struct ath_common;
+struct ath_bus_ops;
+
+struct ath_common {
+       void *ah;
+       void *priv;
+       struct net80211_device *dev;
+       int debug_mask;
+       enum ath_device_state state;
+
+       struct ath_ani ani;
+
+       u16 cachelsz;
+       u16 curaid;
+       u8 macaddr[ETH_ALEN];
+       u8 curbssid[ETH_ALEN];
+       u8 bssidmask[ETH_ALEN];
+
+       u8 tx_chainmask;
+       u8 rx_chainmask;
+
+       u32 rx_bufsize;
+
+       u32 keymax;
+       enum ath_crypt_caps crypt_caps;
+
+       unsigned int clockrate;
+
+       struct ath_cycle_counters cc_ani;
+       struct ath_cycle_counters cc_survey;
+
+       struct ath_regulatory regulatory;
+       const struct ath_ops *ops;
+       const struct ath_bus_ops *bus_ops;
+
+       int btcoex_enabled;
+};
+
+struct io_buffer *ath_rxbuf_alloc(struct ath_common *common,
+                               u32 len,
+                               u32 *iob_addr);
+
+void ath_hw_setbssidmask(struct ath_common *common);
+int ath_hw_keyreset(struct ath_common *common, u16 entry);
+void ath_hw_cycle_counters_update(struct ath_common *common);
+int32_t ath_hw_get_listen_time(struct ath_common *common);
+
+#endif /* ATH_H */
diff --git a/src/drivers/net/ath/ath9k/ani.h b/src/drivers/net/ath/ath9k/ani.h
new file mode 100644 (file)
index 0000000..9a333b5
--- /dev/null
@@ -0,0 +1,168 @@
+/*
+ * Copyright (c) 2008-2011 Atheros Communications Inc.
+ *
+ * Modified for iPXE by Scott K Logan <logans@cottsay.net> July 2011
+ * Original from Linux kernel 3.0.1
+ *
+ * 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 ANI_H
+#define ANI_H
+
+#define HAL_PROCESS_ANI           0x00000001
+
+#define DO_ANI(ah) (((ah)->proc_phyerr & HAL_PROCESS_ANI) && ah->curchan)
+
+#define BEACON_RSSI(ahp) (ahp->stats.avgbrssi)
+
+/* units are errors per second */
+#define ATH9K_ANI_OFDM_TRIG_HIGH_OLD      500
+#define ATH9K_ANI_OFDM_TRIG_HIGH_NEW      1000
+
+/* units are errors per second */
+#define ATH9K_ANI_OFDM_TRIG_LOW_OLD       200
+#define ATH9K_ANI_OFDM_TRIG_LOW_NEW       400
+
+/* units are errors per second */
+#define ATH9K_ANI_CCK_TRIG_HIGH_OLD       200
+#define ATH9K_ANI_CCK_TRIG_HIGH_NEW       600
+
+/* units are errors per second */
+#define ATH9K_ANI_CCK_TRIG_LOW_OLD        100
+#define ATH9K_ANI_CCK_TRIG_LOW_NEW        300
+
+#define ATH9K_ANI_NOISE_IMMUNE_LVL        4
+#define ATH9K_ANI_USE_OFDM_WEAK_SIG       1
+#define ATH9K_ANI_CCK_WEAK_SIG_THR        0
+
+#define ATH9K_ANI_SPUR_IMMUNE_LVL_OLD     7
+#define ATH9K_ANI_SPUR_IMMUNE_LVL_NEW     3
+
+#define ATH9K_ANI_FIRSTEP_LVL_OLD         0
+#define ATH9K_ANI_FIRSTEP_LVL_NEW         2
+
+#define ATH9K_ANI_RSSI_THR_HIGH           40
+#define ATH9K_ANI_RSSI_THR_LOW            7
+
+#define ATH9K_ANI_PERIOD_OLD              100
+#define ATH9K_ANI_PERIOD_NEW              1000
+
+/* in ms */
+#define ATH9K_ANI_POLLINTERVAL_OLD        100
+#define ATH9K_ANI_POLLINTERVAL_NEW        1000
+
+#define HAL_NOISE_IMMUNE_MAX              4
+#define HAL_SPUR_IMMUNE_MAX               7
+#define HAL_FIRST_STEP_MAX                2
+
+#define ATH9K_SIG_FIRSTEP_SETTING_MIN     0
+#define ATH9K_SIG_FIRSTEP_SETTING_MAX     20
+#define ATH9K_SIG_SPUR_IMM_SETTING_MIN    0
+#define ATH9K_SIG_SPUR_IMM_SETTING_MAX    22
+
+#define ATH9K_ANI_ENABLE_MRC_CCK          1
+
+/* values here are relative to the INI */
+
+enum ath9k_ani_cmd {
+       ATH9K_ANI_PRESENT = 0x1,
+       ATH9K_ANI_NOISE_IMMUNITY_LEVEL = 0x2,
+       ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION = 0x4,
+       ATH9K_ANI_CCK_WEAK_SIGNAL_THR = 0x8,
+       ATH9K_ANI_FIRSTEP_LEVEL = 0x10,
+       ATH9K_ANI_SPUR_IMMUNITY_LEVEL = 0x20,
+       ATH9K_ANI_MODE = 0x40,
+       ATH9K_ANI_PHYERR_RESET = 0x80,
+       ATH9K_ANI_MRC_CCK = 0x100,
+       ATH9K_ANI_ALL = 0xfff
+};
+
+struct ath9k_mib_stats {
+       u32 ackrcv_bad;
+       u32 rts_bad;
+       u32 rts_good;
+       u32 fcs_bad;
+       u32 beacons;
+};
+
+/* INI default values for ANI registers */
+struct ath9k_ani_default {
+       u16 m1ThreshLow;
+       u16 m2ThreshLow;
+       u16 m1Thresh;
+       u16 m2Thresh;
+       u16 m2CountThr;
+       u16 m2CountThrLow;
+       u16 m1ThreshLowExt;
+       u16 m2ThreshLowExt;
+       u16 m1ThreshExt;
+       u16 m2ThreshExt;
+       u16 firstep;
+       u16 firstepLow;
+       u16 cycpwrThr1;
+       u16 cycpwrThr1Ext;
+};
+
+struct ar5416AniState {
+       struct ath9k_channel *c;
+       u8 noiseImmunityLevel;
+       u8 ofdmNoiseImmunityLevel;
+       u8 cckNoiseImmunityLevel;
+       int ofdmsTurn;
+       u8 mrcCCKOff;
+       u8 spurImmunityLevel;
+       u8 firstepLevel;
+       u8 ofdmWeakSigDetectOff;
+       u8 cckWeakSigThreshold;
+       u32 listenTime;
+       int32_t rssiThrLow;
+       int32_t rssiThrHigh;
+       u32 noiseFloor;
+       u32 ofdmPhyErrCount;
+       u32 cckPhyErrCount;
+       int16_t pktRssi[2];
+       int16_t ofdmErrRssi[2];
+       int16_t cckErrRssi[2];
+       struct ath9k_ani_default iniDef;
+};
+
+struct ar5416Stats {
+       u32 ast_ani_niup;
+       u32 ast_ani_nidown;
+       u32 ast_ani_spurup;
+       u32 ast_ani_spurdown;
+       u32 ast_ani_ofdmon;
+       u32 ast_ani_ofdmoff;
+       u32 ast_ani_cckhigh;
+       u32 ast_ani_ccklow;
+       u32 ast_ani_stepup;
+       u32 ast_ani_stepdown;
+       u32 ast_ani_ofdmerrs;
+       u32 ast_ani_cckerrs;
+       u32 ast_ani_reset;
+       u32 ast_ani_lzero;
+       u32 ast_ani_lneg;
+       u32 avgbrssi;
+       struct ath9k_mib_stats ast_mibstats;
+};
+#define ah_mibStats stats.ast_mibstats
+
+void ath9k_enable_mib_counters(struct ath_hw *ah);
+void ath9k_hw_disable_mib_counters(struct ath_hw *ah);
+void ath9k_hw_ani_setup(struct ath_hw *ah);
+void ath9k_hw_ani_init(struct ath_hw *ah);
+int ath9k_hw_get_ani_channel_idx(struct ath_hw *ah,
+                                struct ath9k_channel *chan);
+
+#endif /* ANI_H */
diff --git a/src/drivers/net/ath/ath9k/ar5008_initvals.h b/src/drivers/net/ath/ath9k/ar5008_initvals.h
new file mode 100644 (file)
index 0000000..479aed5
--- /dev/null
@@ -0,0 +1,672 @@
+/*
+ * Copyright (c) 2010-2011 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.
+ */
+
+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] = {
+       /* Addr      allmodes  */
+       {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, 0x88000010},
+       {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] = {
+       /* Addr      allmodes  */
+       {0x000098b0, 0x1e5795e5},
+       {0x000098e0, 0x02008020},
+};
+
+static const u32 ar5416BB_RfGain[][3] = {
+       /* Addr      5G_HT20     5G_HT40   */
+       {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] = {
+       /* Addr      allmodes  */
+       {0x000098b0, 0x02108421},
+       {0x000098ec, 0x00000008},
+};
+
+static const u32 ar5416Bank2[][2] = {
+       /* Addr      allmodes  */
+       {0x000098b0, 0x0e73ff17},
+       {0x000098e0, 0x00000420},
+};
+
+static const u32 ar5416Bank3[][3] = {
+       /* Addr      5G_HT20     5G_HT40   */
+       {0x000098f0, 0x01400018, 0x01c00018},
+};
+
+static const u32 ar5416Bank6[][3] = {
+       /* Addr      5G_HT20     5G_HT40   */
+       {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] = {
+       /* Addr      5G_HT20     5G_HT40   */
+       {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] = {
+       /* Addr      allmodes  */
+       {0x0000989c, 0x00000500},
+       {0x0000989c, 0x00000800},
+       {0x000098cc, 0x0000000e},
+};
+
+static const u32 ar5416Addac[][2] = {
+       /* Addr      allmodes  */
+       {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},
+};
diff --git a/src/drivers/net/ath/ath9k/ar9001_initvals.h b/src/drivers/net/ath/ath9k/ar9001_initvals.h
new file mode 100644 (file)
index 0000000..7dca474
--- /dev/null
@@ -0,0 +1,1356 @@
+/*
+ * Copyright (c) 2010-2011 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.
+ */
+
+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},
+       {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, 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, 0x6d48b4e2, 0x6d48b0e2, 0x6c48b0e2, 0x6c48b0e2},
+       {0x00009858, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e},
+       {0x0000985c, 0x31395d5e, 0x3139605e, 0x3139605e, 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},
+       {0x00009940, 0x00750604, 0x00754604, 0xfff81204, 0xfff81204, 0xfff81204},
+       {0x00009944, 0xdfb81020, 0xdfb81020, 0xdfb81020, 0xdfb81020, 0xdfb81020},
+       {0x00009954, 0x5f3ca3de, 0x5f3ca3de, 0xe250a51e, 0xe250a51e, 0xe250a51e},
+       {0x00009958, 0x2108ecff, 0x2108ecff, 0x3388ffff, 0x3388ffff, 0x3388ffff},
+       {0x00009960, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0},
+       {0x0000a960, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0},
+       {0x0000b960, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0},
+       {0x00009964, 0x00001120, 0x00001120, 0x00001120, 0x00001120, 0x00001120},
+       {0x0000c9bc, 0x001a0600, 0x001a0600, 0x001a1000, 0x001a0c00, 0x001a0c00},
+       {0x000099c0, 0x038919be, 0x038919be, 0x038919be, 0x038919be, 0x038919be},
+       {0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77},
+       {0x000099c8, 0x6af65329, 0x6af65329, 0x6af65329, 0x6af65329, 0x6af65329},
+       {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] = {
+       /* Addr      allmodes  */
+       {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, 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, 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] = {
+       /* Addr      allmodes  */
+       {0x000098b0, 0x1e5795e5},
+       {0x000098e0, 0x02008020},
+};
+
+static const u32 ar5416BB_RfGain_9100[][3] = {
+       /* Addr      5G_HT20     5G_HT40   */
+       {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] = {
+       /* Addr      allmodes  */
+       {0x000098b0, 0x02108421},
+       {0x000098ec, 0x00000008},
+};
+
+static const u32 ar5416Bank2_9100[][2] = {
+       /* Addr      allmodes  */
+       {0x000098b0, 0x0e73ff17},
+       {0x000098e0, 0x00000420},
+};
+
+static const u32 ar5416Bank3_9100[][3] = {
+       /* Addr      5G_HT20     5G_HT40   */
+       {0x000098f0, 0x01400018, 0x01c00018},
+};
+
+static const u32 ar5416Bank6_9100[][3] = {
+       /* Addr      5G_HT20     5G_HT40   */
+       {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] = {
+       /* Addr      5G_HT20     5G_HT40   */
+       {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] = {
+       /* Addr      allmodes  */
+       {0x0000989c, 0x00000500},
+       {0x0000989c, 0x00000800},
+       {0x000098cc, 0x0000000e},
+};
+
+static const u32 ar5416Addac_9100[][2] = {
+       /* Addr      allmodes  */
+       {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},
+       {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, 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, 0x6d48b4e2, 0x6d48b0e2, 0x6c48b0e2, 0x6c48b0e2},
+       {0x00009858, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e},
+       {0x0000985c, 0x31395d5e, 0x3139605e, 0x3139605e, 0x31395d5e, 0x31395d5e},
+       {0x00009860, 0x00048d18, 0x00048d18, 0x00048d20, 0x00048d20, 0x00048d18},
+       {0x00009864, 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},
+       {0x000099bc, 0x001a0600, 0x001a0600, 0x001a0c00, 0x001a0c00, 0x001a0c00},
+       {0x000099c0, 0x038919be, 0x038919be, 0x038919be, 0x038919be, 0x038919be},
+       {0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77},
+       {0x000099c8, 0x6af65329, 0x6af65329, 0x6af65329, 0x6af65329, 0x6af65329},
+       {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] = {
+       /* Addr      allmodes  */
+       {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},
+       {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, 0x88a00010},
+       {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, 0x0e79e5c6},
+       {0x0000b26c, 0x0e79e5c6},
+       {0x0000c26c, 0x0e79e5c6},
+       {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] = {
+       /* Addr      allmodes  */
+       {0x000098b0, 0x1e5795e5},
+       {0x000098e0, 0x02008020},
+};
+
+static const u32 ar5416BB_RfGain_9160[][3] = {
+       /* Addr      5G_HT20     5G_HT40   */
+       {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] = {
+       /* Addr      allmodes  */
+       {0x000098b0, 0x02108421},
+       {0x000098ec, 0x00000008},
+};
+
+static const u32 ar5416Bank2_9160[][2] = {
+       /* Addr      allmodes  */
+       {0x000098b0, 0x0e73ff17},
+       {0x000098e0, 0x00000420},
+};
+
+static const u32 ar5416Bank3_9160[][3] = {
+       /* Addr      5G_HT20     5G_HT40   */
+       {0x000098f0, 0x01400018, 0x01c00018},
+};
+
+static const u32 ar5416Bank6_9160[][3] = {
+       /* Addr      5G_HT20     5G_HT40   */
+       {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] = {
+       /* Addr      5G_HT20     5G_HT40   */
+       {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] = {
+       /* Addr      allmodes  */
+       {0x0000989c, 0x00000500},
+       {0x0000989c, 0x00000800},
+       {0x000098cc, 0x0000000e},
+};
+
+static const u32 ar5416Addac_9160[][2] = {
+       /* Addr      allmodes  */
+       {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_9160_1_1[][2] = {
+       /* Addr      allmodes  */
+       {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/src/drivers/net/ath/ath9k/ar9002_initvals.h b/src/drivers/net/ath/ath9k/ar9002_initvals.h
new file mode 100644 (file)
index 0000000..dd12151
--- /dev/null
@@ -0,0 +1,3264 @@
+/*
+ * Copyright (c) 2010-2011 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.
+ */
+
+static const u32 ar9280Modes_9280_2[][6] = {
+       {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0},
+       {0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0},
+       {0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180},
+       {0x000010f0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000008},
+       {0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00, 0x06e006e0},
+       {0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b, 0x0988004f},
+       {0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810, 0x08f04810},
+       {0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a, 0x0000320a},
+       {0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440, 0x00006880},
+       {0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303},
+       {0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200},
+       {0x00009824, 0x01000e0e, 0x01000e0e, 0x01000e0e, 0x01000e0e, 0x01000e0e},
+       {0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001},
+       {0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e},
+       {0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007},
+       {0x00009840, 0x206a022e, 0x206a022e, 0x206a012e, 0x206a012e, 0x206a012e},
+       {0x00009844, 0x0372161e, 0x0372161e, 0x037216a0, 0x037216a0, 0x037216a0},
+       {0x00009850, 0x6c4000e2, 0x6d4000e2, 0x6d4000e2, 0x6c4000e2, 0x6c4000e2},
+       {0x00009858, 0x7ec88d2e, 0x7ec88d2e, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e},
+       {0x0000985c, 0x31395d5e, 0x3139605e, 0x3139605e, 0x31395d5e, 0x31395d5e},
+       {0x00009860, 0x00048d18, 0x00048d18, 0x00048d20, 0x00048d20, 0x00048d18},
+       {0x00009864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00},
+       {0x00009868, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0},
+       {0x0000986c, 0x06903081, 0x06903081, 0x06903881, 0x06903881, 0x06903881},
+       {0x00009914, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898, 0x000007d0},
+       {0x00009918, 0x0000000a, 0x00000014, 0x00000268, 0x0000000b, 0x00000016},
+       {0x00009924, 0xd00a8a0b, 0xd00a8a0b, 0xd00a8a0d, 0xd00a8a0d, 0xd00a8a0d},
+       {0x00009944, 0xffbc1010, 0xffbc1010, 0xffbc1010, 0xffbc1010, 0xffbc1010},
+       {0x00009960, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010},
+       {0x0000a960, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010},
+       {0x00009964, 0x00000210, 0x00000210, 0x00000210, 0x00000210, 0x00000210},
+       {0x0000c968, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce, 0x000003ce},
+       {0x000099b8, 0x0000001c, 0x0000001c, 0x0000001c, 0x0000001c, 0x0000001c},
+       {0x000099bc, 0x00000a00, 0x00000a00, 0x00000c00, 0x00000c00, 0x00000c00},
+       {0x000099c0, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4},
+       {0x0000a204, 0x00000444, 0x00000444, 0x00000444, 0x00000444, 0x00000444},
+       {0x0000a20c, 0x00000014, 0x00000014, 0x0001f019, 0x0001f019, 0x0001f019},
+       {0x0000b20c, 0x00000014, 0x00000014, 0x0001f019, 0x0001f019, 0x0001f019},
+       {0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a},
+       {0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000},
+       {0x0000a23c, 0x13c88000, 0x13c88000, 0x13c88001, 0x13c88000, 0x13c88000},
+       {0x0000a250, 0x001ff000, 0x001ff000, 0x0004a000, 0x0004a000, 0x0004a000},
+       {0x0000a358, 0x7999aa02, 0x7999aa02, 0x7999aa0e, 0x7999aa0e, 0x7999aa0e},
+       {0x0000a388, 0x0c000000, 0x0c000000, 0x08000000, 0x0c000000, 0x0c000000},
+       {0x0000a3d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x00007894, 0x5a508000, 0x5a508000, 0x5a508000, 0x5a508000, 0x5a508000},
+};
+
+static const u32 ar9280Common_9280_2[][2] = {
+       /* Addr      allmodes  */
+       {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},
+       {0x00004024, 0x0000001f},
+       {0x00004060, 0x00000000},
+       {0x00004064, 0x00000000},
+       {0x00007010, 0x00000033},
+       {0x00007034, 0x00000002},
+       {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},
+       {0x00008070, 0x00000000},
+       {0x000080c0, 0x2a80001a},
+       {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},
+       {0x000081c0, 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, 0x88a00010},
+       {0x00008270, 0x00000000},
+       {0x00008274, 0x40000000},
+       {0x00008278, 0x003e4180},
+       {0x0000827c, 0x00000000},
+       {0x00008284, 0x0000002c},
+       {0x00008288, 0x0000002c},
+       {0x0000828c, 0x00000000},
+       {0x00008294, 0x00000000},
+       {0x00008298, 0x00000000},
+       {0x0000829c, 0x00000000},
+       {0x00008300, 0x00000040},
+       {0x00008314, 0x00000000},
+       {0x00008328, 0x00000000},
+       {0x0000832c, 0x00000007},
+       {0x00008330, 0x00000302},
+       {0x00008334, 0x00000e00},
+       {0x00008338, 0x00ff0000},
+       {0x0000833c, 0x00000000},
+       {0x00008340, 0x000107ff},
+       {0x00008344, 0x00481043},
+       {0x00009808, 0x00000000},
+       {0x0000980c, 0xafa68e30},
+       {0x00009810, 0xfd14e000},
+       {0x00009814, 0x9c0a9f6b},
+       {0x0000981c, 0x00000000},
+       {0x0000982c, 0x0000a000},
+       {0x00009830, 0x00000000},
+       {0x0000983c, 0x00200400},
+       {0x0000984c, 0x0040233c},
+       {0x0000a84c, 0x0040233c},
+       {0x00009854, 0x00000044},
+       {0x00009900, 0x00000000},
+       {0x00009904, 0x00000000},
+       {0x00009908, 0x00000000},
+       {0x0000990c, 0x00000000},
+       {0x00009910, 0x01002310},
+       {0x0000991c, 0x10000fff},
+       {0x00009920, 0x04900000},
+       {0x0000a920, 0x04900000},
+       {0x00009928, 0x00000001},
+       {0x0000992c, 0x00000004},
+       {0x00009934, 0x1e1f2022},
+       {0x00009938, 0x0a0b0c0d},
+       {0x0000993c, 0x00000000},
+       {0x00009948, 0x9280c00a},
+       {0x0000994c, 0x00020028},
+       {0x00009954, 0x5f3ca3de},
+       {0x00009958, 0x2108ecff},
+       {0x00009940, 0x14750604},
+       {0x0000c95c, 0x004b6a8e},
+       {0x00009970, 0x190fb514},
+       {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},
+       {0x000099b4, 0x00000820},
+       {0x000099c4, 0x06336f77},
+       {0x000099c8, 0x6af6532f},
+       {0x000099cc, 0x08f186c8},
+       {0x000099d0, 0x00046384},
+       {0x000099d4, 0x00000000},
+       {0x000099d8, 0x00000000},
+       {0x000099dc, 0x00000000},
+       {0x000099e0, 0x00000000},
+       {0x000099e4, 0xaaaaaaaa},
+       {0x000099e8, 0x3c466478},
+       {0x000099ec, 0x0cc80caa},
+       {0x000099f0, 0x00000000},
+       {0x000099fc, 0x00001042},
+       {0x0000a208, 0x803e4788},
+       {0x0000a210, 0x4080a333},
+       {0x0000a214, 0x40206c10},
+       {0x0000a218, 0x009c4060},
+       {0x0000a220, 0x01834061},
+       {0x0000a224, 0x00000400},
+       {0x0000a228, 0x000003b5},
+       {0x0000a22c, 0x233f7180},
+       {0x0000a234, 0x20202020},
+       {0x0000a238, 0x20202020},
+       {0x0000a240, 0x38490a20},
+       {0x0000a244, 0x00007bb6},
+       {0x0000a248, 0x0fff3ffc},
+       {0x0000a24c, 0x00000000},
+       {0x0000a254, 0x00000000},
+       {0x0000a258, 0x0cdbd380},
+       {0x0000a25c, 0x0f0f0f01},
+       {0x0000a260, 0xdfa91f01},
+       {0x0000a268, 0x00000000},
+       {0x0000a26c, 0x0e79e5c6},
+       {0x0000b26c, 0x0e79e5c6},
+       {0x0000d270, 0x00820820},
+       {0x0000a278, 0x1ce739ce},
+       {0x0000d35c, 0x07ffffef},
+       {0x0000d360, 0x0fffffe7},
+       {0x0000d364, 0x17ffffe5},
+       {0x0000d368, 0x1fffffe4},
+       {0x0000d36c, 0x37ffffe3},
+       {0x0000d370, 0x3fffffe3},
+       {0x0000d374, 0x57ffffe3},
+       {0x0000d378, 0x5fffffe2},
+       {0x0000d37c, 0x7fffffe2},
+       {0x0000d380, 0x7f3c7bba},
+       {0x0000d384, 0xf3307ff0},
+       {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},
+       {0x0000a3e4, 0x00000000},
+       {0x0000a3e8, 0x18c43433},
+       {0x00007800, 0x00040000},
+       {0x00007804, 0xdb005012},
+       {0x00007808, 0x04924914},
+       {0x0000780c, 0x21084210},
+       {0x00007810, 0x6d801300},
+       {0x00007818, 0x07e41000},
+       {0x00007824, 0x00040000},
+       {0x00007828, 0xdb005012},
+       {0x0000782c, 0x04924914},
+       {0x00007830, 0x21084210},
+       {0x00007834, 0x6d801300},
+       {0x0000783c, 0x07e40000},
+       {0x00007848, 0x00100000},
+       {0x0000784c, 0x773f0567},
+       {0x00007850, 0x54214514},
+       {0x00007854, 0x12035828},
+       {0x00007858, 0x9259269a},
+       {0x00007860, 0x52802000},
+       {0x00007864, 0x0a8e370e},
+       {0x00007868, 0xc0102850},
+       {0x0000786c, 0x812d4000},
+       {0x00007870, 0x807ec400},
+       {0x00007874, 0x001b6db0},
+       {0x00007878, 0x00376b63},
+       {0x0000787c, 0x06db6db6},
+       {0x00007880, 0x006d8000},
+       {0x00007884, 0xffeffffe},
+       {0x00007888, 0xffeffffe},
+       {0x0000788c, 0x00010000},
+       {0x00007890, 0x02060aeb},
+       {0x00007898, 0x2a850160},
+};
+
+static const u32 ar9280Modes_fast_clock_9280_2[][3] = {
+       /* Addr      5G_HT20     5G_HT40   */
+       {0x00001030, 0x00000268, 0x000004d0},
+       {0x00001070, 0x0000018c, 0x00000318},
+       {0x000010b0, 0x00000fd0, 0x00001fa0},
+       {0x00008014, 0x044c044c, 0x08980898},
+       {0x0000801c, 0x148ec02b, 0x148ec057},
+       {0x00008318, 0x000044c0, 0x00008980},
+       {0x00009820, 0x02020200, 0x02020200},
+       {0x00009824, 0x01000f0f, 0x01000f0f},
+       {0x00009828, 0x0b020001, 0x0b020001},
+       {0x00009834, 0x00000f0f, 0x00000f0f},
+       {0x00009844, 0x03721821, 0x03721821},
+       {0x00009914, 0x00000898, 0x00001130},
+       {0x00009918, 0x0000000b, 0x00000016},
+};
+
+static const u32 ar9280Modes_backoff_23db_rxgain_9280_2[][6] = {
+       {0x00009a00, 0x00008184, 0x00008184, 0x00000290, 0x00000290, 0x00000290},
+       {0x00009a04, 0x00008188, 0x00008188, 0x00000300, 0x00000300, 0x00000300},
+       {0x00009a08, 0x0000818c, 0x0000818c, 0x00000304, 0x00000304, 0x00000304},
+       {0x00009a0c, 0x00008190, 0x00008190, 0x00000308, 0x00000308, 0x00000308},
+       {0x00009a10, 0x00008194, 0x00008194, 0x0000030c, 0x0000030c, 0x0000030c},
+       {0x00009a14, 0x00008200, 0x00008200, 0x00008000, 0x00008000, 0x00008000},
+       {0x00009a18, 0x00008204, 0x00008204, 0x00008004, 0x00008004, 0x00008004},
+       {0x00009a1c, 0x00008208, 0x00008208, 0x00008008, 0x00008008, 0x00008008},
+       {0x00009a20, 0x0000820c, 0x0000820c, 0x0000800c, 0x0000800c, 0x0000800c},
+       {0x00009a24, 0x00008210, 0x00008210, 0x00008080, 0x00008080, 0x00008080},
+       {0x00009a28, 0x00008214, 0x00008214, 0x00008084, 0x00008084, 0x00008084},
+       {0x00009a2c, 0x00008280, 0x00008280, 0x00008088, 0x00008088, 0x00008088},
+       {0x00009a30, 0x00008284, 0x00008284, 0x0000808c, 0x0000808c, 0x0000808c},
+       {0x00009a34, 0x00008288, 0x00008288, 0x00008100, 0x00008100, 0x00008100},
+       {0x00009a38, 0x0000828c, 0x0000828c, 0x00008104, 0x00008104, 0x00008104},
+       {0x00009a3c, 0x00008290, 0x00008290, 0x00008108, 0x00008108, 0x00008108},
+       {0x00009a40, 0x00008300, 0x00008300, 0x0000810c, 0x0000810c, 0x0000810c},
+       {0x00009a44, 0x00008304, 0x00008304, 0x00008110, 0x00008110, 0x00008110},
+       {0x00009a48, 0x00008308, 0x00008308, 0x00008114, 0x00008114, 0x00008114},
+       {0x00009a4c, 0x0000830c, 0x0000830c, 0x00008180, 0x00008180, 0x00008180},
+       {0x00009a50, 0x00008310, 0x00008310, 0x00008184, 0x00008184, 0x00008184},
+       {0x00009a54, 0x00008314, 0x00008314, 0x00008188, 0x00008188, 0x00008188},
+       {0x00009a58, 0x00008380, 0x00008380, 0x0000818c, 0x0000818c, 0x0000818c},
+       {0x00009a5c, 0x00008384, 0x00008384, 0x00008190, 0x00008190, 0x00008190},
+       {0x00009a60, 0x00008388, 0x00008388, 0x00008194, 0x00008194, 0x00008194},
+       {0x00009a64, 0x0000838c, 0x0000838c, 0x000081a0, 0x000081a0, 0x000081a0},
+       {0x00009a68, 0x00008390, 0x00008390, 0x0000820c, 0x0000820c, 0x0000820c},
+       {0x00009a6c, 0x00008394, 0x00008394, 0x000081a8, 0x000081a8, 0x000081a8},
+       {0x00009a70, 0x0000a380, 0x0000a380, 0x00008284, 0x00008284, 0x00008284},
+       {0x00009a74, 0x0000a384, 0x0000a384, 0x00008288, 0x00008288, 0x00008288},
+       {0x00009a78, 0x0000a388, 0x0000a388, 0x00008224, 0x00008224, 0x00008224},
+       {0x00009a7c, 0x0000a38c, 0x0000a38c, 0x00008290, 0x00008290, 0x00008290},
+       {0x00009a80, 0x0000a390, 0x0000a390, 0x00008300, 0x00008300, 0x00008300},
+       {0x00009a84, 0x0000a394, 0x0000a394, 0x00008304, 0x00008304, 0x00008304},
+       {0x00009a88, 0x0000a780, 0x0000a780, 0x00008308, 0x00008308, 0x00008308},
+       {0x00009a8c, 0x0000a784, 0x0000a784, 0x0000830c, 0x0000830c, 0x0000830c},
+       {0x00009a90, 0x0000a788, 0x0000a788, 0x00008380, 0x00008380, 0x00008380},
+       {0x00009a94, 0x0000a78c, 0x0000a78c, 0x00008384, 0x00008384, 0x00008384},
+       {0x00009a98, 0x0000a790, 0x0000a790, 0x00008700, 0x00008700, 0x00008700},
+       {0x00009a9c, 0x0000a794, 0x0000a794, 0x00008704, 0x00008704, 0x00008704},
+       {0x00009aa0, 0x0000ab84, 0x0000ab84, 0x00008708, 0x00008708, 0x00008708},
+       {0x00009aa4, 0x0000ab88, 0x0000ab88, 0x0000870c, 0x0000870c, 0x0000870c},
+       {0x00009aa8, 0x0000ab8c, 0x0000ab8c, 0x00008780, 0x00008780, 0x00008780},
+       {0x00009aac, 0x0000ab90, 0x0000ab90, 0x00008784, 0x00008784, 0x00008784},
+       {0x00009ab0, 0x0000ab94, 0x0000ab94, 0x00008b00, 0x00008b00, 0x00008b00},
+       {0x00009ab4, 0x0000af80, 0x0000af80, 0x00008b04, 0x00008b04, 0x00008b04},
+       {0x00009ab8, 0x0000af84, 0x0000af84, 0x00008b08, 0x00008b08, 0x00008b08},
+       {0x00009abc, 0x0000af88, 0x0000af88, 0x00008b0c, 0x00008b0c, 0x00008b0c},
+       {0x00009ac0, 0x0000af8c, 0x0000af8c, 0x00008b10, 0x00008b10, 0x00008b10},
+       {0x00009ac4, 0x0000af90, 0x0000af90, 0x00008b80, 0x00008b80, 0x00008b80},
+       {0x00009ac8, 0x0000af94, 0x0000af94, 0x00008b84, 0x00008b84, 0x00008b84},
+       {0x00009acc, 0x0000b380, 0x0000b380, 0x00008b88, 0x00008b88, 0x00008b88},
+       {0x00009ad0, 0x0000b384, 0x0000b384, 0x00008b8c, 0x00008b8c, 0x00008b8c},
+       {0x00009ad4, 0x0000b388, 0x0000b388, 0x00008b90, 0x00008b90, 0x00008b90},
+       {0x00009ad8, 0x0000b38c, 0x0000b38c, 0x00008b94, 0x00008b94, 0x00008b94},
+       {0x00009adc, 0x0000b390, 0x0000b390, 0x00008b98, 0x00008b98, 0x00008b98},
+       {0x00009ae0, 0x0000b394, 0x0000b394, 0x00008ba4, 0x00008ba4, 0x00008ba4},
+       {0x00009ae4, 0x0000b398, 0x0000b398, 0x00008ba8, 0x00008ba8, 0x00008ba8},
+       {0x00009ae8, 0x0000b780, 0x0000b780, 0x00008bac, 0x00008bac, 0x00008bac},
+       {0x00009aec, 0x0000b784, 0x0000b784, 0x00008bb0, 0x00008bb0, 0x00008bb0},
+       {0x00009af0, 0x0000b788, 0x0000b788, 0x00008bb4, 0x00008bb4, 0x00008bb4},
+       {0x00009af4, 0x0000b78c, 0x0000b78c, 0x00008ba1, 0x00008ba1, 0x00008ba1},
+       {0x00009af8, 0x0000b790, 0x0000b790, 0x00008ba5, 0x00008ba5, 0x00008ba5},
+       {0x00009afc, 0x0000b794, 0x0000b794, 0x00008ba9, 0x00008ba9, 0x00008ba9},
+       {0x00009b00, 0x0000b798, 0x0000b798, 0x00008bad, 0x00008bad, 0x00008bad},
+       {0x00009b04, 0x0000d784, 0x0000d784, 0x00008bb1, 0x00008bb1, 0x00008bb1},
+       {0x00009b08, 0x0000d788, 0x0000d788, 0x00008bb5, 0x00008bb5, 0x00008bb5},
+       {0x00009b0c, 0x0000d78c, 0x0000d78c, 0x00008ba2, 0x00008ba2, 0x00008ba2},
+       {0x00009b10, 0x0000d790, 0x0000d790, 0x00008ba6, 0x00008ba6, 0x00008ba6},
+       {0x00009b14, 0x0000f780, 0x0000f780, 0x00008baa, 0x00008baa, 0x00008baa},
+       {0x00009b18, 0x0000f784, 0x0000f784, 0x00008bae, 0x00008bae, 0x00008bae},
+       {0x00009b1c, 0x0000f788, 0x0000f788, 0x00008bb2, 0x00008bb2, 0x00008bb2},
+       {0x00009b20, 0x0000f78c, 0x0000f78c, 0x00008bb6, 0x00008bb6, 0x00008bb6},
+       {0x00009b24, 0x0000f790, 0x0000f790, 0x00008ba3, 0x00008ba3, 0x00008ba3},
+       {0x00009b28, 0x0000f794, 0x0000f794, 0x00008ba7, 0x00008ba7, 0x00008ba7},
+       {0x00009b2c, 0x0000f7a4, 0x0000f7a4, 0x00008bab, 0x00008bab, 0x00008bab},
+       {0x00009b30, 0x0000f7a8, 0x0000f7a8, 0x00008baf, 0x00008baf, 0x00008baf},
+       {0x00009b34, 0x0000f7ac, 0x0000f7ac, 0x00008bb3, 0x00008bb3, 0x00008bb3},
+       {0x00009b38, 0x0000f7b0, 0x0000f7b0, 0x00008bb7, 0x00008bb7, 0x00008bb7},
+       {0x00009b3c, 0x0000f7b4, 0x0000f7b4, 0x00008bc3, 0x00008bc3, 0x00008bc3},
+       {0x00009b40, 0x0000f7a1, 0x0000f7a1, 0x00008bc7, 0x00008bc7, 0x00008bc7},
+       {0x00009b44, 0x0000f7a5, 0x0000f7a5, 0x00008bcb, 0x00008bcb, 0x00008bcb},
+       {0x00009b48, 0x0000f7a9, 0x0000f7a9, 0x00008bcf, 0x00008bcf, 0x00008bcf},
+       {0x00009b4c, 0x0000f7ad, 0x0000f7ad, 0x00008bd3, 0x00008bd3, 0x00008bd3},
+       {0x00009b50, 0x0000f7b1, 0x0000f7b1, 0x00008bd7, 0x00008bd7, 0x00008bd7},
+       {0x00009b54, 0x0000f7b5, 0x0000f7b5, 0x00008bdb, 0x00008bdb, 0x00008bdb},
+       {0x00009b58, 0x0000f7c5, 0x0000f7c5, 0x00008bdb, 0x00008bdb, 0x00008bdb},
+       {0x00009b5c, 0x0000f7c9, 0x0000f7c9, 0x00008bdb, 0x00008bdb, 0x00008bdb},
+       {0x00009b60, 0x0000f7cd, 0x0000f7cd, 0x00008bdb, 0x00008bdb, 0x00008bdb},
+       {0x00009b64, 0x0000f7d1, 0x0000f7d1, 0x00008bdb, 0x00008bdb, 0x00008bdb},
+       {0x00009b68, 0x0000f7d5, 0x0000f7d5, 0x00008bdb, 0x00008bdb, 0x00008bdb},
+       {0x00009b6c, 0x0000f7c2, 0x0000f7c2, 0x00008bdb, 0x00008bdb, 0x00008bdb},
+       {0x00009b70, 0x0000f7c6, 0x0000f7c6, 0x00008bdb, 0x00008bdb, 0x00008bdb},
+       {0x00009b74, 0x0000f7ca, 0x0000f7ca, 0x00008bdb, 0x00008bdb, 0x00008bdb},
+       {0x00009b78, 0x0000f7ce, 0x0000f7ce, 0x00008bdb, 0x00008bdb, 0x00008bdb},
+       {0x00009b7c, 0x0000f7d2, 0x0000f7d2, 0x00008bdb, 0x00008bdb, 0x00008bdb},
+       {0x00009b80, 0x0000f7d6, 0x0000f7d6, 0x00008bdb, 0x00008bdb, 0x00008bdb},
+       {0x00009b84, 0x0000f7c3, 0x0000f7c3, 0x00008bdb, 0x00008bdb, 0x00008bdb},
+       {0x00009b88, 0x0000f7c7, 0x0000f7c7, 0x00008bdb, 0x00008bdb, 0x00008bdb},
+       {0x00009b8c, 0x0000f7cb, 0x0000f7cb, 0x00008bdb, 0x00008bdb, 0x00008bdb},
+       {0x00009b90, 0x0000f7d3, 0x0000f7d3, 0x00008bdb, 0x00008bdb, 0x00008bdb},
+       {0x00009b94, 0x0000f7d7, 0x0000f7d7, 0x00008bdb, 0x00008bdb, 0x00008bdb},
+       {0x00009b98, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb},
+       {0x00009b9c, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb},
+       {0x00009ba0, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb},
+       {0x00009ba4, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb},
+       {0x00009ba8, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb},
+       {0x00009bac, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb},
+       {0x00009bb0, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb},
+       {0x00009bb4, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb},
+       {0x00009bb8, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb},
+       {0x00009bbc, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb},
+       {0x00009bc0, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb},
+       {0x00009bc4, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb},
+       {0x00009bc8, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb},
+       {0x00009bcc, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb},
+       {0x00009bd0, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb},
+       {0x00009bd4, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb},
+       {0x00009bd8, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb},
+       {0x00009bdc, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb},
+       {0x00009be0, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb},
+       {0x00009be4, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb},
+       {0x00009be8, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb},
+       {0x00009bec, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb},
+       {0x00009bf0, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb},
+       {0x00009bf4, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb},
+       {0x00009bf8, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb},
+       {0x00009bfc, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb},
+       {0x00009848, 0x00001066, 0x00001066, 0x00001055, 0x00001055, 0x00001055},
+       {0x0000a848, 0x00001066, 0x00001066, 0x00001055, 0x00001055, 0x00001055},
+};
+
+static const u32 ar9280Modes_original_rxgain_9280_2[][6] = {
+       {0x00009a00, 0x00008184, 0x00008184, 0x00008000, 0x00008000, 0x00008000},
+       {0x00009a04, 0x00008188, 0x00008188, 0x00008000, 0x00008000, 0x00008000},
+       {0x00009a08, 0x0000818c, 0x0000818c, 0x00008000, 0x00008000, 0x00008000},
+       {0x00009a0c, 0x00008190, 0x00008190, 0x00008000, 0x00008000, 0x00008000},
+       {0x00009a10, 0x00008194, 0x00008194, 0x00008000, 0x00008000, 0x00008000},
+       {0x00009a14, 0x00008200, 0x00008200, 0x00008000, 0x00008000, 0x00008000},
+       {0x00009a18, 0x00008204, 0x00008204, 0x00008004, 0x00008004, 0x00008004},
+       {0x00009a1c, 0x00008208, 0x00008208, 0x00008008, 0x00008008, 0x00008008},
+       {0x00009a20, 0x0000820c, 0x0000820c, 0x0000800c, 0x0000800c, 0x0000800c},
+       {0x00009a24, 0x00008210, 0x00008210, 0x00008080, 0x00008080, 0x00008080},
+       {0x00009a28, 0x00008214, 0x00008214, 0x00008084, 0x00008084, 0x00008084},
+       {0x00009a2c, 0x00008280, 0x00008280, 0x00008088, 0x00008088, 0x00008088},
+       {0x00009a30, 0x00008284, 0x00008284, 0x0000808c, 0x0000808c, 0x0000808c},
+       {0x00009a34, 0x00008288, 0x00008288, 0x00008100, 0x00008100, 0x00008100},
+       {0x00009a38, 0x0000828c, 0x0000828c, 0x00008104, 0x00008104, 0x00008104},
+       {0x00009a3c, 0x00008290, 0x00008290, 0x00008108, 0x00008108, 0x00008108},
+       {0x00009a40, 0x00008300, 0x00008300, 0x0000810c, 0x0000810c, 0x0000810c},
+       {0x00009a44, 0x00008304, 0x00008304, 0x00008110, 0x00008110, 0x00008110},
+       {0x00009a48, 0x00008308, 0x00008308, 0x00008114, 0x00008114, 0x00008114},
+       {0x00009a4c, 0x0000830c, 0x0000830c, 0x00008180, 0x00008180, 0x00008180},
+       {0x00009a50, 0x00008310, 0x00008310, 0x00008184, 0x00008184, 0x00008184},
+       {0x00009a54, 0x00008314, 0x00008314, 0x00008188, 0x00008188, 0x00008188},
+       {0x00009a58, 0x00008380, 0x00008380, 0x0000818c, 0x0000818c, 0x0000818c},
+       {0x00009a5c, 0x00008384, 0x00008384, 0x00008190, 0x00008190, 0x00008190},
+       {0x00009a60, 0x00008388, 0x00008388, 0x00008194, 0x00008194, 0x00008194},
+       {0x00009a64, 0x0000838c, 0x0000838c, 0x000081a0, 0x000081a0, 0x000081a0},
+       {0x00009a68, 0x00008390, 0x00008390, 0x0000820c, 0x0000820c, 0x0000820c},
+       {0x00009a6c, 0x00008394, 0x00008394, 0x000081a8, 0x000081a8, 0x000081a8},
+       {0x00009a70, 0x0000a380, 0x0000a380, 0x00008284, 0x00008284, 0x00008284},
+       {0x00009a74, 0x0000a384, 0x0000a384, 0x00008288, 0x00008288, 0x00008288},
+       {0x00009a78, 0x0000a388, 0x0000a388, 0x00008224, 0x00008224, 0x00008224},
+       {0x00009a7c, 0x0000a38c, 0x0000a38c, 0x00008290, 0x00008290, 0x00008290},
+       {0x00009a80, 0x0000a390, 0x0000a390, 0x00008300, 0x00008300, 0x00008300},
+       {0x00009a84, 0x0000a394, 0x0000a394, 0x00008304, 0x00008304, 0x00008304},
+       {0x00009a88, 0x0000a780, 0x0000a780, 0x00008308, 0x00008308, 0x00008308},
+       {0x00009a8c, 0x0000a784, 0x0000a784, 0x0000830c, 0x0000830c, 0x0000830c},
+       {0x00009a90, 0x0000a788, 0x0000a788, 0x00008380, 0x00008380, 0x00008380},
+       {0x00009a94, 0x0000a78c, 0x0000a78c, 0x00008384, 0x00008384, 0x00008384},
+       {0x00009a98, 0x0000a790, 0x0000a790, 0x00008700, 0x00008700, 0x00008700},
+       {0x00009a9c, 0x0000a794, 0x0000a794, 0x00008704, 0x00008704, 0x00008704},
+       {0x00009aa0, 0x0000ab84, 0x0000ab84, 0x00008708, 0x00008708, 0x00008708},
+       {0x00009aa4, 0x0000ab88, 0x0000ab88, 0x0000870c, 0x0000870c, 0x0000870c},
+       {0x00009aa8, 0x0000ab8c, 0x0000ab8c, 0x00008780, 0x00008780, 0x00008780},
+       {0x00009aac, 0x0000ab90, 0x0000ab90, 0x00008784, 0x00008784, 0x00008784},
+       {0x00009ab0, 0x0000ab94, 0x0000ab94, 0x00008b00, 0x00008b00, 0x00008b00},
+       {0x00009ab4, 0x0000af80, 0x0000af80, 0x00008b04, 0x00008b04, 0x00008b04},
+       {0x00009ab8, 0x0000af84, 0x0000af84, 0x00008b08, 0x00008b08, 0x00008b08},
+       {0x00009abc, 0x0000af88, 0x0000af88, 0x00008b0c, 0x00008b0c, 0x00008b0c},
+       {0x00009ac0, 0x0000af8c, 0x0000af8c, 0x00008b80, 0x00008b80, 0x00008b80},
+       {0x00009ac4, 0x0000af90, 0x0000af90, 0x00008b84, 0x00008b84, 0x00008b84},
+       {0x00009ac8, 0x0000af94, 0x0000af94, 0x00008b88, 0x00008b88, 0x00008b88},
+       {0x00009acc, 0x0000b380, 0x0000b380, 0x00008b8c, 0x00008b8c, 0x00008b8c},
+       {0x00009ad0, 0x0000b384, 0x0000b384, 0x00008b90, 0x00008b90, 0x00008b90},
+       {0x00009ad4, 0x0000b388, 0x0000b388, 0x00008f80, 0x00008f80, 0x00008f80},
+       {0x00009ad8, 0x0000b38c, 0x0000b38c, 0x00008f84, 0x00008f84, 0x00008f84},
+       {0x00009adc, 0x0000b390, 0x0000b390, 0x00008f88, 0x00008f88, 0x00008f88},
+       {0x00009ae0, 0x0000b394, 0x0000b394, 0x00008f8c, 0x00008f8c, 0x00008f8c},
+       {0x00009ae4, 0x0000b398, 0x0000b398, 0x00008f90, 0x00008f90, 0x00008f90},
+       {0x00009ae8, 0x0000b780, 0x0000b780, 0x0000930c, 0x0000930c, 0x0000930c},
+       {0x00009aec, 0x0000b784, 0x0000b784, 0x00009310, 0x00009310, 0x00009310},
+       {0x00009af0, 0x0000b788, 0x0000b788, 0x00009384, 0x00009384, 0x00009384},
+       {0x00009af4, 0x0000b78c, 0x0000b78c, 0x00009388, 0x00009388, 0x00009388},
+       {0x00009af8, 0x0000b790, 0x0000b790, 0x00009324, 0x00009324, 0x00009324},
+       {0x00009afc, 0x0000b794, 0x0000b794, 0x00009704, 0x00009704, 0x00009704},
+       {0x00009b00, 0x0000b798, 0x0000b798, 0x000096a4, 0x000096a4, 0x000096a4},
+       {0x00009b04, 0x0000d784, 0x0000d784, 0x000096a8, 0x000096a8, 0x000096a8},
+       {0x00009b08, 0x0000d788, 0x0000d788, 0x00009710, 0x00009710, 0x00009710},
+       {0x00009b0c, 0x0000d78c, 0x0000d78c, 0x00009714, 0x00009714, 0x00009714},
+       {0x00009b10, 0x0000d790, 0x0000d790, 0x00009720, 0x00009720, 0x00009720},
+       {0x00009b14, 0x0000f780, 0x0000f780, 0x00009724, 0x00009724, 0x00009724},
+       {0x00009b18, 0x0000f784, 0x0000f784, 0x00009728, 0x00009728, 0x00009728},
+       {0x00009b1c, 0x0000f788, 0x0000f788, 0x0000972c, 0x0000972c, 0x0000972c},
+       {0x00009b20, 0x0000f78c, 0x0000f78c, 0x000097a0, 0x000097a0, 0x000097a0},
+       {0x00009b24, 0x0000f790, 0x0000f790, 0x000097a4, 0x000097a4, 0x000097a4},
+       {0x00009b28, 0x0000f794, 0x0000f794, 0x000097a8, 0x000097a8, 0x000097a8},
+       {0x00009b2c, 0x0000f7a4, 0x0000f7a4, 0x000097b0, 0x000097b0, 0x000097b0},
+       {0x00009b30, 0x0000f7a8, 0x0000f7a8, 0x000097b4, 0x000097b4, 0x000097b4},
+       {0x00009b34, 0x0000f7ac, 0x0000f7ac, 0x000097b8, 0x000097b8, 0x000097b8},
+       {0x00009b38, 0x0000f7b0, 0x0000f7b0, 0x000097a5, 0x000097a5, 0x000097a5},
+       {0x00009b3c, 0x0000f7b4, 0x0000f7b4, 0x000097a9, 0x000097a9, 0x000097a9},
+       {0x00009b40, 0x0000f7a1, 0x0000f7a1, 0x000097ad, 0x000097ad, 0x000097ad},
+       {0x00009b44, 0x0000f7a5, 0x0000f7a5, 0x000097b1, 0x000097b1, 0x000097b1},
+       {0x00009b48, 0x0000f7a9, 0x0000f7a9, 0x000097b5, 0x000097b5, 0x000097b5},
+       {0x00009b4c, 0x0000f7ad, 0x0000f7ad, 0x000097b9, 0x000097b9, 0x000097b9},
+       {0x00009b50, 0x0000f7b1, 0x0000f7b1, 0x000097c5, 0x000097c5, 0x000097c5},
+       {0x00009b54, 0x0000f7b5, 0x0000f7b5, 0x000097c9, 0x000097c9, 0x000097c9},
+       {0x00009b58, 0x0000f7c5, 0x0000f7c5, 0x000097d1, 0x000097d1, 0x000097d1},
+       {0x00009b5c, 0x0000f7c9, 0x0000f7c9, 0x000097d5, 0x000097d5, 0x000097d5},
+       {0x00009b60, 0x0000f7cd, 0x0000f7cd, 0x000097d9, 0x000097d9, 0x000097d9},
+       {0x00009b64, 0x0000f7d1, 0x0000f7d1, 0x000097c6, 0x000097c6, 0x000097c6},
+       {0x00009b68, 0x0000f7d5, 0x0000f7d5, 0x000097ca, 0x000097ca, 0x000097ca},
+       {0x00009b6c, 0x0000f7c2, 0x0000f7c2, 0x000097ce, 0x000097ce, 0x000097ce},
+       {0x00009b70, 0x0000f7c6, 0x0000f7c6, 0x000097d2, 0x000097d2, 0x000097d2},
+       {0x00009b74, 0x0000f7ca, 0x0000f7ca, 0x000097d6, 0x000097d6, 0x000097d6},
+       {0x00009b78, 0x0000f7ce, 0x0000f7ce, 0x000097c3, 0x000097c3, 0x000097c3},
+       {0x00009b7c, 0x0000f7d2, 0x0000f7d2, 0x000097c7, 0x000097c7, 0x000097c7},
+       {0x00009b80, 0x0000f7d6, 0x0000f7d6, 0x000097cb, 0x000097cb, 0x000097cb},
+       {0x00009b84, 0x0000f7c3, 0x0000f7c3, 0x000097cf, 0x000097cf, 0x000097cf},
+       {0x00009b88, 0x0000f7c7, 0x0000f7c7, 0x000097d7, 0x000097d7, 0x000097d7},
+       {0x00009b8c, 0x0000f7cb, 0x0000f7cb, 0x000097db, 0x000097db, 0x000097db},
+       {0x00009b90, 0x0000f7d3, 0x0000f7d3, 0x000097db, 0x000097db, 0x000097db},
+       {0x00009b94, 0x0000f7d7, 0x0000f7d7, 0x000097db, 0x000097db, 0x000097db},
+       {0x00009b98, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db},
+       {0x00009b9c, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db},
+       {0x00009ba0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db},
+       {0x00009ba4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db},
+       {0x00009ba8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db},
+       {0x00009bac, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db},
+       {0x00009bb0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db},
+       {0x00009bb4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db},
+       {0x00009bb8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db},
+       {0x00009bbc, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db},
+       {0x00009bc0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db},
+       {0x00009bc4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db},
+       {0x00009bc8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db},
+       {0x00009bcc, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db},
+       {0x00009bd0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db},
+       {0x00009bd4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db},
+       {0x00009bd8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db},
+       {0x00009bdc, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db},
+       {0x00009be0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db},
+       {0x00009be4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db},
+       {0x00009be8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db},
+       {0x00009bec, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db},
+       {0x00009bf0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db},
+       {0x00009bf4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db},
+       {0x00009bf8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db},
+       {0x00009bfc, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db},
+       {0x00009848, 0x00001066, 0x00001066, 0x00001063, 0x00001063, 0x00001063},
+       {0x0000a848, 0x00001066, 0x00001066, 0x00001063, 0x00001063, 0x00001063},
+};
+
+static const u32 ar9280Modes_backoff_13db_rxgain_9280_2[][6] = {
+       {0x00009a00, 0x00008184, 0x00008184, 0x00000290, 0x00000290, 0x00000290},
+       {0x00009a04, 0x00008188, 0x00008188, 0x00000300, 0x00000300, 0x00000300},
+       {0x00009a08, 0x0000818c, 0x0000818c, 0x00000304, 0x00000304, 0x00000304},
+       {0x00009a0c, 0x00008190, 0x00008190, 0x00000308, 0x00000308, 0x00000308},
+       {0x00009a10, 0x00008194, 0x00008194, 0x0000030c, 0x0000030c, 0x0000030c},
+       {0x00009a14, 0x00008200, 0x00008200, 0x00008000, 0x00008000, 0x00008000},
+       {0x00009a18, 0x00008204, 0x00008204, 0x00008004, 0x00008004, 0x00008004},
+       {0x00009a1c, 0x00008208, 0x00008208, 0x00008008, 0x00008008, 0x00008008},
+       {0x00009a20, 0x0000820c, 0x0000820c, 0x0000800c, 0x0000800c, 0x0000800c},
+       {0x00009a24, 0x00008210, 0x00008210, 0x00008080, 0x00008080, 0x00008080},
+       {0x00009a28, 0x00008214, 0x00008214, 0x00008084, 0x00008084, 0x00008084},
+       {0x00009a2c, 0x00008280, 0x00008280, 0x00008088, 0x00008088, 0x00008088},
+       {0x00009a30, 0x00008284, 0x00008284, 0x0000808c, 0x0000808c, 0x0000808c},
+       {0x00009a34, 0x00008288, 0x00008288, 0x00008100, 0x00008100, 0x00008100},
+       {0x00009a38, 0x0000828c, 0x0000828c, 0x00008104, 0x00008104, 0x00008104},
+       {0x00009a3c, 0x00008290, 0x00008290, 0x00008108, 0x00008108, 0x00008108},
+       {0x00009a40, 0x00008300, 0x00008300, 0x0000810c, 0x0000810c, 0x0000810c},
+       {0x00009a44, 0x00008304, 0x00008304, 0x00008110, 0x00008110, 0x00008110},
+       {0x00009a48, 0x00008308, 0x00008308, 0x00008114, 0x00008114, 0x00008114},
+       {0x00009a4c, 0x0000830c, 0x0000830c, 0x00008180, 0x00008180, 0x00008180},
+       {0x00009a50, 0x00008310, 0x00008310, 0x00008184, 0x00008184, 0x00008184},
+       {0x00009a54, 0x00008314, 0x00008314, 0x00008188, 0x00008188, 0x00008188},
+       {0x00009a58, 0x00008380, 0x00008380, 0x0000818c, 0x0000818c, 0x0000818c},
+       {0x00009a5c, 0x00008384, 0x00008384, 0x00008190, 0x00008190, 0x00008190},
+       {0x00009a60, 0x00008388, 0x00008388, 0x00008194, 0x00008194, 0x00008194},
+       {0x00009a64, 0x0000838c, 0x0000838c, 0x000081a0, 0x000081a0, 0x000081a0},
+       {0x00009a68, 0x00008390, 0x00008390, 0x0000820c, 0x0000820c, 0x0000820c},
+       {0x00009a6c, 0x00008394, 0x00008394, 0x000081a8, 0x000081a8, 0x000081a8},
+       {0x00009a70, 0x0000a380, 0x0000a380, 0x00008284, 0x00008284, 0x00008284},
+       {0x00009a74, 0x0000a384, 0x0000a384, 0x00008288, 0x00008288, 0x00008288},
+       {0x00009a78, 0x0000a388, 0x0000a388, 0x00008224, 0x00008224, 0x00008224},
+       {0x00009a7c, 0x0000a38c, 0x0000a38c, 0x00008290, 0x00008290, 0x00008290},
+       {0x00009a80, 0x0000a390, 0x0000a390, 0x00008300, 0x00008300, 0x00008300},
+       {0x00009a84, 0x0000a394, 0x0000a394, 0x00008304, 0x00008304, 0x00008304},
+       {0x00009a88, 0x0000a780, 0x0000a780, 0x00008308, 0x00008308, 0x00008308},
+       {0x00009a8c, 0x0000a784, 0x0000a784, 0x0000830c, 0x0000830c, 0x0000830c},
+       {0x00009a90, 0x0000a788, 0x0000a788, 0x00008380, 0x00008380, 0x00008380},
+       {0x00009a94, 0x0000a78c, 0x0000a78c, 0x00008384, 0x00008384, 0x00008384},
+       {0x00009a98, 0x0000a790, 0x0000a790, 0x00008700, 0x00008700, 0x00008700},
+       {0x00009a9c, 0x0000a794, 0x0000a794, 0x00008704, 0x00008704, 0x00008704},
+       {0x00009aa0, 0x0000ab84, 0x0000ab84, 0x00008708, 0x00008708, 0x00008708},
+       {0x00009aa4, 0x0000ab88, 0x0000ab88, 0x0000870c, 0x0000870c, 0x0000870c},
+       {0x00009aa8, 0x0000ab8c, 0x0000ab8c, 0x00008780, 0x00008780, 0x00008780},
+       {0x00009aac, 0x0000ab90, 0x0000ab90, 0x00008784, 0x00008784, 0x00008784},
+       {0x00009ab0, 0x0000ab94, 0x0000ab94, 0x00008b00, 0x00008b00, 0x00008b00},
+       {0x00009ab4, 0x0000af80, 0x0000af80, 0x00008b04, 0x00008b04, 0x00008b04},
+       {0x00009ab8, 0x0000af84, 0x0000af84, 0x00008b08, 0x00008b08, 0x00008b08},
+       {0x00009abc, 0x0000af88, 0x0000af88, 0x00008b0c, 0x00008b0c, 0x00008b0c},
+       {0x00009ac0, 0x0000af8c, 0x0000af8c, 0x00008b80, 0x00008b80, 0x00008b80},
+       {0x00009ac4, 0x0000af90, 0x0000af90, 0x00008b84, 0x00008b84, 0x00008b84},
+       {0x00009ac8, 0x0000af94, 0x0000af94, 0x00008b88, 0x00008b88, 0x00008b88},
+       {0x00009acc, 0x0000b380, 0x0000b380, 0x00008b8c, 0x00008b8c, 0x00008b8c},
+       {0x00009ad0, 0x0000b384, 0x0000b384, 0x00008b90, 0x00008b90, 0x00008b90},
+       {0x00009ad4, 0x0000b388, 0x0000b388, 0x00008f80, 0x00008f80, 0x00008f80},
+       {0x00009ad8, 0x0000b38c, 0x0000b38c, 0x00008f84, 0x00008f84, 0x00008f84},
+       {0x00009adc, 0x0000b390, 0x0000b390, 0x00008f88, 0x00008f88, 0x00008f88},
+       {0x00009ae0, 0x0000b394, 0x0000b394, 0x00008f8c, 0x00008f8c, 0x00008f8c},
+       {0x00009ae4, 0x0000b398, 0x0000b398, 0x00008f90, 0x00008f90, 0x00008f90},
+       {0x00009ae8, 0x0000b780, 0x0000b780, 0x00009310, 0x00009310, 0x00009310},
+       {0x00009aec, 0x0000b784, 0x0000b784, 0x00009314, 0x00009314, 0x00009314},
+       {0x00009af0, 0x0000b788, 0x0000b788, 0x00009320, 0x00009320, 0x00009320},
+       {0x00009af4, 0x0000b78c, 0x0000b78c, 0x00009324, 0x00009324, 0x00009324},
+       {0x00009af8, 0x0000b790, 0x0000b790, 0x00009328, 0x00009328, 0x00009328},
+       {0x00009afc, 0x0000b794, 0x0000b794, 0x0000932c, 0x0000932c, 0x0000932c},
+       {0x00009b00, 0x0000b798, 0x0000b798, 0x00009330, 0x00009330, 0x00009330},
+       {0x00009b04, 0x0000d784, 0x0000d784, 0x00009334, 0x00009334, 0x00009334},
+       {0x00009b08, 0x0000d788, 0x0000d788, 0x00009321, 0x00009321, 0x00009321},
+       {0x00009b0c, 0x0000d78c, 0x0000d78c, 0x00009325, 0x00009325, 0x00009325},
+       {0x00009b10, 0x0000d790, 0x0000d790, 0x00009329, 0x00009329, 0x00009329},
+       {0x00009b14, 0x0000f780, 0x0000f780, 0x0000932d, 0x0000932d, 0x0000932d},
+       {0x00009b18, 0x0000f784, 0x0000f784, 0x00009331, 0x00009331, 0x00009331},
+       {0x00009b1c, 0x0000f788, 0x0000f788, 0x00009335, 0x00009335, 0x00009335},
+       {0x00009b20, 0x0000f78c, 0x0000f78c, 0x00009322, 0x00009322, 0x00009322},
+       {0x00009b24, 0x0000f790, 0x0000f790, 0x00009326, 0x00009326, 0x00009326},
+       {0x00009b28, 0x0000f794, 0x0000f794, 0x0000932a, 0x0000932a, 0x0000932a},
+       {0x00009b2c, 0x0000f7a4, 0x0000f7a4, 0x0000932e, 0x0000932e, 0x0000932e},
+       {0x00009b30, 0x0000f7a8, 0x0000f7a8, 0x00009332, 0x00009332, 0x00009332},
+       {0x00009b34, 0x0000f7ac, 0x0000f7ac, 0x00009336, 0x00009336, 0x00009336},
+       {0x00009b38, 0x0000f7b0, 0x0000f7b0, 0x00009323, 0x00009323, 0x00009323},
+       {0x00009b3c, 0x0000f7b4, 0x0000f7b4, 0x00009327, 0x00009327, 0x00009327},
+       {0x00009b40, 0x0000f7a1, 0x0000f7a1, 0x0000932b, 0x0000932b, 0x0000932b},
+       {0x00009b44, 0x0000f7a5, 0x0000f7a5, 0x0000932f, 0x0000932f, 0x0000932f},
+       {0x00009b48, 0x0000f7a9, 0x0000f7a9, 0x00009333, 0x00009333, 0x00009333},
+       {0x00009b4c, 0x0000f7ad, 0x0000f7ad, 0x00009337, 0x00009337, 0x00009337},
+       {0x00009b50, 0x0000f7b1, 0x0000f7b1, 0x00009343, 0x00009343, 0x00009343},
+       {0x00009b54, 0x0000f7b5, 0x0000f7b5, 0x00009347, 0x00009347, 0x00009347},
+       {0x00009b58, 0x0000f7c5, 0x0000f7c5, 0x0000934b, 0x0000934b, 0x0000934b},
+       {0x00009b5c, 0x0000f7c9, 0x0000f7c9, 0x0000934f, 0x0000934f, 0x0000934f},
+       {0x00009b60, 0x0000f7cd, 0x0000f7cd, 0x00009353, 0x00009353, 0x00009353},
+       {0x00009b64, 0x0000f7d1, 0x0000f7d1, 0x00009357, 0x00009357, 0x00009357},
+       {0x00009b68, 0x0000f7d5, 0x0000f7d5, 0x0000935b, 0x0000935b, 0x0000935b},
+       {0x00009b6c, 0x0000f7c2, 0x0000f7c2, 0x0000935b, 0x0000935b, 0x0000935b},
+       {0x00009b70, 0x0000f7c6, 0x0000f7c6, 0x0000935b, 0x0000935b, 0x0000935b},
+       {0x00009b74, 0x0000f7ca, 0x0000f7ca, 0x0000935b, 0x0000935b, 0x0000935b},
+       {0x00009b78, 0x0000f7ce, 0x0000f7ce, 0x0000935b, 0x0000935b, 0x0000935b},
+       {0x00009b7c, 0x0000f7d2, 0x0000f7d2, 0x0000935b, 0x0000935b, 0x0000935b},
+       {0x00009b80, 0x0000f7d6, 0x0000f7d6, 0x0000935b, 0x0000935b, 0x0000935b},
+       {0x00009b84, 0x0000f7c3, 0x0000f7c3, 0x0000935b, 0x0000935b, 0x0000935b},
+       {0x00009b88, 0x0000f7c7, 0x0000f7c7, 0x0000935b, 0x0000935b, 0x0000935b},
+       {0x00009b8c, 0x0000f7cb, 0x0000f7cb, 0x0000935b, 0x0000935b, 0x0000935b},
+       {0x00009b90, 0x0000f7d3, 0x0000f7d3, 0x0000935b, 0x0000935b, 0x0000935b},
+       {0x00009b94, 0x0000f7d7, 0x0000f7d7, 0x0000935b, 0x0000935b, 0x0000935b},
+       {0x00009b98, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b},
+       {0x00009b9c, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b},
+       {0x00009ba0, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b},
+       {0x00009ba4, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b},
+       {0x00009ba8, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b},
+       {0x00009bac, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b},
+       {0x00009bb0, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b},
+       {0x00009bb4, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b},
+       {0x00009bb8, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b},
+       {0x00009bbc, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b},
+       {0x00009bc0, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b},
+       {0x00009bc4, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b},
+       {0x00009bc8, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b},
+       {0x00009bcc, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b},
+       {0x00009bd0, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b},
+       {0x00009bd4, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b},
+       {0x00009bd8, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b},
+       {0x00009bdc, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b},
+       {0x00009be0, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b},
+       {0x00009be4, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b},
+       {0x00009be8, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b},
+       {0x00009bec, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b},
+       {0x00009bf0, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b},
+       {0x00009bf4, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b},
+       {0x00009bf8, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b},
+       {0x00009bfc, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b},
+       {0x00009848, 0x00001066, 0x00001066, 0x0000105a, 0x0000105a, 0x0000105a},
+       {0x0000a848, 0x00001066, 0x00001066, 0x0000105a, 0x0000105a, 0x0000105a},
+};
+
+static const u32 ar9280Modes_high_power_tx_gain_9280_2[][6] = {
+       {0x0000a274, 0x0a19e652, 0x0a19e652, 0x0a1aa652, 0x0a1aa652, 0x0a1aa652},
+       {0x0000a27c, 0x050739ce, 0x050739ce, 0x050739ce, 0x050739ce, 0x050739ce},
+       {0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000a304, 0x00003002, 0x00003002, 0x00004002, 0x00004002, 0x00004002},
+       {0x0000a308, 0x00006004, 0x00006004, 0x00007008, 0x00007008, 0x00007008},
+       {0x0000a30c, 0x0000a006, 0x0000a006, 0x0000c010, 0x0000c010, 0x0000c010},
+       {0x0000a310, 0x0000e012, 0x0000e012, 0x00010012, 0x00010012, 0x00010012},
+       {0x0000a314, 0x00011014, 0x00011014, 0x00013014, 0x00013014, 0x00013014},
+       {0x0000a318, 0x0001504a, 0x0001504a, 0x0001820a, 0x0001820a, 0x0001820a},
+       {0x0000a31c, 0x0001904c, 0x0001904c, 0x0001b211, 0x0001b211, 0x0001b211},
+       {0x0000a320, 0x0001c04e, 0x0001c04e, 0x0001e213, 0x0001e213, 0x0001e213},
+       {0x0000a324, 0x00021092, 0x00021092, 0x00022411, 0x00022411, 0x00022411},
+       {0x0000a328, 0x0002510a, 0x0002510a, 0x00025413, 0x00025413, 0x00025413},
+       {0x0000a32c, 0x0002910c, 0x0002910c, 0x00029811, 0x00029811, 0x00029811},
+       {0x0000a330, 0x0002c18b, 0x0002c18b, 0x0002c813, 0x0002c813, 0x0002c813},
+       {0x0000a334, 0x0002f1cc, 0x0002f1cc, 0x00030a14, 0x00030a14, 0x00030a14},
+       {0x0000a338, 0x000321eb, 0x000321eb, 0x00035a50, 0x00035a50, 0x00035a50},
+       {0x0000a33c, 0x000341ec, 0x000341ec, 0x00039c4c, 0x00039c4c, 0x00039c4c},
+       {0x0000a340, 0x000341ec, 0x000341ec, 0x0003de8a, 0x0003de8a, 0x0003de8a},
+       {0x0000a344, 0x000341ec, 0x000341ec, 0x00042e92, 0x00042e92, 0x00042e92},
+       {0x0000a348, 0x000341ec, 0x000341ec, 0x00046ed2, 0x00046ed2, 0x00046ed2},
+       {0x0000a34c, 0x000341ec, 0x000341ec, 0x0004bed5, 0x0004bed5, 0x0004bed5},
+       {0x0000a350, 0x000341ec, 0x000341ec, 0x0004ff54, 0x0004ff54, 0x0004ff54},
+       {0x0000a354, 0x000341ec, 0x000341ec, 0x00055fd5, 0x00055fd5, 0x00055fd5},
+       {0x0000a3ec, 0x00f70081, 0x00f70081, 0x00f70081, 0x00f70081, 0x00f70081},
+       {0x00007814, 0x00198eff, 0x00198eff, 0x00198eff, 0x00198eff, 0x00198eff},
+       {0x00007838, 0x00198eff, 0x00198eff, 0x00198eff, 0x00198eff, 0x00198eff},
+       {0x0000781c, 0x00172000, 0x00172000, 0x00172000, 0x00172000, 0x00172000},
+       {0x00007840, 0x00172000, 0x00172000, 0x00172000, 0x00172000, 0x00172000},
+       {0x00007820, 0xf258a480, 0xf258a480, 0xf258a480, 0xf258a480, 0xf258a480},
+       {0x00007844, 0xf258a480, 0xf258a480, 0xf258a480, 0xf258a480, 0xf258a480},
+};
+
+static const u32 ar9280Modes_original_tx_gain_9280_2[][6] = {
+       {0x0000a274, 0x0a19c652, 0x0a19c652, 0x0a1aa652, 0x0a1aa652, 0x0a1aa652},
+       {0x0000a27c, 0x050701ce, 0x050701ce, 0x050701ce, 0x050701ce, 0x050701ce},
+       {0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000a304, 0x00003002, 0x00003002, 0x00003002, 0x00003002, 0x00003002},
+       {0x0000a308, 0x00006004, 0x00006004, 0x00008009, 0x00008009, 0x00008009},
+       {0x0000a30c, 0x0000a006, 0x0000a006, 0x0000b00b, 0x0000b00b, 0x0000b00b},
+       {0x0000a310, 0x0000e012, 0x0000e012, 0x0000e012, 0x0000e012, 0x0000e012},
+       {0x0000a314, 0x00011014, 0x00011014, 0x00012048, 0x00012048, 0x00012048},
+       {0x0000a318, 0x0001504a, 0x0001504a, 0x0001604a, 0x0001604a, 0x0001604a},
+       {0x0000a31c, 0x0001904c, 0x0001904c, 0x0001a211, 0x0001a211, 0x0001a211},
+       {0x0000a320, 0x0001c04e, 0x0001c04e, 0x0001e213, 0x0001e213, 0x0001e213},
+       {0x0000a324, 0x00020092, 0x00020092, 0x0002121b, 0x0002121b, 0x0002121b},
+       {0x0000a328, 0x0002410a, 0x0002410a, 0x00024412, 0x00024412, 0x00024412},
+       {0x0000a32c, 0x0002710c, 0x0002710c, 0x00028414, 0x00028414, 0x00028414},
+       {0x0000a330, 0x0002b18b, 0x0002b18b, 0x0002b44a, 0x0002b44a, 0x0002b44a},
+       {0x0000a334, 0x0002e1cc, 0x0002e1cc, 0x00030649, 0x00030649, 0x00030649},
+       {0x0000a338, 0x000321ec, 0x000321ec, 0x0003364b, 0x0003364b, 0x0003364b},
+       {0x0000a33c, 0x000321ec, 0x000321ec, 0x00038a49, 0x00038a49, 0x00038a49},
+       {0x0000a340, 0x000321ec, 0x000321ec, 0x0003be48, 0x0003be48, 0x0003be48},
+       {0x0000a344, 0x000321ec, 0x000321ec, 0x0003ee4a, 0x0003ee4a, 0x0003ee4a},
+       {0x0000a348, 0x000321ec, 0x000321ec, 0x00042e88, 0x00042e88, 0x00042e88},
+       {0x0000a34c, 0x000321ec, 0x000321ec, 0x00046e8a, 0x00046e8a, 0x00046e8a},
+       {0x0000a350, 0x000321ec, 0x000321ec, 0x00049ec9, 0x00049ec9, 0x00049ec9},
+       {0x0000a354, 0x000321ec, 0x000321ec, 0x0004bf42, 0x0004bf42, 0x0004bf42},
+       {0x0000a3ec, 0x00f70081, 0x00f70081, 0x00f70081, 0x00f70081, 0x00f70081},
+       {0x00007814, 0x0019beff, 0x0019beff, 0x0019beff, 0x0019beff, 0x0019beff},
+       {0x00007838, 0x0019beff, 0x0019beff, 0x0019beff, 0x0019beff, 0x0019beff},
+       {0x0000781c, 0x00392000, 0x00392000, 0x00392000, 0x00392000, 0x00392000},
+       {0x00007840, 0x00392000, 0x00392000, 0x00392000, 0x00392000, 0x00392000},
+       {0x00007820, 0x92592480, 0x92592480, 0x92592480, 0x92592480, 0x92592480},
+       {0x00007844, 0x92592480, 0x92592480, 0x92592480, 0x92592480, 0x92592480},
+};
+
+static const u32 ar9280PciePhy_clkreq_off_L1_9280[][2] = {
+       /* Addr      allmodes  */
+       {0x00004040, 0x9248fd00},
+       {0x00004040, 0x24924924},
+       {0x00004040, 0xa8000019},
+       {0x00004040, 0x13160820},
+       {0x00004040, 0xe5980560},
+       {0x00004040, 0xc01dcffc},
+       {0x00004040, 0x1aaabe41},
+       {0x00004040, 0xbe105554},
+       {0x00004040, 0x00043007},
+       {0x00004044, 0x00000000},
+};
+
+static const u32 ar9280PciePhy_clkreq_always_on_L1_9280[][2] = {
+       /* Addr      allmodes  */
+       {0x00004040, 0x9248fd00},
+       {0x00004040, 0x24924924},
+       {0x00004040, 0xa8000019},
+       {0x00004040, 0x13160820},
+       {0x00004040, 0xe5980560},
+       {0x00004040, 0xc01dcffd},
+       {0x00004040, 0x1aaabe41},
+       {0x00004040, 0xbe105554},
+       {0x00004040, 0x00043007},
+       {0x00004044, 0x00000000},
+};
+
+static const u32 ar9285PciePhy_clkreq_always_on_L1_9285[][2] = {
+       /* Addr      allmodes  */
+       {0x00004040, 0x9248fd00},
+       {0x00004040, 0x24924924},
+       {0x00004040, 0xa8000019},
+       {0x00004040, 0x13160820},
+       {0x00004040, 0xe5980560},
+       {0x00004040, 0xc01dcffd},
+       {0x00004040, 0x1aaabe41},
+       {0x00004040, 0xbe105554},
+       {0x00004040, 0x00043007},
+       {0x00004044, 0x00000000},
+};
+
+static const u32 ar9285PciePhy_clkreq_off_L1_9285[][2] = {
+       /* Addr      allmodes  */
+       {0x00004040, 0x9248fd00},
+       {0x00004040, 0x24924924},
+       {0x00004040, 0xa8000019},
+       {0x00004040, 0x13160820},
+       {0x00004040, 0xe5980560},
+       {0x00004040, 0xc01dcffc},
+       {0x00004040, 0x1aaabe41},
+       {0x00004040, 0xbe105554},
+       {0x00004040, 0x00043007},
+       {0x00004044, 0x00000000},
+};
+
+static const u32 ar9285Modes_9285_1_2[][6] = {
+       {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0},
+       {0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0},
+       {0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180},
+       {0x000010f0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000008},
+       {0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00, 0x06e006e0},
+       {0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b, 0x0988004f},
+       {0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440, 0x00006880},
+       {0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303},
+       {0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200},
+       {0x00009824, 0x01000e0e, 0x01000e0e, 0x01000e0e, 0x01000e0e, 0x01000e0e},
+       {0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001},
+       {0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e},
+       {0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007},
+       {0x00009840, 0x206a012e, 0x206a012e, 0x206a012e, 0x206a012e, 0x206a012e},
+       {0x00009844, 0x0372161e, 0x0372161e, 0x03721620, 0x03721620, 0x037216a0},
+       {0x00009848, 0x00001066, 0x00001066, 0x00001053, 0x00001053, 0x00001059},
+       {0x0000a848, 0x00001066, 0x00001066, 0x00001053, 0x00001053, 0x00001059},
+       {0x00009850, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2},
+       {0x00009858, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e},
+       {0x0000985c, 0x3139605e, 0x3139605e, 0x3137605e, 0x3137605e, 0x3139605e},
+       {0x00009860, 0x00058d18, 0x00058d18, 0x00058d20, 0x00058d20, 0x00058d18},
+       {0x00009864, 0x0000fe00, 0x0000fe00, 0x0001ce00, 0x0001ce00, 0x0001ce00},
+       {0x00009868, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0},
+       {0x0000986c, 0x06903081, 0x06903081, 0x06903881, 0x06903881, 0x06903881},
+       {0x00009914, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898, 0x000007d0},
+       {0x00009918, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b, 0x00000016},
+       {0x00009924, 0xd00a8007, 0xd00a8007, 0xd00a800d, 0xd00a800d, 0xd00a800d},
+       {0x00009944, 0xffbc1010, 0xffbc1010, 0xffbc1020, 0xffbc1020, 0xffbc1010},
+       {0x00009960, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x00009964, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x000099b8, 0x0000421c, 0x0000421c, 0x0000421c, 0x0000421c, 0x0000421c},
+       {0x000099bc, 0x00000600, 0x00000600, 0x00000c00, 0x00000c00, 0x00000c00},
+       {0x000099c0, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4},
+       {0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77},
+       {0x000099c8, 0x6af6532f, 0x6af6532f, 0x6af6532f, 0x6af6532f, 0x6af6532f},
+       {0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8},
+       {0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, 0x00046384},
+       {0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x00009a00, 0x00000000, 0x00000000, 0x00058084, 0x00058084, 0x00000000},
+       {0x00009a04, 0x00000000, 0x00000000, 0x00058088, 0x00058088, 0x00000000},
+       {0x00009a08, 0x00000000, 0x00000000, 0x0005808c, 0x0005808c, 0x00000000},
+       {0x00009a0c, 0x00000000, 0x00000000, 0x00058100, 0x00058100, 0x00000000},
+       {0x00009a10, 0x00000000, 0x00000000, 0x00058104, 0x00058104, 0x00000000},
+       {0x00009a14, 0x00000000, 0x00000000, 0x00058108, 0x00058108, 0x00000000},
+       {0x00009a18, 0x00000000, 0x00000000, 0x0005810c, 0x0005810c, 0x00000000},
+       {0x00009a1c, 0x00000000, 0x00000000, 0x00058110, 0x00058110, 0x00000000},
+       {0x00009a20, 0x00000000, 0x00000000, 0x00058114, 0x00058114, 0x00000000},
+       {0x00009a24, 0x00000000, 0x00000000, 0x00058180, 0x00058180, 0x00000000},
+       {0x00009a28, 0x00000000, 0x00000000, 0x00058184, 0x00058184, 0x00000000},
+       {0x00009a2c, 0x00000000, 0x00000000, 0x00058188, 0x00058188, 0x00000000},
+       {0x00009a30, 0x00000000, 0x00000000, 0x0005818c, 0x0005818c, 0x00000000},
+       {0x00009a34, 0x00000000, 0x00000000, 0x00058190, 0x00058190, 0x00000000},
+       {0x00009a38, 0x00000000, 0x00000000, 0x00058194, 0x00058194, 0x00000000},
+       {0x00009a3c, 0x00000000, 0x00000000, 0x000581a0, 0x000581a0, 0x00000000},
+       {0x00009a40, 0x00000000, 0x00000000, 0x0005820c, 0x0005820c, 0x00000000},
+       {0x00009a44, 0x00000000, 0x00000000, 0x000581a8, 0x000581a8, 0x00000000},
+       {0x00009a48, 0x00000000, 0x00000000, 0x00058284, 0x00058284, 0x00000000},
+       {0x00009a4c, 0x00000000, 0x00000000, 0x00058288, 0x00058288, 0x00000000},
+       {0x00009a50, 0x00000000, 0x00000000, 0x00058224, 0x00058224, 0x00000000},
+       {0x00009a54, 0x00000000, 0x00000000, 0x00058290, 0x00058290, 0x00000000},
+       {0x00009a58, 0x00000000, 0x00000000, 0x00058300, 0x00058300, 0x00000000},
+       {0x00009a5c, 0x00000000, 0x00000000, 0x00058304, 0x00058304, 0x00000000},
+       {0x00009a60, 0x00000000, 0x00000000, 0x00058308, 0x00058308, 0x00000000},
+       {0x00009a64, 0x00000000, 0x00000000, 0x0005830c, 0x0005830c, 0x00000000},
+       {0x00009a68, 0x00000000, 0x00000000, 0x00058380, 0x00058380, 0x00000000},
+       {0x00009a6c, 0x00000000, 0x00000000, 0x00058384, 0x00058384, 0x00000000},
+       {0x00009a70, 0x00000000, 0x00000000, 0x00068700, 0x00068700, 0x00000000},
+       {0x00009a74, 0x00000000, 0x00000000, 0x00068704, 0x00068704, 0x00000000},
+       {0x00009a78, 0x00000000, 0x00000000, 0x00068708, 0x00068708, 0x00000000},
+       {0x00009a7c, 0x00000000, 0x00000000, 0x0006870c, 0x0006870c, 0x00000000},
+       {0x00009a80, 0x00000000, 0x00000000, 0x00068780, 0x00068780, 0x00000000},
+       {0x00009a84, 0x00000000, 0x00000000, 0x00068784, 0x00068784, 0x00000000},
+       {0x00009a88, 0x00000000, 0x00000000, 0x00078b00, 0x00078b00, 0x00000000},
+       {0x00009a8c, 0x00000000, 0x00000000, 0x00078b04, 0x00078b04, 0x00000000},
+       {0x00009a90, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000},
+       {0x00009a94, 0x00000000, 0x00000000, 0x00078b0c, 0x00078b0c, 0x00000000},
+       {0x00009a98, 0x00000000, 0x00000000, 0x00078b80, 0x00078b80, 0x00000000},
+       {0x00009a9c, 0x00000000, 0x00000000, 0x00078b84, 0x00078b84, 0x00000000},
+       {0x00009aa0, 0x00000000, 0x00000000, 0x00078b88, 0x00078b88, 0x00000000},
+       {0x00009aa4, 0x00000000, 0x00000000, 0x00078b8c, 0x00078b8c, 0x00000000},
+       {0x00009aa8, 0x00000000, 0x00000000, 0x00078b90, 0x00078b90, 0x00000000},
+       {0x00009aac, 0x00000000, 0x00000000, 0x000caf80, 0x000caf80, 0x00000000},
+       {0x00009ab0, 0x00000000, 0x00000000, 0x000caf84, 0x000caf84, 0x00000000},
+       {0x00009ab4, 0x00000000, 0x00000000, 0x000caf88, 0x000caf88, 0x00000000},
+       {0x00009ab8, 0x00000000, 0x00000000, 0x000caf8c, 0x000caf8c, 0x00000000},
+       {0x00009abc, 0x00000000, 0x00000000, 0x000caf90, 0x000caf90, 0x00000000},
+       {0x00009ac0, 0x00000000, 0x00000000, 0x000db30c, 0x000db30c, 0x00000000},
+       {0x00009ac4, 0x00000000, 0x00000000, 0x000db310, 0x000db310, 0x00000000},
+       {0x00009ac8, 0x00000000, 0x00000000, 0x000db384, 0x000db384, 0x00000000},
+       {0x00009acc, 0x00000000, 0x00000000, 0x000db388, 0x000db388, 0x00000000},
+       {0x00009ad0, 0x00000000, 0x00000000, 0x000db324, 0x000db324, 0x00000000},
+       {0x00009ad4, 0x00000000, 0x00000000, 0x000eb704, 0x000eb704, 0x00000000},
+       {0x00009ad8, 0x00000000, 0x00000000, 0x000eb6a4, 0x000eb6a4, 0x00000000},
+       {0x00009adc, 0x00000000, 0x00000000, 0x000eb6a8, 0x000eb6a8, 0x00000000},
+       {0x00009ae0, 0x00000000, 0x00000000, 0x000eb710, 0x000eb710, 0x00000000},
+       {0x00009ae4, 0x00000000, 0x00000000, 0x000eb714, 0x000eb714, 0x00000000},
+       {0x00009ae8, 0x00000000, 0x00000000, 0x000eb720, 0x000eb720, 0x00000000},
+       {0x00009aec, 0x00000000, 0x00000000, 0x000eb724, 0x000eb724, 0x00000000},
+       {0x00009af0, 0x00000000, 0x00000000, 0x000eb728, 0x000eb728, 0x00000000},
+       {0x00009af4, 0x00000000, 0x00000000, 0x000eb72c, 0x000eb72c, 0x00000000},
+       {0x00009af8, 0x00000000, 0x00000000, 0x000eb7a0, 0x000eb7a0, 0x00000000},
+       {0x00009afc, 0x00000000, 0x00000000, 0x000eb7a4, 0x000eb7a4, 0x00000000},
+       {0x00009b00, 0x00000000, 0x00000000, 0x000eb7a8, 0x000eb7a8, 0x00000000},
+       {0x00009b04, 0x00000000, 0x00000000, 0x000eb7b0, 0x000eb7b0, 0x00000000},
+       {0x00009b08, 0x00000000, 0x00000000, 0x000eb7b4, 0x000eb7b4, 0x00000000},
+       {0x00009b0c, 0x00000000, 0x00000000, 0x000eb7b8, 0x000eb7b8, 0x00000000},
+       {0x00009b10, 0x00000000, 0x00000000, 0x000eb7a5, 0x000eb7a5, 0x00000000},
+       {0x00009b14, 0x00000000, 0x00000000, 0x000eb7a9, 0x000eb7a9, 0x00000000},
+       {0x00009b18, 0x00000000, 0x00000000, 0x000eb7ad, 0x000eb7ad, 0x00000000},
+       {0x00009b1c, 0x00000000, 0x00000000, 0x000eb7b1, 0x000eb7b1, 0x00000000},
+       {0x00009b20, 0x00000000, 0x00000000, 0x000eb7b5, 0x000eb7b5, 0x00000000},
+       {0x00009b24, 0x00000000, 0x00000000, 0x000eb7b9, 0x000eb7b9, 0x00000000},
+       {0x00009b28, 0x00000000, 0x00000000, 0x000eb7c5, 0x000eb7c5, 0x00000000},
+       {0x00009b2c, 0x00000000, 0x00000000, 0x000eb7c9, 0x000eb7c9, 0x00000000},
+       {0x00009b30, 0x00000000, 0x00000000, 0x000eb7d1, 0x000eb7d1, 0x00000000},
+       {0x00009b34, 0x00000000, 0x00000000, 0x000eb7d5, 0x000eb7d5, 0x00000000},
+       {0x00009b38, 0x00000000, 0x00000000, 0x000eb7d9, 0x000eb7d9, 0x00000000},
+       {0x00009b3c, 0x00000000, 0x00000000, 0x000eb7c6, 0x000eb7c6, 0x00000000},
+       {0x00009b40, 0x00000000, 0x00000000, 0x000eb7ca, 0x000eb7ca, 0x00000000},
+       {0x00009b44, 0x00000000, 0x00000000, 0x000eb7ce, 0x000eb7ce, 0x00000000},
+       {0x00009b48, 0x00000000, 0x00000000, 0x000eb7d2, 0x000eb7d2, 0x00000000},
+       {0x00009b4c, 0x00000000, 0x00000000, 0x000eb7d6, 0x000eb7d6, 0x00000000},
+       {0x00009b50, 0x00000000, 0x00000000, 0x000eb7c3, 0x000eb7c3, 0x00000000},
+       {0x00009b54, 0x00000000, 0x00000000, 0x000eb7c7, 0x000eb7c7, 0x00000000},
+       {0x00009b58, 0x00000000, 0x00000000, 0x000eb7cb, 0x000eb7cb, 0x00000000},
+       {0x00009b5c, 0x00000000, 0x00000000, 0x000eb7cf, 0x000eb7cf, 0x00000000},
+       {0x00009b60, 0x00000000, 0x00000000, 0x000eb7d7, 0x000eb7d7, 0x00000000},
+       {0x00009b64, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x00009b68, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x00009b6c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x00009b70, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x00009b74, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x00009b78, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x00009b7c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x00009b80, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x00009b84, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x00009b88, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x00009b8c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x00009b90, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x00009b94, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x00009b98, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x00009b9c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x00009ba0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x00009ba4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x00009ba8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x00009bac, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x00009bb0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x00009bb4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x00009bb8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x00009bbc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x00009bc0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x00009bc4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x00009bc8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x00009bcc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x00009bd0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x00009bd4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x00009bd8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x00009bdc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x00009be0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x00009be4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x00009be8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x00009bec, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x00009bf0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x00009bf4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x00009bf8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x00009bfc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x0000aa00, 0x00000000, 0x00000000, 0x00058084, 0x00058084, 0x00000000},
+       {0x0000aa04, 0x00000000, 0x00000000, 0x00058088, 0x00058088, 0x00000000},
+       {0x0000aa08, 0x00000000, 0x00000000, 0x0005808c, 0x0005808c, 0x00000000},
+       {0x0000aa0c, 0x00000000, 0x00000000, 0x00058100, 0x00058100, 0x00000000},
+       {0x0000aa10, 0x00000000, 0x00000000, 0x00058104, 0x00058104, 0x00000000},
+       {0x0000aa14, 0x00000000, 0x00000000, 0x00058108, 0x00058108, 0x00000000},
+       {0x0000aa18, 0x00000000, 0x00000000, 0x0005810c, 0x0005810c, 0x00000000},
+       {0x0000aa1c, 0x00000000, 0x00000000, 0x00058110, 0x00058110, 0x00000000},
+       {0x0000aa20, 0x00000000, 0x00000000, 0x00058114, 0x00058114, 0x00000000},
+       {0x0000aa24, 0x00000000, 0x00000000, 0x00058180, 0x00058180, 0x00000000},
+       {0x0000aa28, 0x00000000, 0x00000000, 0x00058184, 0x00058184, 0x00000000},
+       {0x0000aa2c, 0x00000000, 0x00000000, 0x00058188, 0x00058188, 0x00000000},
+       {0x0000aa30, 0x00000000, 0x00000000, 0x0005818c, 0x0005818c, 0x00000000},
+       {0x0000aa34, 0x00000000, 0x00000000, 0x00058190, 0x00058190, 0x00000000},
+       {0x0000aa38, 0x00000000, 0x00000000, 0x00058194, 0x00058194, 0x00000000},
+       {0x0000aa3c, 0x00000000, 0x00000000, 0x000581a0, 0x000581a0, 0x00000000},
+       {0x0000aa40, 0x00000000, 0x00000000, 0x0005820c, 0x0005820c, 0x00000000},
+       {0x0000aa44, 0x00000000, 0x00000000, 0x000581a8, 0x000581a8, 0x00000000},
+       {0x0000aa48, 0x00000000, 0x00000000, 0x00058284, 0x00058284, 0x00000000},
+       {0x0000aa4c, 0x00000000, 0x00000000, 0x00058288, 0x00058288, 0x00000000},
+       {0x0000aa50, 0x00000000, 0x00000000, 0x00058224, 0x00058224, 0x00000000},
+       {0x0000aa54, 0x00000000, 0x00000000, 0x00058290, 0x00058290, 0x00000000},
+       {0x0000aa58, 0x00000000, 0x00000000, 0x00058300, 0x00058300, 0x00000000},
+       {0x0000aa5c, 0x00000000, 0x00000000, 0x00058304, 0x00058304, 0x00000000},
+       {0x0000aa60, 0x00000000, 0x00000000, 0x00058308, 0x00058308, 0x00000000},
+       {0x0000aa64, 0x00000000, 0x00000000, 0x0005830c, 0x0005830c, 0x00000000},
+       {0x0000aa68, 0x00000000, 0x00000000, 0x00058380, 0x00058380, 0x00000000},
+       {0x0000aa6c, 0x00000000, 0x00000000, 0x00058384, 0x00058384, 0x00000000},
+       {0x0000aa70, 0x00000000, 0x00000000, 0x00068700, 0x00068700, 0x00000000},
+       {0x0000aa74, 0x00000000, 0x00000000, 0x00068704, 0x00068704, 0x00000000},
+       {0x0000aa78, 0x00000000, 0x00000000, 0x00068708, 0x00068708, 0x00000000},
+       {0x0000aa7c, 0x00000000, 0x00000000, 0x0006870c, 0x0006870c, 0x00000000},
+       {0x0000aa80, 0x00000000, 0x00000000, 0x00068780, 0x00068780, 0x00000000},
+       {0x0000aa84, 0x00000000, 0x00000000, 0x00068784, 0x00068784, 0x00000000},
+       {0x0000aa88, 0x00000000, 0x00000000, 0x00078b00, 0x00078b00, 0x00000000},
+       {0x0000aa8c, 0x00000000, 0x00000000, 0x00078b04, 0x00078b04, 0x00000000},
+       {0x0000aa90, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000},
+       {0x0000aa94, 0x00000000, 0x00000000, 0x00078b0c, 0x00078b0c, 0x00000000},
+       {0x0000aa98, 0x00000000, 0x00000000, 0x00078b80, 0x00078b80, 0x00000000},
+       {0x0000aa9c, 0x00000000, 0x00000000, 0x00078b84, 0x00078b84, 0x00000000},
+       {0x0000aaa0, 0x00000000, 0x00000000, 0x00078b88, 0x00078b88, 0x00000000},
+       {0x0000aaa4, 0x00000000, 0x00000000, 0x00078b8c, 0x00078b8c, 0x00000000},
+       {0x0000aaa8, 0x00000000, 0x00000000, 0x00078b90, 0x00078b90, 0x00000000},
+       {0x0000aaac, 0x00000000, 0x00000000, 0x000caf80, 0x000caf80, 0x00000000},
+       {0x0000aab0, 0x00000000, 0x00000000, 0x000caf84, 0x000caf84, 0x00000000},
+       {0x0000aab4, 0x00000000, 0x00000000, 0x000caf88, 0x000caf88, 0x00000000},
+       {0x0000aab8, 0x00000000, 0x00000000, 0x000caf8c, 0x000caf8c, 0x00000000},
+       {0x0000aabc, 0x00000000, 0x00000000, 0x000caf90, 0x000caf90, 0x00000000},
+       {0x0000aac0, 0x00000000, 0x00000000, 0x000db30c, 0x000db30c, 0x00000000},
+       {0x0000aac4, 0x00000000, 0x00000000, 0x000db310, 0x000db310, 0x00000000},
+       {0x0000aac8, 0x00000000, 0x00000000, 0x000db384, 0x000db384, 0x00000000},
+       {0x0000aacc, 0x00000000, 0x00000000, 0x000db388, 0x000db388, 0x00000000},
+       {0x0000aad0, 0x00000000, 0x00000000, 0x000db324, 0x000db324, 0x00000000},
+       {0x0000aad4, 0x00000000, 0x00000000, 0x000eb704, 0x000eb704, 0x00000000},
+       {0x0000aad8, 0x00000000, 0x00000000, 0x000eb6a4, 0x000eb6a4, 0x00000000},
+       {0x0000aadc, 0x00000000, 0x00000000, 0x000eb6a8, 0x000eb6a8, 0x00000000},
+       {0x0000aae0, 0x00000000, 0x00000000, 0x000eb710, 0x000eb710, 0x00000000},
+       {0x0000aae4, 0x00000000, 0x00000000, 0x000eb714, 0x000eb714, 0x00000000},
+       {0x0000aae8, 0x00000000, 0x00000000, 0x000eb720, 0x000eb720, 0x00000000},
+       {0x0000aaec, 0x00000000, 0x00000000, 0x000eb724, 0x000eb724, 0x00000000},
+       {0x0000aaf0, 0x00000000, 0x00000000, 0x000eb728, 0x000eb728, 0x00000000},
+       {0x0000aaf4, 0x00000000, 0x00000000, 0x000eb72c, 0x000eb72c, 0x00000000},
+       {0x0000aaf8, 0x00000000, 0x00000000, 0x000eb7a0, 0x000eb7a0, 0x00000000},
+       {0x0000aafc, 0x00000000, 0x00000000, 0x000eb7a4, 0x000eb7a4, 0x00000000},
+       {0x0000ab00, 0x00000000, 0x00000000, 0x000eb7a8, 0x000eb7a8, 0x00000000},
+       {0x0000ab04, 0x00000000, 0x00000000, 0x000eb7b0, 0x000eb7b0, 0x00000000},
+       {0x0000ab08, 0x00000000, 0x00000000, 0x000eb7b4, 0x000eb7b4, 0x00000000},
+       {0x0000ab0c, 0x00000000, 0x00000000, 0x000eb7b8, 0x000eb7b8, 0x00000000},
+       {0x0000ab10, 0x00000000, 0x00000000, 0x000eb7a5, 0x000eb7a5, 0x00000000},
+       {0x0000ab14, 0x00000000, 0x00000000, 0x000eb7a9, 0x000eb7a9, 0x00000000},
+       {0x0000ab18, 0x00000000, 0x00000000, 0x000eb7ad, 0x000eb7ad, 0x00000000},
+       {0x0000ab1c, 0x00000000, 0x00000000, 0x000eb7b1, 0x000eb7b1, 0x00000000},
+       {0x0000ab20, 0x00000000, 0x00000000, 0x000eb7b5, 0x000eb7b5, 0x00000000},
+       {0x0000ab24, 0x00000000, 0x00000000, 0x000eb7b9, 0x000eb7b9, 0x00000000},
+       {0x0000ab28, 0x00000000, 0x00000000, 0x000eb7c5, 0x000eb7c5, 0x00000000},
+       {0x0000ab2c, 0x00000000, 0x00000000, 0x000eb7c9, 0x000eb7c9, 0x00000000},
+       {0x0000ab30, 0x00000000, 0x00000000, 0x000eb7d1, 0x000eb7d1, 0x00000000},
+       {0x0000ab34, 0x00000000, 0x00000000, 0x000eb7d5, 0x000eb7d5, 0x00000000},
+       {0x0000ab38, 0x00000000, 0x00000000, 0x000eb7d9, 0x000eb7d9, 0x00000000},
+       {0x0000ab3c, 0x00000000, 0x00000000, 0x000eb7c6, 0x000eb7c6, 0x00000000},
+       {0x0000ab40, 0x00000000, 0x00000000, 0x000eb7ca, 0x000eb7ca, 0x00000000},
+       {0x0000ab44, 0x00000000, 0x00000000, 0x000eb7ce, 0x000eb7ce, 0x00000000},
+       {0x0000ab48, 0x00000000, 0x00000000, 0x000eb7d2, 0x000eb7d2, 0x00000000},
+       {0x0000ab4c, 0x00000000, 0x00000000, 0x000eb7d6, 0x000eb7d6, 0x00000000},
+       {0x0000ab50, 0x00000000, 0x00000000, 0x000eb7c3, 0x000eb7c3, 0x00000000},
+       {0x0000ab54, 0x00000000, 0x00000000, 0x000eb7c7, 0x000eb7c7, 0x00000000},
+       {0x0000ab58, 0x00000000, 0x00000000, 0x000eb7cb, 0x000eb7cb, 0x00000000},
+       {0x0000ab5c, 0x00000000, 0x00000000, 0x000eb7cf, 0x000eb7cf, 0x00000000},
+       {0x0000ab60, 0x00000000, 0x00000000, 0x000eb7d7, 0x000eb7d7, 0x00000000},
+       {0x0000ab64, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x0000ab68, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x0000ab6c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x0000ab70, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x0000ab74, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x0000ab78, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x0000ab7c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x0000ab80, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x0000ab84, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x0000ab88, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x0000ab8c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x0000ab90, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x0000ab94, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x0000ab98, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x0000ab9c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x0000aba0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x0000aba4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x0000aba8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x0000abac, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x0000abb0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x0000abb4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x0000abb8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x0000abbc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x0000abc0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x0000abc4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x0000abc8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x0000abcc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x0000abd0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x0000abd4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x0000abd8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x0000abdc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x0000abe0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x0000abe4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x0000abe8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x0000abec, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x0000abf0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x0000abf4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x0000abf8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x0000abfc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x0000a204, 0x00000004, 0x00000004, 0x00000004, 0x00000004, 0x00000004},
+       {0x0000a20c, 0x00000014, 0x00000014, 0x0001f000, 0x0001f000, 0x0001f000},
+       {0x0000b20c, 0x00000014, 0x00000014, 0x0001f000, 0x0001f000, 0x0001f000},
+       {0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a},
+       {0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000},
+       {0x0000a250, 0x0004f000, 0x0004f000, 0x0004a000, 0x0004a000, 0x0004a000},
+       {0x0000a358, 0x7999aa02, 0x7999aa02, 0x7999aa0e, 0x7999aa0e, 0x7999aa0e},
+};
+
+static const u32 ar9285Common_9285_1_2[][2] = {
+       /* Addr      allmodes  */
+       {0x0000000c, 0x00000000},
+       {0x00000030, 0x00020045},
+       {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},
+       {0x00004024, 0x0000001f},
+       {0x00004060, 0x00000000},
+       {0x00004064, 0x00000000},
+       {0x00007010, 0x00000031},
+       {0x00007034, 0x00000002},
+       {0x00007038, 0x000004c2},
+       {0x00008004, 0x00000000},
+       {0x00008008, 0x00000000},
+       {0x0000800c, 0x00000000},
+       {0x00008018, 0x00000700},
+       {0x00008020, 0x00000000},
+       {0x00008038, 0x00000000},
+       {0x0000803c, 0x00000000},
+       {0x00008048, 0x00000000},
+       {0x00008054, 0x00000000},
+       {0x00008058, 0x00000000},
+       {0x0000805c, 0x000fc78f},
+       {0x00008060, 0x0000000f},
+       {0x00008064, 0x00000000},
+       {0x00008070, 0x00000000},
+       {0x000080c0, 0x2a80001a},
+       {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, 0x08f04810},
+       {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},
+       {0x000081c0, 0x00000000},
+       {0x000081d0, 0x0000320a},
+       {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, 0x88a00010},
+       {0x00008270, 0x00000000},
+       {0x00008274, 0x40000000},
+       {0x00008278, 0x003e4180},
+       {0x0000827c, 0x00000000},
+       {0x00008284, 0x0000002c},
+       {0x00008288, 0x0000002c},
+       {0x0000828c, 0x00000000},
+       {0x00008294, 0x00000000},
+       {0x00008298, 0x00000000},
+       {0x0000829c, 0x00000000},
+       {0x00008300, 0x00000040},
+       {0x00008314, 0x00000000},
+       {0x00008328, 0x00000000},
+       {0x0000832c, 0x00000001},
+       {0x00008330, 0x00000302},
+       {0x00008334, 0x00000e00},
+       {0x00008338, 0x00ff0000},
+       {0x0000833c, 0x00000000},
+       {0x00008340, 0x00010380},
+       {0x00008344, 0x00481043},
+       {0x00009808, 0x00000000},
+       {0x0000980c, 0xafe68e30},
+       {0x00009810, 0xfd14e000},
+       {0x00009814, 0x9c0a9f6b},
+       {0x0000981c, 0x00000000},
+       {0x0000982c, 0x0000a000},
+       {0x00009830, 0x00000000},
+       {0x0000983c, 0x00200400},
+       {0x0000984c, 0x0040233c},
+       {0x00009854, 0x00000044},
+       {0x00009900, 0x00000000},
+       {0x00009904, 0x00000000},
+       {0x00009908, 0x00000000},
+       {0x0000990c, 0x00000000},
+       {0x00009910, 0x01002310},
+       {0x0000991c, 0x10000fff},
+       {0x00009920, 0x04900000},
+       {0x00009928, 0x00000001},
+       {0x0000992c, 0x00000004},
+       {0x00009934, 0x1e1f2022},
+       {0x00009938, 0x0a0b0c0d},
+       {0x0000993c, 0x00000000},
+       {0x00009940, 0x14750604},
+       {0x00009948, 0x9280c00a},
+       {0x0000994c, 0x00020028},
+       {0x00009954, 0x5f3ca3de},
+       {0x00009958, 0x2108ecff},
+       {0x00009968, 0x000003ce},
+       {0x00009970, 0x192bb514},
+       {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, 0x2def0400},
+       {0x000099b0, 0x03051000},
+       {0x000099b4, 0x00000820},
+       {0x000099dc, 0x00000000},
+       {0x000099e0, 0x00000000},
+       {0x000099e4, 0xaaaaaaaa},
+       {0x000099e8, 0x3c466478},
+       {0x000099ec, 0x0cc80caa},
+       {0x000099f0, 0x00000000},
+       {0x0000a208, 0x803e68c8},
+       {0x0000a210, 0x4080a333},
+       {0x0000a214, 0x00206c10},
+       {0x0000a218, 0x009c4060},
+       {0x0000a220, 0x01834061},
+       {0x0000a224, 0x00000400},
+       {0x0000a228, 0x000003b5},
+       {0x0000a22c, 0x00000000},
+       {0x0000a234, 0x20202020},
+       {0x0000a238, 0x20202020},
+       {0x0000a244, 0x00000000},
+       {0x0000a248, 0xfffffffc},
+       {0x0000a24c, 0x00000000},
+       {0x0000a254, 0x00000000},
+       {0x0000a258, 0x0ccb5380},
+       {0x0000a25c, 0x15151501},
+       {0x0000a260, 0xdfa90f01},
+       {0x0000a268, 0x00000000},
+       {0x0000a26c, 0x0ebae9e6},
+       {0x0000d270, 0x0d820820},
+       {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},
+       {0x0000a39c, 0x00000001},
+       {0x0000a3a0, 0x00000000},
+       {0x0000a3a4, 0x00000000},
+       {0x0000a3a8, 0x00000000},
+       {0x0000a3ac, 0x00000000},
+       {0x0000a3b0, 0x00000000},
+       {0x0000a3b4, 0x00000000},
+       {0x0000a3b8, 0x00000000},
+       {0x0000a3bc, 0x00000000},
+       {0x0000a3c0, 0x00000000},
+       {0x0000a3c4, 0x00000000},
+       {0x0000a3cc, 0x20202020},
+       {0x0000a3d0, 0x20202020},
+       {0x0000a3d4, 0x20202020},
+       {0x0000a3e4, 0x00000000},
+       {0x0000a3e8, 0x18c43433},
+       {0x0000a3ec, 0x00f70081},
+       {0x00007800, 0x00140000},
+       {0x00007804, 0x0e4548d8},
+       {0x00007808, 0x54214514},
+       {0x0000780c, 0x02025830},
+       {0x00007810, 0x71c0d388},
+       {0x0000781c, 0x00000000},
+       {0x00007824, 0x00d86fff},
+       {0x0000782c, 0x6e36d97b},
+       {0x00007834, 0x71400087},
+       {0x00007844, 0x000c0db6},
+       {0x00007848, 0x6db6246f},
+       {0x0000784c, 0x6d9b66db},
+       {0x00007850, 0x6d8c6dba},
+       {0x00007854, 0x00040000},
+       {0x00007858, 0xdb003012},
+       {0x0000785c, 0x04924914},
+       {0x00007860, 0x21084210},
+       {0x00007864, 0xf7d7ffde},
+       {0x00007868, 0xc2034080},
+       {0x00007870, 0x10142c00},
+};
+
+static const u32 ar9285Modes_high_power_tx_gain_9285_1_2[][6] = {
+       {0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000a304, 0x00000000, 0x00000000, 0x00006200, 0x00006200, 0x00000000},
+       {0x0000a308, 0x00000000, 0x00000000, 0x00008201, 0x00008201, 0x00000000},
+       {0x0000a30c, 0x00000000, 0x00000000, 0x0000b240, 0x0000b240, 0x00000000},
+       {0x0000a310, 0x00000000, 0x00000000, 0x0000d241, 0x0000d241, 0x00000000},
+       {0x0000a314, 0x00000000, 0x00000000, 0x0000f600, 0x0000f600, 0x00000000},
+       {0x0000a318, 0x00000000, 0x00000000, 0x00012800, 0x00012800, 0x00000000},
+       {0x0000a31c, 0x00000000, 0x00000000, 0x00016802, 0x00016802, 0x00000000},
+       {0x0000a320, 0x00000000, 0x00000000, 0x0001b805, 0x0001b805, 0x00000000},
+       {0x0000a324, 0x00000000, 0x00000000, 0x00021a80, 0x00021a80, 0x00000000},
+       {0x0000a328, 0x00000000, 0x00000000, 0x00028b00, 0x00028b00, 0x00000000},
+       {0x0000a32c, 0x00000000, 0x00000000, 0x0002ab40, 0x0002ab40, 0x00000000},
+       {0x0000a330, 0x00000000, 0x00000000, 0x0002cd80, 0x0002cd80, 0x00000000},
+       {0x0000a334, 0x00000000, 0x00000000, 0x00033d82, 0x00033d82, 0x00000000},
+       {0x0000a338, 0x0003891e, 0x0003891e, 0x0003891e, 0x0003891e, 0x00000000},
+       {0x0000a33c, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x00000000},
+       {0x0000a340, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000},
+       {0x0000a344, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000},
+       {0x0000a348, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000},
+       {0x0000a34c, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000},
+       {0x0000a350, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000},
+       {0x0000a354, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000},
+       {0x00007814, 0x924934a8, 0x924934a8, 0x924934a8, 0x924934a8, 0x924934a8},
+       {0x00007828, 0x26d2491b, 0x26d2491b, 0x26d2491b, 0x26d2491b, 0x26d2491b},
+       {0x00007830, 0xedb6d96e, 0xedb6d96e, 0xedb6d96e, 0xedb6d96e, 0xedb6d96e},
+       {0x00007838, 0xfac68803, 0xfac68803, 0xfac68803, 0xfac68803, 0xfac68803},
+       {0x0000783c, 0x0001fffe, 0x0001fffe, 0x0001fffe, 0x0001fffe, 0x0001fffe},
+       {0x00007840, 0xffeb1a20, 0xffeb1a20, 0xffeb1a20, 0xffeb1a20, 0xffeb1a20},
+       {0x0000786c, 0x08609ebe, 0x08609ebe, 0x08609ebe, 0x08609ebe, 0x08609ebe},
+       {0x00007820, 0x00000c00, 0x00000c00, 0x00000c00, 0x00000c00, 0x00000c00},
+       {0x0000a274, 0x0a22a652, 0x0a22a652, 0x0a216652, 0x0a216652, 0x0a22a652},
+       {0x0000a278, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7},
+       {0x0000a27c, 0x050380e7, 0x050380e7, 0x050380e7, 0x050380e7, 0x050380e7},
+       {0x0000a394, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7},
+       {0x0000a398, 0x000000e7, 0x000000e7, 0x000000e7, 0x000000e7, 0x000000e7},
+       {0x0000a3dc, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7},
+       {0x0000a3e0, 0x000000e7, 0x000000e7, 0x000000e7, 0x000000e7, 0x000000e7},
+};
+
+static const u32 ar9285Modes_original_tx_gain_9285_1_2[][6] = {
+       {0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000a304, 0x00000000, 0x00000000, 0x00009200, 0x00009200, 0x00000000},
+       {0x0000a308, 0x00000000, 0x00000000, 0x00010208, 0x00010208, 0x00000000},
+       {0x0000a30c, 0x00000000, 0x00000000, 0x00019608, 0x00019608, 0x00000000},
+       {0x0000a310, 0x00000000, 0x00000000, 0x00022618, 0x00022618, 0x00000000},
+       {0x0000a314, 0x00000000, 0x00000000, 0x0002a6c9, 0x0002a6c9, 0x00000000},
+       {0x0000a318, 0x00000000, 0x00000000, 0x00031710, 0x00031710, 0x00000000},
+       {0x0000a31c, 0x00000000, 0x00000000, 0x00035718, 0x00035718, 0x00000000},
+       {0x0000a320, 0x00000000, 0x00000000, 0x00038758, 0x00038758, 0x00000000},
+       {0x0000a324, 0x00000000, 0x00000000, 0x0003c75a, 0x0003c75a, 0x00000000},
+       {0x0000a328, 0x00000000, 0x00000000, 0x0004075c, 0x0004075c, 0x00000000},
+       {0x0000a32c, 0x00000000, 0x00000000, 0x0004475e, 0x0004475e, 0x00000000},
+       {0x0000a330, 0x00000000, 0x00000000, 0x0004679f, 0x0004679f, 0x00000000},
+       {0x0000a334, 0x00000000, 0x00000000, 0x000487df, 0x000487df, 0x00000000},
+       {0x0000a338, 0x0003891e, 0x0003891e, 0x0003891e, 0x0003891e, 0x00000000},
+       {0x0000a33c, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x00000000},
+       {0x0000a340, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000},
+       {0x0000a344, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000},
+       {0x0000a348, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000},
+       {0x0000a34c, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000},
+       {0x0000a350, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000},
+       {0x0000a354, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000},
+       {0x00007814, 0x924934a8, 0x924934a8, 0x924934a8, 0x924934a8, 0x924934a8},
+       {0x00007828, 0x26d2491b, 0x26d2491b, 0x26d2491b, 0x26d2491b, 0x26d2491b},
+       {0x00007830, 0xedb6d96e, 0xedb6d96e, 0xedb6d96e, 0xedb6d96e, 0xedb6d96e},
+       {0x00007838, 0xfac68801, 0xfac68801, 0xfac68801, 0xfac68801, 0xfac68801},
+       {0x0000783c, 0x0001fffe, 0x0001fffe, 0x0001fffe, 0x0001fffe, 0x0001fffe},
+       {0x00007840, 0xffeb1a20, 0xffeb1a20, 0xffeb1a20, 0xffeb1a20, 0xffeb1a20},
+       {0x0000786c, 0x48609eb4, 0x48609eb4, 0x48609eb4, 0x48609eb4, 0x48609eb4},
+       {0x00007820, 0x00000c04, 0x00000c04, 0x00000c04, 0x00000c04, 0x00000c04},
+       {0x0000a274, 0x0a21c652, 0x0a21c652, 0x0a21a652, 0x0a21a652, 0x0a22a652},
+       {0x0000a278, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c},
+       {0x0000a27c, 0x050e039c, 0x050e039c, 0x050e039c, 0x050e039c, 0x050e039c},
+       {0x0000a394, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c},
+       {0x0000a398, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c},
+       {0x0000a3dc, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c},
+       {0x0000a3e0, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c},
+};
+
+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},
+       {0x0000a30c, 0x00000000, 0x00000000, 0x00019608, 0x00019608, 0x00000000},
+       {0x0000a310, 0x00000000, 0x00000000, 0x00022618, 0x00022618, 0x00000000},
+       {0x0000a314, 0x00000000, 0x00000000, 0x0002a6c9, 0x0002a6c9, 0x00000000},
+       {0x0000a318, 0x00000000, 0x00000000, 0x00031710, 0x00031710, 0x00000000},
+       {0x0000a31c, 0x00000000, 0x00000000, 0x00035718, 0x00035718, 0x00000000},
+       {0x0000a320, 0x00000000, 0x00000000, 0x00038758, 0x00038758, 0x00000000},
+       {0x0000a324, 0x00000000, 0x00000000, 0x0003c75a, 0x0003c75a, 0x00000000},
+       {0x0000a328, 0x00000000, 0x00000000, 0x0004075c, 0x0004075c, 0x00000000},
+       {0x0000a32c, 0x00000000, 0x00000000, 0x0004475e, 0x0004475e, 0x00000000},
+       {0x0000a330, 0x00000000, 0x00000000, 0x0004679f, 0x0004679f, 0x00000000},
+       {0x0000a334, 0x00000000, 0x00000000, 0x000487df, 0x000487df, 0x00000000},
+       {0x0000a338, 0x0003891e, 0x0003891e, 0x0003891e, 0x0003891e, 0x00000000},
+       {0x0000a33c, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x00000000},
+       {0x0000a340, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000},
+       {0x0000a344, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000},
+       {0x0000a348, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000},
+       {0x0000a34c, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000},
+       {0x0000a350, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000},
+       {0x0000a354, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000},
+       {0x00007814, 0x92497ca8, 0x92497ca8, 0x92497ca8, 0x92497ca8, 0x92497ca8},
+       {0x00007828, 0x4ad2491b, 0x4ad2491b, 0x2ad2491b, 0x4ad2491b, 0x4ad2491b},
+       {0x00007830, 0xedb6da6e, 0xedb6da6e, 0xedb6da6e, 0xedb6da6e, 0xedb6dbae},
+       {0x00007838, 0xdac71441, 0xdac71441, 0xdac71441, 0xdac71441, 0xdac71441},
+       {0x0000783c, 0x2481f6fe, 0x2481f6fe, 0x2481f6fe, 0x2481f6fe, 0x2481f6fe},
+       {0x00007840, 0xba5f638c, 0xba5f638c, 0xba5f638c, 0xba5f638c, 0xba5f638c},
+       {0x0000786c, 0x48609eb4, 0x48609eb4, 0x48609eb4, 0x48609eb4, 0x48609eb4},
+       {0x00007820, 0x00000c04, 0x00000c04, 0x00000c04, 0x00000c04, 0x00000c04},
+       {0x0000a274, 0x0a21c652, 0x0a21c652, 0x0a21a652, 0x0a21a652, 0x0a22a652},
+       {0x0000a278, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c},
+       {0x0000a27c, 0x050e039c, 0x050e039c, 0x050e039c, 0x050e039c, 0x050e039c},
+       {0x0000a394, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c},
+       {0x0000a398, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c},
+       {0x0000a3dc, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c},
+       {0x0000a3e0, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c},
+};
+
+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},
+       {0x0000a30c, 0x00000000, 0x00000000, 0x0000b240, 0x0000b240, 0x00000000},
+       {0x0000a310, 0x00000000, 0x00000000, 0x0000d241, 0x0000d241, 0x00000000},
+       {0x0000a314, 0x00000000, 0x00000000, 0x0000f600, 0x0000f600, 0x00000000},
+       {0x0000a318, 0x00000000, 0x00000000, 0x00012800, 0x00012800, 0x00000000},
+       {0x0000a31c, 0x00000000, 0x00000000, 0x00016802, 0x00016802, 0x00000000},
+       {0x0000a320, 0x00000000, 0x00000000, 0x0001b805, 0x0001b805, 0x00000000},
+       {0x0000a324, 0x00000000, 0x00000000, 0x00021a80, 0x00021a80, 0x00000000},
+       {0x0000a328, 0x00000000, 0x00000000, 0x00028b00, 0x00028b00, 0x00000000},
+       {0x0000a32c, 0x00000000, 0x00000000, 0x0002ab40, 0x0002ab40, 0x00000000},
+       {0x0000a330, 0x00000000, 0x00000000, 0x0002cd80, 0x0002cd80, 0x00000000},
+       {0x0000a334, 0x00000000, 0x00000000, 0x00033d82, 0x00033d82, 0x00000000},
+       {0x0000a338, 0x0003891e, 0x0003891e, 0x0003891e, 0x0003891e, 0x00000000},
+       {0x0000a33c, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x00000000},
+       {0x0000a340, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000},
+       {0x0000a344, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000},
+       {0x0000a348, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000},
+       {0x0000a34c, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000},
+       {0x0000a350, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000},
+       {0x0000a354, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000},
+       {0x00007814, 0x92497ca8, 0x92497ca8, 0x92497ca8, 0x92497ca8, 0x92497ca8},
+       {0x00007828, 0x4ad2491b, 0x4ad2491b, 0x2ad2491b, 0x4ad2491b, 0x4ad2491b},
+       {0x00007830, 0xedb6da6e, 0xedb6da6e, 0xedb6da6e, 0xedb6da6e, 0xedb6da6e},
+       {0x00007838, 0xdac71443, 0xdac71443, 0xdac71443, 0xdac71443, 0xdac71443},
+       {0x0000783c, 0x2481f6fe, 0x2481f6fe, 0x2481f6fe, 0x2481f6fe, 0x2481f6fe},
+       {0x00007840, 0xba5f638c, 0xba5f638c, 0xba5f638c, 0xba5f638c, 0xba5f638c},
+       {0x0000786c, 0x08609ebe, 0x08609ebe, 0x08609ebe, 0x08609ebe, 0x08609ebe},
+       {0x00007820, 0x00000c00, 0x00000c00, 0x00000c00, 0x00000c00, 0x00000c00},
+       {0x0000a274, 0x0a22a652, 0x0a22a652, 0x0a216652, 0x0a216652, 0x0a22a652},
+       {0x0000a278, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7},
+       {0x0000a27c, 0x050380e7, 0x050380e7, 0x050380e7, 0x050380e7, 0x050380e7},
+       {0x0000a394, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7},
+       {0x0000a398, 0x000000e7, 0x000000e7, 0x000000e7, 0x000000e7, 0x000000e7},
+       {0x0000a3dc, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7},
+       {0x0000a3e0, 0x000000e7, 0x000000e7, 0x000000e7, 0x000000e7, 0x000000e7},
+};
+
+static const u32 ar9285PciePhy_clkreq_always_on_L1_9285_1_2[][2] = {
+       /* Addr      allmodes  */
+       {0x00004040, 0x9248fd00},
+       {0x00004040, 0x24924924},
+       {0x00004040, 0xa8000019},
+       {0x00004040, 0x13160820},
+       {0x00004040, 0xe5980560},
+       {0x00004040, 0xc01dcffd},
+       {0x00004040, 0x1aaabe41},
+       {0x00004040, 0xbe105554},
+       {0x00004040, 0x00043007},
+       {0x00004044, 0x00000000},
+};
+
+static const u32 ar9285PciePhy_clkreq_off_L1_9285_1_2[][2] = {
+       /* Addr      allmodes  */
+       {0x00004040, 0x9248fd00},
+       {0x00004040, 0x24924924},
+       {0x00004040, 0xa8000019},
+       {0x00004040, 0x13160820},
+       {0x00004040, 0xe5980560},
+       {0x00004040, 0xc01dcffc},
+       {0x00004040, 0x1aaabe41},
+       {0x00004040, 0xbe105554},
+       {0x00004040, 0x00043007},
+       {0x00004044, 0x00000000},
+};
+
+static const u32 ar9287Modes_9287_1_1[][6] = {
+       {0x00001030, 0x00000000, 0x00000000, 0x000002c0, 0x00000160, 0x000001e0},
+       {0x00001070, 0x00000000, 0x00000000, 0x00000318, 0x0000018c, 0x000001e0},
+       {0x000010b0, 0x00000000, 0x00000000, 0x00007c70, 0x00003e38, 0x00001180},
+       {0x000010f0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000008},
+       {0x00008014, 0x00000000, 0x00000000, 0x10801600, 0x08400b00, 0x06e006e0},
+       {0x0000801c, 0x00000000, 0x00000000, 0x12e00057, 0x12e0002b, 0x0988004f},
+       {0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810, 0x08f04810},
+       {0x000081d0, 0x00003200, 0x00003200, 0x0000320a, 0x0000320a, 0x0000320a},
+       {0x00008318, 0x00000000, 0x00000000, 0x00006880, 0x00003440, 0x00006880},
+       {0x00009804, 0x00000000, 0x00000000, 0x000003c4, 0x00000300, 0x00000303},
+       {0x00009820, 0x00000000, 0x00000000, 0x02020200, 0x02020200, 0x02020200},
+       {0x00009824, 0x00000000, 0x00000000, 0x01000e0e, 0x01000e0e, 0x01000e0e},
+       {0x00009828, 0x00000000, 0x00000000, 0x3a020001, 0x3a020001, 0x3a020001},
+       {0x00009834, 0x00000000, 0x00000000, 0x00000e0e, 0x00000e0e, 0x00000e0e},
+       {0x00009838, 0x00000003, 0x00000003, 0x00000007, 0x00000007, 0x00000007},
+       {0x00009840, 0x206a002e, 0x206a002e, 0x206a012e, 0x206a012e, 0x206a012e},
+       {0x00009844, 0x03720000, 0x03720000, 0x037216a0, 0x037216a0, 0x037216a0},
+       {0x00009850, 0x60000000, 0x60000000, 0x6d4000e2, 0x6c4000e2, 0x6c4000e2},
+       {0x00009858, 0x7c000d00, 0x7c000d00, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e},
+       {0x0000985c, 0x3100005e, 0x3100005e, 0x3139605e, 0x31395d5e, 0x31395d5e},
+       {0x00009860, 0x00058d00, 0x00058d00, 0x00058d20, 0x00058d20, 0x00058d18},
+       {0x00009864, 0x00000e00, 0x00000e00, 0x0001ce00, 0x0001ce00, 0x0001ce00},
+       {0x00009868, 0x000040c0, 0x000040c0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0},
+       {0x0000986c, 0x00000080, 0x00000080, 0x06903881, 0x06903881, 0x06903881},
+       {0x00009914, 0x00000000, 0x00000000, 0x00001130, 0x00000898, 0x000007d0},
+       {0x00009918, 0x00000000, 0x00000000, 0x00000016, 0x0000000b, 0x00000016},
+       {0x00009924, 0xd00a8a01, 0xd00a8a01, 0xd00a8a0d, 0xd00a8a0d, 0xd00a8a0d},
+       {0x00009944, 0xefbc0000, 0xefbc0000, 0xefbc1010, 0xefbc1010, 0xefbc1010},
+       {0x00009960, 0x00000000, 0x00000000, 0x00000010, 0x00000010, 0x00000010},
+       {0x0000a960, 0x00000000, 0x00000000, 0x00000010, 0x00000010, 0x00000010},
+       {0x00009964, 0x00000000, 0x00000000, 0x00000210, 0x00000210, 0x00000210},
+       {0x0000c968, 0x00000200, 0x00000200, 0x000003ce, 0x000003ce, 0x000003ce},
+       {0x000099b8, 0x00000000, 0x00000000, 0x0000001c, 0x0000001c, 0x0000001c},
+       {0x000099bc, 0x00000000, 0x00000000, 0x00000c00, 0x00000c00, 0x00000c00},
+       {0x000099c0, 0x00000000, 0x00000000, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4},
+       {0x0000a204, 0x00000440, 0x00000440, 0x00000444, 0x00000444, 0x00000444},
+       {0x0000a20c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b20c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000a21c, 0x1803800a, 0x1803800a, 0x1883800a, 0x1883800a, 0x1883800a},
+       {0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000},
+       {0x0000a250, 0x00000000, 0x00000000, 0x0004a000, 0x0004a000, 0x0004a000},
+       {0x0000a358, 0x7999aa02, 0x7999aa02, 0x7999aa0e, 0x7999aa0e, 0x7999aa0e},
+       {0x0000a3d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+};
+
+static const u32 ar9287Common_9287_1_1[][2] = {
+       /* Addr      allmodes  */
+       {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},
+       {0x00004024, 0x0000001f},
+       {0x00004060, 0x00000000},
+       {0x00004064, 0x00000000},
+       {0x00007010, 0x00000033},
+       {0x00007020, 0x00000000},
+       {0x00007034, 0x00000002},
+       {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},
+       {0x00008070, 0x00000000},
+       {0x000080c0, 0x2a80001a},
+       {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, 0x18487320},
+       {0x00008174, 0xfaa4fa50},
+       {0x00008178, 0x00000100},
+       {0x0000817c, 0x00000000},
+       {0x000081c0, 0x00000000},
+       {0x000081c4, 0x00000000},
+       {0x000081d4, 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, 0x88a00010},
+       {0x00008270, 0x00000000},
+       {0x00008274, 0x40000000},
+       {0x00008278, 0x003e4180},
+       {0x0000827c, 0x00000000},
+       {0x00008284, 0x0000002c},
+       {0x00008288, 0x0000002c},
+       {0x0000828c, 0x000000ff},
+       {0x00008294, 0x00000000},
+       {0x00008298, 0x00000000},
+       {0x0000829c, 0x00000000},
+       {0x00008300, 0x00000040},
+       {0x00008314, 0x00000000},
+       {0x00008328, 0x00000000},
+       {0x0000832c, 0x00000007},
+       {0x00008330, 0x00000302},
+       {0x00008334, 0x00000e00},
+       {0x00008338, 0x00ff0000},
+       {0x0000833c, 0x00000000},
+       {0x00008340, 0x000107ff},
+       {0x00008344, 0x01c81043},
+       {0x00008360, 0xffffffff},
+       {0x00008364, 0xffffffff},
+       {0x00008368, 0x00000000},
+       {0x00008370, 0x00000000},
+       {0x00008374, 0x000000ff},
+       {0x00008378, 0x00000000},
+       {0x0000837c, 0x00000000},
+       {0x00008380, 0xffffffff},
+       {0x00008384, 0xffffffff},
+       {0x00008390, 0x0fffffff},
+       {0x00008394, 0x0fffffff},
+       {0x00008398, 0x00000000},
+       {0x0000839c, 0x00000000},
+       {0x000083a0, 0x00000000},
+       {0x00009808, 0x00000000},
+       {0x0000980c, 0xafe68e30},
+       {0x00009810, 0xfd14e000},
+       {0x00009814, 0x9c0a9f6b},
+       {0x0000981c, 0x00000000},
+       {0x0000982c, 0x0000a000},
+       {0x00009830, 0x00000000},
+       {0x0000983c, 0x00200400},
+       {0x0000984c, 0x0040233c},
+       {0x0000a84c, 0x0040233c},
+       {0x00009854, 0x00000044},
+       {0x00009900, 0x00000000},
+       {0x00009904, 0x00000000},
+       {0x00009908, 0x00000000},
+       {0x0000990c, 0x00000000},
+       {0x00009910, 0x10002310},
+       {0x0000991c, 0x10000fff},
+       {0x00009920, 0x04900000},
+       {0x0000a920, 0x04900000},
+       {0x00009928, 0x00000001},
+       {0x0000992c, 0x00000004},
+       {0x00009930, 0x00000000},
+       {0x0000a930, 0x00000000},
+       {0x00009934, 0x1e1f2022},
+       {0x00009938, 0x0a0b0c0d},
+       {0x0000993c, 0x00000000},
+       {0x00009948, 0x9280c00a},
+       {0x0000994c, 0x00020028},
+       {0x00009954, 0x5f3ca3de},
+       {0x00009958, 0x0108ecff},
+       {0x00009940, 0x14750604},
+       {0x0000c95c, 0x004b6a8e},
+       {0x00009970, 0x990bb514},
+       {0x00009974, 0x00000000},
+       {0x00009978, 0x00000001},
+       {0x0000997c, 0x00000000},
+       {0x000099a0, 0x00000000},
+       {0x000099a4, 0x00000001},
+       {0x000099a8, 0x201fff00},
+       {0x000099ac, 0x0c6f0000},
+       {0x000099b0, 0x03051000},
+       {0x000099b4, 0x00000820},
+       {0x000099c4, 0x06336f77},
+       {0x000099c8, 0x6af6532f},
+       {0x000099cc, 0x08f186c8},
+       {0x000099d0, 0x00046384},
+       {0x000099dc, 0x00000000},
+       {0x000099e0, 0x00000000},
+       {0x000099e4, 0xaaaaaaaa},
+       {0x000099e8, 0x3c466478},
+       {0x000099ec, 0x0cc80caa},
+       {0x000099f0, 0x00000000},
+       {0x000099fc, 0x00001042},
+       {0x0000a208, 0x803e4788},
+       {0x0000a210, 0x4080a333},
+       {0x0000a214, 0x40206c10},
+       {0x0000a218, 0x009c4060},
+       {0x0000a220, 0x01834061},
+       {0x0000a224, 0x00000400},
+       {0x0000a228, 0x000003b5},
+       {0x0000a22c, 0x233f7180},
+       {0x0000a234, 0x20202020},
+       {0x0000a238, 0x20202020},
+       {0x0000a23c, 0x13c889af},
+       {0x0000a240, 0x38490a20},
+       {0x0000a244, 0x00000000},
+       {0x0000a248, 0xfffffffc},
+       {0x0000a24c, 0x00000000},
+       {0x0000a254, 0x00000000},
+       {0x0000a258, 0x0cdbd380},
+       {0x0000a25c, 0x0f0f0f01},
+       {0x0000a260, 0xdfa91f01},
+       {0x0000a264, 0x00418a11},
+       {0x0000b264, 0x00418a11},
+       {0x0000a268, 0x00000000},
+       {0x0000a26c, 0x0e79e5c6},
+       {0x0000b26c, 0x0e79e5c6},
+       {0x0000d270, 0x00820820},
+       {0x0000a278, 0x1ce739ce},
+       {0x0000a27c, 0x050701ce},
+       {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},
+       {0x0000b398, 0x000001ce},
+       {0x0000a39c, 0x00000001},
+       {0x0000a3c8, 0x00000246},
+       {0x0000a3cc, 0x20202020},
+       {0x0000a3d0, 0x20202020},
+       {0x0000a3d4, 0x20202020},
+       {0x0000a3dc, 0x1ce739ce},
+       {0x0000a3e0, 0x000001ce},
+       {0x0000a3e4, 0x00000000},
+       {0x0000a3e8, 0x18c43433},
+       {0x0000a3ec, 0x00f70081},
+       {0x0000a3f0, 0x01036a1e},
+       {0x0000a3f4, 0x00000000},
+       {0x0000b3f4, 0x00000000},
+       {0x0000a7d8, 0x000003f1},
+       {0x00007800, 0x00000800},
+       {0x00007804, 0x6c35ffd2},
+       {0x00007808, 0x6db6c000},
+       {0x0000780c, 0x6db6cb30},
+       {0x00007810, 0x6db6cb6c},
+       {0x00007814, 0x0501e200},
+       {0x00007818, 0x0094128d},
+       {0x0000781c, 0x976ee392},
+       {0x00007820, 0xf75ff6fc},
+       {0x00007824, 0x00040000},
+       {0x00007828, 0xdb003012},
+       {0x0000782c, 0x04924914},
+       {0x00007830, 0x21084210},
+       {0x00007834, 0x00140000},
+       {0x00007838, 0x0e4548d8},
+       {0x0000783c, 0x54214514},
+       {0x00007840, 0x02025830},
+       {0x00007844, 0x71c0d388},
+       {0x00007848, 0x934934a8},
+       {0x00007850, 0x00000000},
+       {0x00007854, 0x00000800},
+       {0x00007858, 0x6c35ffd2},
+       {0x0000785c, 0x6db6c000},
+       {0x00007860, 0x6db6cb30},
+       {0x00007864, 0x6db6cb6c},
+       {0x00007868, 0x0501e200},
+       {0x0000786c, 0x0094128d},
+       {0x00007870, 0x976ee392},
+       {0x00007874, 0xf75ff6fc},
+       {0x00007878, 0x00040000},
+       {0x0000787c, 0xdb003012},
+       {0x00007880, 0x04924914},
+       {0x00007884, 0x21084210},
+       {0x00007888, 0x001b6db0},
+       {0x0000788c, 0x00376b63},
+       {0x00007890, 0x06db6db6},
+       {0x00007894, 0x006d8000},
+       {0x00007898, 0x48100000},
+       {0x0000789c, 0x00000000},
+       {0x000078a0, 0x08000000},
+       {0x000078a4, 0x0007ffd8},
+       {0x000078a8, 0x0007ffd8},
+       {0x000078ac, 0x001c0020},
+       {0x000078b0, 0x00060aeb},
+       {0x000078b4, 0x40008080},
+       {0x000078b8, 0x2a850160},
+};
+
+static const u32 ar9287Common_normal_cck_fir_coeff_9287_1_1[][2] = {
+       /* Addr      allmodes  */
+       {0x0000a1f4, 0x00fffeff},
+       {0x0000a1f8, 0x00f5f9ff},
+       {0x0000a1fc, 0xb79f6427},
+};
+
+static const u32 ar9287Common_japan_2484_cck_fir_coeff_9287_1_1[][2] = {
+       /* Addr      allmodes  */
+       {0x0000a1f4, 0x00000000},
+       {0x0000a1f8, 0xefff0301},
+       {0x0000a1fc, 0xca9228ee},
+};
+
+static const u32 ar9287Modes_tx_gain_9287_1_1[][6] = {
+       {0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000a304, 0x00000000, 0x00000000, 0x00004002, 0x00004002, 0x00004002},
+       {0x0000a308, 0x00000000, 0x00000000, 0x00008004, 0x00008004, 0x00008004},
+       {0x0000a30c, 0x00000000, 0x00000000, 0x0000c00a, 0x0000c00a, 0x0000c00a},
+       {0x0000a310, 0x00000000, 0x00000000, 0x0001000c, 0x0001000c, 0x0001000c},
+       {0x0000a314, 0x00000000, 0x00000000, 0x0001420b, 0x0001420b, 0x0001420b},
+       {0x0000a318, 0x00000000, 0x00000000, 0x0001824a, 0x0001824a, 0x0001824a},
+       {0x0000a31c, 0x00000000, 0x00000000, 0x0001c44a, 0x0001c44a, 0x0001c44a},
+       {0x0000a320, 0x00000000, 0x00000000, 0x0002064a, 0x0002064a, 0x0002064a},
+       {0x0000a324, 0x00000000, 0x00000000, 0x0002484a, 0x0002484a, 0x0002484a},
+       {0x0000a328, 0x00000000, 0x00000000, 0x00028a4a, 0x00028a4a, 0x00028a4a},
+       {0x0000a32c, 0x00000000, 0x00000000, 0x0002cc4a, 0x0002cc4a, 0x0002cc4a},
+       {0x0000a330, 0x00000000, 0x00000000, 0x00030e4a, 0x00030e4a, 0x00030e4a},
+       {0x0000a334, 0x00000000, 0x00000000, 0x00034e8a, 0x00034e8a, 0x00034e8a},
+       {0x0000a338, 0x00000000, 0x00000000, 0x00038e8c, 0x00038e8c, 0x00038e8c},
+       {0x0000a33c, 0x00000000, 0x00000000, 0x0003cecc, 0x0003cecc, 0x0003cecc},
+       {0x0000a340, 0x00000000, 0x00000000, 0x00040ed4, 0x00040ed4, 0x00040ed4},
+       {0x0000a344, 0x00000000, 0x00000000, 0x00044edc, 0x00044edc, 0x00044edc},
+       {0x0000a348, 0x00000000, 0x00000000, 0x00048ede, 0x00048ede, 0x00048ede},
+       {0x0000a34c, 0x00000000, 0x00000000, 0x0004cf1e, 0x0004cf1e, 0x0004cf1e},
+       {0x0000a350, 0x00000000, 0x00000000, 0x00050f5e, 0x00050f5e, 0x00050f5e},
+       {0x0000a354, 0x00000000, 0x00000000, 0x00054f9e, 0x00054f9e, 0x00054f9e},
+       {0x0000a780, 0x00000000, 0x00000000, 0x00000062, 0x00000062, 0x00000062},
+       {0x0000a784, 0x00000000, 0x00000000, 0x00004064, 0x00004064, 0x00004064},
+       {0x0000a788, 0x00000000, 0x00000000, 0x000080a4, 0x000080a4, 0x000080a4},
+       {0x0000a78c, 0x00000000, 0x00000000, 0x0000c0aa, 0x0000c0aa, 0x0000c0aa},
+       {0x0000a790, 0x00000000, 0x00000000, 0x000100ac, 0x000100ac, 0x000100ac},
+       {0x0000a794, 0x00000000, 0x00000000, 0x000140b4, 0x000140b4, 0x000140b4},
+       {0x0000a798, 0x00000000, 0x00000000, 0x000180f4, 0x000180f4, 0x000180f4},
+       {0x0000a79c, 0x00000000, 0x00000000, 0x0001c134, 0x0001c134, 0x0001c134},
+       {0x0000a7a0, 0x00000000, 0x00000000, 0x00020174, 0x00020174, 0x00020174},
+       {0x0000a7a4, 0x00000000, 0x00000000, 0x0002417c, 0x0002417c, 0x0002417c},
+       {0x0000a7a8, 0x00000000, 0x00000000, 0x0002817e, 0x0002817e, 0x0002817e},
+       {0x0000a7ac, 0x00000000, 0x00000000, 0x0002c1be, 0x0002c1be, 0x0002c1be},
+       {0x0000a7b0, 0x00000000, 0x00000000, 0x000301fe, 0x000301fe, 0x000301fe},
+       {0x0000a7b4, 0x00000000, 0x00000000, 0x000301fe, 0x000301fe, 0x000301fe},
+       {0x0000a7b8, 0x00000000, 0x00000000, 0x000301fe, 0x000301fe, 0x000301fe},
+       {0x0000a7bc, 0x00000000, 0x00000000, 0x000301fe, 0x000301fe, 0x000301fe},
+       {0x0000a7c0, 0x00000000, 0x00000000, 0x000301fe, 0x000301fe, 0x000301fe},
+       {0x0000a7c4, 0x00000000, 0x00000000, 0x000301fe, 0x000301fe, 0x000301fe},
+       {0x0000a7c8, 0x00000000, 0x00000000, 0x000301fe, 0x000301fe, 0x000301fe},
+       {0x0000a7cc, 0x00000000, 0x00000000, 0x000301fe, 0x000301fe, 0x000301fe},
+       {0x0000a7d0, 0x00000000, 0x00000000, 0x000301fe, 0x000301fe, 0x000301fe},
+       {0x0000a7d4, 0x00000000, 0x00000000, 0x000301fe, 0x000301fe, 0x000301fe},
+       {0x0000a274, 0x0a180000, 0x0a180000, 0x0a1aa000, 0x0a1aa000, 0x0a1aa000},
+};
+
+static const u32 ar9287Modes_rx_gain_9287_1_1[][6] = {
+       {0x00009a00, 0x00000000, 0x00000000, 0x0000a120, 0x0000a120, 0x0000a120},
+       {0x00009a04, 0x00000000, 0x00000000, 0x0000a124, 0x0000a124, 0x0000a124},
+       {0x00009a08, 0x00000000, 0x00000000, 0x0000a128, 0x0000a128, 0x0000a128},
+       {0x00009a0c, 0x00000000, 0x00000000, 0x0000a12c, 0x0000a12c, 0x0000a12c},
+       {0x00009a10, 0x00000000, 0x00000000, 0x0000a130, 0x0000a130, 0x0000a130},
+       {0x00009a14, 0x00000000, 0x00000000, 0x0000a194, 0x0000a194, 0x0000a194},
+       {0x00009a18, 0x00000000, 0x00000000, 0x0000a198, 0x0000a198, 0x0000a198},
+       {0x00009a1c, 0x00000000, 0x00000000, 0x0000a20c, 0x0000a20c, 0x0000a20c},
+       {0x00009a20, 0x00000000, 0x00000000, 0x0000a210, 0x0000a210, 0x0000a210},
+       {0x00009a24, 0x00000000, 0x00000000, 0x0000a284, 0x0000a284, 0x0000a284},
+       {0x00009a28, 0x00000000, 0x00000000, 0x0000a288, 0x0000a288, 0x0000a288},
+       {0x00009a2c, 0x00000000, 0x00000000, 0x0000a28c, 0x0000a28c, 0x0000a28c},
+       {0x00009a30, 0x00000000, 0x00000000, 0x0000a290, 0x0000a290, 0x0000a290},
+       {0x00009a34, 0x00000000, 0x00000000, 0x0000a294, 0x0000a294, 0x0000a294},
+       {0x00009a38, 0x00000000, 0x00000000, 0x0000a2a0, 0x0000a2a0, 0x0000a2a0},
+       {0x00009a3c, 0x00000000, 0x00000000, 0x0000a2a4, 0x0000a2a4, 0x0000a2a4},
+       {0x00009a40, 0x00000000, 0x00000000, 0x0000a2a8, 0x0000a2a8, 0x0000a2a8},
+       {0x00009a44, 0x00000000, 0x00000000, 0x0000a2ac, 0x0000a2ac, 0x0000a2ac},
+       {0x00009a48, 0x00000000, 0x00000000, 0x0000a2b0, 0x0000a2b0, 0x0000a2b0},
+       {0x00009a4c, 0x00000000, 0x00000000, 0x0000a2b4, 0x0000a2b4, 0x0000a2b4},
+       {0x00009a50, 0x00000000, 0x00000000, 0x0000a2b8, 0x0000a2b8, 0x0000a2b8},
+       {0x00009a54, 0x00000000, 0x00000000, 0x0000a2c4, 0x0000a2c4, 0x0000a2c4},
+       {0x00009a58, 0x00000000, 0x00000000, 0x0000a708, 0x0000a708, 0x0000a708},
+       {0x00009a5c, 0x00000000, 0x00000000, 0x0000a70c, 0x0000a70c, 0x0000a70c},
+       {0x00009a60, 0x00000000, 0x00000000, 0x0000a710, 0x0000a710, 0x0000a710},
+       {0x00009a64, 0x00000000, 0x00000000, 0x0000ab04, 0x0000ab04, 0x0000ab04},
+       {0x00009a68, 0x00000000, 0x00000000, 0x0000ab08, 0x0000ab08, 0x0000ab08},
+       {0x00009a6c, 0x00000000, 0x00000000, 0x0000ab0c, 0x0000ab0c, 0x0000ab0c},
+       {0x00009a70, 0x00000000, 0x00000000, 0x0000ab10, 0x0000ab10, 0x0000ab10},
+       {0x00009a74, 0x00000000, 0x00000000, 0x0000ab14, 0x0000ab14, 0x0000ab14},
+       {0x00009a78, 0x00000000, 0x00000000, 0x0000ab18, 0x0000ab18, 0x0000ab18},
+       {0x00009a7c, 0x00000000, 0x00000000, 0x0000ab8c, 0x0000ab8c, 0x0000ab8c},
+       {0x00009a80, 0x00000000, 0x00000000, 0x0000ab90, 0x0000ab90, 0x0000ab90},
+       {0x00009a84, 0x00000000, 0x00000000, 0x0000ab94, 0x0000ab94, 0x0000ab94},
+       {0x00009a88, 0x00000000, 0x00000000, 0x0000ab98, 0x0000ab98, 0x0000ab98},
+       {0x00009a8c, 0x00000000, 0x00000000, 0x0000aba4, 0x0000aba4, 0x0000aba4},
+       {0x00009a90, 0x00000000, 0x00000000, 0x0000aba8, 0x0000aba8, 0x0000aba8},
+       {0x00009a94, 0x00000000, 0x00000000, 0x0000cb04, 0x0000cb04, 0x0000cb04},
+       {0x00009a98, 0x00000000, 0x00000000, 0x0000cb08, 0x0000cb08, 0x0000cb08},
+       {0x00009a9c, 0x00000000, 0x00000000, 0x0000cb0c, 0x0000cb0c, 0x0000cb0c},
+       {0x00009aa0, 0x00000000, 0x00000000, 0x0000cb10, 0x0000cb10, 0x0000cb10},
+       {0x00009aa4, 0x00000000, 0x00000000, 0x0000cb14, 0x0000cb14, 0x0000cb14},
+       {0x00009aa8, 0x00000000, 0x00000000, 0x0000cb18, 0x0000cb18, 0x0000cb18},
+       {0x00009aac, 0x00000000, 0x00000000, 0x0000cb8c, 0x0000cb8c, 0x0000cb8c},
+       {0x00009ab0, 0x00000000, 0x00000000, 0x0000cb90, 0x0000cb90, 0x0000cb90},
+       {0x00009ab4, 0x00000000, 0x00000000, 0x0000cf18, 0x0000cf18, 0x0000cf18},
+       {0x00009ab8, 0x00000000, 0x00000000, 0x0000cf24, 0x0000cf24, 0x0000cf24},
+       {0x00009abc, 0x00000000, 0x00000000, 0x0000cf28, 0x0000cf28, 0x0000cf28},
+       {0x00009ac0, 0x00000000, 0x00000000, 0x0000d314, 0x0000d314, 0x0000d314},
+       {0x00009ac4, 0x00000000, 0x00000000, 0x0000d318, 0x0000d318, 0x0000d318},
+       {0x00009ac8, 0x00000000, 0x00000000, 0x0000d38c, 0x0000d38c, 0x0000d38c},
+       {0x00009acc, 0x00000000, 0x00000000, 0x0000d390, 0x0000d390, 0x0000d390},
+       {0x00009ad0, 0x00000000, 0x00000000, 0x0000d394, 0x0000d394, 0x0000d394},
+       {0x00009ad4, 0x00000000, 0x00000000, 0x0000d398, 0x0000d398, 0x0000d398},
+       {0x00009ad8, 0x00000000, 0x00000000, 0x0000d3a4, 0x0000d3a4, 0x0000d3a4},
+       {0x00009adc, 0x00000000, 0x00000000, 0x0000d3a8, 0x0000d3a8, 0x0000d3a8},
+       {0x00009ae0, 0x00000000, 0x00000000, 0x0000d3ac, 0x0000d3ac, 0x0000d3ac},
+       {0x00009ae4, 0x00000000, 0x00000000, 0x0000d3b0, 0x0000d3b0, 0x0000d3b0},
+       {0x00009ae8, 0x00000000, 0x00000000, 0x0000f380, 0x0000f380, 0x0000f380},
+       {0x00009aec, 0x00000000, 0x00000000, 0x0000f384, 0x0000f384, 0x0000f384},
+       {0x00009af0, 0x00000000, 0x00000000, 0x0000f388, 0x0000f388, 0x0000f388},
+       {0x00009af4, 0x00000000, 0x00000000, 0x0000f710, 0x0000f710, 0x0000f710},
+       {0x00009af8, 0x00000000, 0x00000000, 0x0000f714, 0x0000f714, 0x0000f714},
+       {0x00009afc, 0x00000000, 0x00000000, 0x0000f718, 0x0000f718, 0x0000f718},
+       {0x00009b00, 0x00000000, 0x00000000, 0x0000fb10, 0x0000fb10, 0x0000fb10},
+       {0x00009b04, 0x00000000, 0x00000000, 0x0000fb14, 0x0000fb14, 0x0000fb14},
+       {0x00009b08, 0x00000000, 0x00000000, 0x0000fb18, 0x0000fb18, 0x0000fb18},
+       {0x00009b0c, 0x00000000, 0x00000000, 0x0000fb8c, 0x0000fb8c, 0x0000fb8c},
+       {0x00009b10, 0x00000000, 0x00000000, 0x0000fb90, 0x0000fb90, 0x0000fb90},
+       {0x00009b14, 0x00000000, 0x00000000, 0x0000fb94, 0x0000fb94, 0x0000fb94},
+       {0x00009b18, 0x00000000, 0x00000000, 0x0000ff8c, 0x0000ff8c, 0x0000ff8c},
+       {0x00009b1c, 0x00000000, 0x00000000, 0x0000ff90, 0x0000ff90, 0x0000ff90},
+       {0x00009b20, 0x00000000, 0x00000000, 0x0000ff94, 0x0000ff94, 0x0000ff94},
+       {0x00009b24, 0x00000000, 0x00000000, 0x0000ffa0, 0x0000ffa0, 0x0000ffa0},
+       {0x00009b28, 0x00000000, 0x00000000, 0x0000ffa4, 0x0000ffa4, 0x0000ffa4},
+       {0x00009b2c, 0x00000000, 0x00000000, 0x0000ffa8, 0x0000ffa8, 0x0000ffa8},
+       {0x00009b30, 0x00000000, 0x00000000, 0x0000ffac, 0x0000ffac, 0x0000ffac},
+       {0x00009b34, 0x00000000, 0x00000000, 0x0000ffb0, 0x0000ffb0, 0x0000ffb0},
+       {0x00009b38, 0x00000000, 0x00000000, 0x0000ffb4, 0x0000ffb4, 0x0000ffb4},
+       {0x00009b3c, 0x00000000, 0x00000000, 0x0000ffa1, 0x0000ffa1, 0x0000ffa1},
+       {0x00009b40, 0x00000000, 0x00000000, 0x0000ffa5, 0x0000ffa5, 0x0000ffa5},
+       {0x00009b44, 0x00000000, 0x00000000, 0x0000ffa9, 0x0000ffa9, 0x0000ffa9},
+       {0x00009b48, 0x00000000, 0x00000000, 0x0000ffad, 0x0000ffad, 0x0000ffad},
+       {0x00009b4c, 0x00000000, 0x00000000, 0x0000ffb1, 0x0000ffb1, 0x0000ffb1},
+       {0x00009b50, 0x00000000, 0x00000000, 0x0000ffb5, 0x0000ffb5, 0x0000ffb5},
+       {0x00009b54, 0x00000000, 0x00000000, 0x0000ffb9, 0x0000ffb9, 0x0000ffb9},
+       {0x00009b58, 0x00000000, 0x00000000, 0x0000ffc5, 0x0000ffc5, 0x0000ffc5},
+       {0x00009b5c, 0x00000000, 0x00000000, 0x0000ffc9, 0x0000ffc9, 0x0000ffc9},
+       {0x00009b60, 0x00000000, 0x00000000, 0x0000ffcd, 0x0000ffcd, 0x0000ffcd},
+       {0x00009b64, 0x00000000, 0x00000000, 0x0000ffd1, 0x0000ffd1, 0x0000ffd1},
+       {0x00009b68, 0x00000000, 0x00000000, 0x0000ffd5, 0x0000ffd5, 0x0000ffd5},
+       {0x00009b6c, 0x00000000, 0x00000000, 0x0000ffc2, 0x0000ffc2, 0x0000ffc2},
+       {0x00009b70, 0x00000000, 0x00000000, 0x0000ffc6, 0x0000ffc6, 0x0000ffc6},
+       {0x00009b74, 0x00000000, 0x00000000, 0x0000ffca, 0x0000ffca, 0x0000ffca},
+       {0x00009b78, 0x00000000, 0x00000000, 0x0000ffce, 0x0000ffce, 0x0000ffce},
+       {0x00009b7c, 0x00000000, 0x00000000, 0x0000ffd2, 0x0000ffd2, 0x0000ffd2},
+       {0x00009b80, 0x00000000, 0x00000000, 0x0000ffd6, 0x0000ffd6, 0x0000ffd6},
+       {0x00009b84, 0x00000000, 0x00000000, 0x0000ffda, 0x0000ffda, 0x0000ffda},
+       {0x00009b88, 0x00000000, 0x00000000, 0x0000ffc7, 0x0000ffc7, 0x0000ffc7},
+       {0x00009b8c, 0x00000000, 0x00000000, 0x0000ffcb, 0x0000ffcb, 0x0000ffcb},
+       {0x00009b90, 0x00000000, 0x00000000, 0x0000ffcf, 0x0000ffcf, 0x0000ffcf},
+       {0x00009b94, 0x00000000, 0x00000000, 0x0000ffd3, 0x0000ffd3, 0x0000ffd3},
+       {0x00009b98, 0x00000000, 0x00000000, 0x0000ffd7, 0x0000ffd7, 0x0000ffd7},
+       {0x00009b9c, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+       {0x00009ba0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+       {0x00009ba4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+       {0x00009ba8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+       {0x00009bac, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+       {0x00009bb0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+       {0x00009bb4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+       {0x00009bb8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+       {0x00009bbc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+       {0x00009bc0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+       {0x00009bc4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+       {0x00009bc8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+       {0x00009bcc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+       {0x00009bd0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+       {0x00009bd4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+       {0x00009bd8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+       {0x00009bdc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+       {0x00009be0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+       {0x00009be4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+       {0x00009be8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+       {0x00009bec, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+       {0x00009bf0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+       {0x00009bf4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+       {0x00009bf8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+       {0x00009bfc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+       {0x0000aa00, 0x00000000, 0x00000000, 0x0000a120, 0x0000a120, 0x0000a120},
+       {0x0000aa04, 0x00000000, 0x00000000, 0x0000a124, 0x0000a124, 0x0000a124},
+       {0x0000aa08, 0x00000000, 0x00000000, 0x0000a128, 0x0000a128, 0x0000a128},
+       {0x0000aa0c, 0x00000000, 0x00000000, 0x0000a12c, 0x0000a12c, 0x0000a12c},
+       {0x0000aa10, 0x00000000, 0x00000000, 0x0000a130, 0x0000a130, 0x0000a130},
+       {0x0000aa14, 0x00000000, 0x00000000, 0x0000a194, 0x0000a194, 0x0000a194},
+       {0x0000aa18, 0x00000000, 0x00000000, 0x0000a198, 0x0000a198, 0x0000a198},
+       {0x0000aa1c, 0x00000000, 0x00000000, 0x0000a20c, 0x0000a20c, 0x0000a20c},
+       {0x0000aa20, 0x00000000, 0x00000000, 0x0000a210, 0x0000a210, 0x0000a210},
+       {0x0000aa24, 0x00000000, 0x00000000, 0x0000a284, 0x0000a284, 0x0000a284},
+       {0x0000aa28, 0x00000000, 0x00000000, 0x0000a288, 0x0000a288, 0x0000a288},
+       {0x0000aa2c, 0x00000000, 0x00000000, 0x0000a28c, 0x0000a28c, 0x0000a28c},
+       {0x0000aa30, 0x00000000, 0x00000000, 0x0000a290, 0x0000a290, 0x0000a290},
+       {0x0000aa34, 0x00000000, 0x00000000, 0x0000a294, 0x0000a294, 0x0000a294},
+       {0x0000aa38, 0x00000000, 0x00000000, 0x0000a2a0, 0x0000a2a0, 0x0000a2a0},
+       {0x0000aa3c, 0x00000000, 0x00000000, 0x0000a2a4, 0x0000a2a4, 0x0000a2a4},
+       {0x0000aa40, 0x00000000, 0x00000000, 0x0000a2a8, 0x0000a2a8, 0x0000a2a8},
+       {0x0000aa44, 0x00000000, 0x00000000, 0x0000a2ac, 0x0000a2ac, 0x0000a2ac},
+       {0x0000aa48, 0x00000000, 0x00000000, 0x0000a2b0, 0x0000a2b0, 0x0000a2b0},
+       {0x0000aa4c, 0x00000000, 0x00000000, 0x0000a2b4, 0x0000a2b4, 0x0000a2b4},
+       {0x0000aa50, 0x00000000, 0x00000000, 0x0000a2b8, 0x0000a2b8, 0x0000a2b8},
+       {0x0000aa54, 0x00000000, 0x00000000, 0x0000a2c4, 0x0000a2c4, 0x0000a2c4},
+       {0x0000aa58, 0x00000000, 0x00000000, 0x0000a708, 0x0000a708, 0x0000a708},
+       {0x0000aa5c, 0x00000000, 0x00000000, 0x0000a70c, 0x0000a70c, 0x0000a70c},
+       {0x0000aa60, 0x00000000, 0x00000000, 0x0000a710, 0x0000a710, 0x0000a710},
+       {0x0000aa64, 0x00000000, 0x00000000, 0x0000ab04, 0x0000ab04, 0x0000ab04},
+       {0x0000aa68, 0x00000000, 0x00000000, 0x0000ab08, 0x0000ab08, 0x0000ab08},
+       {0x0000aa6c, 0x00000000, 0x00000000, 0x0000ab0c, 0x0000ab0c, 0x0000ab0c},
+       {0x0000aa70, 0x00000000, 0x00000000, 0x0000ab10, 0x0000ab10, 0x0000ab10},
+       {0x0000aa74, 0x00000000, 0x00000000, 0x0000ab14, 0x0000ab14, 0x0000ab14},
+       {0x0000aa78, 0x00000000, 0x00000000, 0x0000ab18, 0x0000ab18, 0x0000ab18},
+       {0x0000aa7c, 0x00000000, 0x00000000, 0x0000ab8c, 0x0000ab8c, 0x0000ab8c},
+       {0x0000aa80, 0x00000000, 0x00000000, 0x0000ab90, 0x0000ab90, 0x0000ab90},
+       {0x0000aa84, 0x00000000, 0x00000000, 0x0000ab94, 0x0000ab94, 0x0000ab94},
+       {0x0000aa88, 0x00000000, 0x00000000, 0x0000ab98, 0x0000ab98, 0x0000ab98},
+       {0x0000aa8c, 0x00000000, 0x00000000, 0x0000aba4, 0x0000aba4, 0x0000aba4},
+       {0x0000aa90, 0x00000000, 0x00000000, 0x0000aba8, 0x0000aba8, 0x0000aba8},
+       {0x0000aa94, 0x00000000, 0x00000000, 0x0000cb04, 0x0000cb04, 0x0000cb04},
+       {0x0000aa98, 0x00000000, 0x00000000, 0x0000cb08, 0x0000cb08, 0x0000cb08},
+       {0x0000aa9c, 0x00000000, 0x00000000, 0x0000cb0c, 0x0000cb0c, 0x0000cb0c},
+       {0x0000aaa0, 0x00000000, 0x00000000, 0x0000cb10, 0x0000cb10, 0x0000cb10},
+       {0x0000aaa4, 0x00000000, 0x00000000, 0x0000cb14, 0x0000cb14, 0x0000cb14},
+       {0x0000aaa8, 0x00000000, 0x00000000, 0x0000cb18, 0x0000cb18, 0x0000cb18},
+       {0x0000aaac, 0x00000000, 0x00000000, 0x0000cb8c, 0x0000cb8c, 0x0000cb8c},
+       {0x0000aab0, 0x00000000, 0x00000000, 0x0000cb90, 0x0000cb90, 0x0000cb90},
+       {0x0000aab4, 0x00000000, 0x00000000, 0x0000cf18, 0x0000cf18, 0x0000cf18},
+       {0x0000aab8, 0x00000000, 0x00000000, 0x0000cf24, 0x0000cf24, 0x0000cf24},
+       {0x0000aabc, 0x00000000, 0x00000000, 0x0000cf28, 0x0000cf28, 0x0000cf28},
+       {0x0000aac0, 0x00000000, 0x00000000, 0x0000d314, 0x0000d314, 0x0000d314},
+       {0x0000aac4, 0x00000000, 0x00000000, 0x0000d318, 0x0000d318, 0x0000d318},
+       {0x0000aac8, 0x00000000, 0x00000000, 0x0000d38c, 0x0000d38c, 0x0000d38c},
+       {0x0000aacc, 0x00000000, 0x00000000, 0x0000d390, 0x0000d390, 0x0000d390},
+       {0x0000aad0, 0x00000000, 0x00000000, 0x0000d394, 0x0000d394, 0x0000d394},
+       {0x0000aad4, 0x00000000, 0x00000000, 0x0000d398, 0x0000d398, 0x0000d398},
+       {0x0000aad8, 0x00000000, 0x00000000, 0x0000d3a4, 0x0000d3a4, 0x0000d3a4},
+       {0x0000aadc, 0x00000000, 0x00000000, 0x0000d3a8, 0x0000d3a8, 0x0000d3a8},
+       {0x0000aae0, 0x00000000, 0x00000000, 0x0000d3ac, 0x0000d3ac, 0x0000d3ac},
+       {0x0000aae4, 0x00000000, 0x00000000, 0x0000d3b0, 0x0000d3b0, 0x0000d3b0},
+       {0x0000aae8, 0x00000000, 0x00000000, 0x0000f380, 0x0000f380, 0x0000f380},
+       {0x0000aaec, 0x00000000, 0x00000000, 0x0000f384, 0x0000f384, 0x0000f384},
+       {0x0000aaf0, 0x00000000, 0x00000000, 0x0000f388, 0x0000f388, 0x0000f388},
+       {0x0000aaf4, 0x00000000, 0x00000000, 0x0000f710, 0x0000f710, 0x0000f710},
+       {0x0000aaf8, 0x00000000, 0x00000000, 0x0000f714, 0x0000f714, 0x0000f714},
+       {0x0000aafc, 0x00000000, 0x00000000, 0x0000f718, 0x0000f718, 0x0000f718},
+       {0x0000ab00, 0x00000000, 0x00000000, 0x0000fb10, 0x0000fb10, 0x0000fb10},
+       {0x0000ab04, 0x00000000, 0x00000000, 0x0000fb14, 0x0000fb14, 0x0000fb14},
+       {0x0000ab08, 0x00000000, 0x00000000, 0x0000fb18, 0x0000fb18, 0x0000fb18},
+       {0x0000ab0c, 0x00000000, 0x00000000, 0x0000fb8c, 0x0000fb8c, 0x0000fb8c},
+       {0x0000ab10, 0x00000000, 0x00000000, 0x0000fb90, 0x0000fb90, 0x0000fb90},
+       {0x0000ab14, 0x00000000, 0x00000000, 0x0000fb94, 0x0000fb94, 0x0000fb94},
+       {0x0000ab18, 0x00000000, 0x00000000, 0x0000ff8c, 0x0000ff8c, 0x0000ff8c},
+       {0x0000ab1c, 0x00000000, 0x00000000, 0x0000ff90, 0x0000ff90, 0x0000ff90},
+       {0x0000ab20, 0x00000000, 0x00000000, 0x0000ff94, 0x0000ff94, 0x0000ff94},
+       {0x0000ab24, 0x00000000, 0x00000000, 0x0000ffa0, 0x0000ffa0, 0x0000ffa0},
+       {0x0000ab28, 0x00000000, 0x00000000, 0x0000ffa4, 0x0000ffa4, 0x0000ffa4},
+       {0x0000ab2c, 0x00000000, 0x00000000, 0x0000ffa8, 0x0000ffa8, 0x0000ffa8},
+       {0x0000ab30, 0x00000000, 0x00000000, 0x0000ffac, 0x0000ffac, 0x0000ffac},
+       {0x0000ab34, 0x00000000, 0x00000000, 0x0000ffb0, 0x0000ffb0, 0x0000ffb0},
+       {0x0000ab38, 0x00000000, 0x00000000, 0x0000ffb4, 0x0000ffb4, 0x0000ffb4},
+       {0x0000ab3c, 0x00000000, 0x00000000, 0x0000ffa1, 0x0000ffa1, 0x0000ffa1},
+       {0x0000ab40, 0x00000000, 0x00000000, 0x0000ffa5, 0x0000ffa5, 0x0000ffa5},
+       {0x0000ab44, 0x00000000, 0x00000000, 0x0000ffa9, 0x0000ffa9, 0x0000ffa9},
+       {0x0000ab48, 0x00000000, 0x00000000, 0x0000ffad, 0x0000ffad, 0x0000ffad},
+       {0x0000ab4c, 0x00000000, 0x00000000, 0x0000ffb1, 0x0000ffb1, 0x0000ffb1},
+       {0x0000ab50, 0x00000000, 0x00000000, 0x0000ffb5, 0x0000ffb5, 0x0000ffb5},
+       {0x0000ab54, 0x00000000, 0x00000000, 0x0000ffb9, 0x0000ffb9, 0x0000ffb9},
+       {0x0000ab58, 0x00000000, 0x00000000, 0x0000ffc5, 0x0000ffc5, 0x0000ffc5},
+       {0x0000ab5c, 0x00000000, 0x00000000, 0x0000ffc9, 0x0000ffc9, 0x0000ffc9},
+       {0x0000ab60, 0x00000000, 0x00000000, 0x0000ffcd, 0x0000ffcd, 0x0000ffcd},
+       {0x0000ab64, 0x00000000, 0x00000000, 0x0000ffd1, 0x0000ffd1, 0x0000ffd1},
+       {0x0000ab68, 0x00000000, 0x00000000, 0x0000ffd5, 0x0000ffd5, 0x0000ffd5},
+       {0x0000ab6c, 0x00000000, 0x00000000, 0x0000ffc2, 0x0000ffc2, 0x0000ffc2},
+       {0x0000ab70, 0x00000000, 0x00000000, 0x0000ffc6, 0x0000ffc6, 0x0000ffc6},
+       {0x0000ab74, 0x00000000, 0x00000000, 0x0000ffca, 0x0000ffca, 0x0000ffca},
+       {0x0000ab78, 0x00000000, 0x00000000, 0x0000ffce, 0x0000ffce, 0x0000ffce},
+       {0x0000ab7c, 0x00000000, 0x00000000, 0x0000ffd2, 0x0000ffd2, 0x0000ffd2},
+       {0x0000ab80, 0x00000000, 0x00000000, 0x0000ffd6, 0x0000ffd6, 0x0000ffd6},
+       {0x0000ab84, 0x00000000, 0x00000000, 0x0000ffda, 0x0000ffda, 0x0000ffda},
+       {0x0000ab88, 0x00000000, 0x00000000, 0x0000ffc7, 0x0000ffc7, 0x0000ffc7},
+       {0x0000ab8c, 0x00000000, 0x00000000, 0x0000ffcb, 0x0000ffcb, 0x0000ffcb},
+       {0x0000ab90, 0x00000000, 0x00000000, 0x0000ffcf, 0x0000ffcf, 0x0000ffcf},
+       {0x0000ab94, 0x00000000, 0x00000000, 0x0000ffd3, 0x0000ffd3, 0x0000ffd3},
+       {0x0000ab98, 0x00000000, 0x00000000, 0x0000ffd7, 0x0000ffd7, 0x0000ffd7},
+       {0x0000ab9c, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+       {0x0000aba0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+       {0x0000aba4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+       {0x0000aba8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+       {0x0000abac, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+       {0x0000abb0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+       {0x0000abb4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+       {0x0000abb8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+       {0x0000abbc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+       {0x0000abc0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+       {0x0000abc4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+       {0x0000abc8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+       {0x0000abcc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+       {0x0000abd0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+       {0x0000abd4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+       {0x0000abd8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+       {0x0000abdc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+       {0x0000abe0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+       {0x0000abe4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+       {0x0000abe8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+       {0x0000abec, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+       {0x0000abf0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+       {0x0000abf4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+       {0x0000abf8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+       {0x0000abfc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+       {0x00009848, 0x00000000, 0x00000000, 0x00001067, 0x00001067, 0x00001067},
+       {0x0000a848, 0x00000000, 0x00000000, 0x00001067, 0x00001067, 0x00001067},
+};
+
+static const u32 ar9287PciePhy_clkreq_always_on_L1_9287_1_1[][2] = {
+       /* Addr      allmodes  */
+       {0x00004040, 0x9248fd00},
+       {0x00004040, 0x24924924},
+       {0x00004040, 0xa8000019},
+       {0x00004040, 0x13160820},
+       {0x00004040, 0xe5980560},
+       {0x00004040, 0xc01dcffd},
+       {0x00004040, 0x1aaabe41},
+       {0x00004040, 0xbe105554},
+       {0x00004040, 0x00043007},
+       {0x00004044, 0x00000000},
+};
+
+static const u32 ar9287PciePhy_clkreq_off_L1_9287_1_1[][2] = {
+       /* Addr      allmodes  */
+       {0x00004040, 0x9248fd00},
+       {0x00004040, 0x24924924},
+       {0x00004040, 0xa8000019},
+       {0x00004040, 0x13160820},
+       {0x00004040, 0xe5980560},
+       {0x00004040, 0xc01dcffc},
+       {0x00004040, 0x1aaabe41},
+       {0x00004040, 0xbe105554},
+       {0x00004040, 0x00043007},
+       {0x00004044, 0x00000000},
+};
+
+static const u32 ar9271Modes_9271[][6] = {
+       {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0},
+       {0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0},
+       {0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180},
+       {0x000010f0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000008},
+       {0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00, 0x06e006e0},
+       {0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b, 0x0988004f},
+       {0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440, 0x00006880},
+       {0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303},
+       {0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200},
+       {0x00009824, 0x01000e0e, 0x01000e0e, 0x01000e0e, 0x01000e0e, 0x01000e0e},
+       {0x00009828, 0x3a020001, 0x3a020001, 0x3a020001, 0x3a020001, 0x3a020001},
+       {0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e},
+       {0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007},
+       {0x00009840, 0x206a012e, 0x206a012e, 0x206a012e, 0x206a012e, 0x206a012e},
+       {0x00009844, 0x0372161e, 0x0372161e, 0x03721620, 0x03721620, 0x037216a0},
+       {0x00009848, 0x00001066, 0x00001066, 0x00001053, 0x00001053, 0x00001059},
+       {0x0000a848, 0x00001066, 0x00001066, 0x00001053, 0x00001053, 0x00001059},
+       {0x00009850, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2},
+       {0x00009858, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e},
+       {0x0000985c, 0x3139605e, 0x3139605e, 0x3137605e, 0x3137605e, 0x3139605e},
+       {0x00009860, 0x00058d18, 0x00058d18, 0x00058d18, 0x00058d18, 0x00058d18},
+       {0x00009864, 0x0000fe00, 0x0000fe00, 0x0001ce00, 0x0001ce00, 0x0001ce00},
+       {0x00009868, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0},
+       {0x0000986c, 0x06903081, 0x06903081, 0x06903881, 0x06903881, 0x06903881},
+       {0x00009910, 0x30002310, 0x30002310, 0x30002310, 0x30002310, 0x30002310},
+       {0x00009914, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898, 0x000007d0},
+       {0x00009918, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b, 0x00000016},
+       {0x00009924, 0xd00a8007, 0xd00a8007, 0xd00a800d, 0xd00a800d, 0xd00a800d},
+       {0x00009944, 0xffbc1010, 0xffbc1010, 0xffbc1020, 0xffbc1020, 0xffbc1010},
+       {0x00009960, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x00009964, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x000099b8, 0x0000421c, 0x0000421c, 0x0000421c, 0x0000421c, 0x0000421c},
+       {0x000099bc, 0x00000600, 0x00000600, 0x00000c00, 0x00000c00, 0x00000c00},
+       {0x000099c0, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4},
+       {0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77},
+       {0x000099c8, 0x6af6532f, 0x6af6532f, 0x6af6532f, 0x6af6532f, 0x6af6532f},
+       {0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8},
+       {0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, 0x00046384},
+       {0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x00009a00, 0x00000000, 0x00000000, 0x00058084, 0x00058084, 0x00000000},
+       {0x00009a04, 0x00000000, 0x00000000, 0x00058088, 0x00058088, 0x00000000},
+       {0x00009a08, 0x00000000, 0x00000000, 0x0005808c, 0x0005808c, 0x00000000},
+       {0x00009a0c, 0x00000000, 0x00000000, 0x00058100, 0x00058100, 0x00000000},
+       {0x00009a10, 0x00000000, 0x00000000, 0x00058104, 0x00058104, 0x00000000},
+       {0x00009a14, 0x00000000, 0x00000000, 0x00058108, 0x00058108, 0x00000000},
+       {0x00009a18, 0x00000000, 0x00000000, 0x0005810c, 0x0005810c, 0x00000000},
+       {0x00009a1c, 0x00000000, 0x00000000, 0x00058110, 0x00058110, 0x00000000},
+       {0x00009a20, 0x00000000, 0x00000000, 0x00058114, 0x00058114, 0x00000000},
+       {0x00009a24, 0x00000000, 0x00000000, 0x00058180, 0x00058180, 0x00000000},
+       {0x00009a28, 0x00000000, 0x00000000, 0x00058184, 0x00058184, 0x00000000},
+       {0x00009a2c, 0x00000000, 0x00000000, 0x00058188, 0x00058188, 0x00000000},
+       {0x00009a30, 0x00000000, 0x00000000, 0x0005818c, 0x0005818c, 0x00000000},
+       {0x00009a34, 0x00000000, 0x00000000, 0x00058190, 0x00058190, 0x00000000},
+       {0x00009a38, 0x00000000, 0x00000000, 0x00058194, 0x00058194, 0x00000000},
+       {0x00009a3c, 0x00000000, 0x00000000, 0x000581a0, 0x000581a0, 0x00000000},
+       {0x00009a40, 0x00000000, 0x00000000, 0x0005820c, 0x0005820c, 0x00000000},
+       {0x00009a44, 0x00000000, 0x00000000, 0x000581a8, 0x000581a8, 0x00000000},
+       {0x00009a48, 0x00000000, 0x00000000, 0x00058284, 0x00058284, 0x00000000},
+       {0x00009a4c, 0x00000000, 0x00000000, 0x00058288, 0x00058288, 0x00000000},
+       {0x00009a50, 0x00000000, 0x00000000, 0x00058224, 0x00058224, 0x00000000},
+       {0x00009a54, 0x00000000, 0x00000000, 0x00058290, 0x00058290, 0x00000000},
+       {0x00009a58, 0x00000000, 0x00000000, 0x00058300, 0x00058300, 0x00000000},
+       {0x00009a5c, 0x00000000, 0x00000000, 0x00058304, 0x00058304, 0x00000000},
+       {0x00009a60, 0x00000000, 0x00000000, 0x00058308, 0x00058308, 0x00000000},
+       {0x00009a64, 0x00000000, 0x00000000, 0x0005830c, 0x0005830c, 0x00000000},
+       {0x00009a68, 0x00000000, 0x00000000, 0x00058380, 0x00058380, 0x00000000},
+       {0x00009a6c, 0x00000000, 0x00000000, 0x00058384, 0x00058384, 0x00000000},
+       {0x00009a70, 0x00000000, 0x00000000, 0x00068700, 0x00068700, 0x00000000},
+       {0x00009a74, 0x00000000, 0x00000000, 0x00068704, 0x00068704, 0x00000000},
+       {0x00009a78, 0x00000000, 0x00000000, 0x00068708, 0x00068708, 0x00000000},
+       {0x00009a7c, 0x00000000, 0x00000000, 0x0006870c, 0x0006870c, 0x00000000},
+       {0x00009a80, 0x00000000, 0x00000000, 0x00068780, 0x00068780, 0x00000000},
+       {0x00009a84, 0x00000000, 0x00000000, 0x00068784, 0x00068784, 0x00000000},
+       {0x00009a88, 0x00000000, 0x00000000, 0x00078b00, 0x00078b00, 0x00000000},
+       {0x00009a8c, 0x00000000, 0x00000000, 0x00078b04, 0x00078b04, 0x00000000},
+       {0x00009a90, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000},
+       {0x00009a94, 0x00000000, 0x00000000, 0x00078b0c, 0x00078b0c, 0x00000000},
+       {0x00009a98, 0x00000000, 0x00000000, 0x00078b80, 0x00078b80, 0x00000000},
+       {0x00009a9c, 0x00000000, 0x00000000, 0x00078b84, 0x00078b84, 0x00000000},
+       {0x00009aa0, 0x00000000, 0x00000000, 0x00078b88, 0x00078b88, 0x00000000},
+       {0x00009aa4, 0x00000000, 0x00000000, 0x00078b8c, 0x00078b8c, 0x00000000},
+       {0x00009aa8, 0x00000000, 0x00000000, 0x00078b90, 0x00078b90, 0x00000000},
+       {0x00009aac, 0x00000000, 0x00000000, 0x000caf80, 0x000caf80, 0x00000000},
+       {0x00009ab0, 0x00000000, 0x00000000, 0x000caf84, 0x000caf84, 0x00000000},
+       {0x00009ab4, 0x00000000, 0x00000000, 0x000caf88, 0x000caf88, 0x00000000},
+       {0x00009ab8, 0x00000000, 0x00000000, 0x000caf8c, 0x000caf8c, 0x00000000},
+       {0x00009abc, 0x00000000, 0x00000000, 0x000caf90, 0x000caf90, 0x00000000},
+       {0x00009ac0, 0x00000000, 0x00000000, 0x000db30c, 0x000db30c, 0x00000000},
+       {0x00009ac4, 0x00000000, 0x00000000, 0x000db310, 0x000db310, 0x00000000},
+       {0x00009ac8, 0x00000000, 0x00000000, 0x000db384, 0x000db384, 0x00000000},
+       {0x00009acc, 0x00000000, 0x00000000, 0x000db388, 0x000db388, 0x00000000},
+       {0x00009ad0, 0x00000000, 0x00000000, 0x000db324, 0x000db324, 0x00000000},
+       {0x00009ad4, 0x00000000, 0x00000000, 0x000eb704, 0x000eb704, 0x00000000},
+       {0x00009ad8, 0x00000000, 0x00000000, 0x000eb6a4, 0x000eb6a4, 0x00000000},
+       {0x00009adc, 0x00000000, 0x00000000, 0x000eb6a8, 0x000eb6a8, 0x00000000},
+       {0x00009ae0, 0x00000000, 0x00000000, 0x000eb710, 0x000eb710, 0x00000000},
+       {0x00009ae4, 0x00000000, 0x00000000, 0x000eb714, 0x000eb714, 0x00000000},
+       {0x00009ae8, 0x00000000, 0x00000000, 0x000eb720, 0x000eb720, 0x00000000},
+       {0x00009aec, 0x00000000, 0x00000000, 0x000eb724, 0x000eb724, 0x00000000},
+       {0x00009af0, 0x00000000, 0x00000000, 0x000eb728, 0x000eb728, 0x00000000},
+       {0x00009af4, 0x00000000, 0x00000000, 0x000eb72c, 0x000eb72c, 0x00000000},
+       {0x00009af8, 0x00000000, 0x00000000, 0x000eb7a0, 0x000eb7a0, 0x00000000},
+       {0x00009afc, 0x00000000, 0x00000000, 0x000eb7a4, 0x000eb7a4, 0x00000000},
+       {0x00009b00, 0x00000000, 0x00000000, 0x000eb7a8, 0x000eb7a8, 0x00000000},
+       {0x00009b04, 0x00000000, 0x00000000, 0x000eb7b0, 0x000eb7b0, 0x00000000},
+       {0x00009b08, 0x00000000, 0x00000000, 0x000eb7b4, 0x000eb7b4, 0x00000000},
+       {0x00009b0c, 0x00000000, 0x00000000, 0x000eb7b8, 0x000eb7b8, 0x00000000},
+       {0x00009b10, 0x00000000, 0x00000000, 0x000eb7a5, 0x000eb7a5, 0x00000000},
+       {0x00009b14, 0x00000000, 0x00000000, 0x000eb7a9, 0x000eb7a9, 0x00000000},
+       {0x00009b18, 0x00000000, 0x00000000, 0x000eb7ad, 0x000eb7ad, 0x00000000},
+       {0x00009b1c, 0x00000000, 0x00000000, 0x000eb7b1, 0x000eb7b1, 0x00000000},
+       {0x00009b20, 0x00000000, 0x00000000, 0x000eb7b5, 0x000eb7b5, 0x00000000},
+       {0x00009b24, 0x00000000, 0x00000000, 0x000eb7b9, 0x000eb7b9, 0x00000000},
+       {0x00009b28, 0x00000000, 0x00000000, 0x000eb7c5, 0x000eb7c5, 0x00000000},
+       {0x00009b2c, 0x00000000, 0x00000000, 0x000eb7c9, 0x000eb7c9, 0x00000000},
+       {0x00009b30, 0x00000000, 0x00000000, 0x000eb7d1, 0x000eb7d1, 0x00000000},
+       {0x00009b34, 0x00000000, 0x00000000, 0x000eb7d5, 0x000eb7d5, 0x00000000},
+       {0x00009b38, 0x00000000, 0x00000000, 0x000eb7d9, 0x000eb7d9, 0x00000000},
+       {0x00009b3c, 0x00000000, 0x00000000, 0x000eb7c6, 0x000eb7c6, 0x00000000},
+       {0x00009b40, 0x00000000, 0x00000000, 0x000eb7ca, 0x000eb7ca, 0x00000000},
+       {0x00009b44, 0x00000000, 0x00000000, 0x000eb7ce, 0x000eb7ce, 0x00000000},
+       {0x00009b48, 0x00000000, 0x00000000, 0x000eb7d2, 0x000eb7d2, 0x00000000},
+       {0x00009b4c, 0x00000000, 0x00000000, 0x000eb7d6, 0x000eb7d6, 0x00000000},
+       {0x00009b50, 0x00000000, 0x00000000, 0x000eb7c3, 0x000eb7c3, 0x00000000},
+       {0x00009b54, 0x00000000, 0x00000000, 0x000eb7c7, 0x000eb7c7, 0x00000000},
+       {0x00009b58, 0x00000000, 0x00000000, 0x000eb7cb, 0x000eb7cb, 0x00000000},
+       {0x00009b5c, 0x00000000, 0x00000000, 0x000eb7cf, 0x000eb7cf, 0x00000000},
+       {0x00009b60, 0x00000000, 0x00000000, 0x000eb7d7, 0x000eb7d7, 0x00000000},
+       {0x00009b64, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x00009b68, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x00009b6c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x00009b70, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x00009b74, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x00009b78, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x00009b7c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x00009b80, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x00009b84, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x00009b88, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x00009b8c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x00009b90, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x00009b94, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x00009b98, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x00009b9c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x00009ba0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x00009ba4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x00009ba8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x00009bac, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x00009bb0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x00009bb4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x00009bb8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x00009bbc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x00009bc0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x00009bc4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x00009bc8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x00009bcc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x00009bd0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x00009bd4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x00009bd8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x00009bdc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x00009be0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x00009be4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x00009be8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x00009bec, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x00009bf0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x00009bf4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x00009bf8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x00009bfc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x0000aa00, 0x00000000, 0x00000000, 0x00058084, 0x00058084, 0x00000000},
+       {0x0000aa04, 0x00000000, 0x00000000, 0x00058088, 0x00058088, 0x00000000},
+       {0x0000aa08, 0x00000000, 0x00000000, 0x0005808c, 0x0005808c, 0x00000000},
+       {0x0000aa0c, 0x00000000, 0x00000000, 0x00058100, 0x00058100, 0x00000000},
+       {0x0000aa10, 0x00000000, 0x00000000, 0x00058104, 0x00058104, 0x00000000},
+       {0x0000aa14, 0x00000000, 0x00000000, 0x00058108, 0x00058108, 0x00000000},
+       {0x0000aa18, 0x00000000, 0x00000000, 0x0005810c, 0x0005810c, 0x00000000},
+       {0x0000aa1c, 0x00000000, 0x00000000, 0x00058110, 0x00058110, 0x00000000},
+       {0x0000aa20, 0x00000000, 0x00000000, 0x00058114, 0x00058114, 0x00000000},
+       {0x0000aa24, 0x00000000, 0x00000000, 0x00058180, 0x00058180, 0x00000000},
+       {0x0000aa28, 0x00000000, 0x00000000, 0x00058184, 0x00058184, 0x00000000},
+       {0x0000aa2c, 0x00000000, 0x00000000, 0x00058188, 0x00058188, 0x00000000},
+       {0x0000aa30, 0x00000000, 0x00000000, 0x0005818c, 0x0005818c, 0x00000000},
+       {0x0000aa34, 0x00000000, 0x00000000, 0x00058190, 0x00058190, 0x00000000},
+       {0x0000aa38, 0x00000000, 0x00000000, 0x00058194, 0x00058194, 0x00000000},
+       {0x0000aa3c, 0x00000000, 0x00000000, 0x000581a0, 0x000581a0, 0x00000000},
+       {0x0000aa40, 0x00000000, 0x00000000, 0x0005820c, 0x0005820c, 0x00000000},
+       {0x0000aa44, 0x00000000, 0x00000000, 0x000581a8, 0x000581a8, 0x00000000},
+       {0x0000aa48, 0x00000000, 0x00000000, 0x00058284, 0x00058284, 0x00000000},
+       {0x0000aa4c, 0x00000000, 0x00000000, 0x00058288, 0x00058288, 0x00000000},
+       {0x0000aa50, 0x00000000, 0x00000000, 0x00058224, 0x00058224, 0x00000000},
+       {0x0000aa54, 0x00000000, 0x00000000, 0x00058290, 0x00058290, 0x00000000},
+       {0x0000aa58, 0x00000000, 0x00000000, 0x00058300, 0x00058300, 0x00000000},
+       {0x0000aa5c, 0x00000000, 0x00000000, 0x00058304, 0x00058304, 0x00000000},
+       {0x0000aa60, 0x00000000, 0x00000000, 0x00058308, 0x00058308, 0x00000000},
+       {0x0000aa64, 0x00000000, 0x00000000, 0x0005830c, 0x0005830c, 0x00000000},
+       {0x0000aa68, 0x00000000, 0x00000000, 0x00058380, 0x00058380, 0x00000000},
+       {0x0000aa6c, 0x00000000, 0x00000000, 0x00058384, 0x00058384, 0x00000000},
+       {0x0000aa70, 0x00000000, 0x00000000, 0x00068700, 0x00068700, 0x00000000},
+       {0x0000aa74, 0x00000000, 0x00000000, 0x00068704, 0x00068704, 0x00000000},
+       {0x0000aa78, 0x00000000, 0x00000000, 0x00068708, 0x00068708, 0x00000000},
+       {0x0000aa7c, 0x00000000, 0x00000000, 0x0006870c, 0x0006870c, 0x00000000},
+       {0x0000aa80, 0x00000000, 0x00000000, 0x00068780, 0x00068780, 0x00000000},
+       {0x0000aa84, 0x00000000, 0x00000000, 0x00068784, 0x00068784, 0x00000000},
+       {0x0000aa88, 0x00000000, 0x00000000, 0x00078b00, 0x00078b00, 0x00000000},
+       {0x0000aa8c, 0x00000000, 0x00000000, 0x00078b04, 0x00078b04, 0x00000000},
+       {0x0000aa90, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000},
+       {0x0000aa94, 0x00000000, 0x00000000, 0x00078b0c, 0x00078b0c, 0x00000000},
+       {0x0000aa98, 0x00000000, 0x00000000, 0x00078b80, 0x00078b80, 0x00000000},
+       {0x0000aa9c, 0x00000000, 0x00000000, 0x00078b84, 0x00078b84, 0x00000000},
+       {0x0000aaa0, 0x00000000, 0x00000000, 0x00078b88, 0x00078b88, 0x00000000},
+       {0x0000aaa4, 0x00000000, 0x00000000, 0x00078b8c, 0x00078b8c, 0x00000000},
+       {0x0000aaa8, 0x00000000, 0x00000000, 0x00078b90, 0x00078b90, 0x00000000},
+       {0x0000aaac, 0x00000000, 0x00000000, 0x000caf80, 0x000caf80, 0x00000000},
+       {0x0000aab0, 0x00000000, 0x00000000, 0x000caf84, 0x000caf84, 0x00000000},
+       {0x0000aab4, 0x00000000, 0x00000000, 0x000caf88, 0x000caf88, 0x00000000},
+       {0x0000aab8, 0x00000000, 0x00000000, 0x000caf8c, 0x000caf8c, 0x00000000},
+       {0x0000aabc, 0x00000000, 0x00000000, 0x000caf90, 0x000caf90, 0x00000000},
+       {0x0000aac0, 0x00000000, 0x00000000, 0x000db30c, 0x000db30c, 0x00000000},
+       {0x0000aac4, 0x00000000, 0x00000000, 0x000db310, 0x000db310, 0x00000000},
+       {0x0000aac8, 0x00000000, 0x00000000, 0x000db384, 0x000db384, 0x00000000},
+       {0x0000aacc, 0x00000000, 0x00000000, 0x000db388, 0x000db388, 0x00000000},
+       {0x0000aad0, 0x00000000, 0x00000000, 0x000db324, 0x000db324, 0x00000000},
+       {0x0000aad4, 0x00000000, 0x00000000, 0x000eb704, 0x000eb704, 0x00000000},
+       {0x0000aad8, 0x00000000, 0x00000000, 0x000eb6a4, 0x000eb6a4, 0x00000000},
+       {0x0000aadc, 0x00000000, 0x00000000, 0x000eb6a8, 0x000eb6a8, 0x00000000},
+       {0x0000aae0, 0x00000000, 0x00000000, 0x000eb710, 0x000eb710, 0x00000000},
+       {0x0000aae4, 0x00000000, 0x00000000, 0x000eb714, 0x000eb714, 0x00000000},
+       {0x0000aae8, 0x00000000, 0x00000000, 0x000eb720, 0x000eb720, 0x00000000},
+       {0x0000aaec, 0x00000000, 0x00000000, 0x000eb724, 0x000eb724, 0x00000000},
+       {0x0000aaf0, 0x00000000, 0x00000000, 0x000eb728, 0x000eb728, 0x00000000},
+       {0x0000aaf4, 0x00000000, 0x00000000, 0x000eb72c, 0x000eb72c, 0x00000000},
+       {0x0000aaf8, 0x00000000, 0x00000000, 0x000eb7a0, 0x000eb7a0, 0x00000000},
+       {0x0000aafc, 0x00000000, 0x00000000, 0x000eb7a4, 0x000eb7a4, 0x00000000},
+       {0x0000ab00, 0x00000000, 0x00000000, 0x000eb7a8, 0x000eb7a8, 0x00000000},
+       {0x0000ab04, 0x00000000, 0x00000000, 0x000eb7b0, 0x000eb7b0, 0x00000000},
+       {0x0000ab08, 0x00000000, 0x00000000, 0x000eb7b4, 0x000eb7b4, 0x00000000},
+       {0x0000ab0c, 0x00000000, 0x00000000, 0x000eb7b8, 0x000eb7b8, 0x00000000},
+       {0x0000ab10, 0x00000000, 0x00000000, 0x000eb7a5, 0x000eb7a5, 0x00000000},
+       {0x0000ab14, 0x00000000, 0x00000000, 0x000eb7a9, 0x000eb7a9, 0x00000000},
+       {0x0000ab18, 0x00000000, 0x00000000, 0x000eb7ad, 0x000eb7ad, 0x00000000},
+       {0x0000ab1c, 0x00000000, 0x00000000, 0x000eb7b1, 0x000eb7b1, 0x00000000},
+       {0x0000ab20, 0x00000000, 0x00000000, 0x000eb7b5, 0x000eb7b5, 0x00000000},
+       {0x0000ab24, 0x00000000, 0x00000000, 0x000eb7b9, 0x000eb7b9, 0x00000000},
+       {0x0000ab28, 0x00000000, 0x00000000, 0x000eb7c5, 0x000eb7c5, 0x00000000},
+       {0x0000ab2c, 0x00000000, 0x00000000, 0x000eb7c9, 0x000eb7c9, 0x00000000},
+       {0x0000ab30, 0x00000000, 0x00000000, 0x000eb7d1, 0x000eb7d1, 0x00000000},
+       {0x0000ab34, 0x00000000, 0x00000000, 0x000eb7d5, 0x000eb7d5, 0x00000000},
+       {0x0000ab38, 0x00000000, 0x00000000, 0x000eb7d9, 0x000eb7d9, 0x00000000},
+       {0x0000ab3c, 0x00000000, 0x00000000, 0x000eb7c6, 0x000eb7c6, 0x00000000},
+       {0x0000ab40, 0x00000000, 0x00000000, 0x000eb7ca, 0x000eb7ca, 0x00000000},
+       {0x0000ab44, 0x00000000, 0x00000000, 0x000eb7ce, 0x000eb7ce, 0x00000000},
+       {0x0000ab48, 0x00000000, 0x00000000, 0x000eb7d2, 0x000eb7d2, 0x00000000},
+       {0x0000ab4c, 0x00000000, 0x00000000, 0x000eb7d6, 0x000eb7d6, 0x00000000},
+       {0x0000ab50, 0x00000000, 0x00000000, 0x000eb7c3, 0x000eb7c3, 0x00000000},
+       {0x0000ab54, 0x00000000, 0x00000000, 0x000eb7c7, 0x000eb7c7, 0x00000000},
+       {0x0000ab58, 0x00000000, 0x00000000, 0x000eb7cb, 0x000eb7cb, 0x00000000},
+       {0x0000ab5c, 0x00000000, 0x00000000, 0x000eb7cf, 0x000eb7cf, 0x00000000},
+       {0x0000ab60, 0x00000000, 0x00000000, 0x000eb7d7, 0x000eb7d7, 0x00000000},
+       {0x0000ab64, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x0000ab68, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x0000ab6c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x0000ab70, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x0000ab74, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x0000ab78, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x0000ab7c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x0000ab80, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x0000ab84, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x0000ab88, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x0000ab8c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x0000ab90, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x0000ab94, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x0000ab98, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x0000ab9c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x0000aba0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x0000aba4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x0000aba8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x0000abac, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x0000abb0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x0000abb4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x0000abb8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x0000abbc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x0000abc0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x0000abc4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x0000abc8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x0000abcc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x0000abd0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x0000abd4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x0000abd8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x0000abdc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x0000abe0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x0000abe4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x0000abe8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x0000abec, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x0000abf0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x0000abf4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x0000abf8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x0000abfc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000},
+       {0x0000a204, 0x00000004, 0x00000004, 0x00000004, 0x00000004, 0x00000004},
+       {0x0000a20c, 0x00000014, 0x00000014, 0x0001f000, 0x0001f000, 0x0001f000},
+       {0x0000b20c, 0x00000014, 0x00000014, 0x0001f000, 0x0001f000, 0x0001f000},
+       {0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a},
+       {0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000},
+       {0x0000a250, 0x0004f000, 0x0004f000, 0x0004a000, 0x0004a000, 0x0004a000},
+       {0x0000a358, 0x7999aa02, 0x7999aa02, 0x7999aa0e, 0x7999aa0e, 0x7999aa0e},
+};
+
+static const u32 ar9271Common_9271[][2] = {
+       /* Addr      allmodes  */
+       {0x0000000c, 0x00000000},
+       {0x00000030, 0x00020045},
+       {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},
+       {0x00004024, 0x0000001f},
+       {0x00004060, 0x00000000},
+       {0x00004064, 0x00000000},
+       {0x00008004, 0x00000000},
+       {0x00008008, 0x00000000},
+       {0x0000800c, 0x00000000},
+       {0x00008018, 0x00000700},
+       {0x00008020, 0x00000000},
+       {0x00008038, 0x00000000},
+       {0x0000803c, 0x00000000},
+       {0x00008048, 0x00000000},
+       {0x00008054, 0x00000000},
+       {0x00008058, 0x00000000},
+       {0x0000805c, 0x000fc78f},
+       {0x00008060, 0x0000000f},
+       {0x00008064, 0x00000000},
+       {0x00008070, 0x00000000},
+       {0x000080b0, 0x00000000},
+       {0x000080b4, 0x00000000},
+       {0x000080b8, 0x00000000},
+       {0x000080bc, 0x00000000},
+       {0x000080c0, 0x2a80001a},
+       {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, 0x08f04810},
+       {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},
+       {0x000081c0, 0x00000000},
+       {0x000081d0, 0x0000320a},
+       {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, 0x88a00010},
+       {0x00008270, 0x00000000},
+       {0x00008274, 0x40000000},
+       {0x00008278, 0x003e4180},
+       {0x0000827c, 0x00000000},
+       {0x00008284, 0x0000002c},
+       {0x00008288, 0x0000002c},
+       {0x0000828c, 0x00000000},
+       {0x00008294, 0x00000000},
+       {0x00008298, 0x00000000},
+       {0x0000829c, 0x00000000},
+       {0x00008300, 0x00000040},
+       {0x00008314, 0x00000000},
+       {0x00008328, 0x00000000},
+       {0x0000832c, 0x00000001},
+       {0x00008330, 0x00000302},
+       {0x00008334, 0x00000e00},
+       {0x00008338, 0x00ff0000},
+       {0x0000833c, 0x00000000},
+       {0x00008340, 0x00010380},
+       {0x00008344, 0x00581043},
+       {0x00007010, 0x00000030},
+       {0x00007034, 0x00000002},
+       {0x00007038, 0x000004c2},
+       {0x00007800, 0x00140000},
+       {0x00007804, 0x0e4548d8},
+       {0x00007808, 0x54214514},
+       {0x0000780c, 0x02025820},
+       {0x00007810, 0x71c0d388},
+       {0x00007814, 0x924934a8},
+       {0x0000781c, 0x00000000},
+       {0x00007828, 0x66964300},
+       {0x0000782c, 0x8db6d961},
+       {0x00007830, 0x8db6d96c},
+       {0x00007834, 0x6140008b},
+       {0x0000783c, 0x72ee0a72},
+       {0x00007840, 0xbbfffffc},
+       {0x00007844, 0x000c0db6},
+       {0x00007848, 0x6db6246f},
+       {0x0000784c, 0x6d9b66db},
+       {0x00007850, 0x6d8c6dba},
+       {0x00007854, 0x00040000},
+       {0x00007858, 0xdb003012},
+       {0x0000785c, 0x04924914},
+       {0x00007860, 0x21084210},
+       {0x00007864, 0xf7d7ffde},
+       {0x00007868, 0xc2034080},
+       {0x00007870, 0x10142c00},
+       {0x00009808, 0x00000000},
+       {0x0000980c, 0xafe68e30},
+       {0x00009810, 0xfd14e000},
+       {0x00009814, 0x9c0a9f6b},
+       {0x0000981c, 0x00000000},
+       {0x0000982c, 0x0000a000},
+       {0x00009830, 0x00000000},
+       {0x0000983c, 0x00200400},
+       {0x0000984c, 0x0040233c},
+       {0x00009854, 0x00000044},
+       {0x00009900, 0x00000000},
+       {0x00009904, 0x00000000},
+       {0x00009908, 0x00000000},
+       {0x0000990c, 0x00000000},
+       {0x0000991c, 0x10000fff},
+       {0x00009920, 0x04900000},
+       {0x00009928, 0x00000001},
+       {0x0000992c, 0x00000004},
+       {0x00009934, 0x1e1f2022},
+       {0x00009938, 0x0a0b0c0d},
+       {0x0000993c, 0x00000000},
+       {0x00009940, 0x14750604},
+       {0x00009948, 0x9280c00a},
+       {0x0000994c, 0x00020028},
+       {0x00009954, 0x5f3ca3de},
+       {0x00009958, 0x0108ecff},
+       {0x00009968, 0x000003ce},
+       {0x00009970, 0x192bb514},
+       {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, 0x2def0400},
+       {0x000099b0, 0x03051000},
+       {0x000099b4, 0x00000820},
+       {0x000099dc, 0x00000000},
+       {0x000099e0, 0x00000000},
+       {0x000099e4, 0xaaaaaaaa},
+       {0x000099e8, 0x3c466478},
+       {0x000099ec, 0x0cc80caa},
+       {0x000099f0, 0x00000000},
+       {0x0000a208, 0x803e68c8},
+       {0x0000a210, 0x4080a333},
+       {0x0000a214, 0x00206c10},
+       {0x0000a218, 0x009c4060},
+       {0x0000a220, 0x01834061},
+       {0x0000a224, 0x00000400},
+       {0x0000a228, 0x000003b5},
+       {0x0000a22c, 0x00000000},
+       {0x0000a234, 0x20202020},
+       {0x0000a238, 0x20202020},
+       {0x0000a244, 0x00000000},
+       {0x0000a248, 0xfffffffc},
+       {0x0000a24c, 0x00000000},
+       {0x0000a254, 0x00000000},
+       {0x0000a258, 0x0ccb5380},
+       {0x0000a25c, 0x15151501},
+       {0x0000a260, 0xdfa90f01},
+       {0x0000a268, 0x00000000},
+       {0x0000a26c, 0x0ebae9e6},
+       {0x0000a388, 0x0c000000},
+       {0x0000a38c, 0x20202020},
+       {0x0000a390, 0x20202020},
+       {0x0000a39c, 0x00000001},
+       {0x0000a3a0, 0x00000000},
+       {0x0000a3a4, 0x00000000},
+       {0x0000a3a8, 0x00000000},
+       {0x0000a3ac, 0x00000000},
+       {0x0000a3b0, 0x00000000},
+       {0x0000a3b4, 0x00000000},
+       {0x0000a3b8, 0x00000000},
+       {0x0000a3bc, 0x00000000},
+       {0x0000a3c0, 0x00000000},
+       {0x0000a3c4, 0x00000000},
+       {0x0000a3cc, 0x20202020},
+       {0x0000a3d0, 0x20202020},
+       {0x0000a3d4, 0x20202020},
+       {0x0000a3e4, 0x00000000},
+       {0x0000a3e8, 0x18c43433},
+       {0x0000a3ec, 0x00f70081},
+       {0x0000a3f0, 0x01036a2f},
+       {0x0000a3f4, 0x00000000},
+       {0x0000d270, 0x0d820820},
+       {0x0000d35c, 0x07ffffef},
+       {0x0000d360, 0x0fffffe7},
+       {0x0000d364, 0x17ffffe5},
+       {0x0000d368, 0x1fffffe4},
+       {0x0000d36c, 0x37ffffe3},
+       {0x0000d370, 0x3fffffe3},
+       {0x0000d374, 0x57ffffe3},
+       {0x0000d378, 0x5fffffe2},
+       {0x0000d37c, 0x7fffffe2},
+       {0x0000d380, 0x7f3c7bba},
+       {0x0000d384, 0xf3307ff0},
+};
+
+static const u32 ar9271Common_normal_cck_fir_coeff_9271[][2] = {
+       /* Addr      allmodes  */
+       {0x0000a1f4, 0x00fffeff},
+       {0x0000a1f8, 0x00f5f9ff},
+       {0x0000a1fc, 0xb79f6427},
+};
+
+static const u32 ar9271Common_japan_2484_cck_fir_coeff_9271[][2] = {
+       /* Addr      allmodes  */
+       {0x0000a1f4, 0x00000000},
+       {0x0000a1f8, 0xefff0301},
+       {0x0000a1fc, 0xca9228ee},
+};
+
+static const u32 ar9271Modes_9271_1_0_only[][6] = {
+       {0x00009910, 0x30002311, 0x30002311, 0x30002311, 0x30002311, 0x30002311},
+       {0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001},
+};
+
+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},
+       {0x0000986c, 0x06903881, 0x06903881, 0x06903881, 0x06903881, 0x06903881},
+       {0x00009868, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0},
+       {0x0000a208, 0x803e68c8, 0x803e68c8, 0x803e68c8, 0x803e68c8, 0x803e68c8},
+       {0x00009924, 0xd00a8007, 0xd00a8007, 0xd00a800d, 0xd00a800d, 0xd00a800d},
+       {0x000099c0, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4},
+};
+
+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},
+       {0x0000a30c, 0x00000000, 0x00000000, 0x00019608, 0x00019608, 0x00000000},
+       {0x0000a310, 0x00000000, 0x00000000, 0x0001e610, 0x0001e610, 0x00000000},
+       {0x0000a314, 0x00000000, 0x00000000, 0x0002d6d0, 0x0002d6d0, 0x00000000},
+       {0x0000a318, 0x00000000, 0x00000000, 0x00039758, 0x00039758, 0x00000000},
+       {0x0000a31c, 0x00000000, 0x00000000, 0x0003b759, 0x0003b759, 0x00000000},
+       {0x0000a320, 0x00000000, 0x00000000, 0x0003d75a, 0x0003d75a, 0x00000000},
+       {0x0000a324, 0x00000000, 0x00000000, 0x0004175c, 0x0004175c, 0x00000000},
+       {0x0000a328, 0x00000000, 0x00000000, 0x0004575e, 0x0004575e, 0x00000000},
+       {0x0000a32c, 0x00000000, 0x00000000, 0x0004979f, 0x0004979f, 0x00000000},
+       {0x0000a330, 0x00000000, 0x00000000, 0x0004d7df, 0x0004d7df, 0x00000000},
+       {0x0000a334, 0x000368de, 0x000368de, 0x000368de, 0x000368de, 0x00000000},
+       {0x0000a338, 0x0003891e, 0x0003891e, 0x0003891e, 0x0003891e, 0x00000000},
+       {0x0000a33c, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x00000000},
+       {0x0000a340, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000},
+       {0x0000a344, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000},
+       {0x0000a348, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000},
+       {0x0000a34c, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000},
+       {0x0000a350, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000},
+       {0x0000a354, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000},
+       {0x00007838, 0x00000029, 0x00000029, 0x00000029, 0x00000029, 0x00000029},
+       {0x00007824, 0x00d8abff, 0x00d8abff, 0x00d8abff, 0x00d8abff, 0x00d8abff},
+       {0x0000786c, 0x48609eb4, 0x48609eb4, 0x48609eb4, 0x48609eb4, 0x48609eb4},
+       {0x00007820, 0x00000c04, 0x00000c04, 0x00000c04, 0x00000c04, 0x00000c04},
+       {0x0000a274, 0x0a21c652, 0x0a21c652, 0x0a218652, 0x0a218652, 0x0a22a652},
+       {0x0000a278, 0x3bdef7bd, 0x3bdef7bd, 0x3bdef7bd, 0x3bdef7bd, 0x3bdef7bd},
+       {0x0000a27c, 0x050e83bd, 0x050e83bd, 0x050e83bd, 0x050e83bd, 0x050e83bd},
+       {0x0000a394, 0x3bdef7bd, 0x3bdef7bd, 0x3bdef7bd, 0x3bdef7bd, 0x3bdef7bd},
+       {0x0000a398, 0x000003bd, 0x000003bd, 0x000003bd, 0x000003bd, 0x000003bd},
+       {0x0000a3dc, 0x3bdef7bd, 0x3bdef7bd, 0x3bdef7bd, 0x3bdef7bd, 0x3bdef7bd},
+       {0x0000a3e0, 0x000003bd, 0x000003bd, 0x000003bd, 0x000003bd, 0x000003bd},
+};
+
+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},
+       {0x0000a30c, 0x00000000, 0x00000000, 0x0001b240, 0x0001b240, 0x00000000},
+       {0x0000a310, 0x00000000, 0x00000000, 0x0001d241, 0x0001d241, 0x00000000},
+       {0x0000a314, 0x00000000, 0x00000000, 0x0001f600, 0x0001f600, 0x00000000},
+       {0x0000a318, 0x00000000, 0x00000000, 0x00022800, 0x00022800, 0x00000000},
+       {0x0000a31c, 0x00000000, 0x00000000, 0x00026802, 0x00026802, 0x00000000},
+       {0x0000a320, 0x00000000, 0x00000000, 0x0002b805, 0x0002b805, 0x00000000},
+       {0x0000a324, 0x00000000, 0x00000000, 0x0002ea41, 0x0002ea41, 0x00000000},
+       {0x0000a328, 0x00000000, 0x00000000, 0x00038b00, 0x00038b00, 0x00000000},
+       {0x0000a32c, 0x00000000, 0x00000000, 0x0003ab40, 0x0003ab40, 0x00000000},
+       {0x0000a330, 0x00000000, 0x00000000, 0x0003cd80, 0x0003cd80, 0x00000000},
+       {0x0000a334, 0x000368de, 0x000368de, 0x000368de, 0x000368de, 0x00000000},
+       {0x0000a338, 0x0003891e, 0x0003891e, 0x0003891e, 0x0003891e, 0x00000000},
+       {0x0000a33c, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x00000000},
+       {0x0000a340, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000},
+       {0x0000a344, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000},
+       {0x0000a348, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000},
+       {0x0000a34c, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000},
+       {0x0000a350, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000},
+       {0x0000a354, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000},
+       {0x00007838, 0x0000002b, 0x0000002b, 0x0000002b, 0x0000002b, 0x0000002b},
+       {0x00007824, 0x00d8a7ff, 0x00d8a7ff, 0x00d8a7ff, 0x00d8a7ff, 0x00d8a7ff},
+       {0x0000786c, 0x08609eb6, 0x08609eb6, 0x08609eba, 0x08609eba, 0x08609eb6},
+       {0x00007820, 0x00000c00, 0x00000c00, 0x00000c00, 0x00000c00, 0x00000c00},
+       {0x0000a274, 0x0a22a652, 0x0a22a652, 0x0a214652, 0x0a214652, 0x0a22a652},
+       {0x0000a278, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7},
+       {0x0000a27c, 0x05018063, 0x05038063, 0x05018063, 0x05018063, 0x05018063},
+       {0x0000a394, 0x06318c63, 0x06318c63, 0x06318c63, 0x06318c63, 0x06318c63},
+       {0x0000a398, 0x00000063, 0x00000063, 0x00000063, 0x00000063, 0x00000063},
+       {0x0000a3dc, 0x06318c63, 0x06318c63, 0x06318c63, 0x06318c63, 0x06318c63},
+       {0x0000a3e0, 0x00000063, 0x00000063, 0x00000063, 0x00000063, 0x00000063},
+};
diff --git a/src/drivers/net/ath/ath9k/ar9002_phy.h b/src/drivers/net/ath/ath9k/ar9002_phy.h
new file mode 100644 (file)
index 0000000..453af6d
--- /dev/null
@@ -0,0 +1,613 @@
+/*
+ * Copyright (c) 2008-2011 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_FIND_SIG_LOW           0x9840
+#define AR_PHY_FIND_SIG_FIRSTEP_LOW   0x00000FC0L
+#define AR_PHY_FIND_SIG_FIRSTEP_LOW_S 6
+
+#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_FAST_DIV_BIAS          0x00007E00
+#define AR_PHY_9285_FAST_DIV_BIAS_S        9
+#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_TIMING5_CYCPWR_THR1   0x0000FE00L
+#define AR_PHY_EXT_TIMING5_CYCPWR_THR1_S 9
+
+#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_PWRCTRL8       0xa278
+
+#define AR_PHY_TX_PWRCTRL9       0xa27C
+
+#define AR_PHY_TX_PWRCTRL10       0xa394
+#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_CH0_TX_PWRCTRL12  0xa3dc
+#define AR_PHY_CH0_TX_PWRCTRL13  0xa3e0
+#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 AR_PHY_CCA_NOM_VAL_5416_2GHZ            -90
+#define AR_PHY_CCA_NOM_VAL_5416_5GHZ            -100
+#define AR_PHY_CCA_MIN_GOOD_VAL_5416_2GHZ     -100
+#define AR_PHY_CCA_MIN_GOOD_VAL_5416_5GHZ     -110
+#define AR_PHY_CCA_MAX_GOOD_VAL_5416_2GHZ     -80
+#define AR_PHY_CCA_MAX_GOOD_VAL_5416_5GHZ     -90
+
+#define AR_PHY_CCA_NOM_VAL_9280_2GHZ         -112
+#define AR_PHY_CCA_NOM_VAL_9280_5GHZ         -112
+#define AR_PHY_CCA_MIN_GOOD_VAL_9280_2GHZ  -127
+#define AR_PHY_CCA_MIN_GOOD_VAL_9280_5GHZ  -122
+#define AR_PHY_CCA_MAX_GOOD_VAL_9280_2GHZ  -97
+#define AR_PHY_CCA_MAX_GOOD_VAL_9280_5GHZ  -102
+
+#define AR_PHY_CCA_NOM_VAL_9285_2GHZ           -118
+#define AR_PHY_CCA_MIN_GOOD_VAL_9285_2GHZ    -127
+#define AR_PHY_CCA_MAX_GOOD_VAL_9285_2GHZ    -108
+
+#define AR_PHY_CCA_NOM_VAL_9271_2GHZ             -118
+#define AR_PHY_CCA_MIN_GOOD_VAL_9271_2GHZ      -127
+#define AR_PHY_CCA_MAX_GOOD_VAL_9271_2GHZ      -116
+
+#define AR_PHY_CCA_NOM_VAL_9287_2GHZ           -120
+#define AR_PHY_CCA_MIN_GOOD_VAL_9287_2GHZ    -127
+#define AR_PHY_CCA_MAX_GOOD_VAL_9287_2GHZ    -110
+
+#endif
diff --git a/src/drivers/net/ath/ath9k/ar9003_2p2_initvals.h b/src/drivers/net/ath/ath9k/ar9003_2p2_initvals.h
new file mode 100644 (file)
index 0000000..e8ac70d
--- /dev/null
@@ -0,0 +1,1864 @@
+/*
+ * Copyright (c) 2010-2011 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_2P2_H
+#define INITVALS_9003_2P2_H
+
+/* AR9003 2.2 */
+
+static const u32 ar9300_2p2_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},
+       {0x00016140, 0x10804008, 0x10804008, 0x50804008, 0x50804008},
+       {0x0001650c, 0x08000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x00016540, 0x10804008, 0x10804008, 0x50804008, 0x50804008},
+       {0x0001690c, 0x08000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x00016940, 0x10804008, 0x10804008, 0x50804008, 0x50804008},
+};
+
+static const u32 ar9300Modes_lowest_ob_db_tx_gain_table_2p2[][5] = {
+       /* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
+       {0x0000a2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352},
+       {0x0000a2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584},
+       {0x0000a2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800},
+       {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
+       {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9},
+       {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, 0x21002220, 0x21002220, 0x16000402, 0x16000402},
+       {0x0000a51c, 0x27002223, 0x27002223, 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, 0x52022470, 0x52022470, 0x3f001861, 0x3f001861},
+       {0x0000a548, 0x55022490, 0x55022490, 0x43001a81, 0x43001a81},
+       {0x0000a54c, 0x59022492, 0x59022492, 0x47001a83, 0x47001a83},
+       {0x0000a550, 0x5d022692, 0x5d022692, 0x4a001c84, 0x4a001c84},
+       {0x0000a554, 0x61022892, 0x61022892, 0x4e001ce3, 0x4e001ce3},
+       {0x0000a558, 0x65024890, 0x65024890, 0x52001ce5, 0x52001ce5},
+       {0x0000a55c, 0x69024892, 0x69024892, 0x56001ce9, 0x56001ce9},
+       {0x0000a560, 0x6e024c92, 0x6e024c92, 0x5a001ceb, 0x5a001ceb},
+       {0x0000a564, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
+       {0x0000a568, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
+       {0x0000a56c, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
+       {0x0000a570, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
+       {0x0000a574, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
+       {0x0000a578, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
+       {0x0000a57c, 0x74026e92, 0x74026e92, 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, 0x21802220, 0x21802220, 0x16800402, 0x16800402},
+       {0x0000a59c, 0x27802223, 0x27802223, 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, 0x52822470, 0x52822470, 0x3f801861, 0x3f801861},
+       {0x0000a5c8, 0x55822490, 0x55822490, 0x43801a81, 0x43801a81},
+       {0x0000a5cc, 0x59822492, 0x59822492, 0x47801a83, 0x47801a83},
+       {0x0000a5d0, 0x5d822692, 0x5d822692, 0x4a801c84, 0x4a801c84},
+       {0x0000a5d4, 0x61822892, 0x61822892, 0x4e801ce3, 0x4e801ce3},
+       {0x0000a5d8, 0x65824890, 0x65824890, 0x52801ce5, 0x52801ce5},
+       {0x0000a5dc, 0x69824892, 0x69824892, 0x56801ce9, 0x56801ce9},
+       {0x0000a5e0, 0x6e824c92, 0x6e824c92, 0x5a801ceb, 0x5a801ceb},
+       {0x0000a5e4, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
+       {0x0000a5e8, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
+       {0x0000a5ec, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
+       {0x0000a5f0, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
+       {0x0000a5f4, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
+       {0x0000a5f8, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
+       {0x0000a5fc, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
+       {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000a610, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000a614, 0x02004000, 0x02004000, 0x01404000, 0x01404000},
+       {0x0000a618, 0x02004801, 0x02004801, 0x01404501, 0x01404501},
+       {0x0000a61c, 0x02808a02, 0x02808a02, 0x02008501, 0x02008501},
+       {0x0000a620, 0x0380ce03, 0x0380ce03, 0x0280ca03, 0x0280ca03},
+       {0x0000a624, 0x04411104, 0x04411104, 0x03010c04, 0x03010c04},
+       {0x0000a628, 0x04411104, 0x04411104, 0x04014c04, 0x04014c04},
+       {0x0000a62c, 0x04411104, 0x04411104, 0x04015005, 0x04015005},
+       {0x0000a630, 0x04411104, 0x04411104, 0x04015005, 0x04015005},
+       {0x0000a634, 0x04411104, 0x04411104, 0x04015005, 0x04015005},
+       {0x0000a638, 0x04411104, 0x04411104, 0x04015005, 0x04015005},
+       {0x0000a63c, 0x04411104, 0x04411104, 0x04015005, 0x04015005},
+       {0x0000b2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352},
+       {0x0000b2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584},
+       {0x0000b2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800},
+       {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
+       {0x0000c2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352},
+       {0x0000c2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584},
+       {0x0000c2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800},
+       {0x0000c2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
+       {0x00016044, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
+       {0x00016048, 0x62480001, 0x62480001, 0x62480001, 0x62480001},
+       {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
+       {0x00016444, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
+       {0x00016448, 0x62480001, 0x62480001, 0x62480001, 0x62480001},
+       {0x00016468, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
+       {0x00016844, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
+       {0x00016848, 0x62480001, 0x62480001, 0x62480001, 0x62480001},
+       {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
+};
+
+static const u32 ar9300Modes_fast_clock_2p2[][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, 0x0372131c, 0x0372131c},
+       {0x0000a230, 0x0000000b, 0x00000016},
+       {0x0000a254, 0x00000898, 0x00001130},
+};
+
+static const u32 ar9300_2p2_radio_core[][2] = {
+       /* Addr      allmodes  */
+       {0x00016000, 0x36db6db6},
+       {0x00016004, 0x6db6db40},
+       {0x00016008, 0x73f00000},
+       {0x0001600c, 0x00000000},
+       {0x00016040, 0x7f80fff8},
+       {0x0001604c, 0x76d005b5},
+       {0x00016050, 0x556cf031},
+       {0x00016054, 0x13449440},
+       {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},
+       {0x00016144, 0x02084080},
+       {0x00016148, 0x00000000},
+       {0x00016280, 0x058a0001},
+       {0x00016284, 0x3d840208},
+       {0x00016288, 0x05a20408},
+       {0x0001628c, 0x00038c07},
+       {0x00016290, 0x00000004},
+       {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, 0x13449440},
+       {0x00016458, 0x0c51c92c},
+       {0x0001645c, 0x3db7fffc},
+       {0x00016460, 0xfffffffc},
+       {0x00016464, 0x000f0278},
+       {0x0001646c, 0x6db60000},
+       {0x00016500, 0x3fffbe01},
+       {0x00016504, 0xfff80000},
+       {0x00016508, 0x00080010},
+       {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, 0x13449440},
+       {0x00016858, 0x0c51c92c},
+       {0x0001685c, 0x3db7fffc},
+       {0x00016860, 0xfffffffc},
+       {0x00016864, 0x000f0278},
+       {0x0001686c, 0x6db60000},
+       {0x00016900, 0x3fffbe01},
+       {0x00016904, 0xfff80000},
+       {0x00016908, 0x00080010},
+       {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_2p2[][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_2p2_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_2p2_soc_postamble[][5] = {
+       /* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
+       {0x00007010, 0x00000023, 0x00000023, 0x00000023, 0x00000023},
+};
+
+static const u32 ar9200_merlin_2p2_radio_core[][2] = {
+       /* Addr      allmodes  */
+       {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_2p2_baseband_postamble[][5] = {
+       /* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
+       {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8011, 0xd00a8011},
+       {0x00009820, 0x206a022e, 0x206a022e, 0x206a012e, 0x206a012e},
+       {0x00009824, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0},
+       {0x00009828, 0x06903081, 0x06903081, 0x06903881, 0x06903881},
+       {0x0000982c, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4},
+       {0x00009830, 0x0000059c, 0x0000059c, 0x0000119c, 0x0000119c},
+       {0x00009c00, 0x000000c4, 0x000000c4, 0x000000c4, 0x000000c4},
+       {0x00009e00, 0x0372111a, 0x0372111a, 0x037216a0, 0x037216a0},
+       {0x00009e04, 0x001c2020, 0x001c2020, 0x001c2020, 0x001c2020},
+       {0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000e2, 0x6c4000e2},
+       {0x00009e10, 0x7ec88d2e, 0x7ec88d2e, 0x7ec84d2e, 0x7ec84d2e},
+       {0x00009e14, 0x37b95d5e, 0x37b9605e, 0x3379605e, 0x33795d5e},
+       {0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c},
+       {0x00009e20, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce},
+       {0x00009e2c, 0x0000001c, 0x0000001c, 0x00000021, 0x00000021},
+       {0x00009e3c, 0xcf946220, 0xcf946220, 0xcf946222, 0xcf946222},
+       {0x00009e44, 0x02321e27, 0x02321e27, 0x02291e27, 0x02291e27},
+       {0x00009e48, 0x5030201a, 0x5030201a, 0x50302012, 0x50302012},
+       {0x00009fc8, 0x0003f000, 0x0003f000, 0x0001a000, 0x0001a000},
+       {0x0000a204, 0x000037c0, 0x000037c4, 0x000037c4, 0x000037c0},
+       {0x0000a208, 0x00000104, 0x00000104, 0x00000004, 0x00000004},
+       {0x0000a22c, 0x01026a2f, 0x01026a2f, 0x01026a2f, 0x01026a2f},
+       {0x0000a230, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b},
+       {0x0000a234, 0x00000fff, 0x10000fff, 0x10000fff, 0x00000fff},
+       {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, 0x7999a83a, 0x7999a83a, 0x7999a83a, 0x7999a83a},
+       {0x0000a358, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000a830, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c},
+       {0x0000ae04, 0x001c0000, 0x001c0000, 0x001c0000, 0x001c0000},
+       {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, 0x001c0000, 0x001c0000, 0x001c0000, 0x001c0000},
+       {0x0000be18, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000be1c, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c},
+       {0x0000be20, 0x000001b5, 0x000001b5, 0x000001ce, 0x000001ce},
+       {0x0000c284, 0x00000000, 0x00000000, 0x00000150, 0x00000150},
+};
+
+static const u32 ar9300_2p2_baseband_core[][2] = {
+       /* Addr      allmodes  */
+       {0x00009800, 0xafe68e30},
+       {0x00009804, 0xfd14e000},
+       {0x00009808, 0x9c0a9f6b},
+       {0x0000980c, 0x04900000},
+       {0x00009814, 0x9280c00a},
+       {0x00009818, 0x00000000},
+       {0x0000981c, 0x00020028},
+       {0x00009834, 0x6400a290},
+       {0x00009838, 0x0108ecff},
+       {0x0000983c, 0x0d000600},
+       {0x00009880, 0x201fff00},
+       {0x00009884, 0x00001042},
+       {0x000098a4, 0x00200400},
+       {0x000098b0, 0x32840bbe},
+       {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, 0x0038230c},
+       {0x00009e24, 0x990bb515},
+       {0x00009e28, 0x0c6f0000},
+       {0x00009e30, 0x06336f77},
+       {0x00009e34, 0x6af6532f},
+       {0x00009e38, 0x0cc80c00},
+       {0x00009e40, 0x0d261820},
+       {0x00009e4c, 0x00001004},
+       {0x00009e50, 0x00ff03f1},
+       {0x00009e54, 0x00000000},
+       {0x00009fc0, 0x803e4788},
+       {0x00009fc4, 0x0001efb5},
+       {0x00009fcc, 0x40000014},
+       {0x00009fd0, 0x01193b93},
+       {0x0000a20c, 0x00000000},
+       {0x0000a220, 0x00000000},
+       {0x0000a224, 0x00000000},
+       {0x0000a228, 0x10002310},
+       {0x0000a23c, 0x00000000},
+       {0x0000a244, 0x0c000000},
+       {0x0000a2a0, 0x00000001},
+       {0x0000a2c0, 0x00000001},
+       {0x0000a2c8, 0x00000000},
+       {0x0000a2cc, 0x18c43433},
+       {0x0000a2d4, 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, 0x2d001dce},
+       {0x0000a41c, 0x1ce739ce},
+       {0x0000a420, 0x000001ce},
+       {0x0000a424, 0x1ce739ce},
+       {0x0000a428, 0x000001ce},
+       {0x0000a42c, 0x1ce739ce},
+       {0x0000a430, 0x1ce739ce},
+       {0x0000a434, 0x00000000},
+       {0x0000a438, 0x00001801},
+       {0x0000a43c, 0x00100000},
+       {0x0000a440, 0x00000000},
+       {0x0000a444, 0x00000000},
+       {0x0000a448, 0x06000080},
+       {0x0000a44c, 0x00000001},
+       {0x0000a450, 0x00010000},
+       {0x0000a458, 0x00000000},
+       {0x0000a640, 0x00000000},
+       {0x0000a644, 0x3fad9d74},
+       {0x0000a648, 0x0048060a},
+       {0x0000a64c, 0x00003c37},
+       {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},
+       {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},
+       {0x0000c2ec, 0x00000000},
+       {0x0000c2f0, 0x00000000},
+       {0x0000c2f4, 0x00000000},
+       {0x0000c2f8, 0x00000000},
+       {0x0000c408, 0x0e79e5c0},
+       {0x0000c40c, 0x00820820},
+       {0x0000c420, 0x00000000},
+};
+
+static const u32 ar9300Modes_high_power_tx_gain_table_2p2[][5] = {
+       /* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
+       {0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352},
+       {0x0000a2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584},
+       {0x0000a2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800},
+       {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
+       {0x0000a410, 0x000050d8, 0x000050d8, 0x000050d9, 0x000050d9},
+       {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000},
+       {0x0000a504, 0x04002222, 0x04002222, 0x04000002, 0x04000002},
+       {0x0000a508, 0x09002421, 0x09002421, 0x08000004, 0x08000004},
+       {0x0000a50c, 0x0d002621, 0x0d002621, 0x0b000200, 0x0b000200},
+       {0x0000a510, 0x13004620, 0x13004620, 0x0f000202, 0x0f000202},
+       {0x0000a514, 0x19004a20, 0x19004a20, 0x11000400, 0x11000400},
+       {0x0000a518, 0x1d004e20, 0x1d004e20, 0x15000402, 0x15000402},
+       {0x0000a51c, 0x21005420, 0x21005420, 0x19000404, 0x19000404},
+       {0x0000a520, 0x26005e20, 0x26005e20, 0x1b000603, 0x1b000603},
+       {0x0000a524, 0x2b005e40, 0x2b005e40, 0x1f000a02, 0x1f000a02},
+       {0x0000a528, 0x2f005e42, 0x2f005e42, 0x23000a04, 0x23000a04},
+       {0x0000a52c, 0x33005e44, 0x33005e44, 0x26000a20, 0x26000a20},
+       {0x0000a530, 0x38005e65, 0x38005e65, 0x2a000e20, 0x2a000e20},
+       {0x0000a534, 0x3c005e69, 0x3c005e69, 0x2e000e22, 0x2e000e22},
+       {0x0000a538, 0x40005e6b, 0x40005e6b, 0x31000e24, 0x31000e24},
+       {0x0000a53c, 0x44005e6d, 0x44005e6d, 0x34001640, 0x34001640},
+       {0x0000a540, 0x49005e72, 0x49005e72, 0x38001660, 0x38001660},
+       {0x0000a544, 0x4e005eb2, 0x4e005eb2, 0x3b001861, 0x3b001861},
+       {0x0000a548, 0x53005f12, 0x53005f12, 0x3e001a81, 0x3e001a81},
+       {0x0000a54c, 0x59025eb2, 0x59025eb2, 0x42001a83, 0x42001a83},
+       {0x0000a550, 0x5e025f12, 0x5e025f12, 0x44001c84, 0x44001c84},
+       {0x0000a554, 0x61027f12, 0x61027f12, 0x48001ce3, 0x48001ce3},
+       {0x0000a558, 0x6702bf12, 0x6702bf12, 0x4c001ce5, 0x4c001ce5},
+       {0x0000a55c, 0x6b02bf14, 0x6b02bf14, 0x50001ce9, 0x50001ce9},
+       {0x0000a560, 0x6f02bf16, 0x6f02bf16, 0x54001ceb, 0x54001ceb},
+       {0x0000a564, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
+       {0x0000a568, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
+       {0x0000a56c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
+       {0x0000a570, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
+       {0x0000a574, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
+       {0x0000a578, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
+       {0x0000a57c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
+       {0x0000a580, 0x00802220, 0x00802220, 0x00800000, 0x00800000},
+       {0x0000a584, 0x04802222, 0x04802222, 0x04800002, 0x04800002},
+       {0x0000a588, 0x09802421, 0x09802421, 0x08800004, 0x08800004},
+       {0x0000a58c, 0x0d802621, 0x0d802621, 0x0b800200, 0x0b800200},
+       {0x0000a590, 0x13804620, 0x13804620, 0x0f800202, 0x0f800202},
+       {0x0000a594, 0x19804a20, 0x19804a20, 0x11800400, 0x11800400},
+       {0x0000a598, 0x1d804e20, 0x1d804e20, 0x15800402, 0x15800402},
+       {0x0000a59c, 0x21805420, 0x21805420, 0x19800404, 0x19800404},
+       {0x0000a5a0, 0x26805e20, 0x26805e20, 0x1b800603, 0x1b800603},
+       {0x0000a5a4, 0x2b805e40, 0x2b805e40, 0x1f800a02, 0x1f800a02},
+       {0x0000a5a8, 0x2f805e42, 0x2f805e42, 0x23800a04, 0x23800a04},
+       {0x0000a5ac, 0x33805e44, 0x33805e44, 0x26800a20, 0x26800a20},
+       {0x0000a5b0, 0x38805e65, 0x38805e65, 0x2a800e20, 0x2a800e20},
+       {0x0000a5b4, 0x3c805e69, 0x3c805e69, 0x2e800e22, 0x2e800e22},
+       {0x0000a5b8, 0x40805e6b, 0x40805e6b, 0x31800e24, 0x31800e24},
+       {0x0000a5bc, 0x44805e6d, 0x44805e6d, 0x34801640, 0x34801640},
+       {0x0000a5c0, 0x49805e72, 0x49805e72, 0x38801660, 0x38801660},
+       {0x0000a5c4, 0x4e805eb2, 0x4e805eb2, 0x3b801861, 0x3b801861},
+       {0x0000a5c8, 0x53805f12, 0x53805f12, 0x3e801a81, 0x3e801a81},
+       {0x0000a5cc, 0x59825eb2, 0x59825eb2, 0x42801a83, 0x42801a83},
+       {0x0000a5d0, 0x5e825f12, 0x5e825f12, 0x44801c84, 0x44801c84},
+       {0x0000a5d4, 0x61827f12, 0x61827f12, 0x48801ce3, 0x48801ce3},
+       {0x0000a5d8, 0x6782bf12, 0x6782bf12, 0x4c801ce5, 0x4c801ce5},
+       {0x0000a5dc, 0x6b82bf14, 0x6b82bf14, 0x50801ce9, 0x50801ce9},
+       {0x0000a5e0, 0x6f82bf16, 0x6f82bf16, 0x54801ceb, 0x54801ceb},
+       {0x0000a5e4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
+       {0x0000a5e8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
+       {0x0000a5ec, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
+       {0x0000a5f0, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
+       {0x0000a5f4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
+       {0x0000a5f8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
+       {0x0000a5fc, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
+       {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000a610, 0x00804000, 0x00804000, 0x00000000, 0x00000000},
+       {0x0000a614, 0x00804201, 0x00804201, 0x01404000, 0x01404000},
+       {0x0000a618, 0x0280c802, 0x0280c802, 0x01404501, 0x01404501},
+       {0x0000a61c, 0x0280ca03, 0x0280ca03, 0x02008501, 0x02008501},
+       {0x0000a620, 0x04c15104, 0x04c15104, 0x0280ca03, 0x0280ca03},
+       {0x0000a624, 0x04c15305, 0x04c15305, 0x03010c04, 0x03010c04},
+       {0x0000a628, 0x04c15305, 0x04c15305, 0x04014c04, 0x04014c04},
+       {0x0000a62c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
+       {0x0000a630, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
+       {0x0000a634, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
+       {0x0000a638, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
+       {0x0000a63c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
+       {0x0000b2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352},
+       {0x0000b2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584},
+       {0x0000b2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800},
+       {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
+       {0x0000c2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352},
+       {0x0000c2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584},
+       {0x0000c2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800},
+       {0x0000c2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
+       {0x00016044, 0x056db2e6, 0x056db2e6, 0x056db2e6, 0x056db2e6},
+       {0x00016048, 0xae480001, 0xae480001, 0xae480001, 0xae480001},
+       {0x00016068, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c},
+       {0x00016444, 0x056db2e6, 0x056db2e6, 0x056db2e6, 0x056db2e6},
+       {0x00016448, 0xae480001, 0xae480001, 0xae480001, 0xae480001},
+       {0x00016468, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c},
+       {0x00016844, 0x056db2e6, 0x056db2e6, 0x056db2e6, 0x056db2e6},
+       {0x00016848, 0xae480001, 0xae480001, 0xae480001, 0xae480001},
+       {0x00016868, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c},
+};
+
+static const u32 ar9300Modes_high_ob_db_tx_gain_table_2p2[][5] = {
+       /* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
+       {0x0000a2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352},
+       {0x0000a2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584},
+       {0x0000a2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800},
+       {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
+       {0x0000a410, 0x000050d8, 0x000050d8, 0x000050d9, 0x000050d9},
+       {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000},
+       {0x0000a504, 0x04002222, 0x04002222, 0x04000002, 0x04000002},
+       {0x0000a508, 0x09002421, 0x09002421, 0x08000004, 0x08000004},
+       {0x0000a50c, 0x0d002621, 0x0d002621, 0x0b000200, 0x0b000200},
+       {0x0000a510, 0x13004620, 0x13004620, 0x0f000202, 0x0f000202},
+       {0x0000a514, 0x19004a20, 0x19004a20, 0x11000400, 0x11000400},
+       {0x0000a518, 0x1d004e20, 0x1d004e20, 0x15000402, 0x15000402},
+       {0x0000a51c, 0x21005420, 0x21005420, 0x19000404, 0x19000404},
+       {0x0000a520, 0x26005e20, 0x26005e20, 0x1b000603, 0x1b000603},
+       {0x0000a524, 0x2b005e40, 0x2b005e40, 0x1f000a02, 0x1f000a02},
+       {0x0000a528, 0x2f005e42, 0x2f005e42, 0x23000a04, 0x23000a04},
+       {0x0000a52c, 0x33005e44, 0x33005e44, 0x26000a20, 0x26000a20},
+       {0x0000a530, 0x38005e65, 0x38005e65, 0x2a000e20, 0x2a000e20},
+       {0x0000a534, 0x3c005e69, 0x3c005e69, 0x2e000e22, 0x2e000e22},
+       {0x0000a538, 0x40005e6b, 0x40005e6b, 0x31000e24, 0x31000e24},
+       {0x0000a53c, 0x44005e6d, 0x44005e6d, 0x34001640, 0x34001640},
+       {0x0000a540, 0x49005e72, 0x49005e72, 0x38001660, 0x38001660},
+       {0x0000a544, 0x4e005eb2, 0x4e005eb2, 0x3b001861, 0x3b001861},
+       {0x0000a548, 0x53005f12, 0x53005f12, 0x3e001a81, 0x3e001a81},
+       {0x0000a54c, 0x59025eb2, 0x59025eb2, 0x42001a83, 0x42001a83},
+       {0x0000a550, 0x5e025f12, 0x5e025f12, 0x44001c84, 0x44001c84},
+       {0x0000a554, 0x61027f12, 0x61027f12, 0x48001ce3, 0x48001ce3},
+       {0x0000a558, 0x6702bf12, 0x6702bf12, 0x4c001ce5, 0x4c001ce5},
+       {0x0000a55c, 0x6b02bf14, 0x6b02bf14, 0x50001ce9, 0x50001ce9},
+       {0x0000a560, 0x6f02bf16, 0x6f02bf16, 0x54001ceb, 0x54001ceb},
+       {0x0000a564, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
+       {0x0000a568, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
+       {0x0000a56c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
+       {0x0000a570, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
+       {0x0000a574, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
+       {0x0000a578, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
+       {0x0000a57c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
+       {0x0000a580, 0x00802220, 0x00802220, 0x00800000, 0x00800000},
+       {0x0000a584, 0x04802222, 0x04802222, 0x04800002, 0x04800002},
+       {0x0000a588, 0x09802421, 0x09802421, 0x08800004, 0x08800004},
+       {0x0000a58c, 0x0d802621, 0x0d802621, 0x0b800200, 0x0b800200},
+       {0x0000a590, 0x13804620, 0x13804620, 0x0f800202, 0x0f800202},
+       {0x0000a594, 0x19804a20, 0x19804a20, 0x11800400, 0x11800400},
+       {0x0000a598, 0x1d804e20, 0x1d804e20, 0x15800402, 0x15800402},
+       {0x0000a59c, 0x21805420, 0x21805420, 0x19800404, 0x19800404},
+       {0x0000a5a0, 0x26805e20, 0x26805e20, 0x1b800603, 0x1b800603},
+       {0x0000a5a4, 0x2b805e40, 0x2b805e40, 0x1f800a02, 0x1f800a02},
+       {0x0000a5a8, 0x2f805e42, 0x2f805e42, 0x23800a04, 0x23800a04},
+       {0x0000a5ac, 0x33805e44, 0x33805e44, 0x26800a20, 0x26800a20},
+       {0x0000a5b0, 0x38805e65, 0x38805e65, 0x2a800e20, 0x2a800e20},
+       {0x0000a5b4, 0x3c805e69, 0x3c805e69, 0x2e800e22, 0x2e800e22},
+       {0x0000a5b8, 0x40805e6b, 0x40805e6b, 0x31800e24, 0x31800e24},
+       {0x0000a5bc, 0x44805e6d, 0x44805e6d, 0x34801640, 0x34801640},
+       {0x0000a5c0, 0x49805e72, 0x49805e72, 0x38801660, 0x38801660},
+       {0x0000a5c4, 0x4e805eb2, 0x4e805eb2, 0x3b801861, 0x3b801861},
+       {0x0000a5c8, 0x53805f12, 0x53805f12, 0x3e801a81, 0x3e801a81},
+       {0x0000a5cc, 0x59825eb2, 0x59825eb2, 0x42801a83, 0x42801a83},
+       {0x0000a5d0, 0x5e825f12, 0x5e825f12, 0x44801c84, 0x44801c84},
+       {0x0000a5d4, 0x61827f12, 0x61827f12, 0x48801ce3, 0x48801ce3},
+       {0x0000a5d8, 0x6782bf12, 0x6782bf12, 0x4c801ce5, 0x4c801ce5},
+       {0x0000a5dc, 0x6b82bf14, 0x6b82bf14, 0x50801ce9, 0x50801ce9},
+       {0x0000a5e0, 0x6f82bf16, 0x6f82bf16, 0x54801ceb, 0x54801ceb},
+       {0x0000a5e4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
+       {0x0000a5e8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
+       {0x0000a5ec, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
+       {0x0000a5f0, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
+       {0x0000a5f4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
+       {0x0000a5f8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
+       {0x0000a5fc, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
+       {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000a610, 0x00804000, 0x00804000, 0x00000000, 0x00000000},
+       {0x0000a614, 0x00804201, 0x00804201, 0x01404000, 0x01404000},
+       {0x0000a618, 0x0280c802, 0x0280c802, 0x01404501, 0x01404501},
+       {0x0000a61c, 0x0280ca03, 0x0280ca03, 0x02008501, 0x02008501},
+       {0x0000a620, 0x04c15104, 0x04c15104, 0x0280ca03, 0x0280ca03},
+       {0x0000a624, 0x04c15305, 0x04c15305, 0x03010c04, 0x03010c04},
+       {0x0000a628, 0x04c15305, 0x04c15305, 0x04014c04, 0x04014c04},
+       {0x0000a62c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
+       {0x0000a630, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
+       {0x0000a634, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
+       {0x0000a638, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
+       {0x0000a63c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
+       {0x0000b2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352},
+       {0x0000b2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584},
+       {0x0000b2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800},
+       {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
+       {0x0000c2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352},
+       {0x0000c2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584},
+       {0x0000c2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800},
+       {0x0000c2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
+       {0x00016044, 0x056db2e4, 0x056db2e4, 0x056db2e4, 0x056db2e4},
+       {0x00016048, 0x8e480001, 0x8e480001, 0x8e480001, 0x8e480001},
+       {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
+       {0x00016444, 0x056db2e4, 0x056db2e4, 0x056db2e4, 0x056db2e4},
+       {0x00016448, 0x8e480001, 0x8e480001, 0x8e480001, 0x8e480001},
+       {0x00016468, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
+       {0x00016844, 0x056db2e4, 0x056db2e4, 0x056db2e4, 0x056db2e4},
+       {0x00016848, 0x8e480001, 0x8e480001, 0x8e480001, 0x8e480001},
+       {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
+};
+
+static const u32 ar9300Common_rx_gain_table_2p2[][2] = {
+       /* Addr      allmodes  */
+       {0x0000a000, 0x00010000},
+       {0x0000a004, 0x00030002},
+       {0x0000a008, 0x00050004},
+       {0x0000a00c, 0x00810080},
+       {0x0000a010, 0x00830082},
+       {0x0000a014, 0x01810180},
+       {0x0000a018, 0x01830182},
+       {0x0000a01c, 0x01850184},
+       {0x0000a020, 0x01890188},
+       {0x0000a024, 0x018b018a},
+       {0x0000a028, 0x018d018c},
+       {0x0000a02c, 0x01910190},
+       {0x0000a030, 0x01930192},
+       {0x0000a034, 0x01950194},
+       {0x0000a038, 0x038a0196},
+       {0x0000a03c, 0x038c038b},
+       {0x0000a040, 0x0390038d},
+       {0x0000a044, 0x03920391},
+       {0x0000a048, 0x03940393},
+       {0x0000a04c, 0x03960395},
+       {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, 0x22222229},
+       {0x0000a084, 0x1d1d1d1d},
+       {0x0000a088, 0x1d1d1d1d},
+       {0x0000a08c, 0x1d1d1d1d},
+       {0x0000a090, 0x171d1d1d},
+       {0x0000a094, 0x11111717},
+       {0x0000a098, 0x00030311},
+       {0x0000a09c, 0x00000000},
+       {0x0000a0a0, 0x00000000},
+       {0x0000a0a4, 0x00000000},
+       {0x0000a0a8, 0x00000000},
+       {0x0000a0ac, 0x00000000},
+       {0x0000a0b0, 0x00000000},
+       {0x0000a0b4, 0x00000000},
+       {0x0000a0b8, 0x00000000},
+       {0x0000a0bc, 0x00000000},
+       {0x0000a0c0, 0x001f0000},
+       {0x0000a0c4, 0x01000101},
+       {0x0000a0c8, 0x011e011f},
+       {0x0000a0cc, 0x011c011d},
+       {0x0000a0d0, 0x02030204},
+       {0x0000a0d4, 0x02010202},
+       {0x0000a0d8, 0x021f0200},
+       {0x0000a0dc, 0x0302021e},
+       {0x0000a0e0, 0x03000301},
+       {0x0000a0e4, 0x031e031f},
+       {0x0000a0e8, 0x0402031d},
+       {0x0000a0ec, 0x04000401},
+       {0x0000a0f0, 0x041e041f},
+       {0x0000a0f4, 0x0502041d},
+       {0x0000a0f8, 0x05000501},
+       {0x0000a0fc, 0x051e051f},
+       {0x0000a100, 0x06010602},
+       {0x0000a104, 0x061f0600},
+       {0x0000a108, 0x061d061e},
+       {0x0000a10c, 0x07020703},
+       {0x0000a110, 0x07000701},
+       {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, 0x01000101},
+       {0x0000a148, 0x011e011f},
+       {0x0000a14c, 0x011c011d},
+       {0x0000a150, 0x02030204},
+       {0x0000a154, 0x02010202},
+       {0x0000a158, 0x021f0200},
+       {0x0000a15c, 0x0302021e},
+       {0x0000a160, 0x03000301},
+       {0x0000a164, 0x031e031f},
+       {0x0000a168, 0x0402031d},
+       {0x0000a16c, 0x04000401},
+       {0x0000a170, 0x041e041f},
+       {0x0000a174, 0x0502041d},
+       {0x0000a178, 0x05000501},
+       {0x0000a17c, 0x051e051f},
+       {0x0000a180, 0x06010602},
+       {0x0000a184, 0x061f0600},
+       {0x0000a188, 0x061d061e},
+       {0x0000a18c, 0x07020703},
+       {0x0000a190, 0x07000701},
+       {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, 0x2a2d2f32},
+       {0x0000b084, 0x21232328},
+       {0x0000b088, 0x19191c1e},
+       {0x0000b08c, 0x12141417},
+       {0x0000b090, 0x07070e0e},
+       {0x0000b094, 0x03030305},
+       {0x0000b098, 0x00000003},
+       {0x0000b09c, 0x00000000},
+       {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_2p2[][5] = {
+       /* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
+       {0x0000a2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352},
+       {0x0000a2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584},
+       {0x0000a2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800},
+       {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
+       {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9},
+       {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, 0x21002220, 0x21002220, 0x16000402, 0x16000402},
+       {0x0000a51c, 0x27002223, 0x27002223, 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, 0x52022470, 0x52022470, 0x3f001861, 0x3f001861},
+       {0x0000a548, 0x55022490, 0x55022490, 0x43001a81, 0x43001a81},
+       {0x0000a54c, 0x59022492, 0x59022492, 0x47001a83, 0x47001a83},
+       {0x0000a550, 0x5d022692, 0x5d022692, 0x4a001c84, 0x4a001c84},
+       {0x0000a554, 0x61022892, 0x61022892, 0x4e001ce3, 0x4e001ce3},
+       {0x0000a558, 0x65024890, 0x65024890, 0x52001ce5, 0x52001ce5},
+       {0x0000a55c, 0x69024892, 0x69024892, 0x56001ce9, 0x56001ce9},
+       {0x0000a560, 0x6e024c92, 0x6e024c92, 0x5a001ceb, 0x5a001ceb},
+       {0x0000a564, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
+       {0x0000a568, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
+       {0x0000a56c, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
+       {0x0000a570, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
+       {0x0000a574, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
+       {0x0000a578, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
+       {0x0000a57c, 0x74026e92, 0x74026e92, 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, 0x21802220, 0x21802220, 0x16800402, 0x16800402},
+       {0x0000a59c, 0x27802223, 0x27802223, 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, 0x52822470, 0x52822470, 0x3f801861, 0x3f801861},
+       {0x0000a5c8, 0x55822490, 0x55822490, 0x43801a81, 0x43801a81},
+       {0x0000a5cc, 0x59822492, 0x59822492, 0x47801a83, 0x47801a83},
+       {0x0000a5d0, 0x5d822692, 0x5d822692, 0x4a801c84, 0x4a801c84},
+       {0x0000a5d4, 0x61822892, 0x61822892, 0x4e801ce3, 0x4e801ce3},
+       {0x0000a5d8, 0x65824890, 0x65824890, 0x52801ce5, 0x52801ce5},
+       {0x0000a5dc, 0x69824892, 0x69824892, 0x56801ce9, 0x56801ce9},
+       {0x0000a5e0, 0x6e824c92, 0x6e824c92, 0x5a801ceb, 0x5a801ceb},
+       {0x0000a5e4, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
+       {0x0000a5e8, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
+       {0x0000a5ec, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
+       {0x0000a5f0, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
+       {0x0000a5f4, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
+       {0x0000a5f8, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
+       {0x0000a5fc, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
+       {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000a610, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000a614, 0x02004000, 0x02004000, 0x01404000, 0x01404000},
+       {0x0000a618, 0x02004801, 0x02004801, 0x01404501, 0x01404501},
+       {0x0000a61c, 0x02808a02, 0x02808a02, 0x02008501, 0x02008501},
+       {0x0000a620, 0x0380ce03, 0x0380ce03, 0x0280ca03, 0x0280ca03},
+       {0x0000a624, 0x04411104, 0x04411104, 0x03010c04, 0x03010c04},
+       {0x0000a628, 0x04411104, 0x04411104, 0x04014c04, 0x04014c04},
+       {0x0000a62c, 0x04411104, 0x04411104, 0x04015005, 0x04015005},
+       {0x0000a630, 0x04411104, 0x04411104, 0x04015005, 0x04015005},
+       {0x0000a634, 0x04411104, 0x04411104, 0x04015005, 0x04015005},
+       {0x0000a638, 0x04411104, 0x04411104, 0x04015005, 0x04015005},
+       {0x0000a63c, 0x04411104, 0x04411104, 0x04015005, 0x04015005},
+       {0x0000b2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352},
+       {0x0000b2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584},
+       {0x0000b2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800},
+       {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
+       {0x0000c2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352},
+       {0x0000c2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584},
+       {0x0000c2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800},
+       {0x0000c2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
+       {0x00016044, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
+       {0x00016048, 0x66480001, 0x66480001, 0x66480001, 0x66480001},
+       {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
+       {0x00016444, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
+       {0x00016448, 0x66480001, 0x66480001, 0x66480001, 0x66480001},
+       {0x00016468, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
+       {0x00016844, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
+       {0x00016848, 0x66480001, 0x66480001, 0x66480001, 0x66480001},
+       {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
+};
+
+static const u32 ar9300_2p2_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},
+       {0x000081c0, 0x00000000},
+       {0x000081c4, 0x33332210},
+       {0x000081c8, 0x00000000},
+       {0x000081cc, 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, 0x9bc00010},
+       {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_2p2[][2] = {
+       /* Addr      allmodes  */
+       {0x0000a000, 0x00010000},
+       {0x0000a004, 0x00030002},
+       {0x0000a008, 0x00050004},
+       {0x0000a00c, 0x00810080},
+       {0x0000a010, 0x00830082},
+       {0x0000a014, 0x01810180},
+       {0x0000a018, 0x01830182},
+       {0x0000a01c, 0x01850184},
+       {0x0000a020, 0x01890188},
+       {0x0000a024, 0x018b018a},
+       {0x0000a028, 0x018d018c},
+       {0x0000a02c, 0x03820190},
+       {0x0000a030, 0x03840383},
+       {0x0000a034, 0x03880385},
+       {0x0000a038, 0x038a0389},
+       {0x0000a03c, 0x038c038b},
+       {0x0000a040, 0x0390038d},
+       {0x0000a044, 0x03920391},
+       {0x0000a048, 0x03940393},
+       {0x0000a04c, 0x03960395},
+       {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, 0x29292929},
+       {0x0000a084, 0x29292929},
+       {0x0000a088, 0x29292929},
+       {0x0000a08c, 0x29292929},
+       {0x0000a090, 0x22292929},
+       {0x0000a094, 0x1d1d2222},
+       {0x0000a098, 0x0c111117},
+       {0x0000a09c, 0x00030303},
+       {0x0000a0a0, 0x00000000},
+       {0x0000a0a4, 0x00000000},
+       {0x0000a0a8, 0x00000000},
+       {0x0000a0ac, 0x00000000},
+       {0x0000a0b0, 0x00000000},
+       {0x0000a0b4, 0x00000000},
+       {0x0000a0b8, 0x00000000},
+       {0x0000a0bc, 0x00000000},
+       {0x0000a0c0, 0x001f0000},
+       {0x0000a0c4, 0x01000101},
+       {0x0000a0c8, 0x011e011f},
+       {0x0000a0cc, 0x011c011d},
+       {0x0000a0d0, 0x02030204},
+       {0x0000a0d4, 0x02010202},
+       {0x0000a0d8, 0x021f0200},
+       {0x0000a0dc, 0x0302021e},
+       {0x0000a0e0, 0x03000301},
+       {0x0000a0e4, 0x031e031f},
+       {0x0000a0e8, 0x0402031d},
+       {0x0000a0ec, 0x04000401},
+       {0x0000a0f0, 0x041e041f},
+       {0x0000a0f4, 0x0502041d},
+       {0x0000a0f8, 0x05000501},
+       {0x0000a0fc, 0x051e051f},
+       {0x0000a100, 0x06010602},
+       {0x0000a104, 0x061f0600},
+       {0x0000a108, 0x061d061e},
+       {0x0000a10c, 0x07020703},
+       {0x0000a110, 0x07000701},
+       {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, 0x01000101},
+       {0x0000a148, 0x011e011f},
+       {0x0000a14c, 0x011c011d},
+       {0x0000a150, 0x02030204},
+       {0x0000a154, 0x02010202},
+       {0x0000a158, 0x021f0200},
+       {0x0000a15c, 0x0302021e},
+       {0x0000a160, 0x03000301},
+       {0x0000a164, 0x031e031f},
+       {0x0000a168, 0x0402031d},
+       {0x0000a16c, 0x04000401},
+       {0x0000a170, 0x041e041f},
+       {0x0000a174, 0x0502041d},
+       {0x0000a178, 0x05000501},
+       {0x0000a17c, 0x051e051f},
+       {0x0000a180, 0x06010602},
+       {0x0000a184, 0x061f0600},
+       {0x0000a188, 0x061d061e},
+       {0x0000a18c, 0x07020703},
+       {0x0000a190, 0x07000701},
+       {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 ar9300_2p2_soc_preamble[][2] = {
+       /* Addr      allmodes  */
+       {0x000040a4, 0x00a0c1c9},
+       {0x00007008, 0x00000000},
+       {0x00007020, 0x00000000},
+       {0x00007034, 0x00000002},
+       {0x00007038, 0x000004c2},
+       {0x00007048, 0x00000008},
+};
+
+static const u32 ar9300PciePhy_pll_on_clkreq_disable_L1_2p2[][2] = {
+       /* Addr      allmodes  */
+       {0x00004040, 0x0821265e},
+       {0x00004040, 0x0008003b},
+       {0x00004044, 0x00000000},
+};
+
+static const u32 ar9300PciePhy_clkreq_enable_L1_2p2[][2] = {
+       /* Addr      allmodes  */
+       {0x00004040, 0x08253e5e},
+       {0x00004040, 0x0008003b},
+       {0x00004044, 0x00000000},
+};
+
+static const u32 ar9300PciePhy_clkreq_disable_L1_2p2[][2] = {
+       /* Addr      allmodes  */
+       {0x00004040, 0x08213e5e},
+       {0x00004040, 0x0008003b},
+       {0x00004044, 0x00000000},
+};
+
+#endif /* INITVALS_9003_2P2_H */
diff --git a/src/drivers/net/ath/ath9k/ar9003_eeprom.h b/src/drivers/net/ath/ath9k/ar9003_eeprom.h
new file mode 100644 (file)
index 0000000..393f2de
--- /dev/null
@@ -0,0 +1,338 @@
+/*
+ * Copyright (c) 2010-2011 Atheros Communications Inc.
+ *
+ * Modified for iPXE by Scott K Logan <logans@cottsay.net> July 2011
+ * Original from Linux kernel 3.0.1
+ *
+ * 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_EEPROM_H
+#define AR9003_EEPROM_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_NUM_BAND_EDGES_5G     8
+#define AR9300_NUM_BAND_EDGES_2G     4
+#define AR9300_EEPMISC_BIG_ENDIAN    0x01
+#define AR9300_EEPMISC_WOW           0x02
+#define AR9300_CUSTOMER_DATA_SIZE    20
+
+#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_PAPRD_RATE_MASK         0x01ffffff
+#define AR9300_PAPRD_SCALE_1           0x0e000000
+#define AR9300_PAPRD_SCALE_1_S         25
+#define AR9300_PAPRD_SCALE_2           0x70000000
+#define AR9300_PAPRD_SCALE_2_S         28
+
+/* 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
+
+/* byte addressable */
+#define AR9300_EEPROM_SIZE (16*1024)
+
+#define AR9300_BASE_ADDR_4K 0xfff
+#define AR9300_BASE_ADDR 0x3ff
+#define AR9300_BASE_ADDR_512 0x1ff
+
+#define AR9300_OTP_BASE                        0x14000
+#define AR9300_OTP_STATUS              0x15f18
+#define AR9300_OTP_STATUS_TYPE         0x7
+#define AR9300_OTP_STATUS_VALID                0x4
+#define AR9300_OTP_STATUS_ACCESS_BUSY  0x2
+#define AR9300_OTP_STATUS_SM_BUSY      0x1
+#define AR9300_OTP_READ_DATA           0x15f1c
+
+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;
+} __attribute__((packed));
+
+enum CompressAlgorithm {
+       _CompressNone = 0,
+       _CompressLzma,
+       _CompressPairs,
+       _CompressBlock,
+       _Compress4,
+       _Compress5,
+       _Compress6,
+       _Compress7,
+};
+
+struct ar9300_base_eep_hdr {
+       uint16_t 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 */
+       uint32_t swreg;
+} __attribute__((packed));
+
+struct ar9300_modal_eep_header {
+       /* 4 idle, t1, t2, b (4 bits per setting) */
+       uint32_t antCtrlCommon;
+       /* 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12 */
+       uint32_t antCtrlCommon2;
+       /* 6 idle, t, r, rx1, rx12, b (2 bits each) */
+       uint16_t 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[AR_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;
+       uint32_t papdRateMaskHt20;
+       uint32_t papdRateMaskHt40;
+       u8 futureModal[10];
+} __attribute__((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;
+} __attribute__((packed));
+
+struct cal_tgt_pow_legacy {
+       u8 tPow2x[4];
+} __attribute__((packed));
+
+struct cal_tgt_pow_ht {
+       u8 tPow2x[14];
+} __attribute__((packed));
+
+struct cal_ctl_data_2g {
+       u8 ctlEdges[AR9300_NUM_BAND_EDGES_2G];
+} __attribute__((packed));
+
+struct cal_ctl_data_5g {
+       u8 ctlEdges[AR9300_NUM_BAND_EDGES_5G];
+} __attribute__((packed));
+
+struct ar9300_BaseExtension_1 {
+       u8 ant_div_control;
+       u8 future[13];
+} __attribute__((packed));
+
+struct ar9300_BaseExtension_2 {
+       int8_t    tempSlopeLow;
+       int8_t    tempSlopeHigh;
+       u8   xatten1DBLow[AR9300_MAX_CHAINS];
+       u8   xatten1MarginLow[AR9300_MAX_CHAINS];
+       u8   xatten1DBHigh[AR9300_MAX_CHAINS];
+       u8   xatten1MarginHigh[AR9300_MAX_CHAINS];
+} __attribute__((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;
+       struct ar9300_BaseExtension_1 base_ext1;
+       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;
+       struct ar9300_BaseExtension_2 base_ext2;
+       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];
+} __attribute__((packed));
+
+s32 ar9003_hw_get_tx_gain_idx(struct ath_hw *ah);
+s32 ar9003_hw_get_rx_gain_idx(struct ath_hw *ah);
+
+u8 *ar9003_get_spur_chan_ptr(struct ath_hw *ah, int is_2ghz);
+
+unsigned int ar9003_get_paprd_scale_factor(struct ath_hw *ah,
+                                          struct ath9k_channel *chan);
+#endif
diff --git a/src/drivers/net/ath/ath9k/ar9003_mac.h b/src/drivers/net/ath/ath9k/ar9003_mac.h
new file mode 100644 (file)
index 0000000..6442bb7
--- /dev/null
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2010-2011 Atheros Communications Inc.
+ *
+ * Modified for iPXE by Scott K Logan <logans@cottsay.net> July 2011
+ * Original from Linux kernel 3.0.1
+ *
+ * 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_LowRxChain  0x00004000
+
+#define AR_Not_Sounding        0x20000000
+
+/* ctl 12 */
+#define AR_PAPRDChainMask      0x00000e00
+#define AR_PAPRDChainMask_S    9
+
+#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 MAP_ISR_S2_BB_WATCHDOG  6
+
+#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;
+} __attribute__((packed, aligned(4)));
+
+/* 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) */
+} __attribute__((packed, aligned(4)));
+
+struct ar9003_txs {
+       u32 ds_info;
+       u32 status1;
+       u32 status2;
+       u32 status3;
+       u32 status4;
+       u32 status5;
+       u32 status6;
+       u32 status7;
+       u32 status8;
+} __attribute__((packed, aligned(4)));
+
+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/src/drivers/net/ath/ath9k/ar9003_phy.h b/src/drivers/net/ath/ath9k/ar9003_phy.h
new file mode 100644 (file)
index 0000000..443090d
--- /dev/null
@@ -0,0 +1,1124 @@
+/*
+ * Copyright (c) 2010-2011 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_EXT_CYCPWR_THR1 0x0000FE00L
+#define AR_PHY_EXT_CYCPWR_THR1_S 9
+#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)
+
+/*
+ * Antenna Diversity  settings
+ */
+#define AR_PHY_MC_GAIN_CTRL     (AR_AGC_BASE + 0x28)
+#define AR_ANT_DIV_CTRL_ALL    0x7e000000
+#define AR_ANT_DIV_CTRL_ALL_S  25
+#define AR_ANT_DIV_ENABLE      0x1000000
+#define AR_ANT_DIV_ENABLE_S    24
+
+
+#define AR_PHY_9485_ANT_FAST_DIV_BIAS                  0x00007e00
+#define AR_PHY_9485_ANT_FAST_DIV_BIAS_S                  9
+#define AR_PHY_9485_ANT_DIV_LNADIV                     0x01000000
+#define AR_PHY_9485_ANT_DIV_LNADIV_S                   24
+#define AR_PHY_9485_ANT_DIV_ALT_LNACONF                        0x06000000
+#define AR_PHY_9485_ANT_DIV_ALT_LNACONF_S              25
+#define AR_PHY_9485_ANT_DIV_MAIN_LNACONF               0x18000000
+#define AR_PHY_9485_ANT_DIV_MAIN_LNACONF_S             27
+#define AR_PHY_9485_ANT_DIV_ALT_GAINTB                 0x20000000
+#define AR_PHY_9485_ANT_DIV_ALT_GAINTB_S               29
+#define AR_PHY_9485_ANT_DIV_MAIN_GAINTB                        0x40000000
+#define AR_PHY_9485_ANT_DIV_MAIN_GAINTB_S              30
+
+#define AR_PHY_9485_ANT_DIV_LNA1_MINUS_LNA2            0x0
+#define AR_PHY_9485_ANT_DIV_LNA2                       0x1
+#define AR_PHY_9485_ANT_DIV_LNA1                       0x2
+#define AR_PHY_9485_ANT_DIV_LNA1_PLUS_LNA2             0x3
+
+#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_FAST_DIV_ENABLE     0x2000
+#define AR_FAST_DIV_ENABLE_S   13
+
+#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_MRC_CCK_CTRL         (AR_AGC_BASE + 0x1d0)
+#define AR_PHY_MRC_CCK_ENABLE       0x00000001
+#define AR_PHY_MRC_CCK_ENABLE_S              0
+#define AR_PHY_MRC_CCK_MUX_REG      0x00000002
+#define AR_PHY_MRC_CCK_MUX_REG_S             1
+
+#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_CHAN_INFO_MEMORY_CHANINFOMEM_S2_READ    0x00000008
+#define AR_PHY_CHAN_INFO_MEMORY_CHANINFOMEM_S2_READ_S  3
+
+#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_POWER_TX_RATE(_d) (AR_SM_BASE + 0x1c0 + ((_d) << 2))
+
+#define AR_PHY_PWRTX_MAX         (AR_SM_BASE + 0x1f0)
+#define AR_PHY_POWER_TX_SUB      (AR_SM_BASE + 0x1f4)
+
+#define AR_PHY_TPC_1                           (AR_SM_BASE + 0x1f8)
+#define AR_PHY_TPC_1_FORCED_DAC_GAIN           0x0000003e
+#define AR_PHY_TPC_1_FORCED_DAC_GAIN_S         1
+#define AR_PHY_TPC_1_FORCE_DAC_GAIN            0x00000001
+#define AR_PHY_TPC_1_FORCE_DAC_GAIN_S          0
+
+#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_11_B1                       (AR_SM1_BASE + 0x220)
+#define AR_PHY_TPC_11_B2                       (AR_SM2_BASE + 0x220)
+#define AR_PHY_TPC_11_OLPC_GAIN_DELTA          0x00ff0000
+#define AR_PHY_TPC_11_OLPC_GAIN_DELTA_S                16
+
+#define AR_PHY_TPC_12                          (AR_SM_BASE + 0x224)
+#define AR_PHY_TPC_12_DESIRED_SCALE_HT40_5     0x3e000000
+#define AR_PHY_TPC_12_DESIRED_SCALE_HT40_5_S   25
+
+#define AR_PHY_TPC_18                          (AR_SM_BASE + 0x23c)
+#define AR_PHY_TPC_18_THERM_CAL_VALUE           0x000000ff
+#define AR_PHY_TPC_18_THERM_CAL_VALUE_S         0
+#define AR_PHY_TPC_18_VOLT_CAL_VALUE           0x0000ff00
+#define AR_PHY_TPC_18_VOLT_CAL_VALUE_S         8
+
+#define AR_PHY_TPC_19                          (AR_SM_BASE + 0x240)
+#define AR_PHY_TPC_19_ALPHA_VOLT               0x001f0000
+#define AR_PHY_TPC_19_ALPHA_VOLT_S             16
+#define AR_PHY_TPC_19_ALPHA_THERM              0xff
+#define AR_PHY_TPC_19_ALPHA_THERM_S            0
+
+#define AR_PHY_TX_FORCED_GAIN                          (AR_SM_BASE + 0x258)
+#define AR_PHY_TX_FORCED_GAIN_FORCE_TX_GAIN            0x00000001
+#define AR_PHY_TX_FORCED_GAIN_FORCE_TX_GAIN_S          0
+#define AR_PHY_TX_FORCED_GAIN_FORCED_TXBB1DBGAIN       0x0000000e
+#define AR_PHY_TX_FORCED_GAIN_FORCED_TXBB1DBGAIN_S     1
+#define AR_PHY_TX_FORCED_GAIN_FORCED_TXBB6DBGAIN       0x00000030
+#define AR_PHY_TX_FORCED_GAIN_FORCED_TXBB6DBGAIN_S     4
+#define AR_PHY_TX_FORCED_GAIN_FORCED_TXMXRGAIN         0x000003c0
+#define AR_PHY_TX_FORCED_GAIN_FORCED_TXMXRGAIN_S       6
+#define AR_PHY_TX_FORCED_GAIN_FORCED_PADRVGNA          0x00003c00
+#define AR_PHY_TX_FORCED_GAIN_FORCED_PADRVGNA_S                10
+#define AR_PHY_TX_FORCED_GAIN_FORCED_PADRVGNB          0x0003c000
+#define AR_PHY_TX_FORCED_GAIN_FORCED_PADRVGNB_S                14
+#define AR_PHY_TX_FORCED_GAIN_FORCED_PADRVGNC          0x003c0000
+#define AR_PHY_TX_FORCED_GAIN_FORCED_PADRVGNC_S                18
+#define AR_PHY_TX_FORCED_GAIN_FORCED_PADRVGND          0x00c00000
+#define AR_PHY_TX_FORCED_GAIN_FORCED_PADRVGND_S                22
+#define AR_PHY_TX_FORCED_GAIN_FORCED_ENABLE_PAL                0x01000000
+#define AR_PHY_TX_FORCED_GAIN_FORCED_ENABLE_PAL_S      24
+
+
+#define AR_PHY_PDADC_TAB_0       (AR_SM_BASE + 0x280)
+
+#define AR_PHY_TXGAIN_TABLE      (AR_SM_BASE + 0x300)
+
+#define AR_PHY_TX_IQCAL_CONTROL_1   (AR_SM_BASE + AR_SREV_9485(ah) ? \
+                                                0x3c8 : 0x448)
+#define AR_PHY_TX_IQCAL_START       (AR_SM_BASE + AR_SREV_9485(ah) ? \
+                                                0x3c4 : 0x440)
+#define AR_PHY_TX_IQCAL_STATUS_B0   (AR_SM_BASE + AR_SREV_9485(ah) ? \
+                                                0x3f0 : 0x48c)
+#define AR_PHY_TX_IQCAL_CORR_COEFF_B0(_i)    (AR_SM_BASE + \
+                                            (AR_SREV_9485(ah) ? \
+                                             0x3d0 : 0x450) + ((_i) << 2))
+
+#define AR_PHY_WATCHDOG_STATUS      (AR_SM_BASE + 0x5c0)
+#define AR_PHY_WATCHDOG_CTL_1       (AR_SM_BASE + 0x5c4)
+#define AR_PHY_WATCHDOG_CTL_2       (AR_SM_BASE + 0x5c8)
+#define AR_PHY_WATCHDOG_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_BB_THERM_ADC_1_INIT_THERM               0x000000ff
+#define AR_PHY_BB_THERM_ADC_1_INIT_THERM_S             0
+
+#define AR_PHY_BB_THERM_ADC_4                          (AR_SM_BASE + 0x254)
+#define AR_PHY_BB_THERM_ADC_4_LATEST_THERM_VALUE       0x000000ff
+#define AR_PHY_BB_THERM_ADC_4_LATEST_THERM_VALUE_S     0
+#define AR_PHY_BB_THERM_ADC_4_LATEST_VOLT_VALUE                0x0000ff00
+#define AR_PHY_BB_THERM_ADC_4_LATEST_VOLT_VALUE_S      8
+
+
+#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       (AR_SREV_9300(ah) ? 0x16290 : 0x1628c)
+
+#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_CH0_TOP2 (AR_SREV_9485(ah) ? 0x00016284 : 0x0001628c)
+#define AR_CH0_TOP2_XPABIASLVL         0xf000
+#define AR_CH0_TOP2_XPABIASLVL_S       12
+
+#define AR_CH0_XTAL            (AR_SREV_9485(ah) ? 0x16290 : 0x16294)
+#define AR_CH0_XTAL_CAPINDAC   0x7f000000
+#define AR_CH0_XTAL_CAPINDAC_S 24
+#define AR_CH0_XTAL_CAPOUTDAC  0x00fe0000
+#define AR_CH0_XTAL_CAPOUTDAC_S        17
+
+#define AR_PHY_PMU1            0x16c40
+#define AR_PHY_PMU1_PWD                0x1
+#define AR_PHY_PMU1_PWD_S      0
+
+#define AR_PHY_PMU2            0x16c44
+#define AR_PHY_PMU2_PGM                0x00200000
+#define AR_PHY_PMU2_PGM_S      21
+
+#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_FORCE_S            0
+#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_IQCAL_CONTROL_1_IQCORR_I_Q_COFF_DELPT             0x01fc0000
+#define AR_PHY_TX_IQCAL_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_CALIBRATED_GAINS_0       0x3e
+#define AR_PHY_CALIBRATED_GAINS_0_S     1
+
+#define AR_PHY_TX_IQCAL_CORR_COEFF_00_COEFF_TABLE      0x00003fff
+#define AR_PHY_TX_IQCAL_CORR_COEFF_00_COEFF_TABLE_S    0
+#define AR_PHY_TX_IQCAL_CORR_COEFF_01_COEFF_TABLE      0x0fffc000
+#define AR_PHY_TX_IQCAL_CORR_COEFF_01_COEFF_TABLE_S    14
+
+#define AR_PHY_65NM_CH0_RXTX4_THERM_ON          0x10000000
+#define AR_PHY_65NM_CH0_RXTX4_THERM_ON_S        28
+
+/*
+ * 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_B1(_i)    (AR_SM_BASE + 0x450 + ((_i) << 2))
+
+/*
+ * 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_B2(_i)    (AR_SM2_BASE + 0x450 + ((_i) << 2))
+
+#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_WATCHDOG_NON_IDLE_ENABLE    0x00000001
+#define AR_PHY_WATCHDOG_IDLE_ENABLE        0x00000002
+#define AR_PHY_WATCHDOG_IDLE_MASK          0xFFFF0000
+#define AR_PHY_WATCHDOG_NON_IDLE_MASK      0x0000FFFC
+
+#define AR_PHY_WATCHDOG_RST_ENABLE         0x00000002
+#define AR_PHY_WATCHDOG_IRQ_ENABLE         0x00000004
+#define AR_PHY_WATCHDOG_CNTL2_MASK         0xFFFFFFF9
+
+#define AR_PHY_WATCHDOG_INFO               0x00000007
+#define AR_PHY_WATCHDOG_INFO_S             0
+#define AR_PHY_WATCHDOG_DET_HANG           0x00000008
+#define AR_PHY_WATCHDOG_DET_HANG_S         3
+#define AR_PHY_WATCHDOG_RADAR_SM           0x000000F0
+#define AR_PHY_WATCHDOG_RADAR_SM_S         4
+#define AR_PHY_WATCHDOG_RX_OFDM_SM         0x00000F00
+#define AR_PHY_WATCHDOG_RX_OFDM_SM_S       8
+#define AR_PHY_WATCHDOG_RX_CCK_SM          0x0000F000
+#define AR_PHY_WATCHDOG_RX_CCK_SM_S        12
+#define AR_PHY_WATCHDOG_TX_OFDM_SM         0x000F0000
+#define AR_PHY_WATCHDOG_TX_OFDM_SM_S       16
+#define AR_PHY_WATCHDOG_TX_CCK_SM          0x00F00000
+#define AR_PHY_WATCHDOG_TX_CCK_SM_S        20
+#define AR_PHY_WATCHDOG_AGC_SM             0x0F000000
+#define AR_PHY_WATCHDOG_AGC_SM_S           24
+#define AR_PHY_WATCHDOG_SRCH_SM            0xF0000000
+#define AR_PHY_WATCHDOG_SRCH_SM_S          28
+
+#define AR_PHY_WATCHDOG_STATUS_CLR         0x00000008
+
+/*
+ * PAPRD registers
+ */
+#define AR_PHY_XPA_TIMING_CTL          (AR_SM_BASE + 0x64)
+
+#define AR_PHY_PAPRD_AM2AM             (AR_CHAN_BASE + 0xe4)
+#define AR_PHY_PAPRD_AM2AM_MASK                0x01ffffff
+#define AR_PHY_PAPRD_AM2AM_MASK_S      0
+
+#define AR_PHY_PAPRD_AM2PM             (AR_CHAN_BASE + 0xe8)
+#define AR_PHY_PAPRD_AM2PM_MASK                0x01ffffff
+#define AR_PHY_PAPRD_AM2PM_MASK_S      0
+
+#define AR_PHY_PAPRD_HT40              (AR_CHAN_BASE + 0xec)
+#define AR_PHY_PAPRD_HT40_MASK         0x01ffffff
+#define AR_PHY_PAPRD_HT40_MASK_S       0
+
+#define AR_PHY_PAPRD_CTRL0_B0                          (AR_CHAN_BASE + 0xf0)
+#define AR_PHY_PAPRD_CTRL0_B1                          (AR_CHAN1_BASE + 0xf0)
+#define AR_PHY_PAPRD_CTRL0_B2                          (AR_CHAN2_BASE + 0xf0)
+#define AR_PHY_PAPRD_CTRL0_PAPRD_ENABLE                        0x00000001
+#define AR_PHY_PAPRD_CTRL0_PAPRD_ENABLE_S              0
+#define AR_PHY_PAPRD_CTRL0_USE_SINGLE_TABLE_MASK       0x00000002
+#define AR_PHY_PAPRD_CTRL0_USE_SINGLE_TABLE_MASK_S     1
+#define AR_PHY_PAPRD_CTRL0_PAPRD_MAG_THRSH             0xf8000000
+#define AR_PHY_PAPRD_CTRL0_PAPRD_MAG_THRSH_S           27
+
+#define AR_PHY_PAPRD_CTRL1_B0                          (AR_CHAN_BASE + 0xf4)
+#define AR_PHY_PAPRD_CTRL1_B1                          (AR_CHAN1_BASE + 0xf4)
+#define AR_PHY_PAPRD_CTRL1_B2                          (AR_CHAN2_BASE + 0xf4)
+#define AR_PHY_PAPRD_CTRL1_ADAPTIVE_SCALING_ENA                0x00000001
+#define AR_PHY_PAPRD_CTRL1_ADAPTIVE_SCALING_ENA_S      0
+#define AR_PHY_PAPRD_CTRL1_ADAPTIVE_AM2AM_ENABLE       0x00000002
+#define AR_PHY_PAPRD_CTRL1_ADAPTIVE_AM2AM_ENABLE_S     1
+#define AR_PHY_PAPRD_CTRL1_ADAPTIVE_AM2PM_ENABLE       0x00000004
+#define AR_PHY_PAPRD_CTRL1_ADAPTIVE_AM2PM_ENABLE_S     2
+#define AR_PHY_PAPRD_CTRL1_PAPRD_POWER_AT_AM2AM_CAL    0x000001f8
+#define AR_PHY_PAPRD_CTRL1_PAPRD_POWER_AT_AM2AM_CAL_S  3
+#define AR_PHY_PAPRD_CTRL1_PA_GAIN_SCALE_FACT_MASK     0x0001fe00
+#define AR_PHY_PAPRD_CTRL1_PA_GAIN_SCALE_FACT_MASK_S   9
+#define AR_PHY_PAPRD_CTRL1_PAPRD_MAG_SCALE_FACT                0x0ffe0000
+#define AR_PHY_PAPRD_CTRL1_PAPRD_MAG_SCALE_FACT_S      17
+
+#define AR_PHY_PAPRD_TRAINER_CNTL1                             (AR_SM_BASE + \
+                                                                (AR_SREV_9485(ah) ? \
+                                                                 0x580 : 0x490))
+#define AR_PHY_PAPRD_TRAINER_CNTL1_CF_CF_PAPRD_TRAIN_ENABLE    0x00000001
+#define AR_PHY_PAPRD_TRAINER_CNTL1_CF_CF_PAPRD_TRAIN_ENABLE_S  0
+#define AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_AGC2_SETTLING      0x0000007e
+#define AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_AGC2_SETTLING_S    1
+#define AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_IQCORR_ENABLE      0x00000100
+#define AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_IQCORR_ENABLE_S    8
+#define AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_RX_BB_GAIN_FORCE   0x00000200
+#define AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_RX_BB_GAIN_FORCE_S 9
+#define AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_TX_GAIN_FORCE      0x00000400
+#define AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_TX_GAIN_FORCE_S    10
+#define AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_LB_ENABLE          0x00000800
+#define AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_LB_ENABLE_S                11
+#define AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_LB_SKIP            0x0003f000
+#define AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_LB_SKIP_S          12
+
+#define AR_PHY_PAPRD_TRAINER_CNTL2                             (AR_SM_BASE + \
+                                                                (AR_SREV_9485(ah) ? \
+                                                                 0x584 : 0x494))
+#define AR_PHY_PAPRD_TRAINER_CNTL2_CF_PAPRD_INIT_RX_BB_GAIN    0xFFFFFFFF
+#define AR_PHY_PAPRD_TRAINER_CNTL2_CF_PAPRD_INIT_RX_BB_GAIN_S  0
+
+#define AR_PHY_PAPRD_TRAINER_CNTL3                             (AR_SM_BASE + \
+                                                                (AR_SREV_9485(ah) ? \
+                                                                 0x588 : 0x498))
+#define AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_ADC_DESIRED_SIZE   0x0000003f
+#define AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_ADC_DESIRED_SIZE_S 0
+#define AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP         0x00000fc0
+#define AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP_S       6
+#define AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_MIN_LOOPBACK_DEL   0x0001f000
+#define AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_MIN_LOOPBACK_DEL_S 12
+#define AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_NUM_CORR_STAGES    0x000e0000
+#define AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_NUM_CORR_STAGES_S  17
+#define AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_COARSE_CORR_LEN    0x00f00000
+#define AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_COARSE_CORR_LEN_S  20
+#define AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_FINE_CORR_LEN      0x0f000000
+#define AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_FINE_CORR_LEN_S    24
+#define AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_BBTXMIX_DISABLE    0x20000000
+#define AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_BBTXMIX_DISABLE_S  29
+
+#define AR_PHY_PAPRD_TRAINER_CNTL4                             (AR_SM_BASE + \
+                                                                (AR_SREV_9485(ah) ? \
+                                                                 0x58c : 0x49c))
+#define AR_PHY_PAPRD_TRAINER_CNTL4_CF_PAPRD_NUM_TRAIN_SAMPLES  0x03ff0000
+#define AR_PHY_PAPRD_TRAINER_CNTL4_CF_PAPRD_NUM_TRAIN_SAMPLES_S        16
+#define AR_PHY_PAPRD_TRAINER_CNTL4_CF_PAPRD_SAFETY_DELTA       0x0000f000
+#define AR_PHY_PAPRD_TRAINER_CNTL4_CF_PAPRD_SAFETY_DELTA_S     12
+#define AR_PHY_PAPRD_TRAINER_CNTL4_CF_PAPRD_MIN_CORR           0x00000fff
+#define AR_PHY_PAPRD_TRAINER_CNTL4_CF_PAPRD_MIN_CORR_S         0
+
+#define AR_PHY_PAPRD_PRE_POST_SCALE_0_B0                       (AR_CHAN_BASE + 0x100)
+#define AR_PHY_PAPRD_PRE_POST_SCALE_1_B0                       (AR_CHAN_BASE + 0x104)
+#define AR_PHY_PAPRD_PRE_POST_SCALE_2_B0                       (AR_CHAN_BASE + 0x108)
+#define AR_PHY_PAPRD_PRE_POST_SCALE_3_B0                       (AR_CHAN_BASE + 0x10c)
+#define AR_PHY_PAPRD_PRE_POST_SCALE_4_B0                       (AR_CHAN_BASE + 0x110)
+#define AR_PHY_PAPRD_PRE_POST_SCALE_5_B0                       (AR_CHAN_BASE + 0x114)
+#define AR_PHY_PAPRD_PRE_POST_SCALE_6_B0                       (AR_CHAN_BASE + 0x118)
+#define AR_PHY_PAPRD_PRE_POST_SCALE_7_B0                       (AR_CHAN_BASE + 0x11c)
+#define AR_PHY_PAPRD_PRE_POST_SCALING                          0x3FFFF
+#define AR_PHY_PAPRD_PRE_POST_SCALING_S                                0
+
+#define AR_PHY_PAPRD_TRAINER_STAT1                             (AR_SM_BASE + 0x4a0)
+#define AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE            0x00000001
+#define AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE_S          0
+#define AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_INCOMPLETE      0x00000002
+#define AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_INCOMPLETE_S    1
+#define AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_CORR_ERR              0x00000004
+#define AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_CORR_ERR_S            2
+#define AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_ACTIVE          0x00000008
+#define AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_ACTIVE_S                3
+#define AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_RX_GAIN_IDX           0x000001f0
+#define AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_RX_GAIN_IDX_S         4
+#define AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_AGC2_PWR              0x0001fe00
+#define AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_AGC2_PWR_S            9
+
+#define AR_PHY_PAPRD_TRAINER_STAT2                             (AR_SM_BASE + 0x4a4)
+#define AR_PHY_PAPRD_TRAINER_STAT2_PAPRD_FINE_VAL              0x0000ffff
+#define AR_PHY_PAPRD_TRAINER_STAT2_PAPRD_FINE_VAL_S            0
+#define AR_PHY_PAPRD_TRAINER_STAT2_PAPRD_COARSE_IDX            0x001f0000
+#define AR_PHY_PAPRD_TRAINER_STAT2_PAPRD_COARSE_IDX_S          16
+#define AR_PHY_PAPRD_TRAINER_STAT2_PAPRD_FINE_IDX              0x00600000
+#define AR_PHY_PAPRD_TRAINER_STAT2_PAPRD_FINE_IDX_S            21
+
+#define AR_PHY_PAPRD_TRAINER_STAT3                             (AR_SM_BASE + 0x4a8)
+#define AR_PHY_PAPRD_TRAINER_STAT3_PAPRD_TRAIN_SAMPLES_CNT     0x000fffff
+#define AR_PHY_PAPRD_TRAINER_STAT3_PAPRD_TRAIN_SAMPLES_CNT_S   0
+
+#define AR_PHY_PAPRD_MEM_TAB_B0                        (AR_CHAN_BASE + 0x120)
+#define AR_PHY_PAPRD_MEM_TAB_B1                        (AR_CHAN1_BASE + 0x120)
+#define AR_PHY_PAPRD_MEM_TAB_B2                        (AR_CHAN2_BASE + 0x120)
+
+#define AR_PHY_PA_GAIN123_B0                   (AR_CHAN_BASE + 0xf8)
+#define AR_PHY_PA_GAIN123_B1                   (AR_CHAN1_BASE + 0xf8)
+#define AR_PHY_PA_GAIN123_B2                   (AR_CHAN2_BASE + 0xf8)
+#define AR_PHY_PA_GAIN123_PA_GAIN1             0x3FF
+#define AR_PHY_PA_GAIN123_PA_GAIN1_S           0
+
+#define AR_PHY_POWERTX_RATE5                   (AR_SM_BASE + 0x1d0)
+#define AR_PHY_POWERTX_RATE5_POWERTXHT20_0     0x3F
+#define AR_PHY_POWERTX_RATE5_POWERTXHT20_0_S   0
+
+#define AR_PHY_POWERTX_RATE6                   (AR_SM_BASE + 0x1d4)
+#define AR_PHY_POWERTX_RATE6_POWERTXHT20_5     0x3F00
+#define AR_PHY_POWERTX_RATE6_POWERTXHT20_5_S   8
+
+#define AR_PHY_POWERTX_RATE8                   (AR_SM_BASE + 0x1dc)
+#define AR_PHY_POWERTX_RATE8_POWERTXHT40_5     0x3F00
+#define AR_PHY_POWERTX_RATE8_POWERTXHT40_5_S   8
+
+void ar9003_hw_set_chain_masks(struct ath_hw *ah, u8 rx, u8 tx);
+
+#endif  /* AR9003_PHY_H */
diff --git a/src/drivers/net/ath/ath9k/ar9340_initvals.h b/src/drivers/net/ath/ath9k/ar9340_initvals.h
new file mode 100644 (file)
index 0000000..815a8af
--- /dev/null
@@ -0,0 +1,1525 @@
+/*
+ * Copyright (c) 2011 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_9340_H
+#define INITVALS_9340_H
+
+static const u32 ar9340_1p0_radio_postamble[][5] = {
+       /*  Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20  */
+       {0x000160ac, 0xa4646800, 0xa4646800, 0xa4646800, 0xa4646800},
+       {0x0001610c, 0x08000000, 0x08000000, 0x00000000, 0x00000000},
+       {0x00016140, 0x10804000, 0x10804000, 0x50804000, 0x50804000},
+       {0x0001650c, 0x08000000, 0x08000000, 0x00000000, 0x00000000},
+       {0x00016540, 0x10804000, 0x10804000, 0x50804000, 0x50804000},
+};
+
+static const u32 ar9340Modes_lowest_ob_db_tx_gain_table_1p0[][5] = {
+       /*   Addr     5G_HT20     5G_HT40     2G_HT40     2G_HT20  */
+       {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9},
+       {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, 0x056db2db, 0x056db2db, 0x056db2db, 0x056db2db},
+       {0x00016048, 0x24925266, 0x24925266, 0x24925266, 0x24925266},
+       {0x00016444, 0x056db2db, 0x056db2db, 0x056db2db, 0x056db2db},
+       {0x00016448, 0x24925266, 0x24925266, 0x24925266, 0x24925266},
+};
+
+static const u32 ar9340Modes_fast_clock_1p0[][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 ar9340_1p0_radio_core[][2] = {
+       /*  Addr     allmodes  */
+       {0x00016000, 0x36db6db6},
+       {0x00016004, 0x6db6db40},
+       {0x00016008, 0x73f00000},
+       {0x0001600c, 0x00000000},
+       {0x00016040, 0x7f80fff8},
+       {0x00016044, 0x03b6d2db},
+       {0x00016048, 0x24925266},
+       {0x0001604c, 0x000f0278},
+       {0x00016050, 0x6db6db6c},
+       {0x00016054, 0x6db60000},
+       {0x00016080, 0x00080000},
+       {0x00016084, 0x0e48048c},
+       {0x00016088, 0x14214514},
+       {0x0001608c, 0x119f081c},
+       {0x00016090, 0x24926490},
+       {0x00016094, 0x00000000},
+       {0x00016098, 0xd411eb84},
+       {0x0001609c, 0x03e47f32},
+       {0x000160a0, 0xc2108ffe},
+       {0x000160a4, 0x812fc370},
+       {0x000160a8, 0x423c8000},
+       {0x000160ac, 0xa4646800},
+       {0x000160b0, 0x00fe7f46},
+       {0x000160b4, 0x92480000},
+       {0x000160c0, 0x006db6db},
+       {0x000160c4, 0x6db6db60},
+       {0x000160c8, 0x6db6db6c},
+       {0x000160cc, 0x6de6db6c},
+       {0x000160d0, 0xb6da4924},
+       {0x00016100, 0x04cb0001},
+       {0x00016104, 0xfff80000},
+       {0x00016108, 0x00080010},
+       {0x0001610c, 0x00000000},
+       {0x00016140, 0x50804008},
+       {0x00016144, 0x01884080},
+       {0x00016148, 0x000080c0},
+       {0x00016280, 0x01000015},
+       {0x00016284, 0x05530000},
+       {0x00016288, 0x00318000},
+       {0x0001628c, 0x50000000},
+       {0x00016290, 0x4080294f},
+       {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},
+       {0x00016444, 0x03b6d2db},
+       {0x00016448, 0x24927266},
+       {0x0001644c, 0x000f0278},
+       {0x00016450, 0x6db6db6c},
+       {0x00016454, 0x6db60000},
+       {0x00016500, 0x04cb0001},
+       {0x00016504, 0xfff80000},
+       {0x00016508, 0x00080010},
+       {0x0001650c, 0x00000000},
+       {0x00016540, 0x50804008},
+       {0x00016544, 0x01884080},
+       {0x00016548, 0x000080c0},
+       {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},
+};
+
+static const u32 ar9340_1p0_radio_core_40M[][2] = {
+       {0x0001609c, 0x02566f3a},
+       {0x000160ac, 0xa4647c00},
+       {0x000160b0, 0x01885f5a},
+};
+
+static const u32 ar9340_1p0_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 ar9340_1p0_soc_postamble[][5] = {
+       /*   Addr     5G_HT20     5G_HT40     2G_HT40     2G_HT20  */
+       {0x00007010, 0x00000023, 0x00000023, 0x00000023, 0x00000023},
+};
+
+static const u32 ar9340_1p0_baseband_postamble[][5] = {
+       /*  Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20  */
+       {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8011, 0xd00a8011},
+       {0x00009820, 0x206a022e, 0x206a022e, 0x206a022e, 0x206a022e},
+       {0x00009824, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0},
+       {0x00009828, 0x06903081, 0x06903081, 0x06903881, 0x06903881},
+       {0x0000982c, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4},
+       {0x00009830, 0x0000059c, 0x0000059c, 0x0000119c, 0x0000119c},
+       {0x00009c00, 0x00000044, 0x000000c4, 0x000000c4, 0x00000044},
+       {0x00009e00, 0x0372161e, 0x0372161e, 0x037216a0, 0x037216a0},
+       {0x00009e04, 0x00182020, 0x00182020, 0x00182020, 0x00182020},
+       {0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000e2, 0x6c4000e2},
+       {0x00009e10, 0x7ec88d2e, 0x7ec88d2e, 0x7ec88d2e, 0x7ec88d2e},
+       {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, 0x02291e27, 0x02291e27},
+       {0x00009e48, 0x5030201a, 0x5030201a, 0x50302012, 0x50302012},
+       {0x00009fc8, 0x0003f000, 0x0003f000, 0x0001a000, 0x0001a000},
+       {0x0000a204, 0x00003fc0, 0x00003fc4, 0x00003fc4, 0x00003fc0},
+       {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, 0x00000220, 0x00000220, 0x00000110, 0x00000110},
+       {0x0000a28c, 0x00011111, 0x00011111, 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, 0x00180000, 0x00180000, 0x00180000, 0x00180000},
+       {0x0000ae18, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000ae1c, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c},
+       {0x0000ae20, 0x000001b5, 0x000001b5, 0x000001ce, 0x000001ce},
+       {0x0000b284, 0x00000000, 0x00000000, 0x00000150, 0x00000150},
+};
+
+static const u32 ar9340_1p0_baseband_core[][2] = {
+       /*  Addr     allmodes  */
+       {0x00009800, 0xafe68e30},
+       {0x00009804, 0xfd14e000},
+       {0x00009808, 0x9c0a9f6b},
+       {0x0000980c, 0x04900000},
+       {0x00009814, 0xb280c00a},
+       {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, 0x0038230c},
+       {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, 0x2d001dce},
+       {0x0000a41c, 0x1ce739ce},
+       {0x0000a420, 0x000001ce},
+       {0x0000a424, 0x1ce739ce},
+       {0x0000a428, 0x000001ce},
+       {0x0000a42c, 0x1ce739ce},
+       {0x0000a430, 0x1ce739ce},
+       {0x0000a434, 0x00000000},
+       {0x0000a438, 0x00001801},
+       {0x0000a43c, 0x00000000},
+       {0x0000a440, 0x00000000},
+       {0x0000a444, 0x00000000},
+       {0x0000a448, 0x04000080},
+       {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, 0x3fad9d74},
+       {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, 0x00000000},
+       {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},
+};
+
+static const u32 ar9340Modes_high_power_tx_gain_table_1p0[][5] = {
+       /*  Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20  */
+       {0x0000a410, 0x000050d8, 0x000050d8, 0x000050d9, 0x000050d9},
+       {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000},
+       {0x0000a504, 0x04002222, 0x04002222, 0x04000002, 0x04000002},
+       {0x0000a508, 0x09002421, 0x09002421, 0x08000004, 0x08000004},
+       {0x0000a50c, 0x0d002621, 0x0d002621, 0x0b000200, 0x0b000200},
+       {0x0000a510, 0x13004620, 0x13004620, 0x0f000202, 0x0f000202},
+       {0x0000a514, 0x19004a20, 0x19004a20, 0x11000400, 0x11000400},
+       {0x0000a518, 0x1d004e20, 0x1d004e20, 0x15000402, 0x15000402},
+       {0x0000a51c, 0x21005420, 0x21005420, 0x19000404, 0x19000404},
+       {0x0000a520, 0x26005e20, 0x26005e20, 0x1b000603, 0x1b000603},
+       {0x0000a524, 0x2b005e40, 0x2b005e40, 0x1f000a02, 0x1f000a02},
+       {0x0000a528, 0x2f005e42, 0x2f005e42, 0x23000a04, 0x23000a04},
+       {0x0000a52c, 0x33005e44, 0x33005e44, 0x26000a20, 0x26000a20},
+       {0x0000a530, 0x38005e65, 0x38005e65, 0x2a000e20, 0x2a000e20},
+       {0x0000a534, 0x3c005e69, 0x3c005e69, 0x2e000e22, 0x2e000e22},
+       {0x0000a538, 0x40005e6b, 0x40005e6b, 0x31000e24, 0x31000e24},
+       {0x0000a53c, 0x44005e6d, 0x44005e6d, 0x34001640, 0x34001640},
+       {0x0000a540, 0x49005e72, 0x49005e72, 0x38001660, 0x38001660},
+       {0x0000a544, 0x4e005eb2, 0x4e005eb2, 0x3b001861, 0x3b001861},
+       {0x0000a548, 0x53005f12, 0x53005f12, 0x3e001a81, 0x3e001a81},
+       {0x0000a54c, 0x59025eb5, 0x59025eb5, 0x42001a83, 0x42001a83},
+       {0x0000a550, 0x5e025f12, 0x5e025f12, 0x44001c84, 0x44001c84},
+       {0x0000a554, 0x61027f12, 0x61027f12, 0x48001ce3, 0x48001ce3},
+       {0x0000a558, 0x6702bf12, 0x6702bf12, 0x4c001ce5, 0x4c001ce5},
+       {0x0000a55c, 0x6b02bf14, 0x6b02bf14, 0x50001ce9, 0x50001ce9},
+       {0x0000a560, 0x6f02bf16, 0x6f02bf16, 0x54001ceb, 0x54001ceb},
+       {0x0000a564, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
+       {0x0000a568, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
+       {0x0000a56c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
+       {0x0000a570, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
+       {0x0000a574, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
+       {0x0000a578, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
+       {0x0000a57c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
+       {0x0000a580, 0x00802220, 0x00802220, 0x00800000, 0x00800000},
+       {0x0000a584, 0x04802222, 0x04802222, 0x04800002, 0x04800002},
+       {0x0000a588, 0x09802421, 0x09802421, 0x08800004, 0x08800004},
+       {0x0000a58c, 0x0d802621, 0x0d802621, 0x0b800200, 0x0b800200},
+       {0x0000a590, 0x13804620, 0x13804620, 0x0f800202, 0x0f800202},
+       {0x0000a594, 0x19804a20, 0x19804a20, 0x11800400, 0x11800400},
+       {0x0000a598, 0x1d804e20, 0x1d804e20, 0x15800402, 0x15800402},
+       {0x0000a59c, 0x21805420, 0x21805420, 0x19800404, 0x19800404},
+       {0x0000a5a0, 0x26805e20, 0x26805e20, 0x1b800603, 0x1b800603},
+       {0x0000a5a4, 0x2b805e40, 0x2b805e40, 0x1f800a02, 0x1f800a02},
+       {0x0000a5a8, 0x2f805e42, 0x2f805e42, 0x23800a04, 0x23800a04},
+       {0x0000a5ac, 0x33805e44, 0x33805e44, 0x26800a20, 0x26800a20},
+       {0x0000a5b0, 0x38805e65, 0x38805e65, 0x2a800e20, 0x2a800e20},
+       {0x0000a5b4, 0x3c805e69, 0x3c805e69, 0x2e800e22, 0x2e800e22},
+       {0x0000a5b8, 0x40805e6b, 0x40805e6b, 0x31800e24, 0x31800e24},
+       {0x0000a5bc, 0x44805e6d, 0x44805e6d, 0x34801640, 0x34801640},
+       {0x0000a5c0, 0x49805e72, 0x49805e72, 0x38801660, 0x38801660},
+       {0x0000a5c4, 0x4e805eb2, 0x4e805eb2, 0x3b801861, 0x3b801861},
+       {0x0000a5c8, 0x53805f12, 0x53805f12, 0x3e801a81, 0x3e801a81},
+       {0x0000a5cc, 0x59825eb2, 0x59825eb2, 0x42801a83, 0x42801a83},
+       {0x0000a5d0, 0x5e825f12, 0x5e825f12, 0x44801c84, 0x44801c84},
+       {0x0000a5d4, 0x61827f12, 0x61827f12, 0x48801ce3, 0x48801ce3},
+       {0x0000a5d8, 0x6782bf12, 0x6782bf12, 0x4c801ce5, 0x4c801ce5},
+       {0x0000a5dc, 0x6b82bf14, 0x6b82bf14, 0x50801ce9, 0x50801ce9},
+       {0x0000a5e0, 0x6f82bf16, 0x6f82bf16, 0x54801ceb, 0x54801ceb},
+       {0x0000a5e4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
+       {0x0000a5e8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
+       {0x0000a5ec, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
+       {0x0000a5f0, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
+       {0x0000a5f4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
+       {0x0000a5f8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
+       {0x0000a5fc, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
+       {0x00016044, 0x056db2db, 0x056db2db, 0x056db2db, 0x056db2db},
+       {0x00016048, 0x24925266, 0x24925266, 0x24925266, 0x24925266},
+       {0x00016444, 0x056db2db, 0x056db2db, 0x056db2db, 0x056db2db},
+       {0x00016448, 0x24925266, 0x24925266, 0x24925266, 0x24925266},
+};
+
+static const u32 ar9340Modes_high_ob_db_tx_gain_table_1p0[][5] = {
+       /*  Addr       5G_HT20    5G_HT40     2G_HT40     2G_HT20  */
+       {0x0000a410, 0x000050d8, 0x000050d8, 0x000050d9, 0x000050d9},
+       {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000},
+       {0x0000a504, 0x04002222, 0x04002222, 0x04000002, 0x04000002},
+       {0x0000a508, 0x09002421, 0x09002421, 0x08000004, 0x08000004},
+       {0x0000a50c, 0x0d002621, 0x0d002621, 0x0b000200, 0x0b000200},
+       {0x0000a510, 0x13004620, 0x13004620, 0x0f000202, 0x0f000202},
+       {0x0000a514, 0x19004a20, 0x19004a20, 0x11000400, 0x11000400},
+       {0x0000a518, 0x1d004e20, 0x1d004e20, 0x15000402, 0x15000402},
+       {0x0000a51c, 0x21005420, 0x21005420, 0x19000404, 0x19000404},
+       {0x0000a520, 0x26005e20, 0x26005e20, 0x1b000603, 0x1b000603},
+       {0x0000a524, 0x2b005e40, 0x2b005e40, 0x1f000a02, 0x1f000a02},
+       {0x0000a528, 0x2f005e42, 0x2f005e42, 0x23000a04, 0x23000a04},
+       {0x0000a52c, 0x33005e44, 0x33005e44, 0x26000a20, 0x26000a20},
+       {0x0000a530, 0x38005e65, 0x38005e65, 0x2a000e20, 0x2a000e20},
+       {0x0000a534, 0x3c005e69, 0x3c005e69, 0x2e000e22, 0x2e000e22},
+       {0x0000a538, 0x40005e6b, 0x40005e6b, 0x31000e24, 0x31000e24},
+       {0x0000a53c, 0x44005e6d, 0x44005e6d, 0x34001640, 0x34001640},
+       {0x0000a540, 0x49005e72, 0x49005e72, 0x38001660, 0x38001660},
+       {0x0000a544, 0x4e005eb2, 0x4e005eb2, 0x3b001861, 0x3b001861},
+       {0x0000a548, 0x53005f12, 0x53005f12, 0x3e001a81, 0x3e001a81},
+       {0x0000a54c, 0x59025eb5, 0x59025eb5, 0x42001a83, 0x42001a83},
+       {0x0000a550, 0x5e025f12, 0x5e025f12, 0x44001c84, 0x44001c84},
+       {0x0000a554, 0x61027f12, 0x61027f12, 0x48001ce3, 0x48001ce3},
+       {0x0000a558, 0x6702bf12, 0x6702bf12, 0x4c001ce5, 0x4c001ce5},
+       {0x0000a55c, 0x6b02bf14, 0x6b02bf14, 0x50001ce9, 0x50001ce9},
+       {0x0000a560, 0x6f02bf16, 0x6f02bf16, 0x54001ceb, 0x54001ceb},
+       {0x0000a564, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
+       {0x0000a568, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
+       {0x0000a56c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
+       {0x0000a570, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
+       {0x0000a574, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
+       {0x0000a578, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
+       {0x0000a57c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
+       {0x0000a580, 0x00802220, 0x00802220, 0x00800000, 0x00800000},
+       {0x0000a584, 0x04802222, 0x04802222, 0x04800002, 0x04800002},
+       {0x0000a588, 0x09802421, 0x09802421, 0x08800004, 0x08800004},
+       {0x0000a58c, 0x0d802621, 0x0d802621, 0x0b800200, 0x0b800200},
+       {0x0000a590, 0x13804620, 0x13804620, 0x0f800202, 0x0f800202},
+       {0x0000a594, 0x19804a20, 0x19804a20, 0x11800400, 0x11800400},
+       {0x0000a598, 0x1d804e20, 0x1d804e20, 0x15800402, 0x15800402},
+       {0x0000a59c, 0x21805420, 0x21805420, 0x19800404, 0x19800404},
+       {0x0000a5a0, 0x26805e20, 0x26805e20, 0x1b800603, 0x1b800603},
+       {0x0000a5a4, 0x2b805e40, 0x2b805e40, 0x1f800a02, 0x1f800a02},
+       {0x0000a5a8, 0x2f805e42, 0x2f805e42, 0x23800a04, 0x23800a04},
+       {0x0000a5ac, 0x33805e44, 0x33805e44, 0x26800a20, 0x26800a20},
+       {0x0000a5b0, 0x38805e65, 0x38805e65, 0x2a800e20, 0x2a800e20},
+       {0x0000a5b4, 0x3c805e69, 0x3c805e69, 0x2e800e22, 0x2e800e22},
+       {0x0000a5b8, 0x40805e6b, 0x40805e6b, 0x31800e24, 0x31800e24},
+       {0x0000a5bc, 0x44805e6d, 0x44805e6d, 0x34801640, 0x34801640},
+       {0x0000a5c0, 0x49805e72, 0x49805e72, 0x38801660, 0x38801660},
+       {0x0000a5c4, 0x4e805eb2, 0x4e805eb2, 0x3b801861, 0x3b801861},
+       {0x0000a5c8, 0x53805f12, 0x53805f12, 0x3e801a81, 0x3e801a81},
+       {0x0000a5cc, 0x59825eb2, 0x59825eb2, 0x42801a83, 0x42801a83},
+       {0x0000a5d0, 0x5e825f12, 0x5e825f12, 0x44801c84, 0x44801c84},
+       {0x0000a5d4, 0x61827f12, 0x61827f12, 0x48801ce3, 0x48801ce3},
+       {0x0000a5d8, 0x6782bf12, 0x6782bf12, 0x4c801ce5, 0x4c801ce5},
+       {0x0000a5dc, 0x6b82bf14, 0x6b82bf14, 0x50801ce9, 0x50801ce9},
+       {0x0000a5e0, 0x6f82bf16, 0x6f82bf16, 0x54801ceb, 0x54801ceb},
+       {0x0000a5e4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
+       {0x0000a5e8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
+       {0x0000a5ec, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
+       {0x0000a5f0, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
+       {0x0000a5f4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
+       {0x0000a5f8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
+       {0x0000a5fc, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
+       {0x00016044, 0x03b6d2e4, 0x03b6d2e4, 0x03b6d2e4, 0x03b6d2e4},
+       {0x00016048, 0x8e481266, 0x8e481266, 0x8e481266, 0x8e481266},
+       {0x00016444, 0x03b6d2e4, 0x03b6d2e4, 0x03b6d2e4, 0x03b6d2e4},
+       {0x00016448, 0x8e481266, 0x8e481266, 0x8e481266, 0x8e481266},
+};
+static const u32 ar9340Modes_ub124_tx_gain_table_1p0[][5] = {
+       /*  Addr      5G_HT20      5G_HT40     2G_HT40    2G_HT20  */
+       {0x0000a410, 0x000050d8, 0x000050d8, 0x000050d9, 0x000050d9},
+       {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000},
+       {0x0000a504, 0x04002222, 0x04002222, 0x04000002, 0x04000002},
+       {0x0000a508, 0x09002421, 0x09002421, 0x08000004, 0x08000004},
+       {0x0000a50c, 0x0d002621, 0x0d002621, 0x0b000200, 0x0b000200},
+       {0x0000a510, 0x13004620, 0x13004620, 0x0f000202, 0x0f000202},
+       {0x0000a514, 0x19004a20, 0x19004a20, 0x11000400, 0x11000400},
+       {0x0000a518, 0x1d004e20, 0x1d004e20, 0x15000402, 0x15000402},
+       {0x0000a51c, 0x21005420, 0x21005420, 0x19000404, 0x19000404},
+       {0x0000a520, 0x26005e20, 0x26005e20, 0x1b000603, 0x1b000603},
+       {0x0000a524, 0x2b005e40, 0x2b005e40, 0x1f000a02, 0x1f000a02},
+       {0x0000a528, 0x2f005e42, 0x2f005e42, 0x23000a04, 0x23000a04},
+       {0x0000a52c, 0x33005e44, 0x33005e44, 0x26000a20, 0x26000a20},
+       {0x0000a530, 0x38005e65, 0x38005e65, 0x2a000e20, 0x2a000e20},
+       {0x0000a534, 0x3c005e69, 0x3c005e69, 0x2e000e22, 0x2e000e22},
+       {0x0000a538, 0x40005e6b, 0x40005e6b, 0x31000e24, 0x31000e24},
+       {0x0000a53c, 0x44005e6d, 0x44005e6d, 0x34001640, 0x34001640},
+       {0x0000a540, 0x49005e72, 0x49005e72, 0x38001660, 0x38001660},
+       {0x0000a544, 0x4e005eb2, 0x4e005eb2, 0x3b001861, 0x3b001861},
+       {0x0000a548, 0x53005f12, 0x53005f12, 0x3e001a81, 0x3e001a81},
+       {0x0000a54c, 0x59025eb5, 0x59025eb5, 0x42001a83, 0x42001a83},
+       {0x0000a550, 0x5e025f12, 0x5e025f12, 0x44001c84, 0x44001c84},
+       {0x0000a554, 0x61027f12, 0x61027f12, 0x48001ce3, 0x48001ce3},
+       {0x0000a558, 0x6702bf12, 0x6702bf12, 0x4c001ce5, 0x4c001ce5},
+       {0x0000a55c, 0x6b02bf14, 0x6b02bf14, 0x50001ce9, 0x50001ce9},
+       {0x0000a560, 0x6f02bf16, 0x6f02bf16, 0x54001ceb, 0x54001ceb},
+       {0x0000a564, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
+       {0x0000a568, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
+       {0x0000a56c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
+       {0x0000a570, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
+       {0x0000a574, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
+       {0x0000a578, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
+       {0x0000a57c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
+       {0x0000a580, 0x00802220, 0x00802220, 0x00800000, 0x00800000},
+       {0x0000a584, 0x04802222, 0x04802222, 0x04800002, 0x04800002},
+       {0x0000a588, 0x09802421, 0x09802421, 0x08800004, 0x08800004},
+       {0x0000a58c, 0x0d802621, 0x0d802621, 0x0b800200, 0x0b800200},
+       {0x0000a590, 0x13804620, 0x13804620, 0x0f800202, 0x0f800202},
+       {0x0000a594, 0x19804a20, 0x19804a20, 0x11800400, 0x11800400},
+       {0x0000a598, 0x1d804e20, 0x1d804e20, 0x15800402, 0x15800402},
+       {0x0000a59c, 0x21805420, 0x21805420, 0x19800404, 0x19800404},
+       {0x0000a5a0, 0x26805e20, 0x26805e20, 0x1b800603, 0x1b800603},
+       {0x0000a5a4, 0x2b805e40, 0x2b805e40, 0x1f800a02, 0x1f800a02},
+       {0x0000a5a8, 0x2f805e42, 0x2f805e42, 0x23800a04, 0x23800a04},
+       {0x0000a5ac, 0x33805e44, 0x33805e44, 0x26800a20, 0x26800a20},
+       {0x0000a5b0, 0x38805e65, 0x38805e65, 0x2a800e20, 0x2a800e20},
+       {0x0000a5b4, 0x3c805e69, 0x3c805e69, 0x2e800e22, 0x2e800e22},
+       {0x0000a5b8, 0x40805e6b, 0x40805e6b, 0x31800e24, 0x31800e24},
+       {0x0000a5bc, 0x44805e6d, 0x44805e6d, 0x34801640, 0x34801640},
+       {0x0000a5c0, 0x49805e72, 0x49805e72, 0x38801660, 0x38801660},
+       {0x0000a5c4, 0x4e805eb2, 0x4e805eb2, 0x3b801861, 0x3b801861},
+       {0x0000a5c8, 0x53805f12, 0x53805f12, 0x3e801a81, 0x3e801a81},
+       {0x0000a5cc, 0x59825eb2, 0x59825eb2, 0x42801a83, 0x42801a83},
+       {0x0000a5d0, 0x5e825f12, 0x5e825f12, 0x44801c84, 0x44801c84},
+       {0x0000a5d4, 0x61827f12, 0x61827f12, 0x48801ce3, 0x48801ce3},
+       {0x0000a5d8, 0x6782bf12, 0x6782bf12, 0x4c801ce5, 0x4c801ce5},
+       {0x0000a5dc, 0x6b82bf14, 0x6b82bf14, 0x50801ce9, 0x50801ce9},
+       {0x0000a5e0, 0x6f82bf16, 0x6f82bf16, 0x54801ceb, 0x54801ceb},
+       {0x0000a5e4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
+       {0x0000a5e8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
+       {0x0000a5ec, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
+       {0x0000a5f0, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
+       {0x0000a5f4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
+       {0x0000a5f8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
+       {0x0000a5fc, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
+       {0x00016044, 0x036db2db, 0x036db2db, 0x036db2db, 0x036db2db},
+       {0x00016048, 0x69b65266, 0x69b65266, 0x69b65266, 0x69b65266},
+       {0x00016444, 0x036db2db, 0x036db2db, 0x036db2db, 0x036db2db},
+       {0x00016448, 0x69b65266, 0x69b65266, 0x69b65266, 0x69b65266},
+};
+
+
+static const u32 ar9340Common_rx_gain_table_1p0[][2] = {
+       /*   Addr     allmodes */
+       {0x0000a000, 0x00010000},
+       {0x0000a004, 0x00030002},
+       {0x0000a008, 0x00050004},
+       {0x0000a00c, 0x00810080},
+       {0x0000a010, 0x00830082},
+       {0x0000a014, 0x01810180},
+       {0x0000a018, 0x01830182},
+       {0x0000a01c, 0x01850184},
+       {0x0000a020, 0x01890188},
+       {0x0000a024, 0x018b018a},
+       {0x0000a028, 0x018d018c},
+       {0x0000a02c, 0x01910190},
+       {0x0000a030, 0x01930192},
+       {0x0000a034, 0x01950194},
+       {0x0000a038, 0x038a0196},
+       {0x0000a03c, 0x038c038b},
+       {0x0000a040, 0x0390038d},
+       {0x0000a044, 0x03920391},
+       {0x0000a048, 0x03940393},
+       {0x0000a04c, 0x03960395},
+       {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, 0x22222229},
+       {0x0000a084, 0x1d1d1d1d},
+       {0x0000a088, 0x1d1d1d1d},
+       {0x0000a08c, 0x1d1d1d1d},
+       {0x0000a090, 0x171d1d1d},
+       {0x0000a094, 0x11111717},
+       {0x0000a098, 0x00030311},
+       {0x0000a09c, 0x00000000},
+       {0x0000a0a0, 0x00000000},
+       {0x0000a0a4, 0x00000000},
+       {0x0000a0a8, 0x00000000},
+       {0x0000a0ac, 0x00000000},
+       {0x0000a0b0, 0x00000000},
+       {0x0000a0b4, 0x00000000},
+       {0x0000a0b8, 0x00000000},
+       {0x0000a0bc, 0x00000000},
+       {0x0000a0c0, 0x001f0000},
+       {0x0000a0c4, 0x01000101},
+       {0x0000a0c8, 0x011e011f},
+       {0x0000a0cc, 0x011c011d},
+       {0x0000a0d0, 0x02030204},
+       {0x0000a0d4, 0x02010202},
+       {0x0000a0d8, 0x021f0200},
+       {0x0000a0dc, 0x0302021e},
+       {0x0000a0e0, 0x03000301},
+       {0x0000a0e4, 0x031e031f},
+       {0x0000a0e8, 0x0402031d},
+       {0x0000a0ec, 0x04000401},
+       {0x0000a0f0, 0x041e041f},
+       {0x0000a0f4, 0x0502041d},
+       {0x0000a0f8, 0x05000501},
+       {0x0000a0fc, 0x051e051f},
+       {0x0000a100, 0x06010602},
+       {0x0000a104, 0x061f0600},
+       {0x0000a108, 0x061d061e},
+       {0x0000a10c, 0x07020703},
+       {0x0000a110, 0x07000701},
+       {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, 0x01000101},
+       {0x0000a148, 0x011e011f},
+       {0x0000a14c, 0x011c011d},
+       {0x0000a150, 0x02030204},
+       {0x0000a154, 0x02010202},
+       {0x0000a158, 0x021f0200},
+       {0x0000a15c, 0x0302021e},
+       {0x0000a160, 0x03000301},
+       {0x0000a164, 0x031e031f},
+       {0x0000a168, 0x0402031d},
+       {0x0000a16c, 0x04000401},
+       {0x0000a170, 0x041e041f},
+       {0x0000a174, 0x0502041d},
+       {0x0000a178, 0x05000501},
+       {0x0000a17c, 0x051e051f},
+       {0x0000a180, 0x06010602},
+       {0x0000a184, 0x061f0600},
+       {0x0000a188, 0x061d061e},
+       {0x0000a18c, 0x07020703},
+       {0x0000a190, 0x07000701},
+       {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 ar9340Modes_low_ob_db_tx_gain_table_1p0[][5] = {
+       /*  Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20  */
+       {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9},
+       {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, 0x056db2db, 0x056db2db, 0x056db2db, 0x056db2db},
+       {0x00016048, 0x24925266, 0x24925266, 0x24925266, 0x24925266},
+       {0x00016444, 0x056db2db, 0x056db2db, 0x056db2db, 0x056db2db},
+       {0x00016448, 0x24925266, 0x24925266, 0x24925266, 0x24925266},
+};
+
+static const u32 ar9340Modes_mixed_ob_db_tx_gain_table_1p0[][5] = {
+       /*  Addr       5G_HT20     5G_HT40     2G_HT40    2G_HT20  */
+       {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9},
+       {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, 0x11000400, 0x11000400},
+       {0x0000a518, 0x21020220, 0x21020220, 0x15000402, 0x15000402},
+       {0x0000a51c, 0x27020223, 0x27020223, 0x19000404, 0x19000404},
+       {0x0000a520, 0x2b022220, 0x2b022220, 0x1b000603, 0x1b000603},
+       {0x0000a524, 0x2f022222, 0x2f022222, 0x1f000a02, 0x1f000a02},
+       {0x0000a528, 0x34022225, 0x34022225, 0x23000a04, 0x23000a04},
+       {0x0000a52c, 0x3a02222a, 0x3a02222a, 0x26000a20, 0x26000a20},
+       {0x0000a530, 0x3e02222c, 0x3e02222c, 0x2a000e20, 0x2a000e20},
+       {0x0000a534, 0x4202242a, 0x4202242a, 0x2e000e22, 0x2e000e22},
+       {0x0000a538, 0x4702244a, 0x4702244a, 0x31000e24, 0x31000e24},
+       {0x0000a53c, 0x4b02244c, 0x4b02244c, 0x34001640, 0x34001640},
+       {0x0000a540, 0x4e02246c, 0x4e02246c, 0x38001660, 0x38001660},
+       {0x0000a544, 0x5302266c, 0x5302266c, 0x3b001861, 0x3b001861},
+       {0x0000a548, 0x5702286c, 0x5702286c, 0x3e001a81, 0x3e001a81},
+       {0x0000a54c, 0x5c04286b, 0x5c04286b, 0x42001a83, 0x42001a83},
+       {0x0000a550, 0x61042a6c, 0x61042a6c, 0x44001c84, 0x44001c84},
+       {0x0000a554, 0x66062a6c, 0x66062a6c, 0x48001ce3, 0x48001ce3},
+       {0x0000a558, 0x6b062e6c, 0x6b062e6c, 0x4c001ce5, 0x4c001ce5},
+       {0x0000a55c, 0x7006308c, 0x7006308c, 0x50001ce9, 0x50001ce9},
+       {0x0000a560, 0x730a308a, 0x730a308a, 0x54001ceb, 0x54001ceb},
+       {0x0000a564, 0x770a308c, 0x770a308c, 0x56001eec, 0x56001eec},
+       {0x0000a568, 0x770a308c, 0x770a308c, 0x56001eec, 0x56001eec},
+       {0x0000a56c, 0x770a308c, 0x770a308c, 0x56001eec, 0x56001eec},
+       {0x0000a570, 0x770a308c, 0x770a308c, 0x56001eec, 0x56001eec},
+       {0x0000a574, 0x770a308c, 0x770a308c, 0x56001eec, 0x56001eec},
+       {0x0000a578, 0x770a308c, 0x770a308c, 0x56001eec, 0x56001eec},
+       {0x0000a57c, 0x770a308c, 0x770a308c, 0x56001eec, 0x56001eec},
+       {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, 0x11800400, 0x11800400},
+       {0x0000a598, 0x21820220, 0x21820220, 0x15800402, 0x15800402},
+       {0x0000a59c, 0x27820223, 0x27820223, 0x19800404, 0x19800404},
+       {0x0000a5a0, 0x2b822220, 0x2b822220, 0x1b800603, 0x1b800603},
+       {0x0000a5a4, 0x2f822222, 0x2f822222, 0x1f800a02, 0x1f800a02},
+       {0x0000a5a8, 0x34822225, 0x34822225, 0x23800a04, 0x23800a04},
+       {0x0000a5ac, 0x3a82222a, 0x3a82222a, 0x26800a20, 0x26800a20},
+       {0x0000a5b0, 0x3e82222c, 0x3e82222c, 0x2a800e20, 0x2a800e20},
+       {0x0000a5b4, 0x4282242a, 0x4282242a, 0x2e800e22, 0x2e800e22},
+       {0x0000a5b8, 0x4782244a, 0x4782244a, 0x31800e24, 0x31800e24},
+       {0x0000a5bc, 0x4b82244c, 0x4b82244c, 0x34801640, 0x34801640},
+       {0x0000a5c0, 0x4e82246c, 0x4e82246c, 0x38801660, 0x38801660},
+       {0x0000a5c4, 0x5382266c, 0x5382266c, 0x3b801861, 0x3b801861},
+       {0x0000a5c8, 0x5782286c, 0x5782286c, 0x3e801a81, 0x3e801a81},
+       {0x0000a5cc, 0x5c84286b, 0x5c84286b, 0x42801a83, 0x42801a83},
+       {0x0000a5d0, 0x61842a6c, 0x61842a6c, 0x44801c84, 0x44801c84},
+       {0x0000a5d4, 0x66862a6c, 0x66862a6c, 0x48801ce3, 0x48801ce3},
+       {0x0000a5d8, 0x6b862e6c, 0x6b862e6c, 0x4c801ce5, 0x4c801ce5},
+       {0x0000a5dc, 0x7086308c, 0x7086308c, 0x50801ce9, 0x50801ce9},
+       {0x0000a5e0, 0x738a308a, 0x738a308a, 0x54801ceb, 0x54801ceb},
+       {0x0000a5e4, 0x778a308c, 0x778a308c, 0x56801eec, 0x56801eec},
+       {0x0000a5e8, 0x778a308c, 0x778a308c, 0x56801eec, 0x56801eec},
+       {0x0000a5ec, 0x778a308c, 0x778a308c, 0x56801eec, 0x56801eec},
+       {0x0000a5f0, 0x778a308c, 0x778a308c, 0x56801eec, 0x56801eec},
+       {0x0000a5f4, 0x778a308c, 0x778a308c, 0x56801eec, 0x56801eec},
+       {0x0000a5f8, 0x778a308c, 0x778a308c, 0x56801eec, 0x56801eec},
+       {0x0000a5fc, 0x778a308c, 0x778a308c, 0x56801eec, 0x56801eec},
+       {0x00016044, 0x056db2db, 0x056db2db, 0x03b6d2e4, 0x03b6d2e4},
+       {0x00016048, 0x24927266, 0x24927266, 0x8e483266, 0x8e483266},
+       {0x00016444, 0x056db2db, 0x056db2db, 0x03b6d2e4, 0x03b6d2e4},
+       {0x00016448, 0x24927266, 0x24927266, 0x8e482266, 0x8e482266},
+};
+
+static const u32 ar9340_1p0_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, 0x9d400010},
+       {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 ar9340Common_wo_xlna_rx_gain_table_1p0[][2] = {
+       /*    Addr        allmodes        */
+       {0x0000a000, 0x00010000},
+       {0x0000a004, 0x00030002},
+       {0x0000a008, 0x00050004},
+       {0x0000a00c, 0x00810080},
+       {0x0000a010, 0x00830082},
+       {0x0000a014, 0x01810180},
+       {0x0000a018, 0x01830182},
+       {0x0000a01c, 0x01850184},
+       {0x0000a020, 0x01890188},
+       {0x0000a024, 0x018b018a},
+       {0x0000a028, 0x018d018c},
+       {0x0000a02c, 0x03820190},
+       {0x0000a030, 0x03840383},
+       {0x0000a034, 0x03880385},
+       {0x0000a038, 0x038a0389},
+       {0x0000a03c, 0x038c038b},
+       {0x0000a040, 0x0390038d},
+       {0x0000a044, 0x03920391},
+       {0x0000a048, 0x03940393},
+       {0x0000a04c, 0x03960395},
+       {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, 0x29292929},
+       {0x0000a084, 0x29292929},
+       {0x0000a088, 0x29292929},
+       {0x0000a08c, 0x29292929},
+       {0x0000a090, 0x22292929},
+       {0x0000a094, 0x1d1d2222},
+       {0x0000a098, 0x0c111117},
+       {0x0000a09c, 0x00030303},
+       {0x0000a0a0, 0x00000000},
+       {0x0000a0a4, 0x00000000},
+       {0x0000a0a8, 0x00000000},
+       {0x0000a0ac, 0x00000000},
+       {0x0000a0b0, 0x00000000},
+       {0x0000a0b4, 0x00000000},
+       {0x0000a0b8, 0x00000000},
+       {0x0000a0bc, 0x00000000},
+       {0x0000a0c0, 0x001f0000},
+       {0x0000a0c4, 0x01000101},
+       {0x0000a0c8, 0x011e011f},
+       {0x0000a0cc, 0x011c011d},
+       {0x0000a0d0, 0x02030204},
+       {0x0000a0d4, 0x02010202},
+       {0x0000a0d8, 0x021f0200},
+       {0x0000a0dc, 0x0302021e},
+       {0x0000a0e0, 0x03000301},
+       {0x0000a0e4, 0x031e031f},
+       {0x0000a0e8, 0x0402031d},
+       {0x0000a0ec, 0x04000401},
+       {0x0000a0f0, 0x041e041f},
+       {0x0000a0f4, 0x0502041d},
+       {0x0000a0f8, 0x05000501},
+       {0x0000a0fc, 0x051e051f},
+       {0x0000a100, 0x06010602},
+       {0x0000a104, 0x061f0600},
+       {0x0000a108, 0x061d061e},
+       {0x0000a10c, 0x07020703},
+       {0x0000a110, 0x07000701},
+       {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, 0x01000101},
+       {0x0000a148, 0x011e011f},
+       {0x0000a14c, 0x011c011d},
+       {0x0000a150, 0x02030204},
+       {0x0000a154, 0x02010202},
+       {0x0000a158, 0x021f0200},
+       {0x0000a15c, 0x0302021e},
+       {0x0000a160, 0x03000301},
+       {0x0000a164, 0x031e031f},
+       {0x0000a168, 0x0402031d},
+       {0x0000a16c, 0x04000401},
+       {0x0000a170, 0x041e041f},
+       {0x0000a174, 0x0502041d},
+       {0x0000a178, 0x05000501},
+       {0x0000a17c, 0x051e051f},
+       {0x0000a180, 0x06010602},
+       {0x0000a184, 0x061f0600},
+       {0x0000a188, 0x061d061e},
+       {0x0000a18c, 0x07020703},
+       {0x0000a190, 0x07000701},
+       {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 ar9340_1p0_soc_preamble[][2] = {
+       /*    Addr        allmodes        */
+       {0x000040a4, 0x00a0c1c9},
+       {0x00007008, 0x00000000},
+       {0x00007020, 0x00000000},
+       {0x00007034, 0x00000002},
+       {0x00007038, 0x000004c2},
+};
+
+#endif
diff --git a/src/drivers/net/ath/ath9k/ar9485_initvals.h b/src/drivers/net/ath/ath9k/ar9485_initvals.h
new file mode 100644 (file)
index 0000000..611ea6c
--- /dev/null
@@ -0,0 +1,1161 @@
+/*
+ * Copyright (c) 2010-2011 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_9485_H
+#define INITVALS_9485_H
+
+static const u32 ar9485_1_1_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, 0x13881c22},
+       {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},
+       {0x000081d4, 0x00000000},
+       {0x000081ec, 0x00000000},
+       {0x000081f0, 0x00000000},
+       {0x000081f4, 0x00000000},
+       {0x000081f8, 0x00000000},
+       {0x000081fc, 0x00000000},
+       {0x00008240, 0x00100000},
+       {0x00008244, 0x0010f400},
+       {0x00008248, 0x00000800},
+       {0x0000824c, 0x0001e800},
+       {0x00008250, 0x00000000},
+       {0x00008254, 0x00000000},
+       {0x00008258, 0x00000000},
+       {0x0000825c, 0x40000000},
+       {0x00008260, 0x00080922},
+       {0x00008264, 0x9ca00010},
+       {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, 0xa248105b},
+       {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 ar9485_1_1_baseband_core[][2] = {
+       /* Addr       allmodes */
+       {0x00009800, 0xafe68e30},
+       {0x00009804, 0xfd14e000},
+       {0x00009808, 0x9c0a8f6b},
+       {0x0000980c, 0x04800000},
+       {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, 0x00000000},
+       {0x00009c08, 0x03200000},
+       {0x00009c0c, 0x00000000},
+       {0x00009c10, 0x00000000},
+       {0x00009c14, 0x00046384},
+       {0x00009c18, 0x05b6b440},
+       {0x00009c1c, 0x00b6b440},
+       {0x00009d00, 0xc080a333},
+       {0x00009d04, 0x40206c10},
+       {0x00009d08, 0x009c4060},
+       {0x00009d0c, 0x1883800a},
+       {0x00009d10, 0x01834061},
+       {0x00009d14, 0x00c00400},
+       {0x00009d18, 0x00000000},
+       {0x00009d1c, 0x00000000},
+       {0x00009e08, 0x0038233c},
+       {0x00009e24, 0x9927b515},
+       {0x00009e28, 0x12ef0200},
+       {0x00009e30, 0x06336f77},
+       {0x00009e34, 0x6af6532f},
+       {0x00009e38, 0x0cc80c00},
+       {0x00009e40, 0x0d261820},
+       {0x00009e4c, 0x00001004},
+       {0x00009e50, 0x00ff03f1},
+       {0x00009fc0, 0x80be4788},
+       {0x00009fc4, 0x0001efb5},
+       {0x00009fcc, 0x40000014},
+       {0x0000a20c, 0x00000000},
+       {0x0000a210, 0x00000000},
+       {0x0000a220, 0x00000000},
+       {0x0000a224, 0x00000000},
+       {0x0000a228, 0x10002310},
+       {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, 0x000000ff},
+       {0x0000a3a8, 0x3b3b3b3b},
+       {0x0000a3ac, 0x2f2f2f2f},
+       {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, 0x00000006},
+       {0x0000a3f8, 0x0cdbd380},
+       {0x0000a3fc, 0x000f0f01},
+       {0x0000a400, 0x8fa91f01},
+       {0x0000a404, 0x00000000},
+       {0x0000a408, 0x0e79e5c6},
+       {0x0000a40c, 0x00820820},
+       {0x0000a414, 0x1ce739cf},
+       {0x0000a418, 0x2d0019ce},
+       {0x0000a41c, 0x1ce739ce},
+       {0x0000a420, 0x000001ce},
+       {0x0000a424, 0x1ce739ce},
+       {0x0000a428, 0x000001ce},
+       {0x0000a42c, 0x1ce739ce},
+       {0x0000a430, 0x1ce739ce},
+       {0x0000a434, 0x00000000},
+       {0x0000a438, 0x00001801},
+       {0x0000a43c, 0x00000000},
+       {0x0000a440, 0x00000000},
+       {0x0000a444, 0x00000000},
+       {0x0000a448, 0x04000000},
+       {0x0000a44c, 0x00000001},
+       {0x0000a450, 0x00010000},
+       {0x0000a5c4, 0xbfad9d74},
+       {0x0000a5c8, 0x0048060a},
+       {0x0000a5cc, 0x00000637},
+       {0x0000a760, 0x03020100},
+       {0x0000a764, 0x09080504},
+       {0x0000a768, 0x0d0c0b0a},
+       {0x0000a76c, 0x13121110},
+       {0x0000a770, 0x31301514},
+       {0x0000a774, 0x35343332},
+       {0x0000a778, 0x00000036},
+       {0x0000a780, 0x00000838},
+       {0x0000a7c0, 0x00000000},
+       {0x0000a7c4, 0xfffffffc},
+       {0x0000a7c8, 0x00000000},
+       {0x0000a7cc, 0x00000000},
+       {0x0000a7d0, 0x00000000},
+       {0x0000a7d4, 0x00000004},
+       {0x0000a7dc, 0x00000000},
+};
+
+static const u32 ar9485Common_1_1[][2] = {
+       /*  Addr      allmodes */
+       {0x00007010, 0x00000022},
+       {0x00007020, 0x00000000},
+       {0x00007034, 0x00000002},
+       {0x00007038, 0x000004c2},
+};
+
+static const u32 ar9485_1_1_baseband_postamble[][5] = {
+       /* Addr       5G_HT20        5G_HT40       2G_HT40       2G_HT20 */
+       {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8005, 0xd00a8005},
+       {0x00009820, 0x206a002e, 0x206a002e, 0x206a002e, 0x206a002e},
+       {0x00009824, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0},
+       {0x00009828, 0x06903081, 0x06903081, 0x06903881, 0x06903881},
+       {0x0000982c, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4},
+       {0x00009830, 0x0000059c, 0x0000059c, 0x0000059c, 0x0000059c},
+       {0x00009c00, 0x00000044, 0x00000044, 0x00000044, 0x00000044},
+       {0x00009e00, 0x0372161e, 0x0372161e, 0x037216a0, 0x037216a0},
+       {0x00009e04, 0x00182020, 0x00182020, 0x00182020, 0x00182020},
+       {0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000e2, 0x6c4000e2},
+       {0x00009e10, 0x7ec88d2e, 0x7ec88d2e, 0x7ec80d2e, 0x7ec80d2e},
+       {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},
+       {0x00009e3c, 0xcf946220, 0xcf946220, 0xcf946222, 0xcf946222},
+       {0x00009e44, 0x02321e27, 0x02321e27, 0x02282324, 0x02282324},
+       {0x00009e48, 0x5030201a, 0x5030201a, 0x50302010, 0x50302010},
+       {0x00009fc8, 0x0003f000, 0x0003f000, 0x0001a000, 0x0001a000},
+       {0x0000a204, 0x01303fc0, 0x01303fc4, 0x01303fc4, 0x01303fc0},
+       {0x0000a208, 0x00000104, 0x00000104, 0x00000004, 0x00000004},
+       {0x0000a230, 0x0000400a, 0x00004014, 0x00004016, 0x0000400b},
+       {0x0000a234, 0x10000fff, 0x10000fff, 0x10000fff, 0x10000fff},
+       {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, 0x3a021501, 0x3a021501, 0x3a021501, 0x3a021501},
+       {0x0000a264, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e},
+       {0x0000a280, 0x00000007, 0x00000007, 0x0000000b, 0x0000000b},
+       {0x0000a284, 0x00000000, 0x00000000, 0x000002a0, 0x000002a0},
+       {0x0000a288, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000a28c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000a2c4, 0x00158d18, 0x00158d18, 0x00158d18, 0x00158d18},
+       {0x0000a2d0, 0x00071981, 0x00071981, 0x00071982, 0x00071982},
+       {0x0000a2d8, 0xf999a83a, 0xf999a83a, 0xf999a83a, 0xf999a83a},
+       {0x0000a358, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000be04, 0x00802020, 0x00802020, 0x00802020, 0x00802020},
+       {0x0000be18, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+};
+
+static const u32 ar9485Modes_high_ob_db_tx_gain_1_1[][5] = {
+       /* Addr        5G_HT20       5G_HT40       2G_HT40       2G_HT20 */
+       {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002},
+       {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d8, 0x000050d8},
+       {0x0000a458, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000a500, 0x00022200, 0x00022200, 0x00000000, 0x00000000},
+       {0x0000a504, 0x05062002, 0x05062002, 0x04000002, 0x04000002},
+       {0x0000a508, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004},
+       {0x0000a50c, 0x11062202, 0x11062202, 0x0d000200, 0x0d000200},
+       {0x0000a510, 0x17022e00, 0x17022e00, 0x11000202, 0x11000202},
+       {0x0000a514, 0x1d000ec2, 0x1d000ec2, 0x15000400, 0x15000400},
+       {0x0000a518, 0x25020ec0, 0x25020ec0, 0x19000402, 0x19000402},
+       {0x0000a51c, 0x2b020ec3, 0x2b020ec3, 0x1d000404, 0x1d000404},
+       {0x0000a520, 0x2f001f04, 0x2f001f04, 0x21000603, 0x21000603},
+       {0x0000a524, 0x35001fc4, 0x35001fc4, 0x25000605, 0x25000605},
+       {0x0000a528, 0x3c022f04, 0x3c022f04, 0x2a000a03, 0x2a000a03},
+       {0x0000a52c, 0x41023e85, 0x41023e85, 0x2c000a04, 0x2c000a04},
+       {0x0000a530, 0x48023ec6, 0x48023ec6, 0x34000e20, 0x34000e20},
+       {0x0000a534, 0x4d023f01, 0x4d023f01, 0x35000e21, 0x35000e21},
+       {0x0000a538, 0x53023f4b, 0x53023f4b, 0x43000e62, 0x43000e62},
+       {0x0000a53c, 0x5a027f09, 0x5a027f09, 0x45000e63, 0x45000e63},
+       {0x0000a540, 0x5f027fc9, 0x5f027fc9, 0x49000e65, 0x49000e65},
+       {0x0000a544, 0x6502feca, 0x6502feca, 0x4b000e66, 0x4b000e66},
+       {0x0000a548, 0x6b02ff4a, 0x6b02ff4a, 0x4d001645, 0x4d001645},
+       {0x0000a54c, 0x7203feca, 0x7203feca, 0x51001865, 0x51001865},
+       {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x55001a86, 0x55001a86},
+       {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x57001ce9, 0x57001ce9},
+       {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001ceb, 0x5a001ceb},
+       {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a564, 0x960fffcb, 0x960fffcb, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a568, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a56c, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a570, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
+       {0x0000b500, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b504, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b508, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b50c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b510, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b514, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b518, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b51c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b520, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b524, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b528, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b52c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b530, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b534, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b538, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b53c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b540, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b544, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b548, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b54c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b550, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b554, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b558, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b55c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b560, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b564, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b568, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b56c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b570, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b574, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b578, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b57c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x00016044, 0x05d6b2db, 0x05d6b2db, 0x05d6b2db, 0x05d6b2db},
+       {0x00016048, 0x6c924260, 0x6c924260, 0x6c924260, 0x6c924260},
+};
+
+static const u32 ar9485_modes_lowest_ob_db_tx_gain_1_1[][5] = {
+       /* Addr        5G_HT20       5G_HT40       2G_HT40       2G_HT20  */
+       {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002},
+       {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d8, 0x000050d8},
+       {0x0000a458, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000a500, 0x00022200, 0x00022200, 0x00000000, 0x00000000},
+       {0x0000a504, 0x05062002, 0x05062002, 0x04000002, 0x04000002},
+       {0x0000a508, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004},
+       {0x0000a50c, 0x11062202, 0x11062202, 0x0d000200, 0x0d000200},
+       {0x0000a510, 0x17022e00, 0x17022e00, 0x11000202, 0x11000202},
+       {0x0000a514, 0x1d000ec2, 0x1d000ec2, 0x15000400, 0x15000400},
+       {0x0000a518, 0x25020ec0, 0x25020ec0, 0x19000402, 0x19000402},
+       {0x0000a51c, 0x2b020ec3, 0x2b020ec3, 0x1d000404, 0x1d000404},
+       {0x0000a520, 0x2f001f04, 0x2f001f04, 0x21000603, 0x21000603},
+       {0x0000a524, 0x35001fc4, 0x35001fc4, 0x25000605, 0x25000605},
+       {0x0000a528, 0x3c022f04, 0x3c022f04, 0x2a000a03, 0x2a000a03},
+       {0x0000a52c, 0x41023e85, 0x41023e85, 0x2c000a04, 0x2c000a04},
+       {0x0000a530, 0x48023ec6, 0x48023ec6, 0x34000e20, 0x34000e20},
+       {0x0000a534, 0x4d023f01, 0x4d023f01, 0x35000e21, 0x35000e21},
+       {0x0000a538, 0x53023f4b, 0x53023f4b, 0x43000e62, 0x43000e62},
+       {0x0000a53c, 0x5a027f09, 0x5a027f09, 0x45000e63, 0x45000e63},
+       {0x0000a540, 0x5f027fc9, 0x5f027fc9, 0x49000e65, 0x49000e65},
+       {0x0000a544, 0x6502feca, 0x6502feca, 0x4b000e66, 0x4b000e66},
+       {0x0000a548, 0x6b02ff4a, 0x6b02ff4a, 0x4d001645, 0x4d001645},
+       {0x0000a54c, 0x7203feca, 0x7203feca, 0x51001865, 0x51001865},
+       {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x55001a86, 0x55001a86},
+       {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x57001ce9, 0x57001ce9},
+       {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001ceb, 0x5a001ceb},
+       {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a564, 0x960fffcb, 0x960fffcb, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a568, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a56c, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a570, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
+       {0x0000b500, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b504, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b508, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b50c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b510, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b514, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b518, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b51c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b520, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b524, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b528, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b52c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b530, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b534, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b538, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b53c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b540, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b544, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b548, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b54c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b550, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b554, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b558, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b55c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b560, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b564, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b568, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b56c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b570, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b574, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b578, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b57c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x00016044, 0x05d6b2db, 0x05d6b2db, 0x05d6b2db, 0x05d6b2db},
+       {0x00016048, 0x6c924260, 0x6c924260, 0x6c924260, 0x6c924260},
+};
+
+static const u32 ar9485_1_1_radio_postamble[][2] = {
+       /* Addr        allmodes */
+       {0x0001609c, 0x0b283f31},
+       {0x000160ac, 0x24611800},
+       {0x000160b0, 0x03284f3e},
+       {0x0001610c, 0x00170000},
+       {0x00016140, 0x10804008},
+};
+
+static const u32 ar9485_1_1_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 ar9485_1_1_radio_core[][2] = {
+       /* Addr        allmodes */
+       {0x00016000, 0x36db6db6},
+       {0x00016004, 0x6db6db40},
+       {0x00016008, 0x73800000},
+       {0x0001600c, 0x00000000},
+       {0x00016040, 0x7f80fff8},
+       {0x0001604c, 0x000f0278},
+       {0x00016050, 0x4db6db8c},
+       {0x00016054, 0x6db60000},
+       {0x00016080, 0x00080000},
+       {0x00016084, 0x0e48048c},
+       {0x00016088, 0x14214514},
+       {0x0001608c, 0x119f081e},
+       {0x00016090, 0x24926490},
+       {0x00016098, 0xd28b3330},
+       {0x000160a0, 0xc2108ffe},
+       {0x000160a4, 0x812fc370},
+       {0x000160a8, 0x423c8000},
+       {0x000160b4, 0x92480040},
+       {0x000160c0, 0x006db6db},
+       {0x000160c4, 0x0186db60},
+       {0x000160c8, 0x6db6db6c},
+       {0x000160cc, 0x6de6fbe0},
+       {0x000160d0, 0xf7dfcf3c},
+       {0x00016100, 0x04cb0001},
+       {0x00016104, 0xfff80015},
+       {0x00016108, 0x00080010},
+       {0x00016144, 0x01884080},
+       {0x00016148, 0x00008040},
+       {0x00016240, 0x08400000},
+       {0x00016244, 0x1bf90f00},
+       {0x00016248, 0x00000000},
+       {0x0001624c, 0x00000000},
+       {0x00016280, 0x01000015},
+       {0x00016284, 0x00d30000},
+       {0x00016288, 0x00318000},
+       {0x0001628c, 0x50000000},
+       {0x00016290, 0x4b96210f},
+       {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},
+       {0x00016c40, 0x13188278},
+       {0x00016c44, 0x12000000},
+};
+
+static const u32 ar9485_1_1_pcie_phy_pll_on_clkreq_enable_L1[][2] = {
+       /* Addr        allmodes */
+       {0x00018c00, 0x10052e5e},
+       {0x00018c04, 0x000801d8},
+       {0x00018c08, 0x0000080c},
+};
+
+static const u32 ar9485Modes_high_power_tx_gain_1_1[][5] = {
+       /* Addr        5G_HT20       5G_HT40       2G_HT40       2G_HT20 */
+       {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002},
+       {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d8, 0x000050d8},
+       {0x0000a458, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000a500, 0x00022200, 0x00022200, 0x00000000, 0x00000000},
+       {0x0000a504, 0x05062002, 0x05062002, 0x04000002, 0x04000002},
+       {0x0000a508, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004},
+       {0x0000a50c, 0x11062202, 0x11062202, 0x0d000200, 0x0d000200},
+       {0x0000a510, 0x17022e00, 0x17022e00, 0x11000202, 0x11000202},
+       {0x0000a514, 0x1d000ec2, 0x1d000ec2, 0x15000400, 0x15000400},
+       {0x0000a518, 0x25020ec0, 0x25020ec0, 0x19000402, 0x19000402},
+       {0x0000a51c, 0x2b020ec3, 0x2b020ec3, 0x1d000404, 0x1d000404},
+       {0x0000a520, 0x2f001f04, 0x2f001f04, 0x21000603, 0x21000603},
+       {0x0000a524, 0x35001fc4, 0x35001fc4, 0x25000605, 0x25000605},
+       {0x0000a528, 0x3c022f04, 0x3c022f04, 0x2a000a03, 0x2a000a03},
+       {0x0000a52c, 0x41023e85, 0x41023e85, 0x2c000a04, 0x2c000a04},
+       {0x0000a530, 0x48023ec6, 0x48023ec6, 0x34000e20, 0x34000e20},
+       {0x0000a534, 0x4d023f01, 0x4d023f01, 0x35000e21, 0x35000e21},
+       {0x0000a538, 0x53023f4b, 0x53023f4b, 0x43000e62, 0x43000e62},
+       {0x0000a53c, 0x5a027f09, 0x5a027f09, 0x45000e63, 0x45000e63},
+       {0x0000a540, 0x5f027fc9, 0x5f027fc9, 0x49000e65, 0x49000e65},
+       {0x0000a544, 0x6502feca, 0x6502feca, 0x4b000e66, 0x4b000e66},
+       {0x0000a548, 0x6b02ff4a, 0x6b02ff4a, 0x4d001645, 0x4d001645},
+       {0x0000a54c, 0x7203feca, 0x7203feca, 0x51001865, 0x51001865},
+       {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x55001a86, 0x55001a86},
+       {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x57001ce9, 0x57001ce9},
+       {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001ceb, 0x5a001ceb},
+       {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a564, 0x960fffcb, 0x960fffcb, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a568, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a56c, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a570, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
+       {0x0000b500, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b504, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b508, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b50c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b510, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b514, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b518, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b51c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b520, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b524, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b528, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b52c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b530, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b534, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b538, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b53c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b540, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b544, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b548, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b54c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b550, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b554, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b558, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b55c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b560, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b564, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b568, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b56c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b570, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b574, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b578, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b57c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x00016044, 0x05d6b2db, 0x05d6b2db, 0x05d6b2db, 0x05d6b2db},
+       {0x00016048, 0x6c924260, 0x6c924260, 0x6c924260, 0x6c924260},
+};
+
+static const u32 ar9485_1_1[][2] = {
+       /* Addr        allmodes */
+       {0x0000a580, 0x00000000},
+       {0x0000a584, 0x00000000},
+       {0x0000a588, 0x00000000},
+       {0x0000a58c, 0x00000000},
+       {0x0000a590, 0x00000000},
+       {0x0000a594, 0x00000000},
+       {0x0000a598, 0x00000000},
+       {0x0000a59c, 0x00000000},
+       {0x0000a5a0, 0x00000000},
+       {0x0000a5a4, 0x00000000},
+       {0x0000a5a8, 0x00000000},
+       {0x0000a5ac, 0x00000000},
+       {0x0000a5b0, 0x00000000},
+       {0x0000a5b4, 0x00000000},
+       {0x0000a5b8, 0x00000000},
+       {0x0000a5bc, 0x00000000},
+};
+
+static const u32 ar9485_modes_green_ob_db_tx_gain_1_1[][5] = {
+       /* Addr        5G_HT20       5G_HT40       2G_HT40       2G_HT20 */
+       {0x000098bc, 0x00000003, 0x00000003, 0x00000003, 0x00000003},
+       {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d8, 0x000050d8},
+       {0x0000a458, 0x80000000, 0x80000000, 0x80000000, 0x80000000},
+       {0x0000a500, 0x00022200, 0x00022200, 0x00000006, 0x00000006},
+       {0x0000a504, 0x05062002, 0x05062002, 0x03000201, 0x03000201},
+       {0x0000a508, 0x0c002e00, 0x0c002e00, 0x06000203, 0x06000203},
+       {0x0000a50c, 0x11062202, 0x11062202, 0x0a000401, 0x0a000401},
+       {0x0000a510, 0x17022e00, 0x17022e00, 0x0e000403, 0x0e000403},
+       {0x0000a514, 0x1d000ec2, 0x1d000ec2, 0x12000405, 0x12000405},
+       {0x0000a518, 0x25020ec0, 0x25020ec0, 0x15000604, 0x15000604},
+       {0x0000a51c, 0x2b020ec3, 0x2b020ec3, 0x18000605, 0x18000605},
+       {0x0000a520, 0x2f001f04, 0x2f001f04, 0x1c000a04, 0x1c000a04},
+       {0x0000a524, 0x35001fc4, 0x35001fc4, 0x21000a06, 0x21000a06},
+       {0x0000a528, 0x3c022f04, 0x3c022f04, 0x29000a24, 0x29000a24},
+       {0x0000a52c, 0x41023e85, 0x41023e85, 0x2f000e21, 0x2f000e21},
+       {0x0000a530, 0x48023ec6, 0x48023ec6, 0x31000e20, 0x31000e20},
+       {0x0000a534, 0x4d023f01, 0x4d023f01, 0x33000e20, 0x33000e20},
+       {0x0000a538, 0x53023f4b, 0x53023f4b, 0x43000e62, 0x43000e62},
+       {0x0000a53c, 0x5a027f09, 0x5a027f09, 0x45000e63, 0x45000e63},
+       {0x0000a540, 0x5f027fc9, 0x5f027fc9, 0x49000e65, 0x49000e65},
+       {0x0000a544, 0x6502feca, 0x6502feca, 0x4b000e66, 0x4b000e66},
+       {0x0000a548, 0x6b02ff4a, 0x6b02ff4a, 0x4d001645, 0x4d001645},
+       {0x0000a54c, 0x7203feca, 0x7203feca, 0x51001865, 0x51001865},
+       {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x55001a86, 0x55001a86},
+       {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x57001ce9, 0x57001ce9},
+       {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001ceb, 0x5a001ceb},
+       {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a564, 0x960fffcb, 0x960fffcb, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a568, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a56c, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a570, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
+       {0x0000b500, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a},
+       {0x0000b504, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a},
+       {0x0000b508, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a},
+       {0x0000b50c, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a},
+       {0x0000b510, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a},
+       {0x0000b514, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a},
+       {0x0000b518, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a},
+       {0x0000b51c, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a},
+       {0x0000b520, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a},
+       {0x0000b524, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a},
+       {0x0000b528, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a},
+       {0x0000b52c, 0x0000002a, 0x0000002a, 0x0000002a, 0x0000002a},
+       {0x0000b530, 0x0000003a, 0x0000003a, 0x0000003a, 0x0000003a},
+       {0x0000b534, 0x0000004a, 0x0000004a, 0x0000004a, 0x0000004a},
+       {0x0000b538, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
+       {0x0000b53c, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
+       {0x0000b540, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
+       {0x0000b544, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
+       {0x0000b548, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
+       {0x0000b54c, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
+       {0x0000b550, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
+       {0x0000b554, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
+       {0x0000b558, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
+       {0x0000b55c, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
+       {0x0000b560, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
+       {0x0000b564, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
+       {0x0000b568, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
+       {0x0000b56c, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
+       {0x0000b570, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
+       {0x0000b574, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
+       {0x0000b578, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
+       {0x0000b57c, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
+       {0x00016044, 0x05d6b2db, 0x05d6b2db, 0x05d6b2db, 0x05d6b2db},
+       {0x00016048, 0x6c924260, 0x6c924260, 0x6c924260, 0x6c924260},
+};
+
+static const u32 ar9485_1_1_pcie_phy_clkreq_disable_L1[][2] = {
+       /* Addr        allmodes */
+       {0x00018c00, 0x10013e5e},
+       {0x00018c04, 0x000801d8},
+       {0x00018c08, 0x0000080c},
+};
+
+static const u32 ar9485_1_1_soc_preamble[][2] = {
+       /* Addr        allmodes */
+       {0x00004014, 0xba280400},
+       {0x00004090, 0x00aa10aa},
+       {0x000040a4, 0x00a0c9c9},
+       {0x00007010, 0x00000022},
+       {0x00007020, 0x00000000},
+       {0x00007034, 0x00000002},
+       {0x00007038, 0x000004c2},
+       {0x00007048, 0x00000002},
+};
+
+static const u32 ar9485_1_1_baseband_core_txfir_coeff_japan_2484[][2] = {
+       /* Addr        allmodes */
+       {0x0000a398, 0x00000000},
+       {0x0000a39c, 0x6f7f0301},
+       {0x0000a3a0, 0xca9228ee},
+};
+
+static const u32 ar9485Modes_low_ob_db_tx_gain_1_1[][5] = {
+       /* Addr        5G_HT20       5G_HT40       2G_HT40       2G_HT20  */
+       {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002},
+       {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d8, 0x000050d8},
+       {0x0000a458, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000a500, 0x00022200, 0x00022200, 0x00000000, 0x00000000},
+       {0x0000a504, 0x05062002, 0x05062002, 0x04000002, 0x04000002},
+       {0x0000a508, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004},
+       {0x0000a50c, 0x11062202, 0x11062202, 0x0d000200, 0x0d000200},
+       {0x0000a510, 0x17022e00, 0x17022e00, 0x11000202, 0x11000202},
+       {0x0000a514, 0x1d000ec2, 0x1d000ec2, 0x15000400, 0x15000400},
+       {0x0000a518, 0x25020ec0, 0x25020ec0, 0x19000402, 0x19000402},
+       {0x0000a51c, 0x2b020ec3, 0x2b020ec3, 0x1d000404, 0x1d000404},
+       {0x0000a520, 0x2f001f04, 0x2f001f04, 0x21000603, 0x21000603},
+       {0x0000a524, 0x35001fc4, 0x35001fc4, 0x25000605, 0x25000605},
+       {0x0000a528, 0x3c022f04, 0x3c022f04, 0x2a000a03, 0x2a000a03},
+       {0x0000a52c, 0x41023e85, 0x41023e85, 0x2c000a04, 0x2c000a04},
+       {0x0000a530, 0x48023ec6, 0x48023ec6, 0x34000e20, 0x34000e20},
+       {0x0000a534, 0x4d023f01, 0x4d023f01, 0x35000e21, 0x35000e21},
+       {0x0000a538, 0x53023f4b, 0x53023f4b, 0x43000e62, 0x43000e62},
+       {0x0000a53c, 0x5a027f09, 0x5a027f09, 0x45000e63, 0x45000e63},
+       {0x0000a540, 0x5f027fc9, 0x5f027fc9, 0x49000e65, 0x49000e65},
+       {0x0000a544, 0x6502feca, 0x6502feca, 0x4b000e66, 0x4b000e66},
+       {0x0000a548, 0x6b02ff4a, 0x6b02ff4a, 0x4d001645, 0x4d001645},
+       {0x0000a54c, 0x7203feca, 0x7203feca, 0x51001865, 0x51001865},
+       {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x55001a86, 0x55001a86},
+       {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x57001ce9, 0x57001ce9},
+       {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001ceb, 0x5a001ceb},
+       {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a564, 0x960fffcb, 0x960fffcb, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a568, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a56c, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a570, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
+       {0x0000b500, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b504, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b508, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b50c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b510, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b514, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b518, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b51c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b520, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b524, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b528, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b52c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b530, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b534, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b538, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b53c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b540, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b544, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b548, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b54c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b550, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b554, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b558, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b55c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b560, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b564, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b568, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b56c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b570, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b574, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b578, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b57c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x00016044, 0x05d6b2db, 0x05d6b2db, 0x05d6b2db, 0x05d6b2db},
+       {0x00016048, 0x6c924260, 0x6c924260, 0x6c924260, 0x6c924260},
+};
+
+static const u32 ar9485_fast_clock_1_1_baseband_postamble[][3] = {
+       /* Addr        5G_HT2        5G_HT40  */
+       {0x00009e00, 0x03721821, 0x03721821},
+       {0x0000a230, 0x0000400b, 0x00004016},
+       {0x0000a254, 0x00000898, 0x00001130},
+};
+
+static const u32 ar9485_1_1_pcie_phy_pll_on_clkreq_disable_L1[][2] = {
+       /* Addr        allmodes  */
+       {0x00018c00, 0x10012e5e},
+       {0x00018c04, 0x000801d8},
+       {0x00018c08, 0x0000080c},
+};
+
+static const u32 ar9485_common_rx_gain_1_1[][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, 0x111f1100},
+       {0x0000a0c8, 0x111d111e},
+       {0x0000a0cc, 0x111b111c},
+       {0x0000a0d0, 0x22032204},
+       {0x0000a0d4, 0x22012202},
+       {0x0000a0d8, 0x221f2200},
+       {0x0000a0dc, 0x221d221e},
+       {0x0000a0e0, 0x33013302},
+       {0x0000a0e4, 0x331f3300},
+       {0x0000a0e8, 0x4402331e},
+       {0x0000a0ec, 0x44004401},
+       {0x0000a0f0, 0x441e441f},
+       {0x0000a0f4, 0x55015502},
+       {0x0000a0f8, 0x551f5500},
+       {0x0000a0fc, 0x6602551e},
+       {0x0000a100, 0x66006601},
+       {0x0000a104, 0x661e661f},
+       {0x0000a108, 0x7703661d},
+       {0x0000a10c, 0x77017702},
+       {0x0000a110, 0x00007700},
+       {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, 0x111f1100},
+       {0x0000a148, 0x111d111e},
+       {0x0000a14c, 0x111b111c},
+       {0x0000a150, 0x22032204},
+       {0x0000a154, 0x22012202},
+       {0x0000a158, 0x221f2200},
+       {0x0000a15c, 0x221d221e},
+       {0x0000a160, 0x33013302},
+       {0x0000a164, 0x331f3300},
+       {0x0000a168, 0x4402331e},
+       {0x0000a16c, 0x44004401},
+       {0x0000a170, 0x441e441f},
+       {0x0000a174, 0x55015502},
+       {0x0000a178, 0x551f5500},
+       {0x0000a17c, 0x6602551e},
+       {0x0000a180, 0x66006601},
+       {0x0000a184, 0x661e661f},
+       {0x0000a188, 0x7703661d},
+       {0x0000a18c, 0x77017702},
+       {0x0000a190, 0x00007700},
+       {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},
+};
+
+static const u32 ar9485_1_1_pcie_phy_clkreq_enable_L1[][2] = {
+       /* Addr        allmodes */
+       {0x00018c00, 0x10053e5e},
+       {0x00018c04, 0x000801d8},
+       {0x00018c08, 0x0000080c},
+};
+
+static const u32 ar9485Common_wo_xlna_rx_gain_1_1[][2] = {
+       /* Addr        allmodes */
+       {0x0000a000, 0x00060005},
+       {0x0000a004, 0x00810080},
+       {0x0000a008, 0x00830082},
+       {0x0000a00c, 0x00850084},
+       {0x0000a010, 0x01820181},
+       {0x0000a014, 0x01840183},
+       {0x0000a018, 0x01880185},
+       {0x0000a01c, 0x018a0189},
+       {0x0000a020, 0x02850284},
+       {0x0000a024, 0x02890288},
+       {0x0000a028, 0x028b028a},
+       {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, 0x24242428},
+       {0x0000a098, 0x171e1e1e},
+       {0x0000a09c, 0x02020b0b},
+       {0x0000a0a0, 0x02020202},
+       {0x0000a0a4, 0x00000000},
+       {0x0000a0a8, 0x00000000},
+       {0x0000a0ac, 0x00000000},
+       {0x0000a0b0, 0x00000000},
+       {0x0000a0b4, 0x00000000},
+       {0x0000a0b8, 0x00000000},
+       {0x0000a0bc, 0x00000000},
+       {0x0000a0c0, 0x22072208},
+       {0x0000a0c4, 0x22052206},
+       {0x0000a0c8, 0x22032204},
+       {0x0000a0cc, 0x22012202},
+       {0x0000a0d0, 0x221f2200},
+       {0x0000a0d4, 0x221d221e},
+       {0x0000a0d8, 0x33023303},
+       {0x0000a0dc, 0x33003301},
+       {0x0000a0e0, 0x331e331f},
+       {0x0000a0e4, 0x4402331d},
+       {0x0000a0e8, 0x44004401},
+       {0x0000a0ec, 0x441e441f},
+       {0x0000a0f0, 0x55025503},
+       {0x0000a0f4, 0x55005501},
+       {0x0000a0f8, 0x551e551f},
+       {0x0000a0fc, 0x6602551d},
+       {0x0000a100, 0x66006601},
+       {0x0000a104, 0x661e661f},
+       {0x0000a108, 0x7703661d},
+       {0x0000a10c, 0x77017702},
+       {0x0000a110, 0x00007700},
+       {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, 0x111f1100},
+       {0x0000a148, 0x111d111e},
+       {0x0000a14c, 0x111b111c},
+       {0x0000a150, 0x22032204},
+       {0x0000a154, 0x22012202},
+       {0x0000a158, 0x221f2200},
+       {0x0000a15c, 0x221d221e},
+       {0x0000a160, 0x33013302},
+       {0x0000a164, 0x331f3300},
+       {0x0000a168, 0x4402331e},
+       {0x0000a16c, 0x44004401},
+       {0x0000a170, 0x441e441f},
+       {0x0000a174, 0x55015502},
+       {0x0000a178, 0x551f5500},
+       {0x0000a17c, 0x6602551e},
+       {0x0000a180, 0x66006601},
+       {0x0000a184, 0x661e661f},
+       {0x0000a188, 0x7703661d},
+       {0x0000a18c, 0x77017702},
+       {0x0000a190, 0x00007700},
+       {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},
+};
+
+#endif
diff --git a/src/drivers/net/ath/ath9k/ath9k.c b/src/drivers/net/ath/ath9k/ath9k.c
new file mode 100644 (file)
index 0000000..183aa65
--- /dev/null
@@ -0,0 +1,208 @@
+/*
+ * Copyright (c) 2008-2011 Atheros Communications Inc.
+ *
+ * Modified for iPXE by Scott K Logan <logans@cottsay.net> July 2011
+ * Original from Linux kernel 3.0.1
+ *
+ * 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 <ipxe/pci.h>
+
+#include "ath9k.h"
+
+static struct pci_device_id ath_pci_id_table[] = {
+        PCI_ROM(0x168c, 0x0023, "ar5416", "Atheros 5416 PCI", 0),      /* PCI   */
+        PCI_ROM(0x168c, 0x0024, "ar5416", "Atheros 5416 PCI-E", 0),    /* PCI-E */
+        PCI_ROM(0x168c, 0x0027, "ar9160", "Atheros 9160 PCI", 0),      /* PCI   */
+        PCI_ROM(0x168c, 0x0029, "ar9280", "Atheros 9280 PCI", 0),      /* PCI   */
+        PCI_ROM(0x168c, 0x002A, "ar9280", "Atheros 9280 PCI-E", 0),    /* PCI-E */
+        PCI_ROM(0x168c, 0x002B, "ar9285", "Atheros 9285 PCI-E", 0),    /* PCI-E */
+        PCI_ROM(0x168c, 0x002C, "ar2427", "Atheros 2427 PCI-E", 0),    /* PCI-E 802.11n bonded out */
+        PCI_ROM(0x168c, 0x002D, "ar9287", "Atheros 9287 PCI", 0),      /* PCI   */
+        PCI_ROM(0x168c, 0x002E, "ar9287", "Atheros 9287 PCI-E", 0),    /* PCI-E */
+        PCI_ROM(0x168c, 0x0030, "ar9300", "Atheros 9300 PCI-E", 0),    /* PCI-E  AR9300 */
+        PCI_ROM(0x168c, 0x0032, "ar9485", "Atheros 9485 PCI-E", 0),    /* PCI-E  AR9485 */
+};
+
+
+/* return bus cachesize in 4B word units */
+static void ath_pci_read_cachesize(struct ath_common *common, int *csz)
+{
+       struct ath_softc *sc = (struct ath_softc *) common->priv;
+       u8 u8tmp;
+
+       pci_read_config_byte(sc->pdev, PCI_CACHE_LINE_SIZE, &u8tmp);
+       *csz = (int)u8tmp;
+
+       /*
+        * This check was put in to avoid "unpleasant" consequences if
+        * the bootrom has not fully initialized all PCI devices.
+        * Sometimes the cache line size register is not set
+        */
+
+       if (*csz == 0)
+               *csz = DEFAULT_CACHELINE >> 2;   /* Use the default size */
+}
+
+static int ath_pci_eeprom_read(struct ath_common *common, u32 off, u16 *data)
+{
+       struct ath_hw *ah = (struct ath_hw *) common->ah;
+
+       common->ops->read(ah, AR5416_EEPROM_OFFSET +
+                             (off << AR5416_EEPROM_S));
+
+       if (!ath9k_hw_wait(ah,
+                          AR_EEPROM_STATUS_DATA,
+                          AR_EEPROM_STATUS_DATA_BUSY |
+                          AR_EEPROM_STATUS_DATA_PROT_ACCESS, 0,
+                          AH_WAIT_TIMEOUT)) {
+               return 0;
+       }
+
+       *data = MS(common->ops->read(ah, AR_EEPROM_STATUS_DATA),
+                  AR_EEPROM_STATUS_DATA_VAL);
+
+       return 1;
+}
+
+static void ath_pci_extn_synch_enable(struct ath_common *common)
+{
+       struct ath_softc *sc = (struct ath_softc *) common->priv;
+       struct pci_device *pdev = sc->pdev;
+       u8 lnkctl;
+
+       pci_read_config_byte(pdev, sc->sc_ah->caps.pcie_lcr_offset, &lnkctl);
+       lnkctl |= 0x0080;
+       pci_write_config_byte(pdev, sc->sc_ah->caps.pcie_lcr_offset, lnkctl);
+}
+
+static const struct ath_bus_ops ath_pci_bus_ops = {
+       .ath_bus_type = ATH_PCI,
+       .read_cachesize = ath_pci_read_cachesize,
+       .eeprom_read = ath_pci_eeprom_read,
+       .extn_synch_en = ath_pci_extn_synch_enable,
+};
+
+static int ath_pci_probe(struct pci_device *pdev)
+{
+       void *mem;
+       struct ath_softc *sc;
+       struct net80211_device *dev;
+       u8 csz;
+       u16 subsysid;
+       u32 val;
+       int ret = 0;
+       char hw_name[64];
+
+       adjust_pci_device(pdev);
+
+       /*
+        * Cache line size is used to size and align various
+        * structures used to communicate with the hardware.
+        */
+       pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &csz);
+       if (csz == 0) {
+               /*
+                * Linux 2.4.18 (at least) writes the cache line size
+                * register as a 16-bit wide register which is wrong.
+                * We must have this setup properly for rx buffer
+                * DMA to work so force a reasonable value here if it
+                * comes up zero.
+                */
+               csz =16;
+               pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, csz);
+       }
+       /*
+        * The default setting of latency timer yields poor results,
+        * set it to the value used by other systems. It may be worth
+        * tweaking this setting more.
+        */
+       pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0xa8);
+
+       /*
+        * Disable the RETRY_TIMEOUT register (0x41) to keep
+        * PCI Tx retries from interfering with C3 CPU state.
+        */
+       pci_read_config_dword(pdev, 0x40, &val);
+       if ((val & 0x0000ff00) != 0)
+               pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);
+
+       mem = ioremap(pdev->membase, 0x10000);
+       if (!mem) {
+               DBG("ath9K: PCI memory map error\n") ;
+               ret = -EIO;
+               goto err_iomap;
+       }
+
+       dev = net80211_alloc(sizeof(struct ath_softc));
+       if (!dev) {
+               DBG("ath9k: No memory for net80211_device\n");
+               ret = -ENOMEM;
+               goto err_alloc_hw;
+       }
+
+       pci_set_drvdata(pdev, dev);
+       dev->netdev->dev = (struct device *)pdev;
+
+       sc = dev->priv;
+       sc->dev = dev;
+       sc->pdev = pdev;
+       sc->mem = mem;
+
+       /* Will be cleared in ath9k_start() */
+       sc->sc_flags |= SC_OP_INVALID;
+
+       sc->irq = pdev->irq;
+
+       pci_read_config_word(pdev, PCI_SUBSYSTEM_ID, &subsysid);
+       ret = ath9k_init_device(pdev->device, sc, subsysid, &ath_pci_bus_ops);
+       if (ret) {
+               DBG("ath9k: Failed to initialize device\n");
+               goto err_init;
+       }
+
+       ath9k_hw_name(sc->sc_ah, hw_name, sizeof(hw_name));
+       DBG("ath9k: %s mem=0x%lx, irq=%d\n",
+                  hw_name, (unsigned long)mem, pdev->irq);
+
+       return 0;
+
+err_init:
+       net80211_free(dev);
+err_alloc_hw:
+       iounmap(mem);
+err_iomap:
+       return ret;
+}
+
+static void ath_pci_remove(struct pci_device *pdev)
+{
+       struct net80211_device *dev = pci_get_drvdata(pdev);
+       struct ath_softc *sc = dev->priv;
+       void *mem = sc->mem;
+
+       if (!is_ath9k_unloaded)
+               sc->sc_ah->ah_flags |= AH_UNPLUGGED;
+       ath9k_deinit_device(sc);
+       net80211_free(sc->dev);
+
+       iounmap(mem);
+}
+
+struct pci_driver ath_pci_driver __pci_driver = {
+        .id_count   = ARRAY_SIZE(ath_pci_id_table),
+       .ids        = ath_pci_id_table,
+       .probe      = ath_pci_probe,
+       .remove     = ath_pci_remove,
+};
diff --git a/src/drivers/net/ath/ath9k/ath9k.h b/src/drivers/net/ath/ath9k/ath9k.h
new file mode 100644 (file)
index 0000000..d2dce9b
--- /dev/null
@@ -0,0 +1,521 @@
+/*
+ * Copyright (c) 2008-2011 Atheros Communications Inc.
+ *
+ * Modified for iPXE by Scott K Logan <logans@cottsay.net> July 2011
+ * Original from Linux kernel 3.0.1
+ *
+ * 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_H
+#define ATH9K_H
+
+#include "common.h"
+
+/*
+ * Header for the ath9k.ko driver core *only* -- hw code nor any other driver
+ * should rely on this file or its contents.
+ */
+
+struct ath_node;
+struct ath_softc;
+
+/* Macro to expand scalars to 64-bit objects */
+
+#define        ito64(x) (sizeof(x) == 1) ?                     \
+       (((unsigned long long int)(x)) & (0xff)) :      \
+       (sizeof(x) == 2) ?                              \
+       (((unsigned long long int)(x)) & 0xffff) :      \
+       ((sizeof(x) == 4) ?                             \
+        (((unsigned long long int)(x)) & 0xffffffff) : \
+        (unsigned long long int)(x))
+
+/* increment with wrap-around */
+#define INCR(_l, _sz)   do {                   \
+               (_l)++;                         \
+               (_l) &= ((_sz) - 1);            \
+       } while (0)
+
+/* decrement with wrap-around */
+#define DECR(_l,  _sz)  do {                   \
+               (_l)--;                         \
+               (_l) &= ((_sz) - 1);            \
+       } while (0)
+
+#define A_MAX(a, b) ((a) > (b) ? (a) : (b))
+
+#define TSF_TO_TU(_h,_l) \
+       ((((u32)(_h)) << 22) | (((u32)(_l)) >> 10))
+
+#define        ATH_TXQ_SETUP(sc, i)        ((sc)->tx.txqsetup & (1<<i))
+
+struct ath_config {
+       u16 txpowlimit;
+       u8 cabqReadytime;
+};
+
+/*************************/
+/* Descriptor Management */
+/*************************/
+
+#define ATH_TXBUF_RESET(_bf) do {                              \
+               (_bf)->bf_stale = 0;                    \
+               (_bf)->bf_lastbf = NULL;                        \
+               (_bf)->bf_next = NULL;                          \
+               memset(&((_bf)->bf_state), 0,                   \
+                      sizeof(struct ath_buf_state));           \
+       } while (0)
+
+#define ATH_RXBUF_RESET(_bf) do {              \
+               (_bf)->bf_stale = 0;    \
+       } while (0)
+
+/**
+ * enum buffer_type - Buffer type flags
+ *
+ * @BUF_AMPDU: This buffer is an ampdu, as part of an aggregate (during TX)
+ * @BUF_AGGR: Indicates whether the buffer can be aggregated
+ *     (used in aggregation scheduling)
+ * @BUF_XRETRY: To denote excessive retries of the buffer
+ */
+enum buffer_type {
+       BUF_AMPDU               = BIT(0),
+       BUF_AGGR                = BIT(1),
+       BUF_XRETRY              = BIT(2),
+};
+
+#define bf_isampdu(bf)         (bf->bf_state.bf_type & BUF_AMPDU)
+#define bf_isaggr(bf)          (bf->bf_state.bf_type & BUF_AGGR)
+#define bf_isxretried(bf)      (bf->bf_state.bf_type & BUF_XRETRY)
+
+#define ATH_TXSTATUS_RING_SIZE 64
+
+struct ath_descdma {
+       void *dd_desc;
+       u32 dd_desc_paddr;
+       u32 dd_desc_len;
+       struct ath_buf *dd_bufptr;
+};
+
+int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
+                     struct list_head *head, const char *name,
+                     int nbuf, int ndesc, int is_tx);
+void ath_descdma_cleanup(struct ath_softc *sc, struct ath_descdma *dd,
+                        struct list_head *head);
+
+/***********/
+/* RX / TX */
+/***********/
+
+#define ATH_RXBUF               16
+#define ATH_TXBUF               16
+#define ATH_TXBUF_RESERVE       5
+#define ATH_MAX_QDEPTH          (ATH_TXBUF / 4 - ATH_TXBUF_RESERVE)
+#define ATH_TXMAXTRY            13
+
+#define TID_TO_WME_AC(_tid)                            \
+       ((((_tid) == 0) || ((_tid) == 3)) ? WME_AC_BE : \
+        (((_tid) == 1) || ((_tid) == 2)) ? WME_AC_BK : \
+        (((_tid) == 4) || ((_tid) == 5)) ? WME_AC_VI : \
+        WME_AC_VO)
+
+#define ATH_AGGR_DELIM_SZ          4
+#define ATH_AGGR_MINPLEN           256 /* in bytes, minimum packet length */
+/* number of delimiters for encryption padding */
+#define ATH_AGGR_ENCRYPTDELIM      10
+/* minimum h/w qdepth to be sustained to maximize aggregation */
+#define ATH_AGGR_MIN_QDEPTH        2
+#define ATH_AMPDU_SUBFRAME_DEFAULT 32
+
+#define FCS_LEN                    4
+#define IEEE80211_SEQ_SEQ_SHIFT    4
+#define IEEE80211_SEQ_MAX          4096
+#define IEEE80211_WEP_IVLEN        3
+#define IEEE80211_WEP_KIDLEN       1
+#define IEEE80211_WEP_CRCLEN       4
+#define IEEE80211_MAX_MPDU_LEN     (3840 + FCS_LEN +           \
+                                   (IEEE80211_WEP_IVLEN +      \
+                                    IEEE80211_WEP_KIDLEN +     \
+                                    IEEE80211_WEP_CRCLEN))
+
+/* return whether a bit at index _n in bitmap _bm is set
+ * _sz is the size of the bitmap  */
+#define ATH_BA_ISSET(_bm, _n)  (((_n) < (WME_BA_BMP_SIZE)) &&          \
+                               ((_bm)[(_n) >> 5] & (1 << ((_n) & 31))))
+
+/* return block-ack bitmap index given sequence and starting sequence */
+#define ATH_BA_INDEX(_st, _seq) (((_seq) - (_st)) & (IEEE80211_SEQ_MAX - 1))
+
+/* returns delimiter padding required given the packet length */
+#define ATH_AGGR_GET_NDELIM(_len)                                      \
+       (((_len) >= ATH_AGGR_MINPLEN) ? 0 :                             \
+        DIV_ROUND_UP(ATH_AGGR_MINPLEN - (_len), ATH_AGGR_DELIM_SZ))
+
+#define BAW_WITHIN(_start, _bawsz, _seqno) \
+       ((((_seqno) - (_start)) & 4095) < (_bawsz))
+
+#define ATH_AN_2_TID(_an, _tidno)  (&(_an)->tid[(_tidno)])
+
+#define ATH_TX_COMPLETE_POLL_INT       1000
+
+enum ATH_AGGR_STATUS {
+       ATH_AGGR_DONE,
+       ATH_AGGR_BAW_CLOSED,
+       ATH_AGGR_LIMITED,
+};
+
+#define ATH_TXFIFO_DEPTH 8
+struct ath_txq {
+       int mac80211_qnum; /* mac80211 queue number, -1 means not mac80211 Q */
+       u32 axq_qnum; /* ath9k hardware queue number */
+       u32 *axq_link;
+       struct list_head axq_q;
+       u32 axq_depth;
+       u32 axq_ampdu_depth;
+       int stopped;
+       int 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;
+       int pending_frames;
+};
+
+struct ath_atx_ac {
+       struct ath_txq *txq;
+       int sched;
+       struct list_head list;
+       struct list_head tid_q;
+       int clear_ps_filter;
+};
+
+struct ath_frame_info {
+       int framelen;
+       u32 keyix;
+       enum ath9k_key_type keytype;
+       u8 retries;
+       u16 seqno;
+};
+
+struct ath_buf_state {
+       u8 bf_type;
+       u8 bfs_paprd;
+       unsigned long bfs_paprd_timestamp;
+};
+
+struct ath_buf {
+       struct list_head list;
+       struct ath_buf *bf_lastbf;      /* last buf of this unit (a frame or
+                                          an aggregate) */
+       struct ath_buf *bf_next;        /* next subframe in the aggregate */
+       struct io_buffer *bf_mpdu;      /* enclosing frame structure */
+       void *bf_desc;                  /* virtual addr of desc */
+       u32 bf_daddr;                   /* physical addr of desc */
+       u32 bf_buf_addr;                /* physical addr of data buffer, for DMA */
+       int bf_stale;
+       u16 bf_flags;
+       struct ath_buf_state bf_state;
+};
+
+struct ath_atx_tid {
+       struct list_head list;
+       struct list_head buf_q;
+       struct ath_node *an;
+       struct ath_atx_ac *ac;
+       unsigned long tx_buf[BITS_TO_LONGS(ATH_TID_MAX_BUFS)];
+       u16 seq_start;
+       u16 seq_next;
+       u16 baw_size;
+       int tidno;
+       int baw_head;   /* first un-acked tx buffer */
+       int baw_tail;   /* next unused tx buffer slot */
+       int sched;
+       int paused;
+       u8 state;
+};
+
+struct ath_node {
+       struct ath_atx_tid tid[WME_NUM_TID];
+       struct ath_atx_ac ac[WME_NUM_AC];
+       int ps_key;
+
+       u16 maxampdu;
+       u8 mpdudensity;
+
+       int sleeping;
+};
+
+#define AGGR_CLEANUP         BIT(1)
+#define AGGR_ADDBA_COMPLETE  BIT(2)
+#define AGGR_ADDBA_PROGRESS  BIT(3)
+
+struct ath_tx_control {
+       struct ath_txq *txq;
+       struct ath_node *an;
+       int if_id;
+       u8 paprd;
+};
+
+#define ATH_TX_ERROR        0x01
+#define ATH_TX_XRETRY       0x02
+#define ATH_TX_BAR          0x04
+
+/**
+ * @txq_map:  Index is mac80211 queue number.  This is
+ *  not necessarily the same as the hardware queue number
+ *  (axq_qnum).
+ */
+struct ath_tx {
+       u16 seq_no;
+       u32 txqsetup;
+       struct list_head txbuf;
+       struct ath_txq txq[ATH9K_NUM_TX_QUEUES];
+       struct ath_descdma txdma;
+       struct ath_txq *txq_map[WME_NUM_AC];
+};
+
+struct ath_rx_edma {
+       struct list_head rx_fifo;
+       struct list_head rx_buffers;
+       u32 rx_fifo_hwsize;
+};
+
+struct ath_rx {
+       u8 defant;
+       u8 rxotherant;
+       u32 *rxlink;
+       unsigned int rxfilter;
+       struct list_head rxbuf;
+       struct ath_descdma rxdma;
+       struct ath_buf *rx_bufptr;
+       struct ath_rx_edma rx_edma[ATH9K_RX_QUEUE_MAX];
+
+       struct io_buffer *frag;
+};
+
+int ath_startrecv(struct ath_softc *sc);
+int ath_stoprecv(struct ath_softc *sc);
+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 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_drain_all_txq(struct ath_softc *sc, int retry_tx);
+void ath_draintxq(struct ath_softc *sc,
+                    struct ath_txq *txq, int retry_tx);
+void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq);
+int ath_tx_init(struct ath_softc *sc, int nbufs);
+void ath_tx_cleanup(struct ath_softc *sc);
+int ath_txq_update(struct ath_softc *sc, int qnum,
+                  struct ath9k_tx_queue_info *q);
+int ath_tx_start(struct net80211_device *dev, struct io_buffer *iob,
+                struct ath_tx_control *txctl);
+void ath_tx_tasklet(struct ath_softc *sc);
+
+/*******/
+/* ANI */
+/*******/
+
+#define ATH_STA_SHORT_CALINTERVAL 1000    /* 1 second */
+#define ATH_AP_SHORT_CALINTERVAL  100     /* 100 ms */
+#define ATH_ANI_POLLINTERVAL_OLD  100     /* 100 ms */
+#define ATH_ANI_POLLINTERVAL_NEW  1000    /* 1000 ms */
+#define ATH_LONG_CALINTERVAL_INT  1000    /* 1000 ms */
+#define ATH_LONG_CALINTERVAL      30000   /* 30 seconds */
+#define ATH_RESTART_CALINTERVAL   1200000 /* 20 minutes */
+
+void ath_hw_pll_work(struct ath_softc *sc);
+void ath_ani_calibrate(struct ath_softc *sc);
+
+/********************/
+/* Main driver core */
+/********************/
+
+/*
+ * Default cache line size, in bytes.
+ * Used when PCI device not fully initialized by bootrom/BIOS
+*/
+#define DEFAULT_CACHELINE       32
+#define ATH_REGCLASSIDS_MAX     10
+#define ATH_CABQ_READY_TIME     80      /* % of beacon interval */
+#define ATH_MAX_SW_RETRIES      10
+#define ATH_CHAN_MAX            255
+
+#define ATH_TXPOWER_MAX         100     /* .5 dBm units */
+#define ATH_RATE_DUMMY_MARKER   0
+
+#define SC_OP_INVALID                BIT(0)
+#define SC_OP_BEACONS                BIT(1)
+#define SC_OP_RXAGGR                 BIT(2)
+#define SC_OP_TXAGGR                 BIT(3)
+#define SC_OP_OFFCHANNEL             BIT(4)
+#define SC_OP_PREAMBLE_SHORT         BIT(5)
+#define SC_OP_PROTECT_ENABLE         BIT(6)
+#define SC_OP_RXFLUSH                BIT(7)
+#define SC_OP_LED_ASSOCIATED         BIT(8)
+#define SC_OP_LED_ON                 BIT(9)
+#define SC_OP_TSF_RESET              BIT(11)
+#define SC_OP_BT_PRIORITY_DETECTED   BIT(12)
+#define SC_OP_BT_SCAN               BIT(13)
+#define SC_OP_ANI_RUN               BIT(14)
+#define SC_OP_ENABLE_APM            BIT(15)
+#define SC_OP_PRIM_STA_VIF          BIT(16)
+
+/* Powersave flags */
+#define PS_WAIT_FOR_BEACON        BIT(0)
+#define PS_WAIT_FOR_CAB           BIT(1)
+#define PS_WAIT_FOR_PSPOLL_DATA   BIT(2)
+#define PS_WAIT_FOR_TX_ACK        BIT(3)
+#define PS_BEACON_SYNC            BIT(4)
+#define PS_TSFOOR_SYNC            BIT(5)
+
+struct ath_rate_table;
+
+struct ath9k_legacy_rate {
+        u16 bitrate;
+        u32 flags;
+        u16 hw_value;
+        u16 hw_value_short;
+};
+
+enum ath9k_rate_control_flags {
+       IEEE80211_TX_RC_USE_RTS_CTS             = BIT(0),
+       IEEE80211_TX_RC_USE_CTS_PROTECT         = BIT(1),
+       IEEE80211_TX_RC_USE_SHORT_PREAMBLE      = BIT(2),
+
+       /* rate index is an MCS rate number instead of an index */
+       IEEE80211_TX_RC_MCS                     = BIT(3),
+       IEEE80211_TX_RC_GREEN_FIELD             = BIT(4),
+       IEEE80211_TX_RC_40_MHZ_WIDTH            = BIT(5),
+       IEEE80211_TX_RC_DUP_DATA                = BIT(6),
+       IEEE80211_TX_RC_SHORT_GI                = BIT(7),
+};
+
+struct survey_info {
+       struct net80211_channel *channel;
+       u64 channel_time;
+       u64 channel_time_busy;
+       u64 channel_time_ext_busy;
+       u64 channel_time_rx;
+       u64 channel_time_tx;
+       u32 filled;
+       s8 noise;
+};
+
+enum survey_info_flags {
+       SURVEY_INFO_NOISE_DBM = 1<<0,
+       SURVEY_INFO_IN_USE = 1<<1,
+       SURVEY_INFO_CHANNEL_TIME = 1<<2,
+       SURVEY_INFO_CHANNEL_TIME_BUSY = 1<<3,
+       SURVEY_INFO_CHANNEL_TIME_EXT_BUSY = 1<<4,
+       SURVEY_INFO_CHANNEL_TIME_RX = 1<<5,
+       SURVEY_INFO_CHANNEL_TIME_TX = 1<<6,
+};
+
+struct ath9k_vif_iter_data {
+       const u8 *hw_macaddr; /* phy's hardware address, set
+                              * before starting iteration for
+                              * valid bssid mask.
+                              */
+       u8 mask[ETH_ALEN]; /* bssid mask */
+       int naps;      /* number of AP vifs */
+       int nmeshes;   /* number of mesh vifs */
+       int nstations; /* number of station vifs */
+       int nwds;      /* number of nwd vifs */
+       int nadhocs;   /* number of adhoc vifs */
+       int nothers;   /* number of vifs not specified above. */
+};
+
+struct ath_softc {
+       struct net80211_device *dev;
+       struct pci_device *pdev;
+
+       int chan_idx;
+       int chan_is_ht;
+       struct survey_info *cur_survey;
+       struct survey_info survey[ATH9K_NUM_CHANNELS];
+
+       void (*intr_tq)(struct ath_softc *sc);
+       struct ath_hw *sc_ah;
+       void *mem;
+       int irq;
+
+       void (*paprd_work)(struct ath_softc *sc);
+       void (*hw_check_work)(struct ath_softc *sc);
+       void (*paprd_complete)(struct ath_softc *sc);
+
+       unsigned int hw_busy_count;
+
+       u32 intrstatus;
+       u32 sc_flags; /* SC_OP_* */
+       u16 ps_flags; /* PS_* */
+       u16 curtxpow;
+       int ps_enabled;
+       int ps_idle;
+       short nbcnvifs;
+       short nvifs;
+       unsigned long ps_usecount;
+
+       struct ath_config config;
+       struct ath_rx rx;
+       struct ath_tx tx;
+       struct net80211_hw_info *hwinfo;
+       struct ath9k_legacy_rate rates[NET80211_MAX_RATES];
+       int hw_rix;
+
+       struct ath9k_hw_cal_data caldata;
+       int last_rssi;
+
+       void (*tx_complete_work)(struct ath_softc *sc);
+       unsigned long tx_complete_work_timer;
+       void (*hw_pll_work)(struct ath_softc *sc);
+       unsigned long hw_pll_work_timer;
+
+       struct ath_descdma txsdma;
+};
+
+void ath9k_tasklet(struct ath_softc *sc);
+int ath_reset(struct ath_softc *sc, int retry_tx);
+
+static inline void ath_read_cachesize(struct ath_common *common, int *csz)
+{
+       common->bus_ops->read_cachesize(common, csz);
+}
+
+extern struct net80211_device_operations ath9k_ops;
+extern int ath9k_modparam_nohwcrypt;
+extern int is_ath9k_unloaded;
+
+void ath_isr(struct net80211_device *dev);
+void ath9k_init_crypto(struct ath_softc *sc);
+int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid,
+                   const struct ath_bus_ops *bus_ops);
+void ath9k_deinit_device(struct ath_softc *sc);
+void ath9k_set_hw_capab(struct ath_softc *sc, struct net80211_device *dev);
+int ath_set_channel(struct ath_softc *sc, struct net80211_device *dev,
+                   struct ath9k_channel *hchan);
+
+void ath_radio_enable(struct ath_softc *sc, struct net80211_device *dev);
+void ath_radio_disable(struct ath_softc *sc, struct net80211_device *dev);
+int ath9k_setpower(struct ath_softc *sc, enum ath9k_power_mode mode);
+int ath9k_uses_beacons(int type);
+
+u8 ath_txchainmask_reduction(struct ath_softc *sc, u8 chainmask, u32 rate);
+
+void ath_start_rfkill_poll(struct ath_softc *sc);
+extern void ath9k_rfkill_poll_state(struct net80211_device *dev);
+
+#endif /* ATH9K_H */
diff --git a/src/drivers/net/ath/ath9k/ath9k_ani.c b/src/drivers/net/ath/ath9k/ath9k_ani.c
new file mode 100644 (file)
index 0000000..ff7df49
--- /dev/null
@@ -0,0 +1,733 @@
+/*
+ * Copyright (c) 2008-2011 Atheros Communications Inc.
+ *
+ * Modified for iPXE by Scott K Logan <logans@cottsay.net> July 2011
+ * Original from Linux kernel 3.0.1
+ *
+ * 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"
+
+struct ani_ofdm_level_entry {
+       int spur_immunity_level;
+       int fir_step_level;
+       int ofdm_weak_signal_on;
+};
+
+/* values here are relative to the INI */
+
+/*
+ * Legend:
+ *
+ * SI: Spur immunity
+ * FS: FIR Step
+ * WS: OFDM / CCK Weak Signal detection
+ * MRC-CCK: Maximal Ratio Combining for CCK
+ */
+
+static const struct ani_ofdm_level_entry ofdm_level_table[] = {
+       /* SI  FS  WS */
+       {  0,  0,  1  }, /* lvl 0 */
+       {  1,  1,  1  }, /* lvl 1 */
+       {  2,  2,  1  }, /* lvl 2 */
+       {  3,  2,  1  }, /* lvl 3  (default) */
+       {  4,  3,  1  }, /* lvl 4 */
+       {  5,  4,  1  }, /* lvl 5 */
+       {  6,  5,  1  }, /* lvl 6 */
+       {  7,  6,  1  }, /* lvl 7 */
+       {  7,  7,  1  }, /* lvl 8 */
+       {  7,  8,  0  }  /* lvl 9 */
+};
+#define ATH9K_ANI_OFDM_NUM_LEVEL \
+       ARRAY_SIZE(ofdm_level_table)
+#define ATH9K_ANI_OFDM_MAX_LEVEL \
+       (ATH9K_ANI_OFDM_NUM_LEVEL-1)
+#define ATH9K_ANI_OFDM_DEF_LEVEL \
+       3 /* default level - matches the INI settings */
+
+/*
+ * MRC (Maximal Ratio Combining) has always been used with multi-antenna ofdm.
+ * With OFDM for single stream you just add up all antenna inputs, you're
+ * only interested in what you get after FFT. Signal aligment is also not
+ * required for OFDM because any phase difference adds up in the frequency
+ * domain.
+ *
+ * MRC requires extra work for use with CCK. You need to align the antenna
+ * signals from the different antenna before you can add the signals together.
+ * You need aligment of signals as CCK is in time domain, so addition can cancel
+ * your signal completely if phase is 180 degrees (think of adding sine waves).
+ * You also need to remove noise before the addition and this is where ANI
+ * MRC CCK comes into play. One of the antenna inputs may be stronger but
+ * lower SNR, so just adding after alignment can be dangerous.
+ *
+ * Regardless of alignment in time, the antenna signals add constructively after
+ * FFT and improve your reception. For more information:
+ *
+ * http://en.wikipedia.org/wiki/Maximal-ratio_combining
+ */
+
+struct ani_cck_level_entry {
+       int fir_step_level;
+       int mrc_cck_on;
+};
+
+static const struct ani_cck_level_entry cck_level_table[] = {
+       /* FS  MRC-CCK  */
+       {  0,  1  }, /* lvl 0 */
+       {  1,  1  }, /* lvl 1 */
+       {  2,  1  }, /* lvl 2  (default) */
+       {  3,  1  }, /* lvl 3 */
+       {  4,  0  }, /* lvl 4 */
+       {  5,  0  }, /* lvl 5 */
+       {  6,  0  }, /* lvl 6 */
+       {  7,  0  }, /* lvl 7 (only for high rssi) */
+       {  8,  0  }  /* lvl 8 (only for high rssi) */
+};
+
+#define ATH9K_ANI_CCK_NUM_LEVEL \
+       ARRAY_SIZE(cck_level_table)
+#define ATH9K_ANI_CCK_MAX_LEVEL \
+       (ATH9K_ANI_CCK_NUM_LEVEL-1)
+#define ATH9K_ANI_CCK_MAX_LEVEL_LOW_RSSI \
+       (ATH9K_ANI_CCK_NUM_LEVEL-3)
+#define ATH9K_ANI_CCK_DEF_LEVEL \
+       2 /* default level - matches the INI settings */
+
+static int use_new_ani(struct ath_hw *ah)
+{
+       return AR_SREV_9300_20_OR_LATER(ah) || modparam_force_new_ani;
+}
+
+static void ath9k_hw_update_mibstats(struct ath_hw *ah,
+                                    struct ath9k_mib_stats *stats)
+{
+       stats->ackrcv_bad += REG_READ(ah, AR_ACK_FAIL);
+       stats->rts_bad += REG_READ(ah, AR_RTS_FAIL);
+       stats->fcs_bad += REG_READ(ah, AR_FCS_FAIL);
+       stats->rts_good += REG_READ(ah, AR_RTS_OK);
+       stats->beacons += REG_READ(ah, AR_BEACON_CNT);
+}
+
+static void ath9k_ani_restart(struct ath_hw *ah)
+{
+       struct ar5416AniState *aniState;
+       u32 ofdm_base = 0, cck_base = 0;
+
+       if (!DO_ANI(ah))
+               return;
+
+       aniState = &ah->curchan->ani;
+       aniState->listenTime = 0;
+
+       if (!use_new_ani(ah)) {
+               ofdm_base = AR_PHY_COUNTMAX - ah->config.ofdm_trig_high;
+               cck_base = AR_PHY_COUNTMAX - ah->config.cck_trig_high;
+       }
+
+       DBG2("ath9k: "
+               "Writing ofdmbase=%d   cckbase=%d\n", ofdm_base, cck_base);
+
+       ENABLE_REGWRITE_BUFFER(ah);
+
+       REG_WRITE(ah, AR_PHY_ERR_1, ofdm_base);
+       REG_WRITE(ah, AR_PHY_ERR_2, cck_base);
+       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);
+
+       ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);
+
+       aniState->ofdmPhyErrCount = 0;
+       aniState->cckPhyErrCount = 0;
+}
+
+static void ath9k_hw_ani_ofdm_err_trigger_old(struct ath_hw *ah)
+{
+       struct ar5416AniState *aniState;
+       int32_t rssi;
+
+       aniState = &ah->curchan->ani;
+
+       if (aniState->noiseImmunityLevel < HAL_NOISE_IMMUNE_MAX) {
+               if (ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL,
+                                        aniState->noiseImmunityLevel + 1)) {
+                       return;
+               }
+       }
+
+       if (aniState->spurImmunityLevel < HAL_SPUR_IMMUNE_MAX) {
+               if (ath9k_hw_ani_control(ah, ATH9K_ANI_SPUR_IMMUNITY_LEVEL,
+                                        aniState->spurImmunityLevel + 1)) {
+                       return;
+               }
+       }
+
+       rssi = BEACON_RSSI(ah);
+       if (rssi > aniState->rssiThrHigh) {
+               if (!aniState->ofdmWeakSigDetectOff) {
+                       if (ath9k_hw_ani_control(ah,
+                                        ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
+                                        0)) {
+                               ath9k_hw_ani_control(ah,
+                                       ATH9K_ANI_SPUR_IMMUNITY_LEVEL, 0);
+                               return;
+                       }
+               }
+               if (aniState->firstepLevel < HAL_FIRST_STEP_MAX) {
+                       ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
+                                            aniState->firstepLevel + 1);
+                       return;
+               }
+       } else if (rssi > aniState->rssiThrLow) {
+               if (aniState->ofdmWeakSigDetectOff)
+                       ath9k_hw_ani_control(ah,
+                                    ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
+                                    1);
+               if (aniState->firstepLevel < HAL_FIRST_STEP_MAX)
+                       ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
+                                            aniState->firstepLevel + 1);
+               return;
+       } else {
+               if ((ah->dev->channels + ah->dev->channel)->band == NET80211_BAND_2GHZ) {
+                       if (!aniState->ofdmWeakSigDetectOff)
+                               ath9k_hw_ani_control(ah,
+                                    ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
+                                    0);
+                       if (aniState->firstepLevel > 0)
+                               ath9k_hw_ani_control(ah,
+                                            ATH9K_ANI_FIRSTEP_LEVEL, 0);
+                       return;
+               }
+       }
+}
+
+static void ath9k_hw_ani_cck_err_trigger_old(struct ath_hw *ah)
+{
+       struct ar5416AniState *aniState;
+       int32_t rssi;
+
+       aniState = &ah->curchan->ani;
+       if (aniState->noiseImmunityLevel < HAL_NOISE_IMMUNE_MAX) {
+               if (ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL,
+                                        aniState->noiseImmunityLevel + 1)) {
+                       return;
+               }
+       }
+       rssi = BEACON_RSSI(ah);
+       if (rssi > aniState->rssiThrLow) {
+               if (aniState->firstepLevel < HAL_FIRST_STEP_MAX)
+                       ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
+                                            aniState->firstepLevel + 1);
+       } else {
+               if ((ah->dev->channels + ah->dev->channel)->band == NET80211_BAND_2GHZ) {
+                       if (aniState->firstepLevel > 0)
+                               ath9k_hw_ani_control(ah,
+                                            ATH9K_ANI_FIRSTEP_LEVEL, 0);
+               }
+       }
+}
+
+/* Adjust the OFDM Noise Immunity Level */
+static void ath9k_hw_set_ofdm_nil(struct ath_hw *ah, u8 immunityLevel)
+{
+       struct ar5416AniState *aniState = &ah->curchan->ani;
+       const struct ani_ofdm_level_entry *entry_ofdm;
+       const struct ani_cck_level_entry *entry_cck;
+
+       aniState->noiseFloor = BEACON_RSSI(ah);
+
+       DBG2("ath9k: "
+               "**** ofdmlevel %d=>%d, rssi=%d[lo=%d hi=%d]\n",
+               aniState->ofdmNoiseImmunityLevel,
+               immunityLevel, aniState->noiseFloor,
+               aniState->rssiThrLow, aniState->rssiThrHigh);
+
+       aniState->ofdmNoiseImmunityLevel = immunityLevel;
+
+       entry_ofdm = &ofdm_level_table[aniState->ofdmNoiseImmunityLevel];
+       entry_cck = &cck_level_table[aniState->cckNoiseImmunityLevel];
+
+       if (aniState->spurImmunityLevel != entry_ofdm->spur_immunity_level)
+               ath9k_hw_ani_control(ah,
+                                    ATH9K_ANI_SPUR_IMMUNITY_LEVEL,
+                                    entry_ofdm->spur_immunity_level);
+
+       if (aniState->firstepLevel != entry_ofdm->fir_step_level &&
+           entry_ofdm->fir_step_level >= entry_cck->fir_step_level)
+               ath9k_hw_ani_control(ah,
+                                    ATH9K_ANI_FIRSTEP_LEVEL,
+                                    entry_ofdm->fir_step_level);
+}
+
+static void ath9k_hw_ani_ofdm_err_trigger(struct ath_hw *ah)
+{
+       struct ar5416AniState *aniState;
+
+       if (!DO_ANI(ah))
+               return;
+
+       if (!use_new_ani(ah)) {
+               ath9k_hw_ani_ofdm_err_trigger_old(ah);
+               return;
+       }
+
+       aniState = &ah->curchan->ani;
+
+       if (aniState->ofdmNoiseImmunityLevel < ATH9K_ANI_OFDM_MAX_LEVEL)
+               ath9k_hw_set_ofdm_nil(ah, aniState->ofdmNoiseImmunityLevel + 1);
+}
+
+/*
+ * Set the ANI settings to match an CCK level.
+ */
+static void ath9k_hw_set_cck_nil(struct ath_hw *ah, uint8_t immunityLevel)
+{
+       struct ar5416AniState *aniState = &ah->curchan->ani;
+       const struct ani_ofdm_level_entry *entry_ofdm;
+       const struct ani_cck_level_entry *entry_cck;
+
+       aniState->noiseFloor = BEACON_RSSI(ah);
+       DBG2("ath9k: "
+               "**** ccklevel %d=>%d, rssi=%d[lo=%d hi=%d]\n",
+               aniState->cckNoiseImmunityLevel, immunityLevel,
+               aniState->noiseFloor, aniState->rssiThrLow,
+               aniState->rssiThrHigh);
+
+       if (aniState->noiseFloor <= (unsigned int)aniState->rssiThrLow &&
+           immunityLevel > ATH9K_ANI_CCK_MAX_LEVEL_LOW_RSSI)
+               immunityLevel = ATH9K_ANI_CCK_MAX_LEVEL_LOW_RSSI;
+
+       aniState->cckNoiseImmunityLevel = immunityLevel;
+
+       entry_ofdm = &ofdm_level_table[aniState->ofdmNoiseImmunityLevel];
+       entry_cck = &cck_level_table[aniState->cckNoiseImmunityLevel];
+
+       if (aniState->firstepLevel != entry_cck->fir_step_level &&
+           entry_cck->fir_step_level >= entry_ofdm->fir_step_level)
+               ath9k_hw_ani_control(ah,
+                                    ATH9K_ANI_FIRSTEP_LEVEL,
+                                    entry_cck->fir_step_level);
+
+       /* Skip MRC CCK for pre AR9003 families */
+       if (!AR_SREV_9300_20_OR_LATER(ah) || AR_SREV_9485(ah))
+               return;
+
+       if (aniState->mrcCCKOff == entry_cck->mrc_cck_on)
+               ath9k_hw_ani_control(ah,
+                                    ATH9K_ANI_MRC_CCK,
+                                    entry_cck->mrc_cck_on);
+}
+
+static void ath9k_hw_ani_cck_err_trigger(struct ath_hw *ah)
+{
+       struct ar5416AniState *aniState;
+
+       if (!DO_ANI(ah))
+               return;
+
+       if (!use_new_ani(ah)) {
+               ath9k_hw_ani_cck_err_trigger_old(ah);
+               return;
+       }
+
+       aniState = &ah->curchan->ani;
+
+       if (aniState->cckNoiseImmunityLevel < ATH9K_ANI_CCK_MAX_LEVEL)
+               ath9k_hw_set_cck_nil(ah, aniState->cckNoiseImmunityLevel + 1);
+}
+
+static void ath9k_hw_ani_lower_immunity_old(struct ath_hw *ah)
+{
+       struct ar5416AniState *aniState;
+       int32_t rssi;
+
+       aniState = &ah->curchan->ani;
+
+       rssi = BEACON_RSSI(ah);
+       if (rssi > aniState->rssiThrHigh) {
+               /* XXX: Handle me */
+       } else if (rssi > aniState->rssiThrLow) {
+               if (aniState->ofdmWeakSigDetectOff) {
+                       if (ath9k_hw_ani_control(ah,
+                                ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
+                                1) == 1)
+                               return;
+               }
+               if (aniState->firstepLevel > 0) {
+                       if (ath9k_hw_ani_control(ah,
+                                ATH9K_ANI_FIRSTEP_LEVEL,
+                                aniState->firstepLevel - 1) == 1)
+                               return;
+               }
+       } else {
+               if (aniState->firstepLevel > 0) {
+                       if (ath9k_hw_ani_control(ah,
+                                ATH9K_ANI_FIRSTEP_LEVEL,
+                                aniState->firstepLevel - 1) == 1)
+                               return;
+               }
+       }
+
+       if (aniState->spurImmunityLevel > 0) {
+               if (ath9k_hw_ani_control(ah, ATH9K_ANI_SPUR_IMMUNITY_LEVEL,
+                                        aniState->spurImmunityLevel - 1))
+                       return;
+       }
+
+       if (aniState->noiseImmunityLevel > 0) {
+               ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL,
+                                    aniState->noiseImmunityLevel - 1);
+               return;
+       }
+}
+
+/*
+ * only lower either OFDM or CCK errors per turn
+ * we lower the other one next time
+ */
+static void ath9k_hw_ani_lower_immunity(struct ath_hw *ah)
+{
+       struct ar5416AniState *aniState;
+
+       aniState = &ah->curchan->ani;
+
+       if (!use_new_ani(ah)) {
+               ath9k_hw_ani_lower_immunity_old(ah);
+               return;
+       }
+
+       /* lower OFDM noise immunity */
+       if (aniState->ofdmNoiseImmunityLevel > 0 &&
+           (aniState->ofdmsTurn || aniState->cckNoiseImmunityLevel == 0)) {
+               ath9k_hw_set_ofdm_nil(ah, aniState->ofdmNoiseImmunityLevel - 1);
+               return;
+       }
+
+       /* lower CCK noise immunity */
+       if (aniState->cckNoiseImmunityLevel > 0)
+               ath9k_hw_set_cck_nil(ah, aniState->cckNoiseImmunityLevel - 1);
+}
+
+static void ath9k_ani_reset_old(struct ath_hw *ah)
+{
+       struct ar5416AniState *aniState;
+
+       if (!DO_ANI(ah))
+               return;
+
+       aniState = &ah->curchan->ani;
+
+       if (aniState->noiseImmunityLevel != 0)
+               ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL,
+                                    aniState->noiseImmunityLevel);
+       if (aniState->spurImmunityLevel != 0)
+               ath9k_hw_ani_control(ah, ATH9K_ANI_SPUR_IMMUNITY_LEVEL,
+                                    aniState->spurImmunityLevel);
+       if (aniState->ofdmWeakSigDetectOff)
+               ath9k_hw_ani_control(ah, ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
+                                    !aniState->ofdmWeakSigDetectOff);
+       if (aniState->cckWeakSigThreshold)
+               ath9k_hw_ani_control(ah, ATH9K_ANI_CCK_WEAK_SIGNAL_THR,
+                                    aniState->cckWeakSigThreshold);
+       if (aniState->firstepLevel != 0)
+               ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
+                                    aniState->firstepLevel);
+
+       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);
+}
+
+/*
+ * Restore the ANI parameters in the HAL and reset the statistics.
+ * This routine should be called for every hardware reset and for
+ * every channel change.
+ */
+void ath9k_ani_reset(struct ath_hw *ah, int is_scanning)
+{
+       struct ar5416AniState *aniState = &ah->curchan->ani;
+       struct ath9k_channel *chan = ah->curchan;
+
+       if (!DO_ANI(ah))
+               return;
+
+       if (!use_new_ani(ah))
+               return ath9k_ani_reset_old(ah);
+
+       ah->stats.ast_ani_reset++;
+
+       /* always allow mode (on/off) to be controlled */
+       ah->ani_function |= ATH9K_ANI_MODE;
+
+       if (is_scanning) {
+               /*
+                * If we're scanning or in AP mode, the defaults (ini)
+                * should be in place. For an AP we assume the historical
+                * levels for this channel are probably outdated so start
+                * from defaults instead.
+                */
+               if (aniState->ofdmNoiseImmunityLevel !=
+                   ATH9K_ANI_OFDM_DEF_LEVEL ||
+                   aniState->cckNoiseImmunityLevel !=
+                   ATH9K_ANI_CCK_DEF_LEVEL) {
+                       DBG("ath9k: "
+                               "Restore defaults: chan %d Mhz/0x%x is_scanning=%d ofdm:%d cck:%d\n",
+                               chan->channel,
+                               chan->channelFlags,
+                               is_scanning,
+                               aniState->ofdmNoiseImmunityLevel,
+                               aniState->cckNoiseImmunityLevel);
+
+                       ath9k_hw_set_ofdm_nil(ah, ATH9K_ANI_OFDM_DEF_LEVEL);
+                       ath9k_hw_set_cck_nil(ah, ATH9K_ANI_CCK_DEF_LEVEL);
+               }
+       } else {
+               /*
+                * restore historical levels for this channel
+                */
+               DBG2("ath9k: "
+                       "Restore history: chan %d Mhz/0x%x is_scanning=%d ofdm:%d cck:%d\n",
+                       chan->channel,
+                       chan->channelFlags,
+                       is_scanning,
+                       aniState->ofdmNoiseImmunityLevel,
+                       aniState->cckNoiseImmunityLevel);
+
+                       ath9k_hw_set_ofdm_nil(ah,
+                                             aniState->ofdmNoiseImmunityLevel);
+                       ath9k_hw_set_cck_nil(ah,
+                                            aniState->cckNoiseImmunityLevel);
+       }
+
+       /*
+        * enable phy counters if hw supports or if not, enable phy
+        * interrupts (so we can count each one)
+        */
+       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);
+}
+
+static int ath9k_hw_ani_read_counters(struct ath_hw *ah)
+{
+       struct ath_common *common = ath9k_hw_common(ah);
+       struct ar5416AniState *aniState = &ah->curchan->ani;
+       u32 ofdm_base = 0;
+       u32 cck_base = 0;
+       u32 ofdmPhyErrCnt, cckPhyErrCnt;
+       u32 phyCnt1, phyCnt2;
+       int32_t listenTime;
+
+       ath_hw_cycle_counters_update(common);
+       listenTime = ath_hw_get_listen_time(common);
+
+       if (listenTime <= 0) {
+               ah->stats.ast_ani_lneg++;
+               ath9k_ani_restart(ah);
+               return 0;
+       }
+
+       if (!use_new_ani(ah)) {
+               ofdm_base = AR_PHY_COUNTMAX - ah->config.ofdm_trig_high;
+               cck_base = AR_PHY_COUNTMAX - ah->config.cck_trig_high;
+       }
+
+       aniState->listenTime += listenTime;
+
+       phyCnt1 = REG_READ(ah, AR_PHY_ERR_1);
+       phyCnt2 = REG_READ(ah, AR_PHY_ERR_2);
+
+       if (!use_new_ani(ah) && (phyCnt1 < ofdm_base || phyCnt2 < cck_base)) {
+               if (phyCnt1 < ofdm_base) {
+                       DBG2("ath9k: "
+                               "phyCnt1 0x%x, resetting counter value to 0x%x\n",
+                               phyCnt1, ofdm_base);
+                       REG_WRITE(ah, AR_PHY_ERR_1, ofdm_base);
+                       REG_WRITE(ah, AR_PHY_ERR_MASK_1,
+                                 AR_PHY_ERR_OFDM_TIMING);
+               }
+               if (phyCnt2 < cck_base) {
+                       DBG2("ath9k: "
+                               "phyCnt2 0x%x, resetting counter value to 0x%x\n",
+                               phyCnt2, cck_base);
+                       REG_WRITE(ah, AR_PHY_ERR_2, cck_base);
+                       REG_WRITE(ah, AR_PHY_ERR_MASK_2,
+                                 AR_PHY_ERR_CCK_TIMING);
+               }
+               return 0;
+       }
+
+       ofdmPhyErrCnt = phyCnt1 - ofdm_base;
+       ah->stats.ast_ani_ofdmerrs +=
+               ofdmPhyErrCnt - aniState->ofdmPhyErrCount;
+       aniState->ofdmPhyErrCount = ofdmPhyErrCnt;
+
+       cckPhyErrCnt = phyCnt2 - cck_base;
+       ah->stats.ast_ani_cckerrs +=
+               cckPhyErrCnt - aniState->cckPhyErrCount;
+       aniState->cckPhyErrCount = cckPhyErrCnt;
+       return 1;
+}
+
+void ath9k_hw_ani_monitor(struct ath_hw *ah, struct ath9k_channel *chan __unused)
+{
+       struct ar5416AniState *aniState;
+       u32 ofdmPhyErrRate, cckPhyErrRate;
+
+       if (!DO_ANI(ah))
+               return;
+
+       aniState = &ah->curchan->ani;
+       if (!aniState)
+               return;
+
+       if (!ath9k_hw_ani_read_counters(ah))
+               return;
+
+       ofdmPhyErrRate = aniState->ofdmPhyErrCount * 1000 /
+                        aniState->listenTime;
+       cckPhyErrRate =  aniState->cckPhyErrCount * 1000 /
+                        aniState->listenTime;
+
+       DBG2("ath9k: "
+               "listenTime=%d OFDM:%d errs=%d/s CCK:%d errs=%d/s ofdm_turn=%d\n",
+               aniState->listenTime,
+               aniState->ofdmNoiseImmunityLevel,
+               ofdmPhyErrRate, aniState->cckNoiseImmunityLevel,
+               cckPhyErrRate, aniState->ofdmsTurn);
+
+       if (aniState->listenTime > 5 * ah->aniperiod) {
+               if (ofdmPhyErrRate <= ah->config.ofdm_trig_low &&
+                   cckPhyErrRate <= ah->config.cck_trig_low) {
+                       ath9k_hw_ani_lower_immunity(ah);
+                       aniState->ofdmsTurn = !aniState->ofdmsTurn;
+               }
+               ath9k_ani_restart(ah);
+       } else if (aniState->listenTime > ah->aniperiod) {
+               /* check to see if need to raise immunity */
+               if (ofdmPhyErrRate > ah->config.ofdm_trig_high &&
+                   (cckPhyErrRate <= ah->config.cck_trig_high ||
+                    aniState->ofdmsTurn)) {
+                       ath9k_hw_ani_ofdm_err_trigger(ah);
+                       ath9k_ani_restart(ah);
+                       aniState->ofdmsTurn = 0;
+               } else if (cckPhyErrRate > ah->config.cck_trig_high) {
+                       ath9k_hw_ani_cck_err_trigger(ah);
+                       ath9k_ani_restart(ah);
+                       aniState->ofdmsTurn = 1;
+               }
+       }
+}
+
+void ath9k_hw_ani_setup(struct ath_hw *ah)
+{
+       int i;
+
+       static const int totalSizeDesired[] = { -55, -55, -55, -55, -62 };
+       static const int coarseHigh[] = { -14, -14, -14, -14, -12 };
+       static const int coarseLow[] = { -64, -64, -64, -64, -70 };
+       static const int firpwr[] = { -78, -78, -78, -78, -80 };
+
+       for (i = 0; i < 5; i++) {
+               ah->totalSizeDesired[i] = totalSizeDesired[i];
+               ah->coarse_high[i] = coarseHigh[i];
+               ah->coarse_low[i] = coarseLow[i];
+               ah->firpwr[i] = firpwr[i];
+       }
+}
+
+void ath9k_hw_ani_init(struct ath_hw *ah)
+{
+       unsigned int i;
+
+       DBG2("ath9k: Initialize ANI\n");
+
+       if (use_new_ani(ah)) {
+               ah->config.ofdm_trig_high = ATH9K_ANI_OFDM_TRIG_HIGH_NEW;
+               ah->config.ofdm_trig_low = ATH9K_ANI_OFDM_TRIG_LOW_NEW;
+
+               ah->config.cck_trig_high = ATH9K_ANI_CCK_TRIG_HIGH_NEW;
+               ah->config.cck_trig_low = ATH9K_ANI_CCK_TRIG_LOW_NEW;
+       } else {
+               ah->config.ofdm_trig_high = ATH9K_ANI_OFDM_TRIG_HIGH_OLD;
+               ah->config.ofdm_trig_low = ATH9K_ANI_OFDM_TRIG_LOW_OLD;
+
+               ah->config.cck_trig_high = ATH9K_ANI_CCK_TRIG_HIGH_OLD;
+               ah->config.cck_trig_low = ATH9K_ANI_CCK_TRIG_LOW_OLD;
+       }
+
+       for (i = 0; i < ARRAY_SIZE(ah->channels); i++) {
+               struct ath9k_channel *chan = &ah->channels[i];
+               struct ar5416AniState *ani = &chan->ani;
+
+               if (use_new_ani(ah)) {
+                       ani->spurImmunityLevel =
+                               ATH9K_ANI_SPUR_IMMUNE_LVL_NEW;
+
+                       ani->firstepLevel = ATH9K_ANI_FIRSTEP_LVL_NEW;
+
+                       if (AR_SREV_9300_20_OR_LATER(ah))
+                               ani->mrcCCKOff =
+                                       !ATH9K_ANI_ENABLE_MRC_CCK;
+                       else
+                               ani->mrcCCKOff = 1;
+
+                       ani->ofdmsTurn = 1;
+               } else {
+                       ani->spurImmunityLevel =
+                               ATH9K_ANI_SPUR_IMMUNE_LVL_OLD;
+                       ani->firstepLevel = ATH9K_ANI_FIRSTEP_LVL_OLD;
+
+                       ani->cckWeakSigThreshold =
+                               ATH9K_ANI_CCK_WEAK_SIG_THR;
+               }
+
+               ani->rssiThrHigh = ATH9K_ANI_RSSI_THR_HIGH;
+               ani->rssiThrLow = ATH9K_ANI_RSSI_THR_LOW;
+               ani->ofdmWeakSigDetectOff =
+                       !ATH9K_ANI_USE_OFDM_WEAK_SIG;
+               ani->cckNoiseImmunityLevel = ATH9K_ANI_CCK_DEF_LEVEL;
+       }
+
+       /*
+        * since we expect some ongoing maintenance on the tables, let's sanity
+        * check here default level should not modify INI setting.
+        */
+       if (use_new_ani(ah)) {
+               ah->aniperiod = ATH9K_ANI_PERIOD_NEW;
+               ah->config.ani_poll_interval = ATH9K_ANI_POLLINTERVAL_NEW;
+       } else {
+               ah->aniperiod = ATH9K_ANI_PERIOD_OLD;
+               ah->config.ani_poll_interval = ATH9K_ANI_POLLINTERVAL_OLD;
+       }
+
+       if (ah->config.enable_ani)
+               ah->proc_phyerr |= HAL_PROCESS_ANI;
+
+       ath9k_ani_restart(ah);
+}
diff --git a/src/drivers/net/ath/ath9k/ath9k_ar5008_phy.c b/src/drivers/net/ath/ath9k/ath9k_ar5008_phy.c
new file mode 100644 (file)
index 0000000..60e87e9
--- /dev/null
@@ -0,0 +1,1663 @@
+/*
+ * Copyright (c) 2008-2011 Atheros Communications Inc.
+ *
+ * Modified for iPXE by Scott K Logan <logans@cottsay.net> July 2011
+ * Original from Linux kernel 3.0.1
+ *
+ * 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 <ipxe/malloc.h>
+#include <ipxe/io.h>
+
+#include "hw.h"
+#include "hw-ops.h"
+#include "../regd.h"
+#include "ar9002_phy.h"
+
+/* All code below is for AR5008, AR9001, AR9002 */
+
+static const int firstep_table[] =
+/* level:  0   1   2   3   4   5   6   7   8  */
+       { -4, -2,  0,  2,  4,  6,  8, 10, 12 }; /* lvl 0-8, default 2 */
+
+static const int cycpwrThr1_table[] =
+/* level:  0   1   2   3   4   5   6   7   8  */
+       { -6, -4, -2,  0,  2,  4,  6,  8 };     /* lvl 0-7, default 3 */
+
+/*
+ * register values to turn OFDM weak signal detection OFF
+ */
+static const int m1ThreshLow_off = 127;
+static const int m2ThreshLow_off = 127;
+static const int m1Thresh_off = 127;
+static const int m2Thresh_off = 127;
+static const int m2CountThr_off =  31;
+static const int m2CountThrLow_off =  63;
+static const int m1ThreshLowExt_off = 127;
+static const int m2ThreshLowExt_off = 127;
+static const int m1ThreshExt_off = 127;
+static const int m2ThreshExt_off = 127;
+
+
+static void ar5008_rf_bank_setup(u32 *bank, struct ar5416IniArray *array,
+                                int col)
+{
+       unsigned int i;
+
+       for (i = 0; i < array->ia_rows; i++)
+               bank[i] = INI_RA(array, i, col);
+}
+
+
+#define REG_WRITE_RF_ARRAY(iniarray, regData, regWr) \
+       ar5008_write_rf_array(ah, iniarray, regData, &(regWr))
+
+static void ar5008_write_rf_array(struct ath_hw *ah, struct ar5416IniArray *array,
+                                 u32 *data, unsigned int *writecnt)
+{
+       unsigned int r;
+
+       ENABLE_REGWRITE_BUFFER(ah);
+
+       for (r = 0; r < array->ia_rows; r++) {
+               REG_WRITE(ah, INI_RA(array, r, 0), data[r]);
+               DO_DELAY(*writecnt);
+       }
+
+       REGWRITE_BUFFER_FLUSH(ah);
+}
+
+/**
+ * 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)
+{
+       u32 tmp_reg;
+       unsigned int reg_writes = 0;
+       u32 new_bias = 0;
+
+       if (!AR_SREV_5416(ah) || synth_freq >= 3000)
+               return;
+
+       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);
+
+       DBG("ath9k: 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 structure
+ * @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)
+{
+       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 {
+                       DBG("ath9k: Invalid channel %d 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 {
+               DBG("ath9k: Invalid channel %d 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;
+       static int pilot_mask_reg[4] = {
+               AR_PHY_TIMING7, AR_PHY_TIMING8,
+               AR_PHY_PILOT_MASK_01_30, AR_PHY_PILOT_MASK_31_60
+       };
+       static int chan_mask_reg[4] = {
+               AR_PHY_TIMING9, AR_PHY_TIMING10,
+               AR_PHY_CHANNEL_MASK_01_30, AR_PHY_CHANNEL_MASK_31_60
+       };
+       static 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;
+       int 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 = zalloc((sizeof(u32) * size)); \
+               if (!bank) { \
+                       DBG("ath9k: Cannot allocate RF banks\n"); \
+                       return -ENOMEM; \
+               } \
+       } while (0);
+
+       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 { \
+               free(bank); \
+               bank = NULL; \
+       } while (0);
+
+       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 int 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;
+       unsigned 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_20_OR_LATER(ah))
+               return 1;
+
+       /* Setup rf parameters */
+       eepMinorRev = ah->eep_ops->get_eeprom(ah, EEP_MINOR_REV);
+
+       /* Setup Bank 0 Write */
+       ar5008_rf_bank_setup(ah->analogBank0Data, &ah->iniBank0, 1);
+
+       /* Setup Bank 1 Write */
+       ar5008_rf_bank_setup(ah->analogBank1Data, &ah->iniBank1, 1);
+
+       /* Setup Bank 2 Write */
+       ar5008_rf_bank_setup(ah->analogBank2Data, &ah->iniBank2, 1);
+
+       /* Setup Bank 6 Write */
+       ar5008_rf_bank_setup(ah->analogBank3Data, &ah->iniBank3,
+                     modesIndex);
+       {
+               unsigned 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 */
+       ar5008_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 1;
+}
+
+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;
+
+
+       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:
+               ENABLE_REGWRITE_BUFFER(ah);
+               REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx_chainmask);
+               REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx_chainmask);
+               break;
+       default:
+               ENABLE_REGWRITE_BUFFER(ah);
+               break;
+       }
+
+       REG_WRITE(ah, AR_SELFGEN_MASK, tx_chainmask);
+
+       REGWRITE_BUFFER_FLUSH(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 __unused)
+{
+       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_20_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_11_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_20_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_12_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);
+}
+
+
+static int ar5008_hw_process_ini(struct ath_hw *ah,
+                                struct ath9k_channel *chan)
+{
+       struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
+       struct ath_common *common = ath9k_hw_common(ah);
+       unsigned int i, regWrites = 0;
+       struct net80211_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);
+
+       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
+                   && (common->bus_ops->ath_bus_type != ATH_USB)) {
+                       udelay(100);
+               }
+
+               DO_DELAY(regWrites);
+       }
+
+       REGWRITE_BUFFER_FLUSH(ah);
+
+       if (AR_SREV_9280(ah) || AR_SREV_9287_11_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_11_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
+                   && (common->bus_ops->ath_bus_type != ATH_USB)) {
+                       udelay(100);
+               }
+
+               DO_DELAY(regWrites);
+       }
+
+       REGWRITE_BUFFER_FLUSH(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 (IS_CHAN_A_FAST_CLOCK(ah, 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),
+                                0,
+                                channel->maxpower * 2,
+                                min((u32) MAX_RATE_POWER,
+                                (u32) regulatory->power_limit), 0);
+
+       /* Write analog registers */
+       if (!ath9k_hw_set_rf_regs(ah, chan, freqIndex)) {
+               DBG("ath9k: 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_20_OR_LATER(ah))
+               rfMode |= (IS_CHAN_5GHZ(chan)) ?
+                       AR_PHY_MODE_RF5GHZ : AR_PHY_MODE_RF2GHZ;
+
+       if (IS_CHAN_A_FAST_CLOCK(ah, 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 int 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_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, int 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 __unused,
+                                        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 __unused,
+                                        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 __unused,
+                                        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 int ar5008_hw_ani_control_old(struct ath_hw *ah,
+                                     enum ath9k_ani_cmd cmd,
+                                     int param)
+{
+       struct ar5416AniState *aniState = &ah->curchan->ani;
+
+       switch (cmd & ah->ani_function) {
+       case ATH9K_ANI_NOISE_IMMUNITY_LEVEL:{
+               u32 level = param;
+
+               if (level >= ARRAY_SIZE(ah->totalSizeDesired)) {
+                       DBG("ath9k: "
+                               "level out of range (%d > %zd)\n",
+                               level, ARRAY_SIZE(ah->totalSizeDesired));
+                       return 0;
+               }
+
+               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:{
+               static const int m1ThreshLow[] = { 127, 50 };
+               static const int m2ThreshLow[] = { 127, 40 };
+               static const int m1Thresh[] = { 127, 0x4d };
+               static const int m2Thresh[] = { 127, 0x40 };
+               static const int m2CountThr[] = { 31, 16 };
+               static 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:{
+               static 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:{
+               static const int firstep[] = { 0, 4, 8 };
+               u32 level = param;
+
+               if (level >= ARRAY_SIZE(firstep)) {
+                       DBG("ath9k: "
+                               "level out of range (%d > %zd)\n",
+                               level, ARRAY_SIZE(firstep));
+                       return 0;
+               }
+               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:{
+               static const int cycpwrThr1[] = { 2, 4, 6, 8, 10, 12, 14, 16 };
+               u32 level = param;
+
+               if (level >= ARRAY_SIZE(cycpwrThr1)) {
+                       DBG("ath9k: "
+                               "level out of range (%d > %zd)\n",
+                               level, ARRAY_SIZE(cycpwrThr1));
+                       return 0;
+               }
+               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:
+               DBG("ath9k: invalid cmd %d\n", cmd);
+               return 0;
+       }
+
+       DBG2("ath9k: ANI parameters:\n");
+       DBG2(
+               "noiseImmunityLevel=%d, spurImmunityLevel=%d, ofdmWeakSigDetectOff=%d\n",
+               aniState->noiseImmunityLevel,
+               aniState->spurImmunityLevel,
+               !aniState->ofdmWeakSigDetectOff);
+       DBG2(
+               "cckWeakSigThreshold=%d, firstepLevel=%d, listenTime=%d\n",
+               aniState->cckWeakSigThreshold,
+               aniState->firstepLevel,
+               aniState->listenTime);
+       DBG2(
+               "ofdmPhyErrCount=%d, cckPhyErrCount=%d\n\n",
+               aniState->ofdmPhyErrCount,
+               aniState->cckPhyErrCount);
+
+       return 1;
+}
+
+static int ar5008_hw_ani_control_new(struct ath_hw *ah,
+                                     enum ath9k_ani_cmd cmd,
+                                     int param)
+{
+       struct ath9k_channel *chan = ah->curchan;
+       struct ar5416AniState *aniState = &chan->ani;
+       s32 value, value2;
+
+       switch (cmd & ah->ani_function) {
+       case ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION:{
+               /*
+                * on == 1 means ofdm weak signal detection is ON
+                * on == 1 is the default, for less noise immunity
+                *
+                * on == 0 means ofdm weak signal detection is OFF
+                * on == 0 means more noise imm
+                */
+               u32 on = param ? 1 : 0;
+               /*
+                * make register setting for default
+                * (weak sig detect ON) come from INI file
+                */
+               int m1ThreshLow = on ?
+                       aniState->iniDef.m1ThreshLow : m1ThreshLow_off;
+               int m2ThreshLow = on ?
+                       aniState->iniDef.m2ThreshLow : m2ThreshLow_off;
+               int m1Thresh = on ?
+                       aniState->iniDef.m1Thresh : m1Thresh_off;
+               int m2Thresh = on ?
+                       aniState->iniDef.m2Thresh : m2Thresh_off;
+               int m2CountThr = on ?
+                       aniState->iniDef.m2CountThr : m2CountThr_off;
+               int m2CountThrLow = on ?
+                       aniState->iniDef.m2CountThrLow : m2CountThrLow_off;
+               int m1ThreshLowExt = on ?
+                       aniState->iniDef.m1ThreshLowExt : m1ThreshLowExt_off;
+               int m2ThreshLowExt = on ?
+                       aniState->iniDef.m2ThreshLowExt : m2ThreshLowExt_off;
+               int m1ThreshExt = on ?
+                       aniState->iniDef.m1ThreshExt : m1ThreshExt_off;
+               int m2ThreshExt = on ?
+                       aniState->iniDef.m2ThreshExt : m2ThreshExt_off;
+
+               REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
+                             AR_PHY_SFCORR_LOW_M1_THRESH_LOW,
+                             m1ThreshLow);
+               REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
+                             AR_PHY_SFCORR_LOW_M2_THRESH_LOW,
+                             m2ThreshLow);
+               REG_RMW_FIELD(ah, AR_PHY_SFCORR,
+                             AR_PHY_SFCORR_M1_THRESH, m1Thresh);
+               REG_RMW_FIELD(ah, AR_PHY_SFCORR,
+                             AR_PHY_SFCORR_M2_THRESH, m2Thresh);
+               REG_RMW_FIELD(ah, AR_PHY_SFCORR,
+                             AR_PHY_SFCORR_M2COUNT_THR, m2CountThr);
+               REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
+                             AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW,
+                             m2CountThrLow);
+
+               REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
+                             AR_PHY_SFCORR_EXT_M1_THRESH_LOW, m1ThreshLowExt);
+               REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
+                             AR_PHY_SFCORR_EXT_M2_THRESH_LOW, m2ThreshLowExt);
+               REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
+                             AR_PHY_SFCORR_EXT_M1_THRESH, m1ThreshExt);
+               REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
+                             AR_PHY_SFCORR_EXT_M2_THRESH, m2ThreshExt);
+
+               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) {
+                       DBG2("ath9k: "
+                               "** ch %d: ofdm weak signal: %s=>%s\n",
+                               chan->channel,
+                               !aniState->ofdmWeakSigDetectOff ?
+                               "on" : "off",
+                               on ? "on" : "off");
+                       if (on)
+                               ah->stats.ast_ani_ofdmon++;
+                       else
+                               ah->stats.ast_ani_ofdmoff++;
+                       aniState->ofdmWeakSigDetectOff = !on;
+               }
+               break;
+       }
+       case ATH9K_ANI_FIRSTEP_LEVEL:{
+               u32 level = param;
+
+               if (level >= ARRAY_SIZE(firstep_table)) {
+                       DBG("ath9k: "
+                               "ATH9K_ANI_FIRSTEP_LEVEL: level out of range (%d > %zd)\n",
+                               level, ARRAY_SIZE(firstep_table));
+                       return 0;
+               }
+
+               /*
+                * make register setting relative to default
+                * from INI file & cap value
+                */
+               value = firstep_table[level] -
+                       firstep_table[ATH9K_ANI_FIRSTEP_LVL_NEW] +
+                       aniState->iniDef.firstep;
+               if (value < ATH9K_SIG_FIRSTEP_SETTING_MIN)
+                       value = ATH9K_SIG_FIRSTEP_SETTING_MIN;
+               if (value > ATH9K_SIG_FIRSTEP_SETTING_MAX)
+                       value = ATH9K_SIG_FIRSTEP_SETTING_MAX;
+               REG_RMW_FIELD(ah, AR_PHY_FIND_SIG,
+                             AR_PHY_FIND_SIG_FIRSTEP,
+                             value);
+               /*
+                * we need to set first step low register too
+                * make register setting relative to default
+                * from INI file & cap value
+                */
+               value2 = firstep_table[level] -
+                        firstep_table[ATH9K_ANI_FIRSTEP_LVL_NEW] +
+                        aniState->iniDef.firstepLow;
+               if (value2 < ATH9K_SIG_FIRSTEP_SETTING_MIN)
+                       value2 = ATH9K_SIG_FIRSTEP_SETTING_MIN;
+               if (value2 > ATH9K_SIG_FIRSTEP_SETTING_MAX)
+                       value2 = ATH9K_SIG_FIRSTEP_SETTING_MAX;
+
+               REG_RMW_FIELD(ah, AR_PHY_FIND_SIG_LOW,
+                             AR_PHY_FIND_SIG_FIRSTEP_LOW, value2);
+
+               if (level != aniState->firstepLevel) {
+                       DBG2("ath9k: "
+                               "** ch %d: level %d=>%d[def:%d] firstep[level]=%d ini=%d\n",
+                               chan->channel,
+                               aniState->firstepLevel,
+                               level,
+                               ATH9K_ANI_FIRSTEP_LVL_NEW,
+                               value,
+                               aniState->iniDef.firstep);
+                       DBG2("ath9k: "
+                               "** ch %d: level %d=>%d[def:%d] firstep_low[level]=%d ini=%d\n",
+                               chan->channel,
+                               aniState->firstepLevel,
+                               level,
+                               ATH9K_ANI_FIRSTEP_LVL_NEW,
+                               value2,
+                               aniState->iniDef.firstepLow);
+                       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:{
+               u32 level = param;
+
+               if (level >= ARRAY_SIZE(cycpwrThr1_table)) {
+                       DBG("ath9k: "
+                               "ATH9K_ANI_SPUR_IMMUNITY_LEVEL: level out of range (%d > %zd)\n",
+                               level, ARRAY_SIZE(cycpwrThr1_table));
+                       return 0;
+               }
+               /*
+                * make register setting relative to default
+                * from INI file & cap value
+                */
+               value = cycpwrThr1_table[level] -
+                       cycpwrThr1_table[ATH9K_ANI_SPUR_IMMUNE_LVL_NEW] +
+                       aniState->iniDef.cycpwrThr1;
+               if (value < ATH9K_SIG_SPUR_IMM_SETTING_MIN)
+                       value = ATH9K_SIG_SPUR_IMM_SETTING_MIN;
+               if (value > ATH9K_SIG_SPUR_IMM_SETTING_MAX)
+                       value = ATH9K_SIG_SPUR_IMM_SETTING_MAX;
+               REG_RMW_FIELD(ah, AR_PHY_TIMING5,
+                             AR_PHY_TIMING5_CYCPWR_THR1,
+                             value);
+
+               /*
+                * set AR_PHY_EXT_CCA for extension channel
+                * make register setting relative to default
+                * from INI file & cap value
+                */
+               value2 = cycpwrThr1_table[level] -
+                        cycpwrThr1_table[ATH9K_ANI_SPUR_IMMUNE_LVL_NEW] +
+                        aniState->iniDef.cycpwrThr1Ext;
+               if (value2 < ATH9K_SIG_SPUR_IMM_SETTING_MIN)
+                       value2 = ATH9K_SIG_SPUR_IMM_SETTING_MIN;
+               if (value2 > ATH9K_SIG_SPUR_IMM_SETTING_MAX)
+                       value2 = ATH9K_SIG_SPUR_IMM_SETTING_MAX;
+               REG_RMW_FIELD(ah, AR_PHY_EXT_CCA,
+                             AR_PHY_EXT_TIMING5_CYCPWR_THR1, value2);
+
+               if (level != aniState->spurImmunityLevel) {
+                       DBG2("ath9k: "
+                               "** ch %d: level %d=>%d[def:%d] cycpwrThr1[level]=%d ini=%d\n",
+                               chan->channel,
+                               aniState->spurImmunityLevel,
+                               level,
+                               ATH9K_ANI_SPUR_IMMUNE_LVL_NEW,
+                               value,
+                               aniState->iniDef.cycpwrThr1);
+                       DBG2("ath9k: "
+                               "** ch %d: level %d=>%d[def:%d] cycpwrThr1Ext[level]=%d ini=%d\n",
+                               chan->channel,
+                               aniState->spurImmunityLevel,
+                               level,
+                               ATH9K_ANI_SPUR_IMMUNE_LVL_NEW,
+                               value2,
+                               aniState->iniDef.cycpwrThr1Ext);
+                       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_MRC_CCK:
+               /*
+                * You should not see this as AR5008, AR9001, AR9002
+                * does not have hardware support for MRC CCK.
+                */
+               break;
+       case ATH9K_ANI_PRESENT:
+               break;
+       default:
+               DBG("ath9k: invalid cmd %d\n", cmd);
+               return 0;
+       }
+
+       DBG2("ath9k: "
+               "ANI parameters: SI=%d, ofdmWS=%s FS=%d MRCcck=%s listenTime=%d ofdmErrs=%d cckErrs=%d\n",
+               aniState->spurImmunityLevel,
+               !aniState->ofdmWeakSigDetectOff ? "on" : "off",
+               aniState->firstepLevel,
+               !aniState->mrcCCKOff ? "on" : "off",
+               aniState->listenTime,
+               aniState->ofdmPhyErrCount,
+               aniState->cckPhyErrCount);
+       return 1;
+}
+
+static void ar5008_hw_do_getnf(struct ath_hw *ah,
+                             int16_t nfarray[NUM_NF_READINGS])
+{
+       int16_t nf;
+
+       nf = MS(REG_READ(ah, AR_PHY_CCA), AR_PHY_MINCCA_PWR);
+       nfarray[0] = sign_extend32(nf, 8);
+
+       nf = MS(REG_READ(ah, AR_PHY_CH1_CCA), AR_PHY_CH1_MINCCA_PWR);
+       nfarray[1] = sign_extend32(nf, 8);
+
+       nf = MS(REG_READ(ah, AR_PHY_CH2_CCA), AR_PHY_CH2_MINCCA_PWR);
+       nfarray[2] = sign_extend32(nf, 8);
+
+       if (!IS_CHAN_HT40(ah->curchan))
+               return;
+
+       nf = MS(REG_READ(ah, AR_PHY_EXT_CCA), AR_PHY_EXT_MINCCA_PWR);
+       nfarray[3] = sign_extend32(nf, 8);
+
+       nf = MS(REG_READ(ah, AR_PHY_CH1_EXT_CCA), AR_PHY_CH1_EXT_MINCCA_PWR);
+       nfarray[4] = sign_extend32(nf, 8);
+
+       nf = MS(REG_READ(ah, AR_PHY_CH2_EXT_CCA), AR_PHY_CH2_EXT_MINCCA_PWR);
+       nfarray[5] = sign_extend32(nf, 8);
+}
+
+/*
+ * Initialize the ANI register values with default (ini) values.
+ * This routine is called during a (full) hardware reset after
+ * all the registers are initialised from the INI.
+ */
+static void ar5008_hw_ani_cache_ini_regs(struct ath_hw *ah)
+{
+       struct ath9k_channel *chan = ah->curchan;
+       struct ar5416AniState *aniState = &chan->ani;
+       struct ath9k_ani_default *iniDef;
+       u32 val;
+
+       iniDef = &aniState->iniDef;
+
+       DBG2("ath9k: ver %d.%d chan %d Mhz/0x%x\n",
+               ah->hw_version.macVersion,
+               ah->hw_version.macRev,
+               chan->channel,
+               chan->channelFlags);
+
+       val = REG_READ(ah, AR_PHY_SFCORR);
+       iniDef->m1Thresh = MS(val, AR_PHY_SFCORR_M1_THRESH);
+       iniDef->m2Thresh = MS(val, AR_PHY_SFCORR_M2_THRESH);
+       iniDef->m2CountThr = MS(val, AR_PHY_SFCORR_M2COUNT_THR);
+
+       val = REG_READ(ah, AR_PHY_SFCORR_LOW);
+       iniDef->m1ThreshLow = MS(val, AR_PHY_SFCORR_LOW_M1_THRESH_LOW);
+       iniDef->m2ThreshLow = MS(val, AR_PHY_SFCORR_LOW_M2_THRESH_LOW);
+       iniDef->m2CountThrLow = MS(val, AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW);
+
+       val = REG_READ(ah, AR_PHY_SFCORR_EXT);
+       iniDef->m1ThreshExt = MS(val, AR_PHY_SFCORR_EXT_M1_THRESH);
+       iniDef->m2ThreshExt = MS(val, AR_PHY_SFCORR_EXT_M2_THRESH);
+       iniDef->m1ThreshLowExt = MS(val, AR_PHY_SFCORR_EXT_M1_THRESH_LOW);
+       iniDef->m2ThreshLowExt = MS(val, AR_PHY_SFCORR_EXT_M2_THRESH_LOW);
+       iniDef->firstep = REG_READ_FIELD(ah,
+                                        AR_PHY_FIND_SIG,
+                                        AR_PHY_FIND_SIG_FIRSTEP);
+       iniDef->firstepLow = REG_READ_FIELD(ah,
+                                           AR_PHY_FIND_SIG_LOW,
+                                           AR_PHY_FIND_SIG_FIRSTEP_LOW);
+       iniDef->cycpwrThr1 = REG_READ_FIELD(ah,
+                                           AR_PHY_TIMING5,
+                                           AR_PHY_TIMING5_CYCPWR_THR1);
+       iniDef->cycpwrThr1Ext = REG_READ_FIELD(ah,
+                                              AR_PHY_EXT_CCA,
+                                              AR_PHY_EXT_TIMING5_CYCPWR_THR1);
+
+       /* these levels just got reset to defaults by the INI */
+       aniState->spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL_NEW;
+       aniState->firstepLevel = ATH9K_ANI_FIRSTEP_LVL_NEW;
+       aniState->ofdmWeakSigDetectOff = !ATH9K_ANI_USE_OFDM_WEAK_SIG;
+       aniState->mrcCCKOff = 1; /* not available on pre AR9003 */
+}
+
+static void ar5008_hw_set_nf_limits(struct ath_hw *ah)
+{
+       ah->nf_2g.max = AR_PHY_CCA_MAX_GOOD_VAL_5416_2GHZ;
+       ah->nf_2g.min = AR_PHY_CCA_MIN_GOOD_VAL_5416_2GHZ;
+       ah->nf_2g.nominal = AR_PHY_CCA_NOM_VAL_5416_2GHZ;
+       ah->nf_5g.max = AR_PHY_CCA_MAX_GOOD_VAL_5416_5GHZ;
+       ah->nf_5g.min = AR_PHY_CCA_MIN_GOOD_VAL_5416_5GHZ;
+       ah->nf_5g.nominal = AR_PHY_CCA_NOM_VAL_5416_5GHZ;
+}
+
+static void ar5008_hw_set_radar_params(struct ath_hw *ah,
+                                      struct ath_hw_radar_conf *conf)
+{
+       u32 radar_0 = 0, radar_1 = 0;
+
+       if (!conf) {
+               REG_CLR_BIT(ah, AR_PHY_RADAR_0, AR_PHY_RADAR_0_ENA);
+               return;
+       }
+
+       radar_0 |= AR_PHY_RADAR_0_ENA | AR_PHY_RADAR_0_FFT_ENA;
+       radar_0 |= SM(conf->fir_power, AR_PHY_RADAR_0_FIRPWR);
+       radar_0 |= SM(conf->radar_rssi, AR_PHY_RADAR_0_RRSSI);
+       radar_0 |= SM(conf->pulse_height, AR_PHY_RADAR_0_HEIGHT);
+       radar_0 |= SM(conf->pulse_rssi, AR_PHY_RADAR_0_PRSSI);
+       radar_0 |= SM(conf->pulse_inband, AR_PHY_RADAR_0_INBAND);
+
+       radar_1 |= AR_PHY_RADAR_1_MAX_RRSSI;
+       radar_1 |= AR_PHY_RADAR_1_BLOCK_CHECK;
+       radar_1 |= SM(conf->pulse_maxlen, AR_PHY_RADAR_1_MAXLEN);
+       radar_1 |= SM(conf->pulse_inband_step, AR_PHY_RADAR_1_RELSTEP_THRESH);
+       radar_1 |= SM(conf->radar_inband, AR_PHY_RADAR_1_RELPWR_THRESH);
+
+       REG_WRITE(ah, AR_PHY_RADAR_0, radar_0);
+       REG_WRITE(ah, AR_PHY_RADAR_1, radar_1);
+       if (conf->ext_channel)
+               REG_SET_BIT(ah, AR_PHY_RADAR_EXT, AR_PHY_RADAR_EXT_ENA);
+       else
+               REG_CLR_BIT(ah, AR_PHY_RADAR_EXT, AR_PHY_RADAR_EXT_ENA);
+}
+
+static void ar5008_hw_set_radar_conf(struct ath_hw *ah)
+{
+       struct ath_hw_radar_conf *conf = &ah->radar_conf;
+
+       conf->fir_power = -33;
+       conf->radar_rssi = 20;
+       conf->pulse_height = 10;
+       conf->pulse_rssi = 24;
+       conf->pulse_inband = 15;
+       conf->pulse_maxlen = 255;
+       conf->pulse_inband_step = 12;
+       conf->radar_inband = 8;
+}
+
+void ar5008_hw_attach_phy_ops(struct ath_hw *ah)
+{
+       struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
+       static 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
+       };
+
+       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->restore_chainmask = ar5008_restore_chainmask;
+       priv_ops->set_diversity = ar5008_set_diversity;
+       priv_ops->do_getnf = ar5008_hw_do_getnf;
+       priv_ops->set_radar_params = ar5008_hw_set_radar_params;
+
+       if (modparam_force_new_ani) {
+               priv_ops->ani_control = ar5008_hw_ani_control_new;
+               priv_ops->ani_cache_ini_regs = ar5008_hw_ani_cache_ini_regs;
+       } else
+               priv_ops->ani_control = ar5008_hw_ani_control_old;
+
+       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;
+
+       ar5008_hw_set_nf_limits(ah);
+       ar5008_hw_set_radar_conf(ah);
+       memcpy(ah->nf_regs, ar5416_cca_regs, sizeof(ah->nf_regs));
+}
diff --git a/src/drivers/net/ath/ath9k/ath9k_ar9002_calib.c b/src/drivers/net/ath/ath9k/ath9k_ar9002_calib.c
new file mode 100644 (file)
index 0000000..f8978a5
--- /dev/null
@@ -0,0 +1,997 @@
+/*
+ * Copyright (c) 2008-2011 Atheros Communications Inc.
+ *
+ * Modified for iPXE by Scott K Logan <logans@cottsay.net> July 2011
+ * Original from Linux kernel 3.0.1
+ *
+ * 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
+
+enum ar9002_cal_types {
+       ADC_GAIN_CAL = BIT(0),
+       ADC_DC_CAL = BIT(1),
+       IQ_MISMATCH_CAL = BIT(2),
+};
+
+static int ar9002_hw_is_cal_supported(struct ath_hw *ah,
+                               struct ath9k_channel *chan,
+                               enum ar9002_cal_types cal_type)
+{
+       int supported = 0;
+       switch (ah->supp_cals & cal_type) {
+       case IQ_MISMATCH_CAL:
+               /* Run IQ Mismatch for non-CCK only */
+               if (!IS_CHAN_B(chan))
+                       supported = 1;
+               break;
+       case ADC_GAIN_CAL:
+       case ADC_DC_CAL:
+               /* Run ADC Gain Cal for non-CCK & non 2GHz-HT20 only */
+               if (!IS_CHAN_B(chan) &&
+                   !(IS_CHAN_2GHZ(chan) && IS_CHAN_HT20(chan)))
+                       supported = 1;
+               break;
+       }
+       return supported;
+}
+
+static void ar9002_hw_setup_calibration(struct ath_hw *ah,
+                                       struct ath9k_cal_list *currCal)
+{
+       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);
+               DBG2("ath9k: "
+                       "starting IQ Mismatch Calibration\n");
+               break;
+       case ADC_GAIN_CAL:
+               REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_GAIN);
+               DBG2("ath9k: "
+                       "starting ADC Gain Calibration\n");
+               break;
+       case ADC_DC_CAL:
+               REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_DC_PER);
+               DBG2("ath9k: "
+                       "starting ADC DC Calibration\n");
+               break;
+       }
+
+       REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4(0),
+                   AR_PHY_TIMING_CTRL4_DO_CAL);
+}
+
+static int ar9002_hw_per_calibration(struct ath_hw *ah,
+                                     struct ath9k_channel *ichan __unused,
+                                     u8 rxchainmask,
+                                     struct ath9k_cal_list *currCal)
+{
+       struct ath9k_hw_cal_data *caldata = ah->caldata;
+       int iscaldone = 0;
+
+       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);
+                               caldata->CalValid |= currCal->calData->calType;
+                               currCal->calState = CAL_DONE;
+                               iscaldone = 1;
+                       } else {
+                               ar9002_hw_setup_calibration(ah, currCal);
+                       }
+               }
+       } else if (!(caldata->CalValid & currCal->calData->calType)) {
+               ath9k_hw_reset_calibration(ah, currCal);
+       }
+
+       return iscaldone;
+}
+
+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));
+               DBG2("ath9k: "
+                       "%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));
+
+               DBG2("ath9k: "
+                       "%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));
+
+               DBG2("ath9k: "
+                       "%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)
+{
+       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];
+
+               DBG2("ath9k: "
+                       "Starting IQ Cal and Correction for Chain %d\n",
+                       i);
+
+               DBG2("ath9k: "
+                       "Orignal: Chn %diq_corr_meas = 0x%08x\n",
+                       i, ah->totalIqCorrMeas[i]);
+
+               iqCorrNeg = 0;
+
+               if (iqCorrMeas > 0x80000000) {
+                       iqCorrMeas = (0xffffffff - iqCorrMeas) + 1;
+                       iqCorrNeg = 1;
+               }
+
+               DBG2("ath9k: "
+                       "Chn %d pwr_meas_i = 0x%08x\n", i, powerMeasI);
+               DBG2("ath9k: "
+                       "Chn %d pwr_meas_q = 0x%08x\n", i, powerMeasQ);
+               DBG2("ath9k: 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;
+                       DBG2("ath9k: "
+                               "Chn %d iCoff = 0x%08x\n", i, iCoff);
+                       DBG2("ath9k: "
+                               "Chn %d qCoff = 0x%08x\n", i, qCoff);
+
+                       iCoff = iCoff & 0x3f;
+                       DBG2("ath9k: "
+                               "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;
+
+                       DBG2("ath9k: "
+                               "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);
+                       DBG2("ath9k: "
+                               "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)
+{
+       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];
+
+               DBG2("ath9k: "
+                       "Starting ADC Gain Cal for Chain %d\n", i);
+
+               DBG2("ath9k: "
+                       "Chn %d pwr_meas_odd_i = 0x%08x\n", i,
+                       iOddMeasOffset);
+               DBG2("ath9k: "
+                       "Chn %d pwr_meas_even_i = 0x%08x\n", i,
+                       iEvenMeasOffset);
+               DBG2("ath9k: "
+                       "Chn %d pwr_meas_odd_q = 0x%08x\n", i,
+                       qOddMeasOffset);
+               DBG2("ath9k: "
+                       "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;
+
+                       DBG2("ath9k: "
+                               "Chn %d gain_mismatch_i = 0x%08x\n", i,
+                               iGainMismatch);
+                       DBG2("ath9k: "
+                               "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);
+
+                       DBG2("ath9k: "
+                               "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)
+{
+       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];
+
+               DBG2("ath9k: "
+                       "Starting ADC DC Offset Cal for Chain %d\n", i);
+
+               DBG2("ath9k: "
+                       "Chn %d pwr_meas_odd_i = %d\n", i,
+                       iOddMeasOffset);
+               DBG2("ath9k: "
+                       "Chn %d pwr_meas_even_i = %d\n", i,
+                       iEvenMeasOffset);
+               DBG2("ath9k: "
+                       "Chn %d pwr_meas_odd_q = %d\n", i,
+                       qOddMeasOffset);
+               DBG2("ath9k: "
+                       "Chn %d pwr_meas_even_q = %d\n", i,
+                       qEvenMeasOffset);
+
+               iDcMismatch = (((iEvenMeasOffset - iOddMeasOffset) * 2) /
+                              numSamples) & 0x1ff;
+               qDcMismatch = (((qOddMeasOffset - qEvenMeasOffset) * 2) /
+                              numSamples) & 0x1ff;
+
+               DBG2("ath9k: "
+                       "Chn %d dc_offset_mismatch_i = 0x%08x\n", i,
+                       iDcMismatch);
+               DBG2("ath9k: "
+                       "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);
+
+               DBG2("ath9k: "
+                       "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, int 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) && ((unsigned int)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);
+}
+
+static inline void ar9285_hw_pa_cal(struct ath_hw *ah, int is_reset)
+{
+       u32 regVal;
+       unsigned int i;
+       int 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 },
+       };
+
+       DBG2("ath9k: 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;
+
+       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);
+}
+
+static void ar9002_hw_pa_cal(struct ath_hw *ah, int 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_12_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 int ar9002_hw_calibrate(struct ath_hw *ah,
+                               struct ath9k_channel *chan,
+                               u8 rxchainmask,
+                               int longcal)
+{
+       int iscaldone = 1;
+       struct ath9k_cal_list *currCal = ah->cal_list_curr;
+       int nfcal, nfcal_pending = 0;
+
+       nfcal = !!(REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF);
+       if (ah->caldata)
+               nfcal_pending = ah->caldata->nfcal_pending;
+
+       if (currCal && !nfcal &&
+           (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 = 0;
+                               ath9k_hw_reset_calibration(ah, currCal);
+                       }
+               }
+       }
+
+       /* Do NF cal only at longer intervals */
+       if (longcal || nfcal_pending) {
+               /*
+                * Get the value from the previous NF cal and update
+                * history buffer.
+                */
+               if (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);
+               }
+
+               if (longcal) {
+                       ath9k_hw_start_nfcal(ah, 0);
+                       /* Do periodic PAOffset Cal */
+                       ar9002_hw_pa_cal(ah, 0);
+                       ar9002_hw_olc_temp_compensation(ah);
+               }
+       }
+
+       return iscaldone;
+}
+
+/* Carrier leakage Calibration fix */
+static int ar9285_hw_cl_cal(struct ath_hw *ah, struct ath9k_channel *chan)
+{
+       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)) {
+                       DBG("ath9k: "
+                               "offset calibration failed to complete in 1ms; noisy environment?\n");
+                       return 0;
+               }
+               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)) {
+               DBG("ath9k: "
+                       "offset calibration failed to complete in 1ms; noisy environment?\n");
+               return 0;
+       }
+
+       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 1;
+}
+
+static int ar9285_hw_clc(struct ath_hw *ah, struct ath9k_channel *chan)
+{
+       unsigned int i;
+       uint32_t txgain_max;
+       uint32_t clc_gain, gain_mask = 0, clc_num = 0;
+       uint32_t reg_clc_I0, reg_clc_Q0;
+       uint32_t i0_num = 0;
+       uint32_t q0_num = 0;
+       uint32_t total_num = 0;
+       uint32_t reg_rf2g5_org;
+       int retv = 1;
+
+       if (!(ar9285_hw_cl_cal(ah, chan)))
+               return 0;
+
+       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 int ar9002_hw_init_cal(struct ath_hw *ah, struct ath9k_channel *chan)
+{
+       if (AR_SREV_9271(ah)) {
+               if (!ar9285_hw_cl_cal(ah, chan))
+                       return 0;
+       } else if (AR_SREV_9285(ah) && AR_SREV_9285_12_OR_LATER(ah)) {
+               if (!ar9285_hw_clc(ah, chan))
+                       return 0;
+       } else {
+               if (AR_SREV_9280_20_OR_LATER(ah)) {
+                       if (!AR_SREV_9287_11_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)) {
+                       DBG("ath9k: "
+                               "offset calibration failed to complete in 1ms; noisy environment?\n");
+                       return 0;
+               }
+
+               if (AR_SREV_9280_20_OR_LATER(ah)) {
+                       if (!AR_SREV_9287_11_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, 1);
+
+       /* Do NF Calibration after DC offset and other calibrations */
+       ath9k_hw_start_nfcal(ah, 1);
+
+       if (ah->caldata)
+               ah->caldata->nfcal_pending = 1;
+
+       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)) {
+               ah->supp_cals = IQ_MISMATCH_CAL;
+
+               if (AR_SREV_9160_10_OR_LATER(ah))
+                       ah->supp_cals |= ADC_GAIN_CAL | ADC_DC_CAL;
+
+               if (AR_SREV_9287(ah))
+                       ah->supp_cals &= ~ADC_GAIN_CAL;
+
+               if (ar9002_hw_is_cal_supported(ah, chan, ADC_GAIN_CAL)) {
+                       INIT_CAL(&ah->adcgain_caldata);
+                       INSERT_CAL(ah, &ah->adcgain_caldata);
+                       DBG2("ath9k: "
+                                       "enabling ADC Gain Calibration.\n");
+               }
+
+               if (ar9002_hw_is_cal_supported(ah, chan, ADC_DC_CAL)) {
+                       INIT_CAL(&ah->adcdc_caldata);
+                       INSERT_CAL(ah, &ah->adcdc_caldata);
+                       DBG2("ath9k: "
+                                       "enabling ADC DC Calibration.\n");
+               }
+
+               if (ar9002_hw_is_cal_supported(ah, chan, IQ_MISMATCH_CAL)) {
+                       INIT_CAL(&ah->iq_caldata);
+                       INSERT_CAL(ah, &ah->iq_caldata);
+                       DBG2("ath9k: "
+                                       "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);
+       }
+
+       if (ah->caldata)
+               ah->caldata->CalValid = 0;
+
+       return 1;
+}
+
+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 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_20_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;
+               } 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->supp_cals = ADC_GAIN_CAL | ADC_DC_CAL | IQ_MISMATCH_CAL;
+
+               if (AR_SREV_9287(ah))
+                       ah->supp_cals &= ~ADC_GAIN_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;
+
+       ops->calibrate = ar9002_hw_calibrate;
+}
diff --git a/src/drivers/net/ath/ath9k/ath9k_ar9002_hw.c b/src/drivers/net/ath/ath9k/ath9k_ar9002_hw.c
new file mode 100644 (file)
index 0000000..cc4edec
--- /dev/null
@@ -0,0 +1,607 @@
+/*
+ * Copyright (c) 2008-2011 Atheros Communications Inc.
+ *
+ * Modified for iPXE by Scott K Logan <logans@cottsay.net> July 2011
+ * Original from Linux kernel 3.0.1
+ *
+ * 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"
+#include "ar9002_phy.h"
+
+int modparam_force_new_ani;
+
+/* General hardware code for the A5008/AR9001/AR9002 hadware families */
+
+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_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_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_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_9160_1_1,
+                                      ARRAY_SIZE(ar5416Addac_9160_1_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_9287_1_1,
+                      ARRAY_SIZE(ar9287Common_normal_cck_fir_coeff_9287_1_1),
+                      2);
+               INIT_INI_ARRAY(&ah->iniCckfirJapan2484,
+                      ar9287Common_japan_2484_cck_fir_coeff_9287_1_1,
+                      ARRAY_SIZE(ar9287Common_japan_2484_cck_fir_coeff_9287_1_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_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_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 != 1)
+               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 {
+                       ENABLE_REGWRITE_BUFFER(ah);
+
+                       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);
+
+                       REGWRITE_BUFFER_FLUSH(ah);
+               }
+
+               udelay(1000);
+       }
+
+       if (power_off) {
+               /* clear bit 19 to disable L1 */
+               REG_CLR_BIT(ah, AR_PCIE_PM_CTRL, AR_PCIE_PM_CTRL_ENA);
+
+               val = REG_READ(ah, AR_WA);
+
+               /*
+                * Set PCIe workaround bits
+                * In AR9280 and AR9285, 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)
+                               val |= 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))) {
+                               val |= AR_WA_D3_L1_DISABLE;
+                       }
+               }
+
+               if (AR_SREV_9280(ah) || AR_SREV_9285(ah) || AR_SREV_9287(ah)) {
+                       /*
+                        * Disable bit 6 and 7 before entering D3 to
+                        * prevent system hang.
+                        */
+                       val &= ~(AR_WA_BIT6 | AR_WA_BIT7);
+               }
+
+               if (AR_SREV_9280(ah))
+                       val |= AR_WA_BIT22;
+
+               if (AR_SREV_9285E_20(ah))
+                       val |= AR_WA_BIT23;
+
+               REG_WRITE(ah, AR_WA, val);
+       } else {
+               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)) {
+                               /*
+                                * For AR9280 chips, bit 22 of 0x4004
+                                * needs to be set.
+                                */
+                               val = AR9280_WA_DEFAULT;
+                               if (!power_off)
+                                       val &= (~AR_WA_D3_L1_DISABLE);
+                       } else {
+                               val = AR_WA_DEFAULT;
+                       }
+               }
+
+               /* WAR for ASPM system hang */
+               if (AR_SREV_9285(ah) || AR_SREV_9287(ah))
+                       val |= (AR_WA_BIT6 | AR_WA_BIT7);
+
+               if (AR_SREV_9285E_20(ah))
+                       val |= AR_WA_BIT23;
+
+               REG_WRITE(ah, AR_WA, val);
+
+               /* 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);
+       }
+}
+
+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);
+
+       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:
+               DBG("ath9k: "
+                       "Radio Chip Rev 0x%02X not supported\n",
+                       val & AR_RADIO_SREV_MAJOR);
+               return -EOPNOTSUPP;
+       }
+
+       ah->hw_version.analog5GhzRev = val;
+
+       return 0;
+}
+
+void ar9002_hw_enable_async_fifo(struct ath_hw *ah)
+{
+       if (AR_SREV_9287_13_OR_LATER(ah)) {
+               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);
+       }
+}
+
+/*
+ * 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_update_async_fifo(struct ath_hw *ah)
+{
+       if (AR_SREV_9287_13_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_13_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;
+
+       ops->config_pci_powersave = ar9002_hw_configpcipowersave;
+
+       ar5008_hw_attach_phy_ops(ah);
+       if (AR_SREV_9280_20_OR_LATER(ah))
+               ar9002_hw_attach_phy_ops(ah);
+
+       ar9002_hw_attach_calib_ops(ah);
+       ar9002_hw_attach_mac_ops(ah);
+}
+
+void ar9002_hw_load_ani_reg(struct ath_hw *ah, struct ath9k_channel *chan)
+{
+       u32 modesIndex;
+       unsigned int i;
+
+       switch (chan->chanmode) {
+       case CHANNEL_A:
+       case CHANNEL_A_HT20:
+               modesIndex = 1;
+               break;
+       case CHANNEL_A_HT40PLUS:
+       case CHANNEL_A_HT40MINUS:
+               modesIndex = 2;
+               break;
+       case CHANNEL_G:
+       case CHANNEL_G_HT20:
+       case CHANNEL_B:
+               modesIndex = 4;
+               break;
+       case CHANNEL_G_HT40PLUS:
+       case CHANNEL_G_HT40MINUS:
+               modesIndex = 3;
+               break;
+
+       default:
+               return;
+       }
+
+       ENABLE_REGWRITE_BUFFER(ah);
+
+       for (i = 0; i < ah->iniModes_9271_ANI_reg.ia_rows; i++) {
+               u32 reg = INI_RA(&ah->iniModes_9271_ANI_reg, i, 0);
+               u32 val = INI_RA(&ah->iniModes_9271_ANI_reg, i, modesIndex);
+               u32 val_orig;
+
+               if (reg == AR_PHY_CCK_DETECT) {
+                       val_orig = REG_READ(ah, reg);
+                       val &= AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK;
+                       val_orig &= ~AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK;
+
+                       REG_WRITE(ah, reg, val|val_orig);
+               } else
+                       REG_WRITE(ah, reg, val);
+       }
+
+       REGWRITE_BUFFER_FLUSH(ah);
+}
diff --git a/src/drivers/net/ath/ath9k/ath9k_ar9002_mac.c b/src/drivers/net/ath/ath9k/ath9k_ar9002_mac.c
new file mode 100644 (file)
index 0000000..057756b
--- /dev/null
@@ -0,0 +1,454 @@
+/*
+ * Copyright (c) 2008-2011 Atheros Communications Inc.
+ *
+ * Modified for iPXE by Scott K Logan <logans@cottsay.net> July 2011
+ * Original from Linux kernel 3.0.1
+ *
+ * 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 <ipxe/io.h>
+
+#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 int 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;
+       int fatal_int = 0;
+
+       if (!AR_SREV_9100(ah) && (ah->ah_ier & AR_IER_ENABLE)) {
+               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 0;
+       } 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 0;
+               }
+
+               *masked = isr & ATH9K_INT_COMMON;
+
+               if (isr & (AR_ISR_RXMINTR | AR_ISR_RXINTM |
+                          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) {
+                       DBG("ath9k: "
+                               "receive FIFO overrun interrupt\n");
+               }
+
+               *masked |= mask2;
+       }
+
+       if (AR_SREV_9100(ah))
+               return 1;
+
+       if (isr & AR_ISR_GENTMR) {
+               u32 s5_s;
+
+               s5_s = REG_READ(ah, AR_ISR_S5_S);
+               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 ((s5_s & AR_ISR_S5_TIM_TIMER) &&
+                   !(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP))
+                       *masked |= ATH9K_INT_TIM_TIMER;
+       }
+
+       if (sync_cause) {
+               fatal_int =
+                       (sync_cause &
+                        (AR_INTR_SYNC_HOST1_FATAL | AR_INTR_SYNC_HOST1_PERR))
+                       ? 1 : 0;
+
+               if (fatal_int) {
+                       if (sync_cause & AR_INTR_SYNC_HOST1_FATAL) {
+                               DBG("ath9k: "
+                                       "received PCI FATAL interrupt\n");
+                       }
+                       if (sync_cause & AR_INTR_SYNC_HOST1_PERR) {
+                               DBG("ath9k: "
+                                       "received PCI PERR interrupt\n");
+                       }
+                       *masked |= ATH9K_INT_FATAL;
+               }
+               if (sync_cause & AR_INTR_SYNC_RADM_CPL_TIMEOUT) {
+                       DBG("ath9k: "
+                               "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) {
+                       DBG("ath9k: "
+                               "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 1;
+}
+
+static void ar9002_hw_fill_txdesc(struct ath_hw *ah __unused, void *ds, u32 seglen,
+                                 int is_firstseg, int is_lastseg,
+                                 const void *ds0, u32 buf_addr,
+                                 unsigned int qcu __unused)
+{
+       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);
+       u32 status;
+
+       status = *(volatile typeof(ads->ds_txstatus9) *)&(ads->ds_txstatus9);
+       if ((status & AR_TxDone) == 0)
+               return -EINPROGRESS;
+
+       ts->ts_tstamp = ads->AR_SendTimestamp;
+       ts->ts_status = 0;
+       ts->ts_flags = 0;
+
+       if (status & AR_TxOpExceeded)
+               ts->ts_status |= ATH9K_TXERR_XTXOP;
+       ts->tid = MS(status, AR_TxTid);
+       ts->ts_rateindex = MS(status, AR_FinalTxIdx);
+       ts->ts_seqnum = MS(status, AR_SeqNum);
+
+       status = *(volatile typeof(ads->ds_txstatus0) *)&(ads->ds_txstatus0);
+       ts->ts_rssi_ctl0 = MS(status, AR_TxRSSIAnt00);
+       ts->ts_rssi_ctl1 = MS(status, AR_TxRSSIAnt01);
+       ts->ts_rssi_ctl2 = MS(status, AR_TxRSSIAnt02);
+       if (status & AR_TxBaStatus) {
+               ts->ts_flags |= ATH9K_TX_BA;
+               ts->ba_low = ads->AR_BaBitmapLow;
+               ts->ba_high = ads->AR_BaBitmapHigh;
+       }
+
+       status = *(volatile typeof(ads->ds_txstatus1) *)&(ads->ds_txstatus1);
+       if (status & AR_FrmXmitOK)
+               ts->ts_status |= ATH9K_TX_ACKED;
+       else {
+               if (status & AR_ExcessiveRetries)
+                       ts->ts_status |= ATH9K_TXERR_XRETRY;
+               if (status & AR_Filtered)
+                       ts->ts_status |= ATH9K_TXERR_FILT;
+               if (status & AR_FIFOUnderrun) {
+                       ts->ts_status |= ATH9K_TXERR_FIFO;
+                       ath9k_hw_updatetxtriglevel(ah, 1);
+               }
+       }
+       if (status & AR_TxTimerExpired)
+               ts->ts_status |= ATH9K_TXERR_TIMER_EXPIRED;
+       if (status & AR_DescCfgErr)
+               ts->ts_flags |= ATH9K_TX_DESC_CFG_ERR;
+       if (status & AR_TxDataUnderrun) {
+               ts->ts_flags |= ATH9K_TX_DATA_UNDERRUN;
+               ath9k_hw_updatetxtriglevel(ah, 1);
+       }
+       if (status & AR_TxDelimUnderrun) {
+               ts->ts_flags |= ATH9K_TX_DELIM_UNDERRUN;
+               ath9k_hw_updatetxtriglevel(ah, 1);
+       }
+       ts->ts_shortretry = MS(status, AR_RTSFailCnt);
+       ts->ts_longretry = MS(status, AR_DataFailCnt);
+       ts->ts_virtcol = MS(status, AR_VirtRetryCnt);
+
+       status = *(volatile typeof(ads->ds_txstatus5) *)&(ads->ds_txstatus5);
+       ts->ts_rssi = MS(status, AR_TxRSSICombined);
+       ts->ts_rssi_ext0 = MS(status, AR_TxRSSIAnt10);
+       ts->ts_rssi_ext1 = MS(status, AR_TxRSSIAnt11);
+       ts->ts_rssi_ext2 = MS(status, AR_TxRSSIAnt12);
+
+       ts->evm0 = ads->AR_TxEVM0;
+       ts->evm1 = ads->AR_TxEVM1;
+       ts->evm2 = ads->AR_TxEVM2;
+
+       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);
+
+       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_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_set_clrdmask(struct ath_hw *ah __unused, void *ds, int val)
+{
+       struct ar5416_desc *ads = AR5416DESC(ds);
+
+       if (val)
+               ads->ds_ctl0 |= AR_ClrDestMask;
+       else
+               ads->ds_ctl0 &= ~AR_ClrDestMask;
+}
+
+static void ar9002_hw_set11n_ratescenario(struct ath_hw *ah __unused, void *ds,
+                                         void *lastds,
+                                         u32 durUpdateEn, u32 rtsctsRate,
+                                         u32 rtsctsDuration __unused,
+                                         struct ath9k_11n_rate_series series[],
+                                         u32 nseries __unused, 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 __unused, 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 __unused, 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 __unused, 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 __unused, void *ds)
+{
+       struct ar5416_desc *ads = AR5416DESC(ds);
+
+       ads->ds_ctl1 &= (~AR_IsAggr & ~AR_MoreAggr);
+}
+
+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));
+}
+
+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->set_clrdmask = ar9002_hw_set_clrdmask;
+}
diff --git a/src/drivers/net/ath/ath9k/ath9k_ar9002_phy.c b/src/drivers/net/ath/ath9k/ath9k_ar9002_phy.c
new file mode 100644 (file)
index 0000000..72203ba
--- /dev/null
@@ -0,0 +1,578 @@
+/*
+ * Copyright (c) 2008-2011 Atheros Communications Inc.
+ *
+ * Modified for iPXE by Scott K Logan <logans@cottsay.net> July 2011
+ * Original from Linux kernel 3.0.1
+ *
+ * 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 <ipxe/io.h>
+
+#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;
+               unsigned 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;
+       static const int pilot_mask_reg[4] = {
+               AR_PHY_TIMING7, AR_PHY_TIMING8,
+               AR_PHY_PILOT_MASK_01_30, AR_PHY_PILOT_MASK_31_60
+       };
+       static const int chan_mask_reg[4] = {
+               AR_PHY_TIMING9, AR_PHY_TIMING10,
+               AR_PHY_CHANNEL_MASK_01_30, AR_PHY_CHANNEL_MASK_31_60
+       };
+       static const 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;
+       int 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 (AR_NO_SPUR == cur_bb_spur)
+                       break;
+
+               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;
+
+               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);
+}
+
+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)) {
+               if (IS_CHAN_A_FAST_CLOCK(ah, chan))
+                       pll = 0x142c;
+               else if (AR_SREV_9280_20(ah))
+                       pll = 0x2850;
+               else
+                       pll |= SM(0x28, AR_RTC_9160_PLL_DIV);
+       } 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])
+{
+       int16_t nf;
+
+       nf = MS(REG_READ(ah, AR_PHY_CCA), AR9280_PHY_MINCCA_PWR);
+       nfarray[0] = sign_extend32(nf, 8);
+
+       nf = MS(REG_READ(ah, AR_PHY_EXT_CCA), AR9280_PHY_EXT_MINCCA_PWR);
+       if (IS_CHAN_HT40(ah->curchan))
+               nfarray[3] = sign_extend32(nf, 8);
+
+       if (AR_SREV_9285(ah) || AR_SREV_9271(ah))
+               return;
+
+       nf = MS(REG_READ(ah, AR_PHY_CH1_CCA), AR9280_PHY_CH1_MINCCA_PWR);
+       nfarray[1] = sign_extend32(nf, 8);
+
+       nf = MS(REG_READ(ah, AR_PHY_CH1_EXT_CCA), AR9280_PHY_CH1_EXT_MINCCA_PWR);
+       if (IS_CHAN_HT40(ah->curchan))
+               nfarray[4] = sign_extend32(nf, 8);
+}
+
+static void ar9002_hw_set_nf_limits(struct ath_hw *ah)
+{
+       if (AR_SREV_9285(ah)) {
+               ah->nf_2g.max = AR_PHY_CCA_MAX_GOOD_VAL_9285_2GHZ;
+               ah->nf_2g.min = AR_PHY_CCA_MIN_GOOD_VAL_9285_2GHZ;
+               ah->nf_2g.nominal = AR_PHY_CCA_NOM_VAL_9285_2GHZ;
+       } else if (AR_SREV_9287(ah)) {
+               ah->nf_2g.max = AR_PHY_CCA_MAX_GOOD_VAL_9287_2GHZ;
+               ah->nf_2g.min = AR_PHY_CCA_MIN_GOOD_VAL_9287_2GHZ;
+               ah->nf_2g.nominal = AR_PHY_CCA_NOM_VAL_9287_2GHZ;
+       } else if (AR_SREV_9271(ah)) {
+               ah->nf_2g.max = AR_PHY_CCA_MAX_GOOD_VAL_9271_2GHZ;
+               ah->nf_2g.min = AR_PHY_CCA_MIN_GOOD_VAL_9271_2GHZ;
+               ah->nf_2g.nominal = AR_PHY_CCA_NOM_VAL_9271_2GHZ;
+       } else {
+               ah->nf_2g.max = AR_PHY_CCA_MAX_GOOD_VAL_9280_2GHZ;
+               ah->nf_2g.min = AR_PHY_CCA_MIN_GOOD_VAL_9280_2GHZ;
+               ah->nf_2g.nominal = AR_PHY_CCA_NOM_VAL_9280_2GHZ;
+               ah->nf_5g.max = AR_PHY_CCA_MAX_GOOD_VAL_9280_5GHZ;
+               ah->nf_5g.min = AR_PHY_CCA_MIN_GOOD_VAL_9280_5GHZ;
+               ah->nf_5g.nominal = AR_PHY_CCA_NOM_VAL_9280_5GHZ;
+       }
+}
+
+static void ar9002_hw_antdiv_comb_conf_get(struct ath_hw *ah,
+                                  struct ath_hw_antcomb_conf *antconf)
+{
+       u32 regval;
+
+       regval = REG_READ(ah, AR_PHY_MULTICHAIN_GAIN_CTL);
+       antconf->main_lna_conf = (regval & AR_PHY_9285_ANT_DIV_MAIN_LNACONF) >>
+                                 AR_PHY_9285_ANT_DIV_MAIN_LNACONF_S;
+       antconf->alt_lna_conf = (regval & AR_PHY_9285_ANT_DIV_ALT_LNACONF) >>
+                                AR_PHY_9285_ANT_DIV_ALT_LNACONF_S;
+       antconf->fast_div_bias = (regval & AR_PHY_9285_FAST_DIV_BIAS) >>
+                                 AR_PHY_9285_FAST_DIV_BIAS_S;
+       antconf->lna1_lna2_delta = -3;
+       antconf->div_group = 0;
+}
+
+static void ar9002_hw_antdiv_comb_conf_set(struct ath_hw *ah,
+                                  struct ath_hw_antcomb_conf *antconf)
+{
+       u32 regval;
+
+       regval = REG_READ(ah, AR_PHY_MULTICHAIN_GAIN_CTL);
+       regval &= ~(AR_PHY_9285_ANT_DIV_MAIN_LNACONF |
+                   AR_PHY_9285_ANT_DIV_ALT_LNACONF |
+                   AR_PHY_9285_FAST_DIV_BIAS);
+       regval |= ((antconf->main_lna_conf << AR_PHY_9285_ANT_DIV_MAIN_LNACONF_S)
+                  & AR_PHY_9285_ANT_DIV_MAIN_LNACONF);
+       regval |= ((antconf->alt_lna_conf << AR_PHY_9285_ANT_DIV_ALT_LNACONF_S)
+                  & AR_PHY_9285_ANT_DIV_ALT_LNACONF);
+       regval |= ((antconf->fast_div_bias << AR_PHY_9285_FAST_DIV_BIAS_S)
+                  & AR_PHY_9285_FAST_DIV_BIAS);
+
+       REG_WRITE(ah, AR_PHY_MULTICHAIN_GAIN_CTL, regval);
+}
+
+void ar9002_hw_attach_phy_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->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;
+
+       ops->antdiv_comb_conf_get = ar9002_hw_antdiv_comb_conf_get;
+       ops->antdiv_comb_conf_set = ar9002_hw_antdiv_comb_conf_set;
+
+       ar9002_hw_set_nf_limits(ah);
+}
diff --git a/src/drivers/net/ath/ath9k/ath9k_ar9003_calib.c b/src/drivers/net/ath/ath9k/ath9k_ar9003_calib.c
new file mode 100644 (file)
index 0000000..c37168b
--- /dev/null
@@ -0,0 +1,932 @@
+/*
+ * Copyright (c) 2010-2011 Atheros Communications Inc.
+ *
+ * Modified for iPXE by Scott K Logan <logans@cottsay.net> July 2011
+ * Original from Linux kernel 3.0.1
+ *
+ * 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 <ipxe/io.h>
+
+#include "hw.h"
+#include "hw-ops.h"
+#include "ar9003_phy.h"
+
+#define MAX_MEASUREMENT        8
+#define MAX_MAG_DELTA  11
+#define MAX_PHS_DELTA  10
+
+struct coeff {
+       int mag_coeff[AR9300_MAX_CHAINS][MAX_MEASUREMENT];
+       int phs_coeff[AR9300_MAX_CHAINS][MAX_MEASUREMENT];
+       int iqc_coeff[2];
+};
+
+enum ar9003_cal_types {
+       IQ_MISMATCH_CAL = BIT(0),
+       TEMP_COMP_CAL = BIT(1),
+};
+
+static void ar9003_hw_setup_calibration(struct ath_hw *ah,
+                                       struct ath9k_cal_list *currCal)
+{
+       /* 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);
+
+               DBG2("ath9k: "
+                       "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);
+
+               DBG2("ath9k: "
+                       "starting Temperature Compensation Calibration\n");
+               break;
+       }
+}
+
+/*
+ * Generic calibration routine.
+ * Recalibrate the lower PHY chips to account for temperature/environment
+ * changes.
+ */
+static int ar9003_hw_per_calibration(struct ath_hw *ah,
+                                     struct ath9k_channel *ichan __unused,
+                                     u8 rxchainmask,
+                                     struct ath9k_cal_list *currCal)
+{
+       struct ath9k_hw_cal_data *caldata = ah->caldata;
+       /* Cal is assumed not done until explicitly set below */
+       int iscaldone = 0;
+
+       /* 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. */
+                               caldata->CalValid |= currCal->calData->calType;
+                               currCal->calState = CAL_DONE;
+                               iscaldone = 1;
+                       } else {
+                       /*
+                        * Set-up collection of another sub-sample until we
+                        * get desired number
+                        */
+                       ar9003_hw_setup_calibration(ah, currCal);
+                       }
+               }
+       } else if (!(caldata->CalValid & currCal->calData->calType)) {
+               /* If current cal is marked invalid in channel, kick it off */
+               ath9k_hw_reset_calibration(ah, currCal);
+       }
+
+       return iscaldone;
+}
+
+static int ar9003_hw_calibrate(struct ath_hw *ah,
+                               struct ath9k_channel *chan,
+                               u8 rxchainmask,
+                               int longcal)
+{
+       int iscaldone = 1;
+       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 = 0;
+                               ath9k_hw_reset_calibration(ah, currCal);
+                       }
+               }
+       }
+
+       /* Do NF cal only at longer intervals */
+       if (longcal) {
+               /*
+                * 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);
+
+               /* start NF calibration, without updating BB NF register */
+               ath9k_hw_start_nfcal(ah, 0);
+       }
+
+       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++) {
+               if (ah->txchainmask & BIT(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));
+                       DBG2("ath9k: "
+                               "%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)
+{
+       u32 powerMeasQ, powerMeasI, iqCorrMeas;
+       u32 qCoffDenom, iCoffDenom;
+       int32_t qCoff, iCoff;
+       int iqCorrNeg, i;
+       static const uint32_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];
+
+               DBG2("ath9k: "
+                       "Starting IQ Cal and Correction for Chain %d\n",
+                       i);
+
+               DBG2("ath9k: "
+                       "Orignal: Chn %diq_corr_meas = 0x%08x\n",
+                       i, ah->totalIqCorrMeas[i]);
+
+               iqCorrNeg = 0;
+
+               if (iqCorrMeas > 0x80000000) {
+                       iqCorrMeas = (0xffffffff - iqCorrMeas) + 1;
+                       iqCorrNeg = 1;
+               }
+
+               DBG2("ath9k: "
+                       "Chn %d pwr_meas_i = 0x%08x\n", i, powerMeasI);
+               DBG2("ath9k: "
+                       "Chn %d pwr_meas_q = 0x%08x\n", i, powerMeasQ);
+               DBG2("ath9k: 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;
+                       DBG2("ath9k: "
+                               "Chn %d iCoff = 0x%08x\n", i, iCoff);
+                       DBG2("ath9k: "
+                               "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;
+
+                       DBG2("ath9k: "
+                               "Chn %d : iCoff = 0x%x  qCoff = 0x%x\n",
+                               i, iCoff, qCoff);
+                       DBG2("ath9k: "
+                               "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);
+                       DBG2("ath9k: "
+                               "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]));
+                       DBG2("ath9k: "
+                               "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]));
+
+                       DBG2("ath9k: "
+                               "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);
+       DBG2("ath9k: "
+               "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;
+}
+
+/*
+ * solve 4x4 linear equation used in loopback iq cal.
+ */
+static int ar9003_hw_solve_iq_cal(struct ath_hw *ah __unused,
+                                  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;
+
+       f2 = (f1 * f1 + f3 * f3) / result_shift;
+
+       if (!f2) {
+               DBG("ath9k: Divide by 0\n");
+               return 0;
+       }
+
+       /* 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 1;
+}
+
+static s32 ar9003_hw_find_mag_approx(struct ath_hw *ah __unused, 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 int 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;
+
+       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)) {
+               DBG("ath9k: "
+                       "Divide by 0:\n"
+                       "a0_d0=%d\n"
+                       "a0_d1=%d\n"
+                       "a2_d0=%d\n"
+                       "a1_d1=%d\n",
+                       i2_p_q2_a0_d0, i2_p_q2_a0_d1,
+                       i2_p_q2_a1_d0, i2_p_q2_a1_d1);
+               return 0;
+       }
+
+       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)) {
+               DBG("ath9k: "
+                       "Divide by 0: mag1=%d, mag2=%d\n",
+                       mag1, mag2);
+               return 0;
+       }
+
+       /* 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)) {
+               DBG("ath9k: "
+                       "Call to ar9003_hw_solve_iq_cal() failed.\n");
+               return 0;
+       }
+
+       mag_tx = solved_eq[0];
+       phs_tx = solved_eq[1];
+       mag_rx = solved_eq[2];
+       phs_rx = solved_eq[3];
+
+       DBG2("ath9k: "
+               "chain %d: mag mismatch=%d phase mismatch=%d\n",
+               chain_idx, mag_tx/res_scale, phs_tx/res_scale);
+
+       if (res_scale == mag_tx) {
+               DBG("ath9k: "
+                       "Divide by 0: mag_tx=%d, res_scale=%d\n",
+                       mag_tx, res_scale);
+               return 0;
+       }
+
+       /* 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);
+
+       DBG2("ath9k: "
+               "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;
+
+       DBG2("ath9k: "
+               "tx chain %d: iq corr coeff=%x\n",
+               chain_idx, iqc_coeff[0]);
+
+       if (-mag_rx == res_scale) {
+               DBG("ath9k: "
+                       "Divide by 0: mag_rx=%d, res_scale=%d\n",
+                       mag_rx, res_scale);
+               return 0;
+       }
+
+       /* 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);
+
+       DBG("ath9k: "
+               "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;
+
+       DBG2("ath9k: "
+               "rx chain %d: iq corr coeff=%x\n",
+               chain_idx, iqc_coeff[1]);
+
+       return 1;
+}
+
+static void ar9003_hw_detect_outlier(int *mp_coeff, int nmeasurement,
+                                    int max_delta)
+{
+       int mp_max = -64, max_idx = 0;
+       int mp_min = 63, min_idx = 0;
+       int mp_avg = 0, i, outlier_idx = 0;
+
+       /* find min/max mismatch across all calibrated gains */
+       for (i = 0; i < nmeasurement; i++) {
+               mp_avg += mp_coeff[i];
+               if (mp_coeff[i] > mp_max) {
+                       mp_max = mp_coeff[i];
+                       max_idx = i;
+               } else if (mp_coeff[i] < mp_min) {
+                       mp_min = mp_coeff[i];
+                       min_idx = i;
+               }
+       }
+
+       /* find average (exclude max abs value) */
+       for (i = 0; i < nmeasurement; i++) {
+               if ((abs(mp_coeff[i]) < abs(mp_max)) ||
+                   (abs(mp_coeff[i]) < abs(mp_min)))
+                       mp_avg += mp_coeff[i];
+       }
+       mp_avg /= (nmeasurement - 1);
+
+       /* detect outlier */
+       if (abs(mp_max - mp_min) > max_delta) {
+               if (abs(mp_max - mp_avg) > abs(mp_min - mp_avg))
+                       outlier_idx = max_idx;
+               else
+                       outlier_idx = min_idx;
+       }
+       mp_coeff[outlier_idx] = mp_avg;
+}
+
+static void ar9003_hw_tx_iqcal_load_avg_2_passes(struct ath_hw *ah,
+                                                u8 num_chains,
+                                                struct coeff *coeff)
+{
+       int i, im, nmeasurement;
+       u32 tx_corr_coeff[MAX_MEASUREMENT][AR9300_MAX_CHAINS];
+
+       memset(tx_corr_coeff, 0, sizeof(tx_corr_coeff));
+       for (i = 0; i < MAX_MEASUREMENT / 2; i++) {
+               tx_corr_coeff[i * 2][0] = tx_corr_coeff[(i * 2) + 1][0] =
+                                       AR_PHY_TX_IQCAL_CORR_COEFF_B0(i);
+               if (!AR_SREV_9485(ah)) {
+                       tx_corr_coeff[i * 2][1] =
+                       tx_corr_coeff[(i * 2) + 1][1] =
+                                       AR_PHY_TX_IQCAL_CORR_COEFF_B1(i);
+
+                       tx_corr_coeff[i * 2][2] =
+                       tx_corr_coeff[(i * 2) + 1][2] =
+                                       AR_PHY_TX_IQCAL_CORR_COEFF_B2(i);
+               }
+       }
+
+       /* Load the average of 2 passes */
+       for (i = 0; i < num_chains; i++) {
+               nmeasurement = REG_READ_FIELD(ah,
+                               AR_PHY_TX_IQCAL_STATUS_B0,
+                               AR_PHY_CALIBRATED_GAINS_0);
+
+               if (nmeasurement > MAX_MEASUREMENT)
+                       nmeasurement = MAX_MEASUREMENT;
+
+               /* detect outlier only if nmeasurement > 1 */
+               if (nmeasurement > 1) {
+                       /* Detect magnitude outlier */
+                       ar9003_hw_detect_outlier(coeff->mag_coeff[i],
+                                       nmeasurement, MAX_MAG_DELTA);
+
+                       /* Detect phase outlier */
+                       ar9003_hw_detect_outlier(coeff->phs_coeff[i],
+                                       nmeasurement, MAX_PHS_DELTA);
+               }
+
+               for (im = 0; im < nmeasurement; im++) {
+
+                       coeff->iqc_coeff[0] = (coeff->mag_coeff[i][im] & 0x7f) |
+                               ((coeff->phs_coeff[i][im] & 0x7f) << 7);
+
+                       if ((im % 2) == 0)
+                               REG_RMW_FIELD(ah, tx_corr_coeff[im][i],
+                                       AR_PHY_TX_IQCAL_CORR_COEFF_00_COEFF_TABLE,
+                                       coeff->iqc_coeff[0]);
+                       else
+                               REG_RMW_FIELD(ah, tx_corr_coeff[im][i],
+                                       AR_PHY_TX_IQCAL_CORR_COEFF_01_COEFF_TABLE,
+                                       coeff->iqc_coeff[0]);
+               }
+       }
+
+       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;
+
+}
+
+static int ar9003_hw_tx_iq_cal_run(struct ath_hw *ah)
+{
+       u8 tx_gain_forced;
+
+       tx_gain_forced = REG_READ_FIELD(ah, AR_PHY_TX_FORCED_GAIN,
+                                       AR_PHY_TXGAIN_FORCE);
+       if (tx_gain_forced)
+               REG_RMW_FIELD(ah, AR_PHY_TX_FORCED_GAIN,
+                             AR_PHY_TXGAIN_FORCE, 0);
+
+       REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_START,
+                     AR_PHY_TX_IQCAL_START_DO_CAL, 1);
+
+       if (!ath9k_hw_wait(ah, AR_PHY_TX_IQCAL_START,
+                       AR_PHY_TX_IQCAL_START_DO_CAL, 0,
+                       AH_WAIT_TIMEOUT)) {
+               DBG2("ath9k: "
+                       "Tx IQ Cal is not completed.\n");
+               return 0;
+       }
+       return 1;
+}
+
+static void ar9003_hw_tx_iq_cal_post_proc(struct ath_hw *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 uint32_t chan_info_tab[] = {
+               AR_PHY_CHAN_INFO_TAB_0,
+               AR_PHY_CHAN_INFO_TAB_1,
+               AR_PHY_CHAN_INFO_TAB_2,
+       };
+       struct coeff coeff;
+       s32 iq_res[6];
+       u8 num_chains = 0;
+       int i, im, j;
+       int nmeasurement;
+
+       for (i = 0; i < AR9300_MAX_CHAINS; i++) {
+               if (ah->txchainmask & (1 << i))
+                       num_chains++;
+       }
+
+       for (i = 0; i < num_chains; i++) {
+               nmeasurement = REG_READ_FIELD(ah,
+                               AR_PHY_TX_IQCAL_STATUS_B0,
+                               AR_PHY_CALIBRATED_GAINS_0);
+               if (nmeasurement > MAX_MEASUREMENT)
+                       nmeasurement = MAX_MEASUREMENT;
+
+               for (im = 0; im < nmeasurement; im++) {
+                       DBG2("ath9k: "
+                               "Doing Tx IQ Cal for chain %d.\n", i);
+
+                       if (REG_READ(ah, txiqcal_status[i]) &
+                                       AR_PHY_TX_IQCAL_STATUS_FAILED) {
+                               DBG("ath9k: "
+                                       "Tx IQ Cal failed for chain %d.\n", i);
+                               goto tx_iqcal_fail;
+                       }
+
+                       for (j = 0; j < 3; j++) {
+                               u32 idx = 2 * j, offset = 4 * (3 * im + 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);
+
+                               DBG2("ath9k: "
+                                       "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,
+                                               coeff.iqc_coeff)) {
+                               DBG("ath9k: "
+                                       "Failed in calculation of \
+                                       IQ correction.\n");
+                               goto tx_iqcal_fail;
+                       }
+
+                       coeff.mag_coeff[i][im] = coeff.iqc_coeff[0] & 0x7f;
+                       coeff.phs_coeff[i][im] =
+                               (coeff.iqc_coeff[0] >> 7) & 0x7f;
+
+                       if (coeff.mag_coeff[i][im] > 63)
+                               coeff.mag_coeff[i][im] -= 128;
+                       if (coeff.phs_coeff[i][im] > 63)
+                               coeff.phs_coeff[i][im] -= 128;
+               }
+       }
+       ar9003_hw_tx_iqcal_load_avg_2_passes(ah, num_chains, &coeff);
+
+       return;
+
+tx_iqcal_fail:
+       DBG("ath9k: Tx IQ Cal failed\n");
+       return;
+}
+static int ar9003_hw_init_cal(struct ath_hw *ah,
+                              struct ath9k_channel *chan __unused)
+{
+       struct ath9k_hw_capabilities *pCap = &ah->caps;
+       int val;
+       int txiqcal_done = 0;
+
+       val = REG_READ(ah, AR_ENT_OTP);
+       DBG2("ath9k: ath9k: AR_ENT_OTP 0x%x\n", val);
+
+       /* Configure rx/tx chains before running AGC/TxiQ cals */
+       if (val & AR_ENT_OTP_CHAIN2_DISABLE)
+               ar9003_hw_set_chain_masks(ah, 0x3, 0x3);
+       else
+               ar9003_hw_set_chain_masks(ah, pCap->rx_chainmask,
+                                         pCap->tx_chainmask);
+
+       /* Do Tx IQ Calibration */
+       REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_1,
+                     AR_PHY_TX_IQCAL_CONTROL_1_IQCORR_I_Q_COFF_DELPT,
+                     DELPT);
+
+       /*
+        * For AR9485 or later chips, TxIQ cal runs as part of
+        * AGC calibration
+        */
+       if (AR_SREV_9485_OR_LATER(ah))
+               txiqcal_done = 1;
+       else {
+               txiqcal_done = ar9003_hw_tx_iq_cal_run(ah);
+               REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS);
+               udelay(5);
+               REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
+       }
+
+       /* 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)) {
+               DBG("ath9k: "
+                       "offset calibration failed to complete in 1ms; noisy environment?\n");
+               return 0;
+       }
+
+       if (txiqcal_done)
+               ar9003_hw_tx_iq_cal_post_proc(ah);
+
+       /* Revert chainmasks to their original values before NF cal */
+       ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask);
+
+       ath9k_hw_start_nfcal(ah, 1);
+
+       /* Initialize list pointers */
+       ah->cal_list = ah->cal_list_last = ah->cal_list_curr = NULL;
+       ah->supp_cals = IQ_MISMATCH_CAL;
+
+       if (ah->supp_cals & IQ_MISMATCH_CAL) {
+               INIT_CAL(&ah->iq_caldata);
+               INSERT_CAL(ah, &ah->iq_caldata);
+               DBG2("ath9k: "
+                       "enabling IQ Calibration.\n");
+       }
+
+       if (ah->supp_cals & TEMP_COMP_CAL) {
+               INIT_CAL(&ah->tempCompCalData);
+               INSERT_CAL(ah, &ah->tempCompCalData);
+               DBG2("ath9k: "
+                       "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);
+
+       if (ah->caldata)
+               ah->caldata->CalValid = 0;
+
+       return 1;
+}
+
+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;
+
+       ops->calibrate = ar9003_hw_calibrate;
+}
diff --git a/src/drivers/net/ath/ath9k/ath9k_ar9003_eeprom.c b/src/drivers/net/ath/ath9k/ath9k_ar9003_eeprom.c
new file mode 100644 (file)
index 0000000..95e54b9
--- /dev/null
@@ -0,0 +1,5005 @@
+/*
+ * Copyright (c) 2010-2011 Atheros Communications Inc.
+ *
+ * Modified for iPXE by Scott K Logan <logans@cottsay.net> July 2011
+ * Original from Linux kernel 3.0.1
+ *
+ * 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 <ipxe/io.h>
+#include <ipxe/malloc.h>
+
+#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 (0x300)
+#define AR_CH0_TOP_XPABIASLVL_S (8)
+
+#define AR_CH0_THERM (0x00016290)
+#define AR_CH0_THERM_XPABIASLVL_MSB 0x3
+#define AR_CH0_THERM_XPABIASLVL_MSB_S 0
+#define AR_CH0_THERM_XPASHORT2GND 0x4
+#define AR_CH0_THERM_XPASHORT2GND_S 2
+
+#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)
+
+#define LE16(x) (uint16_t)(x)
+#define LE32(x) (uint32_t)(x)
+
+/* Local defines to distinguish between extension and control CTL's */
+#define EXT_ADDITIVE (0x8000)
+#define CTL_11A_EXT (CTL_11A | EXT_ADDITIVE)
+#define CTL_11G_EXT (CTL_11G | EXT_ADDITIVE)
+#define CTL_11B_EXT (CTL_11B | EXT_ADDITIVE)
+#define REDUCE_SCALED_POWER_BY_TWO_CHAIN     6  /* 10*log10(2)*2 */
+#define REDUCE_SCALED_POWER_BY_THREE_CHAIN   9  /* 10*log10(3)*2 */
+#define PWRINCR_3_TO_1_CHAIN      9             /* 10*log(3)*2 */
+#define PWRINCR_3_TO_2_CHAIN      3             /* floor(10*log(3/2)*2) */
+#define PWRINCR_2_TO_1_CHAIN      6             /* 10*log(2)*2 */
+
+#define SUB_NUM_CTL_MODES_AT_5G_40 2    /* excluding HT40, EXT-OFDM */
+#define SUB_NUM_CTL_MODES_AT_2G_40 3    /* excluding HT40, EXT-OFDM, EXT-CCK */
+
+#define CTL(_tpower, _flag) ((_tpower) | ((_flag) << 6))
+
+#define EEPROM_DATA_LEN_9485   1088
+
+static int ar9003_hw_power_interpolate(int32_t x,
+                                      int32_t *px, int32_t *py, uint16_t np);
+
+
+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 = { LE16(0), LE16(0x1f) },
+               .txrxMask =  0x77, /* 4 bits tx and 4 bits rx */
+               .opCapFlags = {
+                       .opFlags = AR5416_OPFLAGS_11G | AR5416_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
+                 * bit5 - enable pa predistortion - 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 = LE32(0x110),
+               /* 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12 */
+               .antCtrlCommon2 = LE32(0x22222),
+
+               /*
+                * antCtrlChain[AR9300_MAX_CHAINS]; 6 idle, t, r,
+                * rx1, rx12, b (2 bits each)
+                */
+               .antCtrlChain = { LE16(0x150), LE16(0x150), LE16(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,
+               .papdRateMaskHt20 = LE32(0x0cf0e0e0),
+               .papdRateMaskHt40 = LE32(0x6cf0e0e0),
+               .futureModal = {
+                       0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+               },
+        },
+       .base_ext1 = {
+               .ant_div_control = 0,
+               .future = {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 = {
+                { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+                { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+                { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } },
+
+                { { CTL(60, 1), CTL(60, 0), CTL(0, 0), CTL(0, 0) } },
+                { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+                { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+
+                { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0) } },
+                { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+                { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+
+                { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+                { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
+                { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
+        },
+       .modalHeader5G = {
+               /* 4 idle,t1,t2,b (4 bits per setting) */
+               .antCtrlCommon = LE32(0x110),
+               /* 4 ra1l1, ra2l1, ra1l2,ra2l2,ra12 */
+               .antCtrlCommon2 = LE32(0x22222),
+                /* antCtrlChain 6 idle, t,r,rx1,rx12,b (2 bits each) */
+               .antCtrlChain = {
+                       LE16(0x000), LE16(0x000), LE16(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,
+               .papdRateMaskHt20 = LE32(0x0c80c080),
+               .papdRateMaskHt40 = LE32(0x0080c080),
+               .futureModal = {
+                       0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+               },
+        },
+       .base_ext2 = {
+               .tempSlopeLow = 0,
+               .tempSlopeHigh = 0,
+               .xatten1DBLow = {0, 0, 0},
+               .xatten1MarginLow = {0, 0, 0},
+               .xatten1DBHigh = {0, 0, 0},
+               .xatten1MarginHigh = {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},
+                               {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 = {
+               {
+                       {
+                               CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
+                               CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
+                       }
+               },
+               {
+                       {
+                               CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
+                               CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
+                       }
+               },
+               {
+                       {
+                               CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 1),
+                               CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
+                       }
+               },
+               {
+                       {
+                               CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0),
+                               CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
+                       }
+               },
+               {
+                       {
+                               CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
+                               CTL(60, 0), CTL(60, 0), CTL(60, 0), CTL(60, 0),
+                       }
+               },
+               {
+                       {
+                               CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
+                               CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
+                       }
+               },
+               {
+                       {
+                               CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
+                               CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
+                       }
+               },
+               {
+                       {
+                               CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
+                               CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
+                       }
+               },
+               {
+                       {
+                               CTL(60, 1), CTL(60, 0), CTL(60, 1), CTL(60, 1),
+                               CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
+                       }
+               },
+        }
+};
+
+static const struct ar9300_eeprom ar9300_x113 = {
+       .eepromVersion = 2,
+       .templateVersion = 6,
+       .macAddr = {0x00, 0x03, 0x7f, 0x0, 0x0, 0x0},
+       .custData = {"x113-023-f0000"},
+       .baseEepHeader = {
+               .regDmn = { LE16(0), LE16(0x1f) },
+               .txrxMask =  0x77, /* 4 bits tx and 4 bits rx */
+               .opCapFlags = {
+                       .opFlags = AR5416_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 = 0x0d,
+                /*
+                 * 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
+                 * bit5 - enable pa predistortion - disabled
+                 */
+               .miscConfiguration = 0, /* bit0 - turn down drivestrength */
+               .eepromWriteEnableGpio = 6,
+               .wlanDisableGpio = 0,
+               .wlanLedGpio = 8,
+               .rxBandSelectGpio = 0xff,
+               .txrxgain = 0x21,
+               .swreg = 0,
+        },
+       .modalHeader2G = {
+       /* ar9300_modal_eep_header  2g */
+               /* 4 idle,t1,t2,b(4 bits per setting) */
+               .antCtrlCommon = LE32(0x110),
+               /* 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12 */
+               .antCtrlCommon2 = LE32(0x44444),
+
+               /*
+                * antCtrlChain[AR9300_MAX_CHAINS]; 6 idle, t, r,
+                * rx1, rx12, b (2 bits each)
+                */
+               .antCtrlChain = { LE16(0x150), LE16(0x150), LE16(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 = 25,
+               .voltSlope = 0,
+
+               /*
+                * spurChans[OSPREY_EEPROM_MODAL_SPURS]; spur
+                * channels in usual fbin coding format
+                */
+               .spurChans = {FREQ2FBIN(2464, 1), 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,
+               .papdRateMaskHt20 = LE32(0x0c80c080),
+               .papdRateMaskHt40 = LE32(0x0080c080),
+               .futureModal = {
+                       0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+               },
+        },
+        .base_ext1 = {
+               .ant_div_control = 0,
+               .future = {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(2472, 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 */
+                { {34, 34, 34, 34} },
+                { {34, 34, 34, 34} },
+       },
+       .calTargetPower2G = {
+                /* 6-24,36,48,54 */
+                { {34, 34, 32, 32} },
+                { {34, 34, 32, 32} },
+                { {34, 34, 32, 32} },
+       },
+       .calTargetPower2GHT20 = {
+               { {32, 32, 32, 32, 32, 28, 32, 32, 30, 28, 0, 0, 0, 0} },
+               { {32, 32, 32, 32, 32, 28, 32, 32, 30, 28, 0, 0, 0, 0} },
+               { {32, 32, 32, 32, 32, 28, 32, 32, 30, 28, 0, 0, 0, 0} },
+       },
+       .calTargetPower2GHT40 = {
+               { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 0, 0, 0, 0} },
+               { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 0, 0, 0, 0} },
+               { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 0, 0, 0, 0} },
+       },
+       .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 = {
+                { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+                { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+                { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } },
+
+                { { CTL(60, 1), CTL(60, 0), CTL(0, 0), CTL(0, 0) } },
+                { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+                { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+
+                { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0) } },
+                { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+                { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+
+                { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+                { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
+                { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
+        },
+       .modalHeader5G = {
+               /* 4 idle,t1,t2,b (4 bits per setting) */
+               .antCtrlCommon = LE32(0x220),
+               /* 4 ra1l1, ra2l1, ra1l2,ra2l2,ra12 */
+               .antCtrlCommon2 = LE32(0x11111),
+                /* antCtrlChain 6 idle, t,r,rx1,rx12,b (2 bits each) */
+               .antCtrlChain = {
+                       LE16(0x150), LE16(0x150), LE16(0x150),
+               },
+                /* 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 = {FREQ2FBIN(5500, 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 = 0xf,
+               .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,
+               .papdRateMaskHt20 = LE32(0x0cf0e0e0),
+               .papdRateMaskHt40 = LE32(0x6cf0e0e0),
+               .futureModal = {
+                       0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+               },
+        },
+       .base_ext2 = {
+               .tempSlopeLow = 72,
+               .tempSlopeHigh = 105,
+               .xatten1DBLow = {0, 0, 0},
+               .xatten1MarginLow = {0, 0, 0},
+               .xatten1DBHigh = {0, 0, 0},
+               .xatten1MarginHigh = {0, 0, 0}
+        },
+       .calFreqPier5G = {
+               FREQ2FBIN(5180, 0),
+               FREQ2FBIN(5240, 0),
+               FREQ2FBIN(5320, 0),
+               FREQ2FBIN(5400, 0),
+               FREQ2FBIN(5500, 0),
+               FREQ2FBIN(5600, 0),
+               FREQ2FBIN(5745, 0),
+               FREQ2FBIN(5785, 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},
+                               {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(5745, 0),
+               FREQ2FBIN(5785, 0)
+       },
+       .calTarget_freqbin_5GHT20 = {
+               FREQ2FBIN(5180, 0),
+               FREQ2FBIN(5240, 0),
+               FREQ2FBIN(5320, 0),
+               FREQ2FBIN(5400, 0),
+               FREQ2FBIN(5500, 0),
+               FREQ2FBIN(5700, 0),
+               FREQ2FBIN(5745, 0),
+               FREQ2FBIN(5825, 0)
+       },
+       .calTarget_freqbin_5GHT40 = {
+               FREQ2FBIN(5190, 0),
+               FREQ2FBIN(5230, 0),
+               FREQ2FBIN(5320, 0),
+               FREQ2FBIN(5410, 0),
+               FREQ2FBIN(5510, 0),
+               FREQ2FBIN(5670, 0),
+               FREQ2FBIN(5755, 0),
+               FREQ2FBIN(5825, 0)
+        },
+       .calTargetPower5G = {
+               /* 6-24,36,48,54 */
+               { {42, 40, 40, 34} },
+               { {42, 40, 40, 34} },
+               { {42, 40, 40, 34} },
+               { {42, 40, 40, 34} },
+               { {42, 40, 40, 34} },
+               { {42, 40, 40, 34} },
+               { {42, 40, 40, 34} },
+               { {42, 40, 40, 34} },
+        },
+       .calTargetPower5GHT20 = {
+               /*
+                * 0_8_16,1-3_9-11_17-19,
+                * 4,5,6,7,12,13,14,15,20,21,22,23
+                */
+               { {40, 40, 40, 40, 32, 28, 40, 40, 32, 28, 40, 40, 32, 20} },
+               { {40, 40, 40, 40, 32, 28, 40, 40, 32, 28, 40, 40, 32, 20} },
+               { {40, 40, 40, 40, 32, 28, 40, 40, 32, 28, 40, 40, 32, 20} },
+               { {40, 40, 40, 40, 32, 28, 40, 40, 32, 28, 40, 40, 32, 20} },
+               { {40, 40, 40, 40, 32, 28, 40, 40, 32, 28, 40, 40, 32, 20} },
+               { {40, 40, 40, 40, 32, 28, 40, 40, 32, 28, 40, 40, 32, 20} },
+               { {38, 38, 38, 38, 32, 28, 38, 38, 32, 28, 38, 38, 32, 26} },
+               { {36, 36, 36, 36, 32, 28, 36, 36, 32, 28, 36, 36, 32, 26} },
+        },
+       .calTargetPower5GHT40 =  {
+               /*
+                * 0_8_16,1-3_9-11_17-19,
+                * 4,5,6,7,12,13,14,15,20,21,22,23
+                */
+               { {40, 40, 40, 38, 30, 26, 40, 40, 30, 26, 40, 40, 30, 24} },
+               { {40, 40, 40, 38, 30, 26, 40, 40, 30, 26, 40, 40, 30, 24} },
+               { {40, 40, 40, 38, 30, 26, 40, 40, 30, 26, 40, 40, 30, 24} },
+               { {40, 40, 40, 38, 30, 26, 40, 40, 30, 26, 40, 40, 30, 24} },
+               { {40, 40, 40, 38, 30, 26, 40, 40, 30, 26, 40, 40, 30, 24} },
+               { {40, 40, 40, 38, 30, 26, 40, 40, 30, 26, 40, 40, 30, 24} },
+               { {36, 36, 36, 36, 30, 26, 36, 36, 30, 26, 36, 36, 30, 24} },
+               { {34, 34, 34, 34, 30, 26, 34, 34, 30, 26, 34, 34, 30, 24} },
+        },
+       .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 = {
+               {
+                       {
+                               CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
+                               CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
+                       }
+               },
+               {
+                       {
+                               CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
+                               CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
+                       }
+               },
+               {
+                       {
+                               CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 1),
+                               CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
+                       }
+               },
+               {
+                       {
+                               CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0),
+                               CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
+                       }
+               },
+               {
+                       {
+                               CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
+                               CTL(60, 0), CTL(60, 0), CTL(60, 0), CTL(60, 0),
+                       }
+               },
+               {
+                       {
+                               CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
+                               CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
+                       }
+               },
+               {
+                       {
+                               CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
+                               CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
+                       }
+               },
+               {
+                       {
+                               CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
+                               CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
+                       }
+               },
+               {
+                       {
+                               CTL(60, 1), CTL(60, 0), CTL(60, 1), CTL(60, 1),
+                               CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
+                       }
+               },
+        }
+};
+
+
+static const struct ar9300_eeprom ar9300_h112 = {
+       .eepromVersion = 2,
+       .templateVersion = 3,
+       .macAddr = {0x00, 0x03, 0x7f, 0x0, 0x0, 0x0},
+       .custData = {"h112-241-f0000"},
+       .baseEepHeader = {
+               .regDmn = { LE16(0), LE16(0x1f) },
+               .txrxMask =  0x77, /* 4 bits tx and 4 bits rx */
+               .opCapFlags = {
+                       .opFlags = AR5416_OPFLAGS_11G | AR5416_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 = 0x0d,
+               /*
+                * 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
+                * bit5 - enable pa predistortion - disabled
+                */
+               .miscConfiguration = 0, /* bit0 - turn down drivestrength */
+               .eepromWriteEnableGpio = 6,
+               .wlanDisableGpio = 0,
+               .wlanLedGpio = 8,
+               .rxBandSelectGpio = 0xff,
+               .txrxgain = 0x10,
+               .swreg = 0,
+       },
+       .modalHeader2G = {
+               /* ar9300_modal_eep_header  2g */
+               /* 4 idle,t1,t2,b(4 bits per setting) */
+               .antCtrlCommon = LE32(0x110),
+               /* 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12 */
+               .antCtrlCommon2 = LE32(0x44444),
+
+               /*
+                * antCtrlChain[AR9300_MAX_CHAINS]; 6 idle, t, r,
+                * rx1, rx12, b (2 bits each)
+                */
+               .antCtrlChain = { LE16(0x150), LE16(0x150), LE16(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 = 25,
+               .voltSlope = 0,
+
+               /*
+                * spurChans[OSPREY_EEPROM_MODAL_SPURS]; spur
+                * channels in usual fbin coding format
+                */
+               .spurChans = {FREQ2FBIN(2464, 1), 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,
+               .papdRateMaskHt20 = LE32(0x80c080),
+               .papdRateMaskHt40 = LE32(0x80c080),
+               .futureModal = {
+                       0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+               },
+       },
+       .base_ext1 = {
+               .ant_div_control = 0,
+               .future = {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 */
+               { {34, 34, 34, 34} },
+               { {34, 34, 34, 34} },
+       },
+       .calTargetPower2G = {
+               /* 6-24,36,48,54 */
+               { {34, 34, 32, 32} },
+               { {34, 34, 32, 32} },
+               { {34, 34, 32, 32} },
+       },
+       .calTargetPower2GHT20 = {
+               { {32, 32, 32, 32, 32, 30, 32, 32, 30, 28, 28, 28, 28, 24} },
+               { {32, 32, 32, 32, 32, 30, 32, 32, 30, 28, 28, 28, 28, 24} },
+               { {32, 32, 32, 32, 32, 30, 32, 32, 30, 28, 28, 28, 28, 24} },
+       },
+       .calTargetPower2GHT40 = {
+               { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 26, 26, 26, 22} },
+               { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 26, 26, 26, 22} },
+               { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 26, 26, 26, 22} },
+       },
+       .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 = {
+               { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+               { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+               { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } },
+
+               { { CTL(60, 1), CTL(60, 0), CTL(0, 0), CTL(0, 0) } },
+               { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+               { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+
+               { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0) } },
+               { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+               { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+
+               { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+               { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
+               { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
+       },
+       .modalHeader5G = {
+               /* 4 idle,t1,t2,b (4 bits per setting) */
+               .antCtrlCommon = LE32(0x220),
+               /* 4 ra1l1, ra2l1, ra1l2,ra2l2,ra12 */
+               .antCtrlCommon2 = LE32(0x44444),
+               /* antCtrlChain 6 idle, t,r,rx1,rx12,b (2 bits each) */
+               .antCtrlChain = {
+                       LE16(0x150), LE16(0x150), LE16(0x150),
+               },
+               /* 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 = 45,
+               .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,
+               .papdRateMaskHt20 = LE32(0x0cf0e0e0),
+               .papdRateMaskHt40 = LE32(0x6cf0e0e0),
+               .futureModal = {
+                       0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+               },
+       },
+       .base_ext2 = {
+               .tempSlopeLow = 40,
+               .tempSlopeHigh = 50,
+               .xatten1DBLow = {0, 0, 0},
+               .xatten1MarginLow = {0, 0, 0},
+               .xatten1DBHigh = {0, 0, 0},
+               .xatten1MarginHigh = {0, 0, 0}
+       },
+       .calFreqPier5G = {
+               FREQ2FBIN(5180, 0),
+               FREQ2FBIN(5220, 0),
+               FREQ2FBIN(5320, 0),
+               FREQ2FBIN(5400, 0),
+               FREQ2FBIN(5500, 0),
+               FREQ2FBIN(5600, 0),
+               FREQ2FBIN(5700, 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},
+                       {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(5240, 0),
+               FREQ2FBIN(5320, 0),
+               FREQ2FBIN(5400, 0),
+               FREQ2FBIN(5500, 0),
+               FREQ2FBIN(5600, 0),
+               FREQ2FBIN(5700, 0),
+               FREQ2FBIN(5825, 0)
+       },
+       .calTarget_freqbin_5GHT20 = {
+               FREQ2FBIN(5180, 0),
+               FREQ2FBIN(5240, 0),
+               FREQ2FBIN(5320, 0),
+               FREQ2FBIN(5400, 0),
+               FREQ2FBIN(5500, 0),
+               FREQ2FBIN(5700, 0),
+               FREQ2FBIN(5745, 0),
+               FREQ2FBIN(5825, 0)
+       },
+       .calTarget_freqbin_5GHT40 = {
+               FREQ2FBIN(5180, 0),
+               FREQ2FBIN(5240, 0),
+               FREQ2FBIN(5320, 0),
+               FREQ2FBIN(5400, 0),
+               FREQ2FBIN(5500, 0),
+               FREQ2FBIN(5700, 0),
+               FREQ2FBIN(5745, 0),
+               FREQ2FBIN(5825, 0)
+       },
+       .calTargetPower5G = {
+               /* 6-24,36,48,54 */
+               { {30, 30, 28, 24} },
+               { {30, 30, 28, 24} },
+               { {30, 30, 28, 24} },
+               { {30, 30, 28, 24} },
+               { {30, 30, 28, 24} },
+               { {30, 30, 28, 24} },
+               { {30, 30, 28, 24} },
+               { {30, 30, 28, 24} },
+       },
+       .calTargetPower5GHT20 = {
+               /*
+                * 0_8_16,1-3_9-11_17-19,
+                * 4,5,6,7,12,13,14,15,20,21,22,23
+                */
+               { {30, 30, 30, 28, 24, 20, 30, 28, 24, 20, 20, 20, 20, 16} },
+               { {30, 30, 30, 28, 24, 20, 30, 28, 24, 20, 20, 20, 20, 16} },
+               { {30, 30, 30, 26, 22, 18, 30, 26, 22, 18, 18, 18, 18, 16} },
+               { {30, 30, 30, 26, 22, 18, 30, 26, 22, 18, 18, 18, 18, 16} },
+               { {30, 30, 30, 24, 20, 16, 30, 24, 20, 16, 16, 16, 16, 14} },
+               { {30, 30, 30, 24, 20, 16, 30, 24, 20, 16, 16, 16, 16, 14} },
+               { {30, 30, 30, 22, 18, 14, 30, 22, 18, 14, 14, 14, 14, 12} },
+               { {30, 30, 30, 22, 18, 14, 30, 22, 18, 14, 14, 14, 14, 12} },
+       },
+       .calTargetPower5GHT40 =  {
+               /*
+                * 0_8_16,1-3_9-11_17-19,
+                * 4,5,6,7,12,13,14,15,20,21,22,23
+                */
+               { {28, 28, 28, 26, 22, 18, 28, 26, 22, 18, 18, 18, 18, 14} },
+               { {28, 28, 28, 26, 22, 18, 28, 26, 22, 18, 18, 18, 18, 14} },
+               { {28, 28, 28, 24, 20, 16, 28, 24, 20, 16, 16, 16, 16, 12} },
+               { {28, 28, 28, 24, 20, 16, 28, 24, 20, 16, 16, 16, 16, 12} },
+               { {28, 28, 28, 22, 18, 14, 28, 22, 18, 14, 14, 14, 14, 10} },
+               { {28, 28, 28, 22, 18, 14, 28, 22, 18, 14, 14, 14, 14, 10} },
+               { {28, 28, 28, 20, 16, 12, 28, 20, 16, 12, 12, 12, 12, 8} },
+               { {28, 28, 28, 20, 16, 12, 28, 20, 16, 12, 12, 12, 12, 8} },
+       },
+       .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 = {
+               {
+                       {
+                               CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
+                               CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
+                       }
+               },
+               {
+                       {
+                               CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
+                               CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
+                       }
+               },
+               {
+                       {
+                               CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 1),
+                               CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
+                       }
+               },
+               {
+                       {
+                               CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0),
+                               CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
+                       }
+               },
+               {
+                       {
+                               CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
+                               CTL(60, 0), CTL(60, 0), CTL(60, 0), CTL(60, 0),
+                       }
+               },
+               {
+                       {
+                               CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
+                               CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
+                       }
+               },
+               {
+                       {
+                               CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
+                               CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
+                       }
+               },
+               {
+                       {
+                               CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
+                               CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
+                       }
+               },
+               {
+                       {
+                               CTL(60, 1), CTL(60, 0), CTL(60, 1), CTL(60, 1),
+                               CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
+                       }
+               },
+       }
+};
+
+
+static const struct ar9300_eeprom ar9300_x112 = {
+       .eepromVersion = 2,
+       .templateVersion = 5,
+       .macAddr = {0x00, 0x03, 0x7f, 0x0, 0x0, 0x0},
+       .custData = {"x112-041-f0000"},
+       .baseEepHeader = {
+               .regDmn = { LE16(0), LE16(0x1f) },
+               .txrxMask =  0x77, /* 4 bits tx and 4 bits rx */
+               .opCapFlags = {
+                       .opFlags = AR5416_OPFLAGS_11G | AR5416_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 = 0x0d,
+               /*
+                * 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
+                * bit5 - enable pa predistortion - disabled
+                */
+               .miscConfiguration = 0, /* bit0 - turn down drivestrength */
+               .eepromWriteEnableGpio = 6,
+               .wlanDisableGpio = 0,
+               .wlanLedGpio = 8,
+               .rxBandSelectGpio = 0xff,
+               .txrxgain = 0x0,
+               .swreg = 0,
+       },
+       .modalHeader2G = {
+               /* ar9300_modal_eep_header  2g */
+               /* 4 idle,t1,t2,b(4 bits per setting) */
+               .antCtrlCommon = LE32(0x110),
+               /* 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12 */
+               .antCtrlCommon2 = LE32(0x22222),
+
+               /*
+                * antCtrlChain[ar9300_max_chains]; 6 idle, t, r,
+                * rx1, rx12, b (2 bits each)
+                */
+               .antCtrlChain = { LE16(0x10), LE16(0x10), LE16(0x10) },
+
+               /*
+                * xatten1DB[AR9300_max_chains];  3 xatten1_db
+                * for ar9280 (0xa20c/b20c 5:0)
+                */
+               .xatten1DB = {0x1b, 0x1b, 0x1b},
+
+               /*
+                * xatten1Margin[ar9300_max_chains]; 3 xatten1_margin
+                * for ar9280 (0xa20c/b20c 16:12
+                */
+               .xatten1Margin = {0x15, 0x15, 0x15},
+               .tempSlope = 50,
+               .voltSlope = 0,
+
+               /*
+                * spurChans[OSPrey_eeprom_modal_sPURS]; spur
+                * channels in usual fbin coding format
+                */
+               .spurChans = {FREQ2FBIN(2464, 1), 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,
+               .papdRateMaskHt20 = LE32(0x0c80c080),
+               .papdRateMaskHt40 = LE32(0x0080c080),
+               .futureModal = {
+                       0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+               },
+       },
+       .base_ext1 = {
+               .ant_div_control = 0,
+               .future = {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(2472, 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 */
+               { {38, 38, 38, 38} },
+               { {38, 38, 38, 38} },
+       },
+       .calTargetPower2G = {
+               /* 6-24,36,48,54 */
+               { {38, 38, 36, 34} },
+               { {38, 38, 36, 34} },
+               { {38, 38, 34, 32} },
+       },
+       .calTargetPower2GHT20 = {
+               { {36, 36, 36, 36, 36, 34, 34, 32, 30, 28, 28, 28, 28, 26} },
+               { {36, 36, 36, 36, 36, 34, 36, 34, 32, 30, 30, 30, 28, 26} },
+               { {36, 36, 36, 36, 36, 34, 34, 32, 30, 28, 28, 28, 28, 26} },
+       },
+       .calTargetPower2GHT40 = {
+               { {36, 36, 36, 36, 34, 32, 32, 30, 28, 26, 26, 26, 26, 24} },
+               { {36, 36, 36, 36, 34, 32, 34, 32, 30, 28, 28, 28, 28, 24} },
+               { {36, 36, 36, 36, 34, 32, 32, 30, 28, 26, 26, 26, 26, 24} },
+       },
+       .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 = {
+               { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+               { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+               { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } },
+
+               { { CTL(60, 1), CTL(60, 0), CTL(0, 0), CTL(0, 0) } },
+               { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+               { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+
+               { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0) } },
+               { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+               { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+
+               { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+               { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
+               { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
+       },
+       .modalHeader5G = {
+               /* 4 idle,t1,t2,b (4 bits per setting) */
+               .antCtrlCommon = LE32(0x110),
+               /* 4 ra1l1, ra2l1, ra1l2,ra2l2,ra12 */
+               .antCtrlCommon2 = LE32(0x22222),
+               /* antCtrlChain 6 idle, t,r,rx1,rx12,b (2 bits each) */
+               .antCtrlChain = {
+                       LE16(0x0), LE16(0x0), LE16(0x0),
+               },
+               /* xatten1DB 3 xatten1_db for ar9280 (0xa20c/b20c 5:0) */
+               .xatten1DB = {0x13, 0x19, 0x17},
+
+               /*
+                * xatten1Margin[ar9300_max_chains]; 3 xatten1_margin
+                * for merlin (0xa20c/b20c 16:12
+                */
+               .xatten1Margin = {0x19, 0x19, 0x19},
+               .tempSlope = 70,
+               .voltSlope = 15,
+               /* 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,
+               .papdRateMaskHt20 = LE32(0x0cf0e0e0),
+               .papdRateMaskHt40 = LE32(0x6cf0e0e0),
+               .futureModal = {
+                       0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+               },
+       },
+       .base_ext2 = {
+               .tempSlopeLow = 72,
+               .tempSlopeHigh = 105,
+               .xatten1DBLow = {0x10, 0x14, 0x10},
+               .xatten1MarginLow = {0x19, 0x19 , 0x19},
+               .xatten1DBHigh = {0x1d, 0x20, 0x24},
+               .xatten1MarginHigh = {0x10, 0x10, 0x10}
+       },
+       .calFreqPier5G = {
+               FREQ2FBIN(5180, 0),
+               FREQ2FBIN(5220, 0),
+               FREQ2FBIN(5320, 0),
+               FREQ2FBIN(5400, 0),
+               FREQ2FBIN(5500, 0),
+               FREQ2FBIN(5600, 0),
+               FREQ2FBIN(5700, 0),
+               FREQ2FBIN(5785, 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},
+                       {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(5220, 0),
+               FREQ2FBIN(5320, 0),
+               FREQ2FBIN(5400, 0),
+               FREQ2FBIN(5500, 0),
+               FREQ2FBIN(5600, 0),
+               FREQ2FBIN(5725, 0),
+               FREQ2FBIN(5825, 0)
+       },
+       .calTarget_freqbin_5GHT40 = {
+               FREQ2FBIN(5180, 0),
+               FREQ2FBIN(5220, 0),
+               FREQ2FBIN(5320, 0),
+               FREQ2FBIN(5400, 0),
+               FREQ2FBIN(5500, 0),
+               FREQ2FBIN(5600, 0),
+               FREQ2FBIN(5725, 0),
+               FREQ2FBIN(5825, 0)
+       },
+       .calTargetPower5G = {
+               /* 6-24,36,48,54 */
+               { {32, 32, 28, 26} },
+               { {32, 32, 28, 26} },
+               { {32, 32, 28, 26} },
+               { {32, 32, 26, 24} },
+               { {32, 32, 26, 24} },
+               { {32, 32, 24, 22} },
+               { {30, 30, 24, 22} },
+               { {30, 30, 24, 22} },
+       },
+       .calTargetPower5GHT20 = {
+               /*
+                * 0_8_16,1-3_9-11_17-19,
+                * 4,5,6,7,12,13,14,15,20,21,22,23
+                */
+               { {32, 32, 32, 32, 28, 26, 32, 28, 26, 24, 24, 24, 22, 22} },
+               { {32, 32, 32, 32, 28, 26, 32, 28, 26, 24, 24, 24, 22, 22} },
+               { {32, 32, 32, 32, 28, 26, 32, 28, 26, 24, 24, 24, 22, 22} },
+               { {32, 32, 32, 32, 28, 26, 32, 26, 24, 22, 22, 22, 20, 20} },
+               { {32, 32, 32, 32, 28, 26, 32, 26, 24, 22, 20, 18, 16, 16} },
+               { {32, 32, 32, 32, 28, 26, 32, 24, 20, 16, 18, 16, 14, 14} },
+               { {30, 30, 30, 30, 28, 26, 30, 24, 20, 16, 18, 16, 14, 14} },
+               { {30, 30, 30, 30, 28, 26, 30, 24, 20, 16, 18, 16, 14, 14} },
+       },
+       .calTargetPower5GHT40 =  {
+               /*
+                * 0_8_16,1-3_9-11_17-19,
+                * 4,5,6,7,12,13,14,15,20,21,22,23
+                */
+               { {32, 32, 32, 30, 28, 26, 30, 28, 26, 24, 24, 24, 22, 22} },
+               { {32, 32, 32, 30, 28, 26, 30, 28, 26, 24, 24, 24, 22, 22} },
+               { {32, 32, 32, 30, 28, 26, 30, 28, 26, 24, 24, 24, 22, 22} },
+               { {32, 32, 32, 30, 28, 26, 30, 26, 24, 22, 22, 22, 20, 20} },
+               { {32, 32, 32, 30, 28, 26, 30, 26, 24, 22, 20, 18, 16, 16} },
+               { {32, 32, 32, 30, 28, 26, 30, 22, 20, 16, 18, 16, 14, 14} },
+               { {30, 30, 30, 30, 28, 26, 30, 22, 20, 16, 18, 16, 14, 14} },
+               { {30, 30, 30, 30, 28, 26, 30, 22, 20, 16, 18, 16, 14, 14} },
+       },
+       .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 = {
+               {
+                       {
+                               CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
+                               CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
+                       }
+               },
+               {
+                       {
+                               CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
+                               CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
+                       }
+               },
+               {
+                       {
+                               CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 1),
+                               CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
+                       }
+               },
+               {
+                       {
+                               CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0),
+                               CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
+                       }
+               },
+               {
+                       {
+                               CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
+                               CTL(60, 0), CTL(60, 0), CTL(60, 0), CTL(60, 0),
+                       }
+               },
+               {
+                       {
+                               CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
+                               CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
+                       }
+               },
+               {
+                       {
+                               CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
+                               CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
+                       }
+               },
+               {
+                       {
+                               CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
+                               CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
+                       }
+               },
+               {
+                       {
+                               CTL(60, 1), CTL(60, 0), CTL(60, 1), CTL(60, 1),
+                               CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
+                       }
+               },
+       }
+};
+
+static const struct ar9300_eeprom ar9300_h116 = {
+       .eepromVersion = 2,
+       .templateVersion = 4,
+       .macAddr = {0x00, 0x03, 0x7f, 0x0, 0x0, 0x0},
+       .custData = {"h116-041-f0000"},
+       .baseEepHeader = {
+               .regDmn = { LE16(0), LE16(0x1f) },
+               .txrxMask =  0x33, /* 4 bits tx and 4 bits rx */
+               .opCapFlags = {
+                       .opFlags = AR5416_OPFLAGS_11G | AR5416_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 = 0x0d,
+                /*
+                 * 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
+                 * bit5 - enable pa predistortion - disabled
+                 */
+               .miscConfiguration = 0, /* bit0 - turn down drivestrength */
+               .eepromWriteEnableGpio = 6,
+               .wlanDisableGpio = 0,
+               .wlanLedGpio = 8,
+               .rxBandSelectGpio = 0xff,
+               .txrxgain = 0x10,
+               .swreg = 0,
+        },
+       .modalHeader2G = {
+       /* ar9300_modal_eep_header  2g */
+               /* 4 idle,t1,t2,b(4 bits per setting) */
+               .antCtrlCommon = LE32(0x110),
+               /* 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12 */
+               .antCtrlCommon2 = LE32(0x44444),
+
+               /*
+                * antCtrlChain[AR9300_MAX_CHAINS]; 6 idle, t, r,
+                * rx1, rx12, b (2 bits each)
+                */
+               .antCtrlChain = { LE16(0x10), LE16(0x10), LE16(0x10) },
+
+               /*
+                * xatten1DB[AR9300_MAX_CHAINS];  3 xatten1_db
+                * for ar9280 (0xa20c/b20c 5:0)
+                */
+               .xatten1DB = {0x1f, 0x1f, 0x1f},
+
+               /*
+                * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
+                * for ar9280 (0xa20c/b20c 16:12
+                */
+               .xatten1Margin = {0x12, 0x12, 0x12},
+               .tempSlope = 25,
+               .voltSlope = 0,
+
+               /*
+                * spurChans[OSPREY_EEPROM_MODAL_SPURS]; spur
+                * channels in usual fbin coding format
+                */
+               .spurChans = {FREQ2FBIN(2464, 1), 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,
+               .papdRateMaskHt20 = LE32(0x0c80C080),
+               .papdRateMaskHt40 = LE32(0x0080C080),
+               .futureModal = {
+                       0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+               },
+        },
+        .base_ext1 = {
+               .ant_div_control = 0,
+               .future = {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(2472, 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 */
+                { {34, 34, 34, 34} },
+                { {34, 34, 34, 34} },
+       },
+       .calTargetPower2G = {
+                /* 6-24,36,48,54 */
+                { {34, 34, 32, 32} },
+                { {34, 34, 32, 32} },
+                { {34, 34, 32, 32} },
+       },
+       .calTargetPower2GHT20 = {
+               { {32, 32, 32, 32, 32, 30, 32, 32, 30, 28, 0, 0, 0, 0} },
+               { {32, 32, 32, 32, 32, 30, 32, 32, 30, 28, 0, 0, 0, 0} },
+               { {32, 32, 32, 32, 32, 30, 32, 32, 30, 28, 0, 0, 0, 0} },
+       },
+       .calTargetPower2GHT40 = {
+               { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 0, 0, 0, 0} },
+               { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 0, 0, 0, 0} },
+               { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 0, 0, 0, 0} },
+       },
+       .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 = {
+                { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+                { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+                { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } },
+
+                { { CTL(60, 1), CTL(60, 0), CTL(0, 0), CTL(0, 0) } },
+                { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+                { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+
+                { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0) } },
+                { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+                { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+
+                { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+                { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
+                { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
+        },
+       .modalHeader5G = {
+               /* 4 idle,t1,t2,b (4 bits per setting) */
+               .antCtrlCommon = LE32(0x220),
+               /* 4 ra1l1, ra2l1, ra1l2,ra2l2,ra12 */
+               .antCtrlCommon2 = LE32(0x44444),
+                /* antCtrlChain 6 idle, t,r,rx1,rx12,b (2 bits each) */
+               .antCtrlChain = {
+                       LE16(0x150), LE16(0x150), LE16(0x150),
+               },
+                /* xatten1DB 3 xatten1_db for AR9280 (0xa20c/b20c 5:0) */
+               .xatten1DB = {0x19, 0x19, 0x19},
+
+               /*
+                * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
+                * for merlin (0xa20c/b20c 16:12
+                */
+               .xatten1Margin = {0x14, 0x14, 0x14},
+               .tempSlope = 70,
+               .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,
+               .papdRateMaskHt20 = LE32(0x0cf0e0e0),
+               .papdRateMaskHt40 = LE32(0x6cf0e0e0),
+               .futureModal = {
+                       0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+               },
+        },
+       .base_ext2 = {
+               .tempSlopeLow = 35,
+               .tempSlopeHigh = 50,
+               .xatten1DBLow = {0, 0, 0},
+               .xatten1MarginLow = {0, 0, 0},
+               .xatten1DBHigh = {0, 0, 0},
+               .xatten1MarginHigh = {0, 0, 0}
+        },
+       .calFreqPier5G = {
+               FREQ2FBIN(5180, 0),
+               FREQ2FBIN(5220, 0),
+               FREQ2FBIN(5320, 0),
+               FREQ2FBIN(5400, 0),
+               FREQ2FBIN(5500, 0),
+               FREQ2FBIN(5600, 0),
+               FREQ2FBIN(5700, 0),
+               FREQ2FBIN(5785, 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},
+                               {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(5240, 0),
+               FREQ2FBIN(5320, 0),
+               FREQ2FBIN(5400, 0),
+               FREQ2FBIN(5500, 0),
+               FREQ2FBIN(5600, 0),
+               FREQ2FBIN(5700, 0),
+               FREQ2FBIN(5825, 0)
+       },
+       .calTarget_freqbin_5GHT20 = {
+               FREQ2FBIN(5180, 0),
+               FREQ2FBIN(5240, 0),
+               FREQ2FBIN(5320, 0),
+               FREQ2FBIN(5400, 0),
+               FREQ2FBIN(5500, 0),
+               FREQ2FBIN(5700, 0),
+               FREQ2FBIN(5745, 0),
+               FREQ2FBIN(5825, 0)
+       },
+       .calTarget_freqbin_5GHT40 = {
+               FREQ2FBIN(5180, 0),
+               FREQ2FBIN(5240, 0),
+               FREQ2FBIN(5320, 0),
+               FREQ2FBIN(5400, 0),
+               FREQ2FBIN(5500, 0),
+               FREQ2FBIN(5700, 0),
+               FREQ2FBIN(5745, 0),
+               FREQ2FBIN(5825, 0)
+        },
+       .calTargetPower5G = {
+               /* 6-24,36,48,54 */
+               { {30, 30, 28, 24} },
+               { {30, 30, 28, 24} },
+               { {30, 30, 28, 24} },
+               { {30, 30, 28, 24} },
+               { {30, 30, 28, 24} },
+               { {30, 30, 28, 24} },
+               { {30, 30, 28, 24} },
+               { {30, 30, 28, 24} },
+        },
+       .calTargetPower5GHT20 = {
+               /*
+                * 0_8_16,1-3_9-11_17-19,
+                * 4,5,6,7,12,13,14,15,20,21,22,23
+                */
+               { {30, 30, 30, 28, 24, 20, 30, 28, 24, 20, 0, 0, 0, 0} },
+               { {30, 30, 30, 28, 24, 20, 30, 28, 24, 20, 0, 0, 0, 0} },
+               { {30, 30, 30, 26, 22, 18, 30, 26, 22, 18, 0, 0, 0, 0} },
+               { {30, 30, 30, 26, 22, 18, 30, 26, 22, 18, 0, 0, 0, 0} },
+               { {30, 30, 30, 24, 20, 16, 30, 24, 20, 16, 0, 0, 0, 0} },
+               { {30, 30, 30, 24, 20, 16, 30, 24, 20, 16, 0, 0, 0, 0} },
+               { {30, 30, 30, 22, 18, 14, 30, 22, 18, 14, 0, 0, 0, 0} },
+               { {30, 30, 30, 22, 18, 14, 30, 22, 18, 14, 0, 0, 0, 0} },
+        },
+       .calTargetPower5GHT40 =  {
+               /*
+                * 0_8_16,1-3_9-11_17-19,
+                * 4,5,6,7,12,13,14,15,20,21,22,23
+                */
+               { {28, 28, 28, 26, 22, 18, 28, 26, 22, 18, 0, 0, 0, 0} },
+               { {28, 28, 28, 26, 22, 18, 28, 26, 22, 18, 0, 0, 0, 0} },
+               { {28, 28, 28, 24, 20, 16, 28, 24, 20, 16, 0, 0, 0, 0} },
+               { {28, 28, 28, 24, 20, 16, 28, 24, 20, 16, 0, 0, 0, 0} },
+               { {28, 28, 28, 22, 18, 14, 28, 22, 18, 14, 0, 0, 0, 0} },
+               { {28, 28, 28, 22, 18, 14, 28, 22, 18, 14, 0, 0, 0, 0} },
+               { {28, 28, 28, 20, 16, 12, 28, 20, 16, 12, 0, 0, 0, 0} },
+               { {28, 28, 28, 20, 16, 12, 28, 20, 16, 12, 0, 0, 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 = {
+               {
+                       {
+                               CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
+                               CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
+                       }
+               },
+               {
+                       {
+                               CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
+                               CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
+                       }
+               },
+               {
+                       {
+                               CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 1),
+                               CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
+                       }
+               },
+               {
+                       {
+                               CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0),
+                               CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
+                       }
+               },
+               {
+                       {
+                               CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
+                               CTL(60, 0), CTL(60, 0), CTL(60, 0), CTL(60, 0),
+                       }
+               },
+               {
+                       {
+                               CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
+                               CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
+                       }
+               },
+               {
+                       {
+                               CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
+                               CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
+                       }
+               },
+               {
+                       {
+                               CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
+                               CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
+                       }
+               },
+               {
+                       {
+                               CTL(60, 1), CTL(60, 0), CTL(60, 1), CTL(60, 1),
+                               CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
+                       }
+               },
+        }
+};
+
+
+static const struct ar9300_eeprom *ar9300_eep_templates[] = {
+       &ar9300_default,
+       &ar9300_x112,
+       &ar9300_h116,
+       &ar9300_h112,
+       &ar9300_x113,
+};
+
+static const struct ar9300_eeprom *ar9003_eeprom_struct_find_by_id(int id)
+{
+#define N_LOOP (sizeof(ar9300_eep_templates) / sizeof(ar9300_eep_templates[0]))
+       unsigned int it;
+
+       for (it = 0; it < N_LOOP; it++)
+               if (ar9300_eep_templates[it]->templateVersion == id)
+                       return ar9300_eep_templates[it];
+       return NULL;
+#undef N_LOOP
+}
+
+
+static u16 ath9k_hw_fbin2freq(u8 fbin, int is2GHz)
+{
+       if (fbin == AR5416_BCHAN_UNUSED)
+               return fbin;
+
+       return (u16) ((is2GHz) ? (2300 + fbin) : (4800 + 5 * fbin));
+}
+
+static int ath9k_hw_ar9300_check_eeprom(struct ath_hw *ah __unused)
+{
+       return 0;
+}
+
+static int interpolate(int x, int xa, int xb, int ya, int yb)
+{
+       int bf, factor, plus;
+
+       bf = 2 * (yb - ya) * (x - xa) / (xb - xa);
+       factor = bf / 2;
+       plus = bf % 2;
+       return ya + factor + plus;
+}
+
+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 (uint16_t)(pBase->regDmn[0]);
+       case EEP_REG_1:
+               return (uint16_t)(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 (uint32_t)(pBase->swreg);
+       case EEP_PAPRD:
+               return !!(pBase->featureEnable & BIT(5));
+       case EEP_CHAIN_MASK_REDUCE:
+               return (pBase->miscConfiguration >> 0x3) & 0x1;
+       case EEP_ANT_DIV_CTL1:
+               return (uint32_t)(eep->base_ext1.ant_div_control);
+       default:
+               return 0;
+       }
+}
+
+static int ar9300_eeprom_read_byte(struct ath_common *common, int address,
+                                   u8 *buffer)
+{
+       u16 val;
+
+       if (!ath9k_hw_nvram_read(common, address / 2, &val))
+               return 0;
+
+       *buffer = (val >> (8 * (address % 2))) & 0xff;
+       return 1;
+}
+
+static int ar9300_eeprom_read_word(struct ath_common *common, int address,
+                                   u8 *buffer)
+{
+       u16 val;
+
+       if (!ath9k_hw_nvram_read(common, address / 2, &val))
+               return 0;
+
+       buffer[0] = val >> 8;
+       buffer[1] = val & 0xff;
+
+       return 1;
+}
+
+static int ar9300_read_eeprom(struct ath_hw *ah, int address, u8 *buffer,
+                              int count)
+{
+       struct ath_common *common = ath9k_hw_common(ah);
+       int i;
+
+       if ((address < 0) || ((address + count) / 2 > AR9300_EEPROM_SIZE - 1)) {
+               DBG("ath9k: "
+                       "eeprom address not in range\n");
+               return 0;
+       }
+
+       /*
+        * Since we're reading the bytes in reverse order from a little-endian
+        * word stream, an even address means we only use the lower half of
+        * the 16-bit word at that address
+        */
+       if (address % 2 == 0) {
+               if (!ar9300_eeprom_read_byte(common, address--, buffer++))
+                       goto error;
+
+               count--;
+       }
+
+       for (i = 0; i < count / 2; i++) {
+               if (!ar9300_eeprom_read_word(common, address, buffer))
+                       goto error;
+
+               address -= 2;
+               buffer += 2;
+       }
+
+       if (count % 2)
+               if (!ar9300_eeprom_read_byte(common, address, buffer))
+                       goto error;
+
+       return 1;
+
+error:
+       DBG("ath9k: "
+               "unable to read eeprom region at offset %d\n", address);
+       return 0;
+}
+
+static int ar9300_otp_read_word(struct ath_hw *ah, int addr, u32 *data)
+{
+       REG_READ(ah, AR9300_OTP_BASE + (4 * addr));
+
+       if (!ath9k_hw_wait(ah, AR9300_OTP_STATUS, AR9300_OTP_STATUS_TYPE,
+                          AR9300_OTP_STATUS_VALID, 1000))
+               return 0;
+
+       *data = REG_READ(ah, AR9300_OTP_READ_DATA);
+       return 1;
+}
+
+static int ar9300_read_otp(struct ath_hw *ah, int address, u8 *buffer,
+                           int count)
+{
+       u32 data;
+       int i;
+
+       for (i = 0; i < count; i++) {
+               int offset = 8 * ((address - i) % 4);
+               if (!ar9300_otp_read_word(ah, (address - i) / 4, &data))
+                       return 0;
+
+               buffer[i] = (data >> offset) & 0xff;
+       }
+
+       return 1;
+}
+
+
+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 int ar9300_uncompress_block(struct ath_hw *ah __unused,
+                                   u8 *mptr,
+                                   int mdataSize,
+                                   u8 *block,
+                                   int size)
+{
+       int it;
+       int spot;
+       int offset;
+       int length;
+
+       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) {
+                       DBG2("ath9k: "
+                               "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) {
+                       DBG("ath9k: "
+                               "Bad restore at %d: spot=%d offset=%d length=%d\n",
+                               it, spot, offset, length);
+                       return 0;
+               }
+       }
+       return 1;
+}
+
+static int ar9300_compress_decision(struct ath_hw *ah,
+                                   int it,
+                                   int code,
+                                   int reference,
+                                   u8 *mptr,
+                                   u8 *word, int length, int mdata_size)
+{
+       const struct ar9300_eeprom *eep = NULL;
+
+       switch (code) {
+       case _CompressNone:
+               if (length != mdata_size) {
+                       DBG("ath9k: "
+                               "EEPROM structure size mismatch memory=%d eeprom=%d\n",
+                               mdata_size, length);
+                       return -1;
+               }
+               memcpy(mptr, (u8 *) (word + COMP_HDR_LEN), length);
+               DBG2("ath9k: "
+                       "restored eeprom %d: uncompressed, length %d\n",
+                       it, length);
+               break;
+       case _CompressBlock:
+               if (reference == 0) {
+               } else {
+                       eep = ar9003_eeprom_struct_find_by_id(reference);
+                       if (eep == NULL) {
+                               DBG("ath9k: "
+                                       "can't find reference eeprom struct %d\n",
+                                       reference);
+                               return -1;
+                       }
+                       memcpy(mptr, eep, mdata_size);
+               }
+               DBG2("ath9k: "
+                       "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:
+               DBG("ath9k: "
+                       "unknown compression code %d\n", code);
+               return -1;
+       }
+       return 0;
+}
+
+typedef int (*eeprom_read_op)(struct ath_hw *ah, int address, u8 *buffer,
+                              int count);
+
+static int ar9300_check_header(void *data)
+{
+       u32 *word = data;
+       return !(*word == 0 || *word == (unsigned int)~0);
+}
+
+static int ar9300_check_eeprom_header(struct ath_hw *ah, eeprom_read_op read,
+                                      int base_addr)
+{
+       u8 header[4];
+
+       if (!read(ah, base_addr, header, 4))
+               return 0;
+
+       return ar9300_check_header(header);
+}
+
+static int ar9300_eeprom_restore_flash(struct ath_hw *ah, u8 *mptr,
+                                      int mdata_size)
+{
+       struct ath_common *common = ath9k_hw_common(ah);
+       u16 *data = (u16 *) mptr;
+       int i;
+
+       for (i = 0; i < mdata_size / 2; i++, data++)
+               ath9k_hw_nvram_read(common, i, data);
+
+       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;
+       eeprom_read_op read;
+
+       if (ath9k_hw_use_flash(ah))
+               return ar9300_eeprom_restore_flash(ah, mptr, mdata_size);
+
+       word = zalloc(2048);
+       if (!word)
+               return -1;
+
+       memcpy(mptr, &ar9300_default, mdata_size);
+
+       read = ar9300_read_eeprom;
+       if (AR_SREV_9485(ah))
+               cptr = AR9300_BASE_ADDR_4K;
+       else
+               cptr = AR9300_BASE_ADDR;
+       DBG2("ath9k: "
+               "Trying EEPROM access at Address 0x%04x\n", cptr);
+       if (ar9300_check_eeprom_header(ah, read, cptr))
+               goto found;
+
+       cptr = AR9300_BASE_ADDR_512;
+       DBG2("ath9k: "
+               "Trying EEPROM access at Address 0x%04x\n", cptr);
+       if (ar9300_check_eeprom_header(ah, read, cptr))
+               goto found;
+
+       read = ar9300_read_otp;
+       cptr = AR9300_BASE_ADDR;
+       DBG2("ath9k: "
+               "Trying OTP access at Address 0x%04x\n", cptr);
+       if (ar9300_check_eeprom_header(ah, read, cptr))
+               goto found;
+
+       cptr = AR9300_BASE_ADDR_512;
+       DBG2("ath9k: "
+               "Trying OTP access at Address 0x%04x\n", cptr);
+       if (ar9300_check_eeprom_header(ah, read, cptr))
+               goto found;
+
+       goto fail;
+
+found:
+       DBG2("ath9k: Found valid EEPROM data\n");
+
+       for (it = 0; it < MSTATE; it++) {
+               if (!read(ah, cptr, word, COMP_HDR_LEN))
+                       goto fail;
+
+               if (!ar9300_check_header(word))
+                       break;
+
+               ar9300_comp_hdr_unpack(word, &code, &reference,
+                                      &length, &major, &minor);
+               DBG2("ath9k: "
+                       "Found block at %x: code=%d ref=%d length=%d major=%d minor=%d\n",
+                       cptr, code, reference, length, major, minor);
+               if ((!AR_SREV_9485(ah) && length >= 1024) ||
+                   (AR_SREV_9485(ah) && length > EEPROM_DATA_LEN_9485)) {
+                       DBG2("ath9k: "
+                               "Skipping bad header\n");
+                       cptr -= COMP_HDR_LEN;
+                       continue;
+               }
+
+               osize = length;
+               read(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);
+               DBG2("ath9k: "
+                       "checksum %x %x\n", checksum, mchecksum);
+               if (checksum == mchecksum) {
+                       ar9300_compress_decision(ah, it, code, reference, mptr,
+                                                word, length, mdata_size);
+               } else {
+                       DBG2("ath9k: "
+                               "skipping block with bad checksum\n");
+               }
+               cptr -= (COMP_HDR_LEN + osize + COMP_CKSUM_LEN);
+       }
+
+       free(word);
+       return cptr;
+
+fail:
+       free(word);
+       return -1;
+}
+
+/*
+ * Restore the configuration structure by reading the eeprom.
+ * This function destroys any existing in-memory structure
+ * content.
+ */
+static int ath9k_hw_ar9300_fill_eeprom(struct ath_hw *ah)
+{
+       u8 *mptr = (u8 *) &ah->eeprom.ar9300_eep;
+
+       if (ar9300_eeprom_restore_internal(ah, mptr,
+                       sizeof(struct ar9300_eeprom)) < 0)
+               return 0;
+
+       return 1;
+}
+
+/* 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 __unused)
+{
+       return 0;
+}
+
+static s32 ar9003_hw_xpa_bias_level_get(struct ath_hw *ah, int 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, int is2ghz)
+{
+       int bias = ar9003_hw_xpa_bias_level_get(ah, is2ghz);
+
+       if (AR_SREV_9485(ah) || AR_SREV_9340(ah))
+               REG_RMW_FIELD(ah, AR_CH0_TOP2, AR_CH0_TOP2_XPABIASLVL, bias);
+       else {
+               REG_RMW_FIELD(ah, AR_CH0_TOP, AR_CH0_TOP_XPABIASLVL, bias);
+               REG_RMW_FIELD(ah, AR_CH0_THERM,
+                               AR_CH0_THERM_XPABIASLVL_MSB,
+                               bias >> 2);
+               REG_RMW_FIELD(ah, AR_CH0_THERM,
+                               AR_CH0_THERM_XPASHORT2GND, 1);
+       }
+}
+
+static u32 ar9003_hw_ant_ctrl_common_get(struct ath_hw *ah, int is2ghz)
+{
+       struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
+       uint32_t val;
+
+       if (is2ghz)
+               val = eep->modalHeader2G.antCtrlCommon;
+       else
+               val = eep->modalHeader5G.antCtrlCommon;
+       return (uint32_t)(val);
+}
+
+static u32 ar9003_hw_ant_ctrl_common_2_get(struct ath_hw *ah, int is2ghz)
+{
+       struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
+       uint32_t val;
+
+       if (is2ghz)
+               val = eep->modalHeader2G.antCtrlCommon2;
+       else
+               val = eep->modalHeader5G.antCtrlCommon2;
+       return (uint32_t)(val);
+}
+
+static u16 ar9003_hw_ant_ctrl_chain_get(struct ath_hw *ah,
+                                       int chain,
+                                       int is2ghz)
+{
+       struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
+       uint16_t val = 0;
+
+       if (chain >= 0 && chain < AR9300_MAX_CHAINS) {
+               if (is2ghz)
+                       val = eep->modalHeader2G.antCtrlChain[chain];
+               else
+                       val = eep->modalHeader5G.antCtrlChain[chain];
+       }
+
+       return (uint16_t)(val);
+}
+
+static void ar9003_hw_ant_ctrl_apply(struct ath_hw *ah, int is2ghz)
+{
+       int chain;
+       u32 regval;
+       u32 ant_div_ctl1;
+       static const u32 switch_chain_reg[AR9300_MAX_CHAINS] = {
+                       AR_PHY_SWITCH_CHAIN_0,
+                       AR_PHY_SWITCH_CHAIN_1,
+                       AR_PHY_SWITCH_CHAIN_2,
+       };
+
+       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);
+
+       for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) {
+               if ((ah->rxchainmask & BIT(chain)) ||
+                   (ah->txchainmask & BIT(chain))) {
+                       value = ar9003_hw_ant_ctrl_chain_get(ah, chain,
+                                                            is2ghz);
+                       REG_RMW_FIELD(ah, switch_chain_reg[chain],
+                                     AR_SWITCH_TABLE_ALL, value);
+               }
+       }
+
+       if (AR_SREV_9485(ah)) {
+               value = ath9k_hw_ar9300_get_eeprom(ah, EEP_ANT_DIV_CTL1);
+               /*
+                * main_lnaconf, alt_lnaconf, main_tb, alt_tb
+                * are the fields present
+                */
+               regval = REG_READ(ah, AR_PHY_MC_GAIN_CTRL);
+               regval &= (~AR_ANT_DIV_CTRL_ALL);
+               regval |= (value & 0x3f) << AR_ANT_DIV_CTRL_ALL_S;
+               /* enable_lnadiv */
+               regval &= (~AR_PHY_9485_ANT_DIV_LNADIV);
+               regval |= ((value >> 6) & 0x1) <<
+                               AR_PHY_9485_ANT_DIV_LNADIV_S;
+               REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, regval);
+
+               /*enable fast_div */
+               regval = REG_READ(ah, AR_PHY_CCK_DETECT);
+               regval &= (~AR_FAST_DIV_ENABLE);
+               regval |= ((value >> 7) & 0x1) <<
+                               AR_FAST_DIV_ENABLE_S;
+               REG_WRITE(ah, AR_PHY_CCK_DETECT, regval);
+               ant_div_ctl1 =
+                       ah->eep_ops->get_eeprom(ah, EEP_ANT_DIV_CTL1);
+               /* check whether antenna diversity is enabled */
+               if ((ant_div_ctl1 >> 0x6) == 0x3) {
+                       regval = REG_READ(ah, AR_PHY_MC_GAIN_CTRL);
+                       /*
+                        * clear bits 25-30 main_lnaconf, alt_lnaconf,
+                        * main_tb, alt_tb
+                        */
+                       regval &= (~(AR_PHY_9485_ANT_DIV_MAIN_LNACONF |
+                                       AR_PHY_9485_ANT_DIV_ALT_LNACONF |
+                                       AR_PHY_9485_ANT_DIV_ALT_GAINTB |
+                                       AR_PHY_9485_ANT_DIV_MAIN_GAINTB));
+                       /* by default use LNA1 for the main antenna */
+                       regval |= (AR_PHY_9485_ANT_DIV_LNA1 <<
+                                       AR_PHY_9485_ANT_DIV_MAIN_LNACONF_S);
+                       regval |= (AR_PHY_9485_ANT_DIV_LNA2 <<
+                                       AR_PHY_9485_ANT_DIV_ALT_LNACONF_S);
+                       REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, regval);
+               }
+
+
+       }
+
+}
+
+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 u16 ar9003_hw_atten_chain_get(struct ath_hw *ah, int chain,
+                                    struct ath9k_channel *chan)
+{
+       int f[3], t[3];
+       u16 value;
+       struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
+
+       if (chain >= 0 && chain < 3) {
+               if (IS_CHAN_2GHZ(chan))
+                       return eep->modalHeader2G.xatten1DB[chain];
+               else if (eep->base_ext2.xatten1DBLow[chain] != 0) {
+                       t[0] = eep->base_ext2.xatten1DBLow[chain];
+                       f[0] = 5180;
+                       t[1] = eep->modalHeader5G.xatten1DB[chain];
+                       f[1] = 5500;
+                       t[2] = eep->base_ext2.xatten1DBHigh[chain];
+                       f[2] = 5785;
+                       value = ar9003_hw_power_interpolate((s32) chan->channel,
+                                                           f, t, 3);
+                       return value;
+               } else
+                       return eep->modalHeader5G.xatten1DB[chain];
+       }
+
+       return 0;
+}
+
+
+static u16 ar9003_hw_atten_chain_get_margin(struct ath_hw *ah, int chain,
+                                           struct ath9k_channel *chan)
+{
+       int f[3], t[3];
+       u16 value;
+       struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
+
+       if (chain >= 0 && chain < 3) {
+               if (IS_CHAN_2GHZ(chan))
+                       return eep->modalHeader2G.xatten1Margin[chain];
+               else if (eep->base_ext2.xatten1MarginLow[chain] != 0) {
+                       t[0] = eep->base_ext2.xatten1MarginLow[chain];
+                       f[0] = 5180;
+                       t[1] = eep->modalHeader5G.xatten1Margin[chain];
+                       f[1] = 5500;
+                       t[2] = eep->base_ext2.xatten1MarginHigh[chain];
+                       f[2] = 5785;
+                       value = ar9003_hw_power_interpolate((s32) chan->channel,
+                                                           f, t, 3);
+                       return value;
+               } else
+                       return eep->modalHeader5G.xatten1Margin[chain];
+       }
+
+       return 0;
+}
+
+static void ar9003_hw_atten_apply(struct ath_hw *ah, struct ath9k_channel *chan)
+{
+       int i;
+       u16 value;
+       unsigned long ext_atten_reg[3] = {AR_PHY_EXT_ATTEN_CTL_0,
+                                         AR_PHY_EXT_ATTEN_CTL_1,
+                                         AR_PHY_EXT_ATTEN_CTL_2,
+                                        };
+
+       /* Test value. if 0 then attenuation is unused. Don't load anything. */
+       for (i = 0; i < 3; i++) {
+               if (ah->txchainmask & BIT(i)) {
+                       value = ar9003_hw_atten_chain_get(ah, i, chan);
+                       REG_RMW_FIELD(ah, ext_atten_reg[i],
+                                     AR_PHY_EXT_ATTEN_CTL_XATTEN1_DB, value);
+
+                       value = ar9003_hw_atten_chain_get_margin(ah, i, chan);
+                       REG_RMW_FIELD(ah, ext_atten_reg[i],
+                                     AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN,
+                                     value);
+               }
+       }
+}
+
+static int is_pmu_set(struct ath_hw *ah, u32 pmu_reg, int pmu_set)
+{
+       int timeout = 100;
+
+       while ((unsigned int)pmu_set != REG_READ(ah, pmu_reg)) {
+               if (timeout-- == 0)
+                       return 0;
+               REG_WRITE(ah, pmu_reg, pmu_set);
+               udelay(10);
+       }
+
+       return 1;
+}
+
+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) {
+               if (AR_SREV_9485(ah)) {
+                       int reg_pmu_set;
+
+                       reg_pmu_set = REG_READ(ah, AR_PHY_PMU2) & ~AR_PHY_PMU2_PGM;
+                       REG_WRITE(ah, AR_PHY_PMU2, reg_pmu_set);
+                       if (!is_pmu_set(ah, AR_PHY_PMU2, reg_pmu_set))
+                               return;
+
+                       reg_pmu_set = (5 << 1) | (7 << 4) | (1 << 8) |
+                                     (2 << 14) | (6 << 17) | (1 << 20) |
+                                     (3 << 24) | (1 << 28);
+
+                       REG_WRITE(ah, AR_PHY_PMU1, reg_pmu_set);
+                       if (!is_pmu_set(ah, AR_PHY_PMU1, reg_pmu_set))
+                               return;
+
+                       reg_pmu_set = (REG_READ(ah, AR_PHY_PMU2) & ~0xFFC00000)
+                                       | (4 << 26);
+                       REG_WRITE(ah, AR_PHY_PMU2, reg_pmu_set);
+                       if (!is_pmu_set(ah, AR_PHY_PMU2, reg_pmu_set))
+                               return;
+
+                       reg_pmu_set = (REG_READ(ah, AR_PHY_PMU2) & ~0x00200000)
+                                       | (1 << 21);
+                       REG_WRITE(ah, AR_PHY_PMU2, reg_pmu_set);
+                       if (!is_pmu_set(ah, AR_PHY_PMU2, reg_pmu_set))
+                               return;
+               } else {
+                       /* 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 {
+               if (AR_SREV_9485(ah)) {
+                       REG_RMW_FIELD(ah, AR_PHY_PMU2, AR_PHY_PMU2_PGM, 0);
+                       while (REG_READ_FIELD(ah, AR_PHY_PMU2,
+                                             AR_PHY_PMU2_PGM))
+                               udelay(10);
+
+                       REG_RMW_FIELD(ah, AR_PHY_PMU1, AR_PHY_PMU1_PWD, 0x1);
+                       while (!REG_READ_FIELD(ah, AR_PHY_PMU1,
+                                              AR_PHY_PMU1_PWD))
+                               udelay(10);
+                       REG_RMW_FIELD(ah, AR_PHY_PMU2, AR_PHY_PMU2_PGM, 0x1);
+                       while (!REG_READ_FIELD(ah, AR_PHY_PMU2,
+                                             AR_PHY_PMU2_PGM))
+                               udelay(10);
+               } else
+                       REG_WRITE(ah, AR_RTC_SLEEP_CLK,
+                                 (REG_READ(ah,
+                                  AR_RTC_SLEEP_CLK) |
+                                  AR_RTC_FORCE_SWREG_PRD));
+       }
+
+}
+
+static void ar9003_hw_apply_tuning_caps(struct ath_hw *ah)
+{
+       struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
+       u8 tuning_caps_param = eep->baseEepHeader.params_for_tuning_caps[0];
+
+       if (eep->baseEepHeader.featureEnable & 0x40) {
+               tuning_caps_param &= 0x7f;
+               REG_RMW_FIELD(ah, AR_CH0_XTAL, AR_CH0_XTAL_CAPINDAC,
+                             tuning_caps_param);
+               REG_RMW_FIELD(ah, AR_CH0_XTAL, AR_CH0_XTAL_CAPOUTDAC,
+                             tuning_caps_param);
+       }
+}
+
+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_atten_apply(ah, chan);
+       if (!AR_SREV_9340(ah))
+               ar9003_hw_internal_regulator_apply(ah);
+       if (AR_SREV_9485(ah) || AR_SREV_9340(ah))
+               ar9003_hw_apply_tuning_caps(ah);
+}
+
+static void ath9k_hw_ar9300_set_addac(struct ath_hw *ah __unused,
+                                     struct ath9k_channel *chan __unused)
+{
+}
+
+/*
+ * 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, uint16_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 = interpolate(x, lx, hx, ly, hy);
+               } 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, int 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_2G_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, int 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_2G_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, int 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, AR_PHY_TX_FORCED_GAIN, 0);
+
+       /* Write the OFDM power per rate set */
+
+       /* 6 (LSB), 9, 12, 18 (MSB) */
+       REG_WRITE(ah, AR_PHY_POWER_TX_RATE(0),
+                 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, AR_PHY_POWER_TX_RATE(1),
+                 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, AR_PHY_POWER_TX_RATE(2),
+                 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, AR_PHY_POWER_TX_RATE(3),
+                 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 power for duplicated frames - HT40 */
+
+        /* dup40_cck (LSB), dup40_ofdm, ext20_cck, ext20_ofdm (MSB) */
+       REG_WRITE(ah, 0xa3e0,
+                 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 24) |
+                 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 16) |
+                 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24],  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, AR_PHY_POWER_TX_RATE(4),
+                 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, AR_PHY_POWER_TX_RATE(5),
+                 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, AR_PHY_POWER_TX_RATE(9),
+                 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, AR_PHY_POWER_TX_RATE(10),
+                 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, AR_PHY_POWER_TX_RATE(6),
+                 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, AR_PHY_POWER_TX_RATE(7),
+                 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, AR_PHY_POWER_TX_RATE(11),
+                 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)
+{
+       /* XXX: hard code for now, need to get from eeprom struct */
+       u8 ht40PowerIncForPdadc = 0;
+       int is2GHz = 0;
+       unsigned int i = 0;
+
+       if (freq < 4000)
+               is2GHz = 1;
+
+       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;
+
+       for (i = 0; i < ar9300RateSize; i++) {
+               DBG2("ath9k: "
+                       "TPC[%02d] 0x%08x\n", i, targetPowerValT2[i]);
+       }
+}
+
+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;
+
+       if (ichain >= AR9300_MAX_CHAINS) {
+               DBG("ath9k: "
+                       "Invalid chain index, must be less than %d\n",
+                       AR9300_MAX_CHAINS);
+               return -1;
+       }
+
+       if (mode) {             /* 5GHz */
+               if (ipier >= AR9300_NUM_5G_CAL_PIERS) {
+                       DBG("ath9k: "
+                               "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) {
+                       DBG("ath9k: "
+                               "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 __unused, int *temperature)
+{
+       int tempSlope = 0;
+       struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
+       int f[3], t[3];
+
+       REG_RMW(ah, AR_PHY_TPC_11_B0,
+               (correction[0] << AR_PHY_TPC_OLPC_GAIN_DELTA_S),
+               AR_PHY_TPC_OLPC_GAIN_DELTA);
+       if (ah->caps.tx_chainmask & BIT(1))
+               REG_RMW(ah, AR_PHY_TPC_11_B1,
+                       (correction[1] << AR_PHY_TPC_OLPC_GAIN_DELTA_S),
+                       AR_PHY_TPC_OLPC_GAIN_DELTA);
+       if (ah->caps.tx_chainmask & BIT(2))
+               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);
+       if (ah->caps.tx_chainmask & BIT(1))
+               REG_RMW(ah, AR_PHY_TPC_6_B1,
+                       (3 << AR_PHY_TPC_6_ERROR_EST_MODE_S),
+                       AR_PHY_TPC_6_ERROR_EST_MODE);
+       if (ah->caps.tx_chainmask & BIT(2))
+               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 if (eep->base_ext2.tempSlopeLow != 0) {
+               t[0] = eep->base_ext2.tempSlopeLow;
+               f[0] = 5180;
+               t[1] = eep->modalHeader5G.tempSlope;
+               f[1] = 5500;
+               t[2] = eep->base_ext2.tempSlopeHigh;
+               f[2] = 5785;
+               tempSlope = ar9003_hw_power_interpolate((s32) frequency,
+                                                       f, t, 3);
+       } 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;
+
+       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++) {
+               DBG2("ath9k: "
+                       "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] = interpolate(frequency,
+                                               lfrequency[ichain],
+                                               hfrequency[ichain],
+                                               lcorrection[ichain],
+                                               hcorrection[ichain]);
+
+                               temperature[ichain] = interpolate(frequency,
+                                               lfrequency[ichain],
+                                               hfrequency[ichain],
+                                               ltemperature[ichain],
+                                               htemperature[ichain]);
+
+                               voltage[ichain] = interpolate(frequency,
+                                               lfrequency[ichain],
+                                               hfrequency[ichain],
+                                               lvoltage[ichain],
+                                               hvoltage[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);
+
+       DBG2("ath9k: "
+               "for frequency=%d, calibration correction = %d %d %d\n",
+               frequency, correction[0], correction[1], correction[2]);
+
+       return 0;
+}
+
+static u16 ar9003_hw_get_direct_edge_power(struct ar9300_eeprom *eep,
+                                          int idx,
+                                          int edge,
+                                          int is2GHz)
+{
+       struct cal_ctl_data_2g *ctl_2g = eep->ctlPowerData_2G;
+       struct cal_ctl_data_5g *ctl_5g = eep->ctlPowerData_5G;
+
+       if (is2GHz)
+               return CTL_EDGE_TPOWER(ctl_2g[idx].ctlEdges[edge]);
+       else
+               return CTL_EDGE_TPOWER(ctl_5g[idx].ctlEdges[edge]);
+}
+
+static u16 ar9003_hw_get_indirect_edge_power(struct ar9300_eeprom *eep,
+                                            int idx,
+                                            unsigned int edge,
+                                            u16 freq,
+                                            int is2GHz)
+{
+       struct cal_ctl_data_2g *ctl_2g = eep->ctlPowerData_2G;
+       struct cal_ctl_data_5g *ctl_5g = eep->ctlPowerData_5G;
+
+       u8 *ctl_freqbin = is2GHz ?
+               &eep->ctl_freqbin_2G[idx][0] :
+               &eep->ctl_freqbin_5G[idx][0];
+
+       if (is2GHz) {
+               if (ath9k_hw_fbin2freq(ctl_freqbin[edge - 1], 1) < freq &&
+                   CTL_EDGE_FLAGS(ctl_2g[idx].ctlEdges[edge - 1]))
+                       return CTL_EDGE_TPOWER(ctl_2g[idx].ctlEdges[edge - 1]);
+       } else {
+               if (ath9k_hw_fbin2freq(ctl_freqbin[edge - 1], 0) < freq &&
+                   CTL_EDGE_FLAGS(ctl_5g[idx].ctlEdges[edge - 1]))
+                       return CTL_EDGE_TPOWER(ctl_5g[idx].ctlEdges[edge - 1]);
+       }
+
+       return MAX_RATE_POWER;
+}
+
+/*
+ * Find the maximum conformance test limit for the given channel and CTL info
+ */
+static u16 ar9003_hw_get_max_edge_power(struct ar9300_eeprom *eep,
+                                       u16 freq, int idx, int is2GHz)
+{
+       u16 twiceMaxEdgePower = MAX_RATE_POWER;
+       u8 *ctl_freqbin = is2GHz ?
+               &eep->ctl_freqbin_2G[idx][0] :
+               &eep->ctl_freqbin_5G[idx][0];
+       u16 num_edges = is2GHz ?
+               AR9300_NUM_BAND_EDGES_2G : AR9300_NUM_BAND_EDGES_5G;
+       unsigned int edge;
+
+       /* Get the edge power */
+       for (edge = 0;
+            (edge < num_edges) && (ctl_freqbin[edge] != AR5416_BCHAN_UNUSED);
+            edge++) {
+               /*
+                * If there's an exact channel match or an inband flag set
+                * on the lower channel use the given rdEdgePower
+                */
+               if (freq == ath9k_hw_fbin2freq(ctl_freqbin[edge], is2GHz)) {
+                       twiceMaxEdgePower =
+                               ar9003_hw_get_direct_edge_power(eep, idx,
+                                                               edge, is2GHz);
+                       break;
+               } else if ((edge > 0) &&
+                          (freq < ath9k_hw_fbin2freq(ctl_freqbin[edge],
+                                                     is2GHz))) {
+                       twiceMaxEdgePower =
+                               ar9003_hw_get_indirect_edge_power(eep, idx,
+                                                                 edge, freq,
+                                                                 is2GHz);
+                       /*
+                        * Leave loop - no more affecting edges possible in
+                        * this monotonic increasing list
+                        */
+                       break;
+               }
+       }
+       return twiceMaxEdgePower;
+}
+
+static void ar9003_hw_set_power_per_rate_table(struct ath_hw *ah,
+                                              struct ath9k_channel *chan,
+                                              u8 *pPwrArray, u16 cfgCtl,
+                                              u8 twiceAntennaReduction,
+                                              u8 twiceMaxRegulatoryPower,
+                                              u16 powerLimit)
+{
+       struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
+       struct ar9300_eeprom *pEepData = &ah->eeprom.ar9300_eep;
+       u16 twiceMaxEdgePower = MAX_RATE_POWER;
+       static const u16 tpScaleReductionTable[5] = {
+               0, 3, 6, 9, MAX_RATE_POWER
+       };
+       int i;
+       int16_t  twiceLargestAntenna;
+       u16 scaledPower = 0, minCtlPower, maxRegAllowedPower;
+       static const u16 ctlModesFor11a[] = {
+               CTL_11A, CTL_5GHT20, CTL_11A_EXT, CTL_5GHT40
+       };
+       static const u16 ctlModesFor11g[] = {
+               CTL_11B, CTL_11G, CTL_2GHT20, CTL_11B_EXT,
+               CTL_11G_EXT, CTL_2GHT40
+       };
+       u16 numCtlModes;
+       const u16 *pCtlMode;
+       u16 ctlMode, freq;
+       struct chan_centers centers;
+       u8 *ctlIndex;
+       u8 ctlNum;
+       u16 twiceMinEdgePower;
+       int is2ghz = IS_CHAN_2GHZ(chan);
+
+       ath9k_hw_get_channel_centers(ah, chan, &centers);
+
+       /* Compute TxPower reduction due to Antenna Gain */
+       if (is2ghz)
+               twiceLargestAntenna = pEepData->modalHeader2G.antennaGain;
+       else
+               twiceLargestAntenna = pEepData->modalHeader5G.antennaGain;
+
+       twiceLargestAntenna = (int16_t)min((twiceAntennaReduction) -
+                               twiceLargestAntenna, 0);
+
+       /*
+        * scaledPower is the minimum of the user input power level
+        * and the regulatory allowed power level
+        */
+       maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna;
+
+       if (regulatory->tp_scale != ATH9K_TP_SCALE_MAX) {
+               maxRegAllowedPower -=
+                       (tpScaleReductionTable[(regulatory->tp_scale)] * 2);
+       }
+
+       scaledPower = min(powerLimit, maxRegAllowedPower);
+
+       /*
+        * Reduce scaled Power by number of chains active to get
+        * to per chain tx power level
+        */
+       switch (ar5416_get_ntxchains(ah->txchainmask)) {
+       case 1:
+               break;
+       case 2:
+               if (scaledPower > REDUCE_SCALED_POWER_BY_TWO_CHAIN)
+                       scaledPower -= REDUCE_SCALED_POWER_BY_TWO_CHAIN;
+               else
+                       scaledPower = 0;
+               break;
+       case 3:
+               if (scaledPower > REDUCE_SCALED_POWER_BY_THREE_CHAIN)
+                       scaledPower -= REDUCE_SCALED_POWER_BY_THREE_CHAIN;
+               else
+                       scaledPower = 0;
+               break;
+       }
+
+       scaledPower = max((u16)0, scaledPower);
+
+       /*
+        * Get target powers from EEPROM - our baseline for TX Power
+        */
+       if (is2ghz) {
+               /* Setup for CTL modes */
+               /* CTL_11B, CTL_11G, CTL_2GHT20 */
+               numCtlModes =
+                       ARRAY_SIZE(ctlModesFor11g) -
+                                  SUB_NUM_CTL_MODES_AT_2G_40;
+               pCtlMode = ctlModesFor11g;
+               if (IS_CHAN_HT40(chan))
+                       /* All 2G CTL's */
+                       numCtlModes = ARRAY_SIZE(ctlModesFor11g);
+       } else {
+               /* Setup for CTL modes */
+               /* CTL_11A, CTL_5GHT20 */
+               numCtlModes = ARRAY_SIZE(ctlModesFor11a) -
+                                        SUB_NUM_CTL_MODES_AT_5G_40;
+               pCtlMode = ctlModesFor11a;
+               if (IS_CHAN_HT40(chan))
+                       /* All 5G CTL's */
+                       numCtlModes = ARRAY_SIZE(ctlModesFor11a);
+       }
+
+       /*
+        * For MIMO, need to apply regulatory caps individually across
+        * dynamically running modes: CCK, OFDM, HT20, HT40
+        *
+        * The outer loop walks through each possible applicable runtime mode.
+        * The inner loop walks through each ctlIndex entry in EEPROM.
+        * The ctl value is encoded as [7:4] == test group, [3:0] == test mode.
+        */
+       for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) {
+               int isHt40CtlMode = (pCtlMode[ctlMode] == CTL_5GHT40) ||
+                       (pCtlMode[ctlMode] == CTL_2GHT40);
+               if (isHt40CtlMode)
+                       freq = centers.synth_center;
+               else if (pCtlMode[ctlMode] & EXT_ADDITIVE)
+                       freq = centers.ext_center;
+               else
+                       freq = centers.ctl_center;
+
+               DBG2("ath9k: "
+                       "LOOP-Mode ctlMode %d < %d, isHt40CtlMode %d, EXT_ADDITIVE %d\n",
+                       ctlMode, numCtlModes, isHt40CtlMode,
+                       (pCtlMode[ctlMode] & EXT_ADDITIVE));
+
+               /* walk through each CTL index stored in EEPROM */
+               if (is2ghz) {
+                       ctlIndex = pEepData->ctlIndex_2G;
+                       ctlNum = AR9300_NUM_CTLS_2G;
+               } else {
+                       ctlIndex = pEepData->ctlIndex_5G;
+                       ctlNum = AR9300_NUM_CTLS_5G;
+               }
+
+               for (i = 0; (i < ctlNum) && ctlIndex[i]; i++) {
+                       DBG2("ath9k: "
+                               "LOOP-Ctlidx %d: cfgCtl 0x%2.2x pCtlMode 0x%2.2x ctlIndex 0x%2.2x chan %d\n",
+                               i, cfgCtl, pCtlMode[ctlMode], ctlIndex[i],
+                               chan->channel);
+
+                               /*
+                                * compare test group from regulatory
+                                * channel list with test mode from pCtlMode
+                                * list
+                                */
+                               if ((((cfgCtl & ~CTL_MODE_M) |
+                                      (pCtlMode[ctlMode] & CTL_MODE_M)) ==
+                                       ctlIndex[i]) ||
+                                   (((cfgCtl & ~CTL_MODE_M) |
+                                      (pCtlMode[ctlMode] & CTL_MODE_M)) ==
+                                    ((ctlIndex[i] & CTL_MODE_M) |
+                                      SD_NO_CTL))) {
+                                       twiceMinEdgePower =
+                                         ar9003_hw_get_max_edge_power(pEepData,
+                                                                      freq, i,
+                                                                      is2ghz);
+
+                                       if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL)
+                                               /*
+                                                * Find the minimum of all CTL
+                                                * edge powers that apply to
+                                                * this channel
+                                                */
+                                               twiceMaxEdgePower =
+                                                       min(twiceMaxEdgePower,
+                                                           twiceMinEdgePower);
+                                               else {
+                                                       /* specific */
+                                                       twiceMaxEdgePower =
+                                                         twiceMinEdgePower;
+                                                       break;
+                                               }
+                               }
+                       }
+
+                       minCtlPower = (u8)min(twiceMaxEdgePower, scaledPower);
+
+                       DBG2("ath9k: "
+                               "SEL-Min ctlMode %d pCtlMode %d 2xMaxEdge %d sP %d minCtlPwr %d\n",
+                               ctlMode, pCtlMode[ctlMode], twiceMaxEdgePower,
+                               scaledPower, minCtlPower);
+
+                       /* Apply ctl mode to correct target power set */
+                       switch (pCtlMode[ctlMode]) {
+                       case CTL_11B:
+                               for (i = ALL_TARGET_LEGACY_1L_5L;
+                                    i <= ALL_TARGET_LEGACY_11S; i++)
+                                       pPwrArray[i] =
+                                         (u8)min((u16)pPwrArray[i],
+                                                 minCtlPower);
+                               break;
+                       case CTL_11A:
+                       case CTL_11G:
+                               for (i = ALL_TARGET_LEGACY_6_24;
+                                    i <= ALL_TARGET_LEGACY_54; i++)
+                                       pPwrArray[i] =
+                                         (u8)min((u16)pPwrArray[i],
+                                                 minCtlPower);
+                               break;
+                       case CTL_5GHT20:
+                       case CTL_2GHT20:
+                               for (i = ALL_TARGET_HT20_0_8_16;
+                                    i <= ALL_TARGET_HT20_21; i++)
+                                       pPwrArray[i] =
+                                         (u8)min((u16)pPwrArray[i],
+                                                 minCtlPower);
+                               pPwrArray[ALL_TARGET_HT20_22] =
+                                 (u8)min((u16)pPwrArray[ALL_TARGET_HT20_22],
+                                         minCtlPower);
+                               pPwrArray[ALL_TARGET_HT20_23] =
+                                 (u8)min((u16)pPwrArray[ALL_TARGET_HT20_23],
+                                          minCtlPower);
+                               break;
+                       case CTL_5GHT40:
+                       case CTL_2GHT40:
+                               for (i = ALL_TARGET_HT40_0_8_16;
+                                    i <= ALL_TARGET_HT40_23; i++)
+                                       pPwrArray[i] =
+                                         (u8)min((u16)pPwrArray[i],
+                                                 minCtlPower);
+                               break;
+                       default:
+                           break;
+                       }
+       } /* end ctl mode checking */
+}
+
+static inline u8 mcsidx_to_tgtpwridx(unsigned int mcs_idx, u8 base_pwridx)
+{
+       u8 mod_idx = mcs_idx % 8;
+
+       if (mod_idx <= 3)
+               return mod_idx ? (base_pwridx + 1) : base_pwridx;
+       else
+               return base_pwridx + 4 * (mcs_idx / 8) + mod_idx - 2;
+}
+
+static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah,
+                                       struct ath9k_channel *chan, u16 cfgCtl,
+                                       u8 twiceAntennaReduction,
+                                       u8 twiceMaxRegulatoryPower,
+                                       u8 powerLimit, int test)
+{
+       struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
+       struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
+       struct ar9300_modal_eep_header *modal_hdr;
+       u8 targetPowerValT2[ar9300RateSize];
+       u8 target_power_val_t2_eep[ar9300RateSize];
+       unsigned int i = 0, paprd_scale_factor = 0;
+       u8 pwr_idx, min_pwridx = 0;
+
+       ar9003_hw_set_target_power_eeprom(ah, chan->channel, targetPowerValT2);
+
+       if (ah->eep_ops->get_eeprom(ah, EEP_PAPRD)) {
+               if (IS_CHAN_2GHZ(chan))
+                       modal_hdr = &eep->modalHeader2G;
+               else
+                       modal_hdr = &eep->modalHeader5G;
+
+               ah->paprd_ratemask =
+                               (uint32_t)(modal_hdr->papdRateMaskHt20) &
+                       AR9300_PAPRD_RATE_MASK;
+
+               ah->paprd_ratemask_ht40 =
+                               (uint32_t)(modal_hdr->papdRateMaskHt40) &
+                       AR9300_PAPRD_RATE_MASK;
+
+               paprd_scale_factor = ar9003_get_paprd_scale_factor(ah, chan);
+               min_pwridx = IS_CHAN_HT40(chan) ? ALL_TARGET_HT40_0_8_16 :
+                                                 ALL_TARGET_HT20_0_8_16;
+
+               if (!ah->paprd_table_write_done) {
+                       memcpy(target_power_val_t2_eep, targetPowerValT2,
+                              sizeof(targetPowerValT2));
+                       for (i = 0; i < 24; i++) {
+                               pwr_idx = mcsidx_to_tgtpwridx(i, min_pwridx);
+                               if (ah->paprd_ratemask & (1 << i)) {
+                                       if (targetPowerValT2[pwr_idx] &&
+                                           targetPowerValT2[pwr_idx] ==
+                                           target_power_val_t2_eep[pwr_idx])
+                                               targetPowerValT2[pwr_idx] -=
+                                                       paprd_scale_factor;
+                               }
+                       }
+               }
+               memcpy(target_power_val_t2_eep, targetPowerValT2,
+                      sizeof(targetPowerValT2));
+       }
+
+       ar9003_hw_set_power_per_rate_table(ah, chan,
+                                          targetPowerValT2, cfgCtl,
+                                          twiceAntennaReduction,
+                                          twiceMaxRegulatoryPower,
+                                          powerLimit);
+
+       if (ah->eep_ops->get_eeprom(ah, EEP_PAPRD)) {
+               for (i = 0; i < ar9300RateSize; i++) {
+                       if ((ah->paprd_ratemask & (1 << i)) &&
+                           ((unsigned int)abs(targetPowerValT2[i] -
+                               target_power_val_t2_eep[i]) >
+                           paprd_scale_factor)) {
+                               ah->paprd_ratemask &= ~(1 << i);
+                               DBG2("ath9k: "
+                                       "paprd disabled for mcs %d\n", i);
+                       }
+               }
+       }
+
+       regulatory->max_power_level = 0;
+       for (i = 0; i < ar9300RateSize; i++) {
+               if (targetPowerValT2[i] > regulatory->max_power_level)
+                       regulatory->max_power_level = targetPowerValT2[i];
+       }
+
+       if (test)
+               return;
+
+       for (i = 0; i < ar9300RateSize; i++) {
+               DBG2("ath9k: "
+                       "TPC[%02d] 0x%08x\n", i, targetPowerValT2[i]);
+       }
+
+       /*
+        * This is the TX power we send back to driver core,
+        * and it can use to pass to userspace to display our
+        * currently configured TX power setting.
+        *
+        * Since power is rate dependent, use one of the indices
+        * from the AR9300_Rates enum to select an entry from
+        * targetPowerValT2[] to report. Currently returns the
+        * power for HT40 MCS 0, HT20 MCS 0, or OFDM 6 Mbps
+        * as CCK power is less interesting (?).
+        */
+       i = ALL_TARGET_LEGACY_6_24; /* legacy */
+       if (IS_CHAN_HT40(chan))
+               i = ALL_TARGET_HT40_0_8_16; /* ht40 */
+       else if (IS_CHAN_HT20(chan))
+               i = ALL_TARGET_HT20_0_8_16; /* ht20 */
+
+       ah->txpower_limit = targetPowerValT2[i];
+       regulatory->max_power_level = targetPowerValT2[i];
+
+       /* Write target power array to registers */
+       ar9003_hw_tx_power_regwrite(ah, targetPowerValT2);
+       ar9003_hw_calibration_apply(ah, chan->channel);
+
+       if (IS_CHAN_2GHZ(chan)) {
+               if (IS_CHAN_HT40(chan))
+                       i = ALL_TARGET_HT40_0_8_16;
+               else
+                       i = ALL_TARGET_HT20_0_8_16;
+       } else {
+               if (IS_CHAN_HT40(chan))
+                       i = ALL_TARGET_HT40_7;
+               else
+                       i = ALL_TARGET_HT20_7;
+       }
+       ah->paprd_target_power = targetPowerValT2[i];
+}
+
+static u16 ath9k_hw_ar9300_get_spur_channel(struct ath_hw *ah __unused,
+                                           u16 i __unused, int is2GHz __unused)
+{
+       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 */
+}
+
+u8 *ar9003_get_spur_chan_ptr(struct ath_hw *ah, int is_2ghz)
+{
+       struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
+
+       if (is_2ghz)
+               return eep->modalHeader2G.spurChans;
+       else
+               return eep->modalHeader5G.spurChans;
+}
+
+unsigned int ar9003_get_paprd_scale_factor(struct ath_hw *ah,
+                                          struct ath9k_channel *chan)
+{
+       struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
+
+       if (IS_CHAN_2GHZ(chan))
+               return MS((uint32_t)(eep->modalHeader2G.papdRateMaskHt20),
+                         AR9300_PAPRD_SCALE_1);
+       else {
+               if (chan->channel >= 5700)
+               return MS((uint32_t)(eep->modalHeader5G.papdRateMaskHt20),
+                         AR9300_PAPRD_SCALE_1);
+               else if (chan->channel >= 5400)
+                       return MS((uint32_t)(eep->modalHeader5G.papdRateMaskHt40),
+                                  AR9300_PAPRD_SCALE_2);
+               else
+                       return MS((uint32_t)(eep->modalHeader5G.papdRateMaskHt40),
+                                 AR9300_PAPRD_SCALE_1);
+       }
+}
+
+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,
+       .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/src/drivers/net/ath/ath9k/ath9k_ar9003_hw.c b/src/drivers/net/ath/ath9k/ath9k_ar9003_hw.c
new file mode 100644 (file)
index 0000000..f3020fd
--- /dev/null
@@ -0,0 +1,409 @@
+/*
+ * Copyright (c) 2008-2011 Atheros Communications Inc.
+ *
+ * Modified for iPXE by Scott K Logan <logans@cottsay.net> July 2011
+ * Original from Linux kernel 3.0.1
+ *
+ * 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_2p2_initvals.h"
+#include "ar9485_initvals.h"
+#include "ar9340_initvals.h"
+
+/* General hardware code for the AR9003 hadware family */
+
+/*
+ * The AR9003 family uses a new INI format (pre, core, post
+ * arrays per subsystem). This provides support for the
+ * AR9003 2.2 chipsets.
+ */
+static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
+{
+       if (AR_SREV_9340(ah)) {
+               /* mac */
+               INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0);
+               INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE],
+                               ar9340_1p0_mac_core,
+                               ARRAY_SIZE(ar9340_1p0_mac_core), 2);
+               INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST],
+                               ar9340_1p0_mac_postamble,
+                               ARRAY_SIZE(ar9340_1p0_mac_postamble), 5);
+
+               /* bb */
+               INIT_INI_ARRAY(&ah->iniBB[ATH_INI_PRE], NULL, 0, 0);
+               INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE],
+                               ar9340_1p0_baseband_core,
+                               ARRAY_SIZE(ar9340_1p0_baseband_core), 2);
+               INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST],
+                               ar9340_1p0_baseband_postamble,
+                               ARRAY_SIZE(ar9340_1p0_baseband_postamble), 5);
+
+               /* radio */
+               INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_PRE], NULL, 0, 0);
+               INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE],
+                               ar9340_1p0_radio_core,
+                               ARRAY_SIZE(ar9340_1p0_radio_core), 2);
+               INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST],
+                               ar9340_1p0_radio_postamble,
+                               ARRAY_SIZE(ar9340_1p0_radio_postamble), 5);
+
+               /* soc */
+               INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE],
+                               ar9340_1p0_soc_preamble,
+                               ARRAY_SIZE(ar9340_1p0_soc_preamble), 2);
+               INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_CORE], NULL, 0, 0);
+               INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST],
+                               ar9340_1p0_soc_postamble,
+                               ARRAY_SIZE(ar9340_1p0_soc_postamble), 5);
+
+               /* rx/tx gain */
+               INIT_INI_ARRAY(&ah->iniModesRxGain,
+                               ar9340Common_wo_xlna_rx_gain_table_1p0,
+                               ARRAY_SIZE(ar9340Common_wo_xlna_rx_gain_table_1p0),
+                               5);
+               INIT_INI_ARRAY(&ah->iniModesTxGain,
+                               ar9340Modes_high_ob_db_tx_gain_table_1p0,
+                               ARRAY_SIZE(ar9340Modes_high_ob_db_tx_gain_table_1p0),
+                               5);
+
+               INIT_INI_ARRAY(&ah->iniModesAdditional,
+                               ar9340Modes_fast_clock_1p0,
+                               ARRAY_SIZE(ar9340Modes_fast_clock_1p0),
+                               3);
+
+               INIT_INI_ARRAY(&ah->iniModesAdditional_40M,
+                               ar9340_1p0_radio_core_40M,
+                               ARRAY_SIZE(ar9340_1p0_radio_core_40M),
+                               2);
+       } else if (AR_SREV_9485_11(ah)) {
+               /* mac */
+               INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0);
+               INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE],
+                               ar9485_1_1_mac_core,
+                               ARRAY_SIZE(ar9485_1_1_mac_core), 2);
+               INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST],
+                               ar9485_1_1_mac_postamble,
+                               ARRAY_SIZE(ar9485_1_1_mac_postamble), 5);
+
+               /* bb */
+               INIT_INI_ARRAY(&ah->iniBB[ATH_INI_PRE], ar9485_1_1,
+                               ARRAY_SIZE(ar9485_1_1), 2);
+               INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE],
+                               ar9485_1_1_baseband_core,
+                               ARRAY_SIZE(ar9485_1_1_baseband_core), 2);
+               INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST],
+                               ar9485_1_1_baseband_postamble,
+                               ARRAY_SIZE(ar9485_1_1_baseband_postamble), 5);
+
+               /* radio */
+               INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_PRE], NULL, 0, 0);
+               INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE],
+                               ar9485_1_1_radio_core,
+                               ARRAY_SIZE(ar9485_1_1_radio_core), 2);
+               INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST],
+                               ar9485_1_1_radio_postamble,
+                               ARRAY_SIZE(ar9485_1_1_radio_postamble), 2);
+
+               /* soc */
+               INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE],
+                               ar9485_1_1_soc_preamble,
+                               ARRAY_SIZE(ar9485_1_1_soc_preamble), 2);
+               INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_CORE], NULL, 0, 0);
+               INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST], NULL, 0, 0);
+
+               /* rx/tx gain */
+               INIT_INI_ARRAY(&ah->iniModesRxGain,
+                               ar9485Common_wo_xlna_rx_gain_1_1,
+                               ARRAY_SIZE(ar9485Common_wo_xlna_rx_gain_1_1), 2);
+               INIT_INI_ARRAY(&ah->iniModesTxGain,
+                               ar9485_modes_lowest_ob_db_tx_gain_1_1,
+                               ARRAY_SIZE(ar9485_modes_lowest_ob_db_tx_gain_1_1),
+                               5);
+
+               /* Load PCIE SERDES settings from INI */
+
+               /* Awake Setting */
+
+               INIT_INI_ARRAY(&ah->iniPcieSerdes,
+                               ar9485_1_1_pcie_phy_clkreq_disable_L1,
+                               ARRAY_SIZE(ar9485_1_1_pcie_phy_clkreq_disable_L1),
+                               2);
+
+               /* Sleep Setting */
+
+               INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower,
+                               ar9485_1_1_pcie_phy_clkreq_disable_L1,
+                               ARRAY_SIZE(ar9485_1_1_pcie_phy_clkreq_disable_L1),
+                               2);
+       } else {
+               /* mac */
+               INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0);
+               INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE],
+                               ar9300_2p2_mac_core,
+                               ARRAY_SIZE(ar9300_2p2_mac_core), 2);
+               INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST],
+                               ar9300_2p2_mac_postamble,
+                               ARRAY_SIZE(ar9300_2p2_mac_postamble), 5);
+
+               /* bb */
+               INIT_INI_ARRAY(&ah->iniBB[ATH_INI_PRE], NULL, 0, 0);
+               INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE],
+                               ar9300_2p2_baseband_core,
+                               ARRAY_SIZE(ar9300_2p2_baseband_core), 2);
+               INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST],
+                               ar9300_2p2_baseband_postamble,
+                               ARRAY_SIZE(ar9300_2p2_baseband_postamble), 5);
+
+               /* radio */
+               INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_PRE], NULL, 0, 0);
+               INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE],
+                               ar9300_2p2_radio_core,
+                               ARRAY_SIZE(ar9300_2p2_radio_core), 2);
+               INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST],
+                               ar9300_2p2_radio_postamble,
+                               ARRAY_SIZE(ar9300_2p2_radio_postamble), 5);
+
+               /* soc */
+               INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE],
+                               ar9300_2p2_soc_preamble,
+                               ARRAY_SIZE(ar9300_2p2_soc_preamble), 2);
+               INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_CORE], NULL, 0, 0);
+               INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST],
+                               ar9300_2p2_soc_postamble,
+                               ARRAY_SIZE(ar9300_2p2_soc_postamble), 5);
+
+               /* rx/tx gain */
+               INIT_INI_ARRAY(&ah->iniModesRxGain,
+                               ar9300Common_rx_gain_table_2p2,
+                               ARRAY_SIZE(ar9300Common_rx_gain_table_2p2), 2);
+               INIT_INI_ARRAY(&ah->iniModesTxGain,
+                               ar9300Modes_lowest_ob_db_tx_gain_table_2p2,
+                               ARRAY_SIZE(ar9300Modes_lowest_ob_db_tx_gain_table_2p2),
+                               5);
+
+               /* Load PCIE SERDES settings from INI */
+
+               /* Awake Setting */
+
+               INIT_INI_ARRAY(&ah->iniPcieSerdes,
+                               ar9300PciePhy_pll_on_clkreq_disable_L1_2p2,
+                               ARRAY_SIZE(ar9300PciePhy_pll_on_clkreq_disable_L1_2p2),
+                               2);
+
+               /* Sleep Setting */
+
+               INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower,
+                               ar9300PciePhy_pll_on_clkreq_disable_L1_2p2,
+                               ARRAY_SIZE(ar9300PciePhy_pll_on_clkreq_disable_L1_2p2),
+                               2);
+
+               /* Fast clock modal settings */
+               INIT_INI_ARRAY(&ah->iniModesAdditional,
+                               ar9300Modes_fast_clock_2p2,
+                               ARRAY_SIZE(ar9300Modes_fast_clock_2p2),
+                               3);
+       }
+}
+
+static void ar9003_tx_gain_table_apply(struct ath_hw *ah)
+{
+       switch (ar9003_hw_get_tx_gain_idx(ah)) {
+       case 0:
+       default:
+               if (AR_SREV_9340(ah))
+                       INIT_INI_ARRAY(&ah->iniModesTxGain,
+                                       ar9340Modes_lowest_ob_db_tx_gain_table_1p0,
+                                      ARRAY_SIZE(ar9340Modes_lowest_ob_db_tx_gain_table_1p0),
+                                      5);
+               else if (AR_SREV_9485_11(ah))
+                       INIT_INI_ARRAY(&ah->iniModesTxGain,
+                                      ar9485_modes_lowest_ob_db_tx_gain_1_1,
+                                      ARRAY_SIZE(ar9485_modes_lowest_ob_db_tx_gain_1_1),
+                                      5);
+               else
+                       INIT_INI_ARRAY(&ah->iniModesTxGain,
+                                      ar9300Modes_lowest_ob_db_tx_gain_table_2p2,
+                                      ARRAY_SIZE(ar9300Modes_lowest_ob_db_tx_gain_table_2p2),
+                                      5);
+               break;
+       case 1:
+               if (AR_SREV_9340(ah))
+                       INIT_INI_ARRAY(&ah->iniModesTxGain,
+                                       ar9340Modes_lowest_ob_db_tx_gain_table_1p0,
+                                      ARRAY_SIZE(ar9340Modes_lowest_ob_db_tx_gain_table_1p0),
+                                      5);
+               else if (AR_SREV_9485_11(ah))
+                       INIT_INI_ARRAY(&ah->iniModesTxGain,
+                                      ar9485Modes_high_ob_db_tx_gain_1_1,
+                                      ARRAY_SIZE(ar9485Modes_high_ob_db_tx_gain_1_1),
+                                      5);
+               else
+                       INIT_INI_ARRAY(&ah->iniModesTxGain,
+                                      ar9300Modes_high_ob_db_tx_gain_table_2p2,
+                                      ARRAY_SIZE(ar9300Modes_high_ob_db_tx_gain_table_2p2),
+                                      5);
+               break;
+       case 2:
+               if (AR_SREV_9340(ah))
+                       INIT_INI_ARRAY(&ah->iniModesTxGain,
+                                       ar9340Modes_lowest_ob_db_tx_gain_table_1p0,
+                                      ARRAY_SIZE(ar9340Modes_lowest_ob_db_tx_gain_table_1p0),
+                                      5);
+               else if (AR_SREV_9485_11(ah))
+                       INIT_INI_ARRAY(&ah->iniModesTxGain,
+                                      ar9485Modes_low_ob_db_tx_gain_1_1,
+                                      ARRAY_SIZE(ar9485Modes_low_ob_db_tx_gain_1_1),
+                                      5);
+               else
+                       INIT_INI_ARRAY(&ah->iniModesTxGain,
+                                      ar9300Modes_low_ob_db_tx_gain_table_2p2,
+                                      ARRAY_SIZE(ar9300Modes_low_ob_db_tx_gain_table_2p2),
+                                      5);
+               break;
+       case 3:
+               if (AR_SREV_9340(ah))
+                       INIT_INI_ARRAY(&ah->iniModesTxGain,
+                                       ar9340Modes_lowest_ob_db_tx_gain_table_1p0,
+                                      ARRAY_SIZE(ar9340Modes_lowest_ob_db_tx_gain_table_1p0),
+                                      5);
+               else if (AR_SREV_9485_11(ah))
+                       INIT_INI_ARRAY(&ah->iniModesTxGain,
+                                      ar9485Modes_high_power_tx_gain_1_1,
+                                      ARRAY_SIZE(ar9485Modes_high_power_tx_gain_1_1),
+                                      5);
+               else
+                       INIT_INI_ARRAY(&ah->iniModesTxGain,
+                                      ar9300Modes_high_power_tx_gain_table_2p2,
+                                      ARRAY_SIZE(ar9300Modes_high_power_tx_gain_table_2p2),
+                                      5);
+               break;
+       }
+}
+
+static void ar9003_rx_gain_table_apply(struct ath_hw *ah)
+{
+       switch (ar9003_hw_get_rx_gain_idx(ah)) {
+       case 0:
+       default:
+               if (AR_SREV_9340(ah))
+                       INIT_INI_ARRAY(&ah->iniModesRxGain,
+                                      ar9340Common_rx_gain_table_1p0,
+                                      ARRAY_SIZE(ar9340Common_rx_gain_table_1p0),
+                                      2);
+               else if (AR_SREV_9485_11(ah))
+                       INIT_INI_ARRAY(&ah->iniModesRxGain,
+                                      ar9485Common_wo_xlna_rx_gain_1_1,
+                                      ARRAY_SIZE(ar9485Common_wo_xlna_rx_gain_1_1),
+                                      2);
+               else
+                       INIT_INI_ARRAY(&ah->iniModesRxGain,
+                                      ar9300Common_rx_gain_table_2p2,
+                                      ARRAY_SIZE(ar9300Common_rx_gain_table_2p2),
+                                      2);
+               break;
+       case 1:
+               if (AR_SREV_9340(ah))
+                       INIT_INI_ARRAY(&ah->iniModesRxGain,
+                                      ar9340Common_wo_xlna_rx_gain_table_1p0,
+                                      ARRAY_SIZE(ar9340Common_wo_xlna_rx_gain_table_1p0),
+                                      2);
+               else if (AR_SREV_9485_11(ah))
+                       INIT_INI_ARRAY(&ah->iniModesRxGain,
+                                      ar9485Common_wo_xlna_rx_gain_1_1,
+                                      ARRAY_SIZE(ar9485Common_wo_xlna_rx_gain_1_1),
+                                      2);
+               else
+                       INIT_INI_ARRAY(&ah->iniModesRxGain,
+                                      ar9300Common_wo_xlna_rx_gain_table_2p2,
+                                      ARRAY_SIZE(ar9300Common_wo_xlna_rx_gain_table_2p2),
+                                      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 != 1)
+               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);
+               else
+                       REG_WRITE(ah, AR_WA, ah->WARegVal);
+       }
+
+       /*
+        * Configire PCIE after Ini init. SERDES values now come from ini file
+        * This enables PCIe low power mode.
+        */
+       if (ah->config.pcieSerDesWrite) {
+               unsigned int i;
+               struct ar5416IniArray *array;
+
+               array = power_off ? &ah->iniPcieSerdes :
+                                   &ah->iniPcieSerdesLowPower;
+
+               for (i = 0; i < array->ia_rows; i++) {
+                       REG_WRITE(ah,
+                                 INI_RA(array, i, 0),
+                                 INI_RA(array, i, 1));
+               }
+       }
+}
+
+/* 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;
+
+       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/src/drivers/net/ath/ath9k/ath9k_ar9003_mac.c b/src/drivers/net/ath/ath9k/ath9k_ar9003_mac.c
new file mode 100644 (file)
index 0000000..1fa4039
--- /dev/null
@@ -0,0 +1,669 @@
+/*
+ * Copyright (c) 2010-2011 Atheros Communications Inc.
+ *
+ * Modified for iPXE by Scott K Logan <logans@cottsay.net> July 2011
+ * Original from Linux kernel 3.0.1
+ *
+ * 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 <ipxe/io.h>
+
+#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 int 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;
+
+       if (ah->ah_ier & AR_IER_ENABLE) {
+               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 0;
+       } 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);
+
+                       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);
+                       mask2 |= ((isr2 & AR_ISR_S2_BB_WATCHDOG) >>
+                                 MAP_ISR_S2_BB_WATCHDOG);
+
+                       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 0;
+               }
+
+               *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)
+                       DBG("ath9k: "
+                               "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 1;
+}
+
+static void ar9003_hw_fill_txdesc(struct ath_hw *ah __unused, void *ds, u32 seglen,
+                                 int is_firstseg, int is_lastseg,
+                                 const void *ds0, u32 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 __unused,
+                                struct ath_tx_status *ts)
+{
+       struct ar9003_txs *ads;
+       u32 status;
+
+       ads = &ah->ts_ring[ah->ts_tail];
+
+       status = *(volatile typeof(ads->status8) *)&(ads->status8);
+       if ((status & 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)) {
+               DBG("ath9k: "
+                       "Tx Descriptor error %x\n", ads->ds_info);
+               memset(ads, 0, sizeof(*ads));
+               return -EIO;
+       }
+
+       if (status & AR_TxOpExceeded)
+               ts->ts_status |= ATH9K_TXERR_XTXOP;
+       ts->ts_rateindex = MS(status, AR_FinalTxIdx);
+       ts->ts_seqnum = MS(status, AR_SeqNum);
+       ts->tid = MS(status, AR_TxTid);
+
+       ts->qid = MS(ads->ds_info, AR_TxQcuNum);
+       ts->desc_id = MS(ads->status1, AR_TxDescId);
+       ts->ts_tstamp = ads->status4;
+       ts->ts_status = 0;
+       ts->ts_flags  = 0;
+
+       status = *(volatile typeof(ads->status2) *)&(ads->status2);
+       ts->ts_rssi_ctl0 = MS(status, AR_TxRSSIAnt00);
+       ts->ts_rssi_ctl1 = MS(status, AR_TxRSSIAnt01);
+       ts->ts_rssi_ctl2 = MS(status, AR_TxRSSIAnt02);
+       if (status & AR_TxBaStatus) {
+               ts->ts_flags |= ATH9K_TX_BA;
+               ts->ba_low = ads->status5;
+               ts->ba_high = ads->status6;
+       }
+
+       status = *(volatile typeof(ads->status3) *)&(ads->status3);
+       if (status & AR_ExcessiveRetries)
+               ts->ts_status |= ATH9K_TXERR_XRETRY;
+       if (status & AR_Filtered)
+               ts->ts_status |= ATH9K_TXERR_FILT;
+       if (status & AR_FIFOUnderrun) {
+               ts->ts_status |= ATH9K_TXERR_FIFO;
+               ath9k_hw_updatetxtriglevel(ah, 1);
+       }
+       if (status & AR_TxTimerExpired)
+               ts->ts_status |= ATH9K_TXERR_TIMER_EXPIRED;
+       if (status & AR_DescCfgErr)
+               ts->ts_flags |= ATH9K_TX_DESC_CFG_ERR;
+       if (status & AR_TxDataUnderrun) {
+               ts->ts_flags |= ATH9K_TX_DATA_UNDERRUN;
+               ath9k_hw_updatetxtriglevel(ah, 1);
+       }
+       if (status & AR_TxDelimUnderrun) {
+               ts->ts_flags |= ATH9K_TX_DELIM_UNDERRUN;
+               ath9k_hw_updatetxtriglevel(ah, 1);
+       }
+       ts->ts_shortretry = MS(status, AR_RTSFailCnt);
+       ts->ts_longretry = MS(status, AR_DataFailCnt);
+       ts->ts_virtcol = MS(status, AR_VirtRetryCnt);
+
+       status = *(volatile typeof(ads->status7) *)&(ads->status7);
+       ts->ts_rssi = MS(status, AR_TxRSSICombined);
+       ts->ts_rssi_ext0 = MS(status, AR_TxRSSIAnt10);
+       ts->ts_rssi_ext1 = MS(status, AR_TxRSSIAnt11);
+       ts->ts_rssi_ext2 = MS(status, AR_TxRSSIAnt12);
+
+       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;
+
+       if (txpower > ah->txpower_limit)
+               txpower = ah->txpower_limit;
+
+       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)
+               | (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_set_clrdmask(struct ath_hw *ah __unused, void *ds, int val)
+{
+       struct ar9003_txc *ads = (struct ar9003_txc *) ds;
+
+       if (val)
+               ads->ctl11 |= AR_ClrDestMask;
+       else
+               ads->ctl11 &= ~AR_ClrDestMask;
+}
+
+static void ar9003_hw_set11n_ratescenario(struct ath_hw *ah __unused, void *ds,
+                                         void *lastds,
+                                         u32 durUpdateEn, u32 rtsctsRate,
+                                         u32 rtsctsDuration __unused,
+                                         struct ath9k_11n_rate_series series[],
+                                         u32 nseries __unused, u32 flags)
+{
+       struct ar9003_txc *ads = (struct ar9003_txc *) ds;
+       struct ar9003_txc *last_ads = (struct ar9003_txc *) lastds;
+       uint32_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)
+{
+#define FIRST_DESC_NDELIMS 60
+       struct ar9003_txc *ads = (struct ar9003_txc *) ds;
+
+       ads->ctl12 |= (AR_IsAggr | AR_MoreAggr);
+
+       if (ah->ent_mode & AR_ENT_OTP_MPSD) {
+               u32 ctl17, ndelim;
+               /*
+                * Add delimiter when using RTS/CTS with aggregation
+                * and non enterprise AR9003 card
+                */
+               ctl17 = ads->ctl17;
+               ndelim = MS(ctl17, AR_PadDelim);
+
+               if (ndelim < FIRST_DESC_NDELIMS) {
+                       aggrLen += (FIRST_DESC_NDELIMS - ndelim) * 4;
+                       ndelim = FIRST_DESC_NDELIMS;
+               }
+
+               ctl17 &= ~AR_AggrLen;
+               ctl17 |= SM(aggrLen, AR_AggrLen);
+
+               ctl17 &= ~AR_PadDelim;
+               ctl17 |= SM(ndelim, AR_PadDelim);
+
+               ads->ctl17 = ctl17;
+       } else {
+               ads->ctl17 &= ~AR_AggrLen;
+               ads->ctl17 |= SM(aggrLen, AR_AggrLen);
+       }
+}
+
+static void ar9003_hw_set11n_aggr_middle(struct ath_hw *ah __unused, 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 __unused, 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 __unused, void *ds)
+{
+       struct ar9003_txc *ads = (struct ar9003_txc *) ds;
+
+       ads->ctl12 &= (~AR_IsAggr & ~AR_MoreAggr);
+}
+
+void ar9003_hw_set_paprd_txdesc(struct ath_hw *ah __unused, void *ds, u8 chains)
+{
+       struct ar9003_txc *ads = ds;
+
+       ads->ctl12 |= SM(chains, AR_PAPRDChainMask);
+}
+
+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->set_clrdmask = ar9003_hw_set_clrdmask;
+}
+
+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);
+}
+
+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);
+}
+
+int ath9k_hw_process_rxdesc_edma(struct ath_hw *ah __unused, 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) {
+               /*
+                * AR_CRCErr will bet set to true if we're on the last
+                * subframe and the AR_PostDelimCRCErr is caught.
+                * In a way this also gives us a guarantee that when
+                * (!(AR_CRCErr) && (AR_PostDelimCRCErr)) we cannot
+                * possibly be reviewing the last subframe. AR_CRCErr
+                * is the CRC of the actual data.
+                */
+               if (rxsp->status11 & AR_CRCErr)
+                       rxs->rs_status |= ATH9K_RXERR_CRC;
+               else if (rxsp->status11 & AR_PHYErr) {
+                       phyerr = MS(rxsp->status11, AR_PHYErrCode);
+                       /*
+                        * If we reach a point here where AR_PostDelimCRCErr is
+                        * true it implies we're *not* on the last subframe. In
+                        * in that case that we know already that the CRC of
+                        * the frame was OK, and MAC would send an ACK for that
+                        * subframe, even if we did get a phy error of type
+                        * ATH9K_PHYERR_OFDM_RESTART. This is only applicable
+                        * to frame that are prior to the last subframe.
+                        * The AR_PostDelimCRCErr is the CRC for the MPDU
+                        * delimiter, which contains the 4 reserved bits,
+                        * the MPDU length (12 bits), and follows the MPDU
+                        * delimiter for an A-MPDU subframe (0x4E = 'N' ASCII).
+                        */
+                       if ((phyerr == ATH9K_PHYERR_OFDM_RESTART) &&
+                           (rxsp->status11 & AR_PostDelimCRCErr)) {
+                               rxs->rs_phyerr = 0;
+                       } else {
+                               rxs->rs_status |= ATH9K_RXERR_PHY;
+                               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;
+               else if (rxsp->status11 & AR_KeyMiss)
+                       rxs->rs_status |= ATH9K_RXERR_DECRYPT;
+       }
+
+       return 0;
+}
+
+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));
+
+       DBG2("ath9k: "
+               "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);
+}
diff --git a/src/drivers/net/ath/ath9k/ath9k_ar9003_phy.c b/src/drivers/net/ath/ath9k/ath9k_ar9003_phy.c
new file mode 100644 (file)
index 0000000..6103040
--- /dev/null
@@ -0,0 +1,1277 @@
+/*
+ * Copyright (c) 2010-2011 Atheros Communications Inc.
+ *
+ * Modified for iPXE by Scott K Logan <logans@cottsay.net> July 2011
+ * Original from Linux kernel 3.0.1
+ *
+ * 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 <ipxe/io.h>
+
+#include "hw.h"
+#include "ar9003_phy.h"
+
+static const int firstep_table[] =
+/* level:  0   1   2   3   4   5   6   7   8  */
+       { -4, -2,  0,  2,  4,  6,  8, 10, 12 }; /* lvl 0-8, default 2 */
+
+static const int cycpwrThr1_table[] =
+/* level:  0   1   2   3   4   5   6   7   8  */
+       { -6, -4, -2,  0,  2,  4,  6,  8 };     /* lvl 0-7, default 3 */
+
+/*
+ * register values to turn OFDM weak signal detection OFF
+ */
+static const int m1ThreshLow_off = 127;
+static const int m2ThreshLow_off = 127;
+static const int m1Thresh_off = 127;
+static const int m2Thresh_off = 127;
+static const int m2CountThr_off =  31;
+static const int m2CountThrLow_off =  63;
+static const int m1ThreshLowExt_off = 127;
+static const int m2ThreshLowExt_off = 127;
+static const int m1ThreshExt_off = 127;
+static const int m2ThreshExt_off = 127;
+
+/**
+ * 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 */
+               if (AR_SREV_9485(ah)) {
+                       u32 chan_frac;
+
+                       /*
+                        * freq_ref = 40 / (refdiva >> amoderefsel); where refdiva=1 and amoderefsel=0
+                        * ndiv = ((chan_mhz * 4) / 3) / freq_ref;
+                        * chansel = int(ndiv), chanfrac = (ndiv - chansel) * 0x20000
+                        */
+                       channelSel = (freq * 4) / 120;
+                       chan_frac = (((freq * 4) % 120) * 0x20000) / 120;
+                       channelSel = (channelSel << 17) | chan_frac;
+               } else if (AR_SREV_9340(ah)) {
+                       if (ah->is_clk_25mhz) {
+                               u32 chan_frac;
+
+                               channelSel = (freq * 2) / 75;
+                               chan_frac = (((freq * 2) % 75) * 0x20000) / 75;
+                               channelSel = (channelSel << 17) | chan_frac;
+                       } else
+                               channelSel = CHANSEL_2G(freq) >> 1;
+               } else
+                       channelSel = CHANSEL_2G(freq);
+               /* Set to 2G mode */
+               bMode = 1;
+       } else {
+               if (AR_SREV_9340(ah) && ah->is_clk_25mhz) {
+                       u32 chan_frac;
+
+                       channelSel = (freq * 2) / 75;
+                       chan_frac = ((freq % 75) * 0x20000) / 75;
+                       channelSel = (channelSel << 17) | chan_frac;
+               } 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_mrc_cck - 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)
+{
+       static const u32 spur_freq[4] = { 2420, 2440, 2464, 2480 };
+       int cur_bb_spur, negative = 0, cck_spur_freq;
+       int i;
+       int range, max_spur_cnts, synth_freq;
+       u8 *spur_fbin_ptr = NULL;
+
+       /*
+        * Need to verify range +/- 10 MHz in control channel, otherwise spur
+        * is out-of-band and can be ignored.
+        */
+
+       if (AR_SREV_9485(ah) || AR_SREV_9340(ah)) {
+               spur_fbin_ptr = ar9003_get_spur_chan_ptr(ah,
+                                                        IS_CHAN_2GHZ(chan));
+               if (spur_fbin_ptr[0] == 0) /* No spur */
+                       return;
+               max_spur_cnts = 5;
+               if (IS_CHAN_HT40(chan)) {
+                       range = 19;
+                       if (REG_READ_FIELD(ah, AR_PHY_GEN_CTRL,
+                                          AR_PHY_GC_DYN2040_PRI_CH) == 0)
+                               synth_freq = chan->channel + 10;
+                       else
+                               synth_freq = chan->channel - 10;
+               } else {
+                       range = 10;
+                       synth_freq = chan->channel;
+               }
+       } else {
+               range = 10;
+               max_spur_cnts = 4;
+               synth_freq = chan->channel;
+       }
+
+       for (i = 0; i < max_spur_cnts; i++) {
+               negative = 0;
+               if (AR_SREV_9485(ah) || AR_SREV_9340(ah))
+                       cur_bb_spur = FBIN2FREQ(spur_fbin_ptr[i],
+                                       IS_CHAN_2GHZ(chan)) - synth_freq;
+               else
+                       cur_bb_spur = spur_freq[i] - synth_freq;
+
+               if (cur_bb_spur < 0) {
+                       negative = 1;
+                       cur_bb_spur = -cur_bb_spur;
+               }
+               if (cur_bb_spur < range) {
+                       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; i < AR_EEPROM_MODAL_SPURS && spurChansPtr[i]; 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 __unused,
+                                        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);
+
+       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;
+       }
+
+       if ((ah->caps.hw_caps & ATH9K_HW_CAP_APM) && (tx == 0x7))
+               REG_WRITE(ah, AR_SELFGEN_MASK, 0x3);
+       else
+               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 ((unsigned int)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);
+
+               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 net80211_channel *channel = chan->chan;
+       u32 modesIndex;
+
+       switch (chan->chanmode) {
+       case CHANNEL_A:
+       case CHANNEL_A_HT20:
+               modesIndex = 1;
+               break;
+       case CHANNEL_A_HT40PLUS:
+       case CHANNEL_A_HT40MINUS:
+               modesIndex = 2;
+               break;
+       case CHANNEL_G:
+       case CHANNEL_G_HT20:
+       case CHANNEL_B:
+               modesIndex = 4;
+               break;
+       case CHANNEL_G_HT40PLUS:
+       case CHANNEL_G_HT40MINUS:
+               modesIndex = 3;
+               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_FAST_CLOCK(ah, chan))
+               REG_WRITE_ARRAY(&ah->iniModesAdditional,
+                               modesIndex, regWrites);
+
+       if (AR_SREV_9340(ah) && !ah->is_clk_25mhz)
+               REG_WRITE_ARRAY(&ah->iniModesAdditional_40M, 1, 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),
+                                0,
+                                channel->maxpower * 2,
+                                min((u32) MAX_RATE_POWER,
+                                (u32) regulatory->power_limit), 0);
+
+       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_FAST_CLOCK(ah, 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 int 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);
+}
+
+static void ar9003_hw_set_diversity(struct ath_hw *ah, int 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 int ar9003_hw_ani_control(struct ath_hw *ah,
+                                 enum ath9k_ani_cmd cmd, int param)
+{
+       struct ath9k_channel *chan = ah->curchan;
+       struct ar5416AniState *aniState = &chan->ani;
+       s32 value, value2;
+
+       switch (cmd & ah->ani_function) {
+       case ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION:{
+               /*
+                * on == 1 means ofdm weak signal detection is ON
+                * on == 1 is the default, for less noise immunity
+                *
+                * on == 0 means ofdm weak signal detection is OFF
+                * on == 0 means more noise imm
+                */
+               u32 on = param ? 1 : 0;
+               /*
+                * make register setting for default
+                * (weak sig detect ON) come from INI file
+                */
+               int m1ThreshLow = on ?
+                       aniState->iniDef.m1ThreshLow : m1ThreshLow_off;
+               int m2ThreshLow = on ?
+                       aniState->iniDef.m2ThreshLow : m2ThreshLow_off;
+               int m1Thresh = on ?
+                       aniState->iniDef.m1Thresh : m1Thresh_off;
+               int m2Thresh = on ?
+                       aniState->iniDef.m2Thresh : m2Thresh_off;
+               int m2CountThr = on ?
+                       aniState->iniDef.m2CountThr : m2CountThr_off;
+               int m2CountThrLow = on ?
+                       aniState->iniDef.m2CountThrLow : m2CountThrLow_off;
+               int m1ThreshLowExt = on ?
+                       aniState->iniDef.m1ThreshLowExt : m1ThreshLowExt_off;
+               int m2ThreshLowExt = on ?
+                       aniState->iniDef.m2ThreshLowExt : m2ThreshLowExt_off;
+               int m1ThreshExt = on ?
+                       aniState->iniDef.m1ThreshExt : m1ThreshExt_off;
+               int m2ThreshExt = on ?
+                       aniState->iniDef.m2ThreshExt : m2ThreshExt_off;
+
+               REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
+                             AR_PHY_SFCORR_LOW_M1_THRESH_LOW,
+                             m1ThreshLow);
+               REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
+                             AR_PHY_SFCORR_LOW_M2_THRESH_LOW,
+                             m2ThreshLow);
+               REG_RMW_FIELD(ah, AR_PHY_SFCORR,
+                             AR_PHY_SFCORR_M1_THRESH, m1Thresh);
+               REG_RMW_FIELD(ah, AR_PHY_SFCORR,
+                             AR_PHY_SFCORR_M2_THRESH, m2Thresh);
+               REG_RMW_FIELD(ah, AR_PHY_SFCORR,
+                             AR_PHY_SFCORR_M2COUNT_THR, m2CountThr);
+               REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
+                             AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW,
+                             m2CountThrLow);
+
+               REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
+                             AR_PHY_SFCORR_EXT_M1_THRESH_LOW, m1ThreshLowExt);
+               REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
+                             AR_PHY_SFCORR_EXT_M2_THRESH_LOW, m2ThreshLowExt);
+               REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
+                             AR_PHY_SFCORR_EXT_M1_THRESH, m1ThreshExt);
+               REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
+                             AR_PHY_SFCORR_EXT_M2_THRESH, m2ThreshExt);
+
+               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) {
+                       DBG2("ath9k: "
+                               "** ch %d: ofdm weak signal: %s=>%s\n",
+                               chan->channel,
+                               !aniState->ofdmWeakSigDetectOff ?
+                               "on" : "off",
+                               on ? "on" : "off");
+                       if (on)
+                               ah->stats.ast_ani_ofdmon++;
+                       else
+                               ah->stats.ast_ani_ofdmoff++;
+                       aniState->ofdmWeakSigDetectOff = !on;
+               }
+               break;
+       }
+       case ATH9K_ANI_FIRSTEP_LEVEL:{
+               u32 level = param;
+
+               if (level >= ARRAY_SIZE(firstep_table)) {
+                       DBG("ath9k: "
+                               "ATH9K_ANI_FIRSTEP_LEVEL: level out of range (%d > %zd)\n",
+                               level, ARRAY_SIZE(firstep_table));
+                       return 0;
+               }
+
+               /*
+                * make register setting relative to default
+                * from INI file & cap value
+                */
+               value = firstep_table[level] -
+                       firstep_table[ATH9K_ANI_FIRSTEP_LVL_NEW] +
+                       aniState->iniDef.firstep;
+               if (value < ATH9K_SIG_FIRSTEP_SETTING_MIN)
+                       value = ATH9K_SIG_FIRSTEP_SETTING_MIN;
+               if (value > ATH9K_SIG_FIRSTEP_SETTING_MAX)
+                       value = ATH9K_SIG_FIRSTEP_SETTING_MAX;
+               REG_RMW_FIELD(ah, AR_PHY_FIND_SIG,
+                             AR_PHY_FIND_SIG_FIRSTEP,
+                             value);
+               /*
+                * we need to set first step low register too
+                * make register setting relative to default
+                * from INI file & cap value
+                */
+               value2 = firstep_table[level] -
+                        firstep_table[ATH9K_ANI_FIRSTEP_LVL_NEW] +
+                        aniState->iniDef.firstepLow;
+               if (value2 < ATH9K_SIG_FIRSTEP_SETTING_MIN)
+                       value2 = ATH9K_SIG_FIRSTEP_SETTING_MIN;
+               if (value2 > ATH9K_SIG_FIRSTEP_SETTING_MAX)
+                       value2 = ATH9K_SIG_FIRSTEP_SETTING_MAX;
+
+               REG_RMW_FIELD(ah, AR_PHY_FIND_SIG_LOW,
+                             AR_PHY_FIND_SIG_LOW_FIRSTEP_LOW, value2);
+
+               if (level != aniState->firstepLevel) {
+                       DBG2("ath9k: "
+                               "** ch %d: level %d=>%d[def:%d] firstep[level]=%d ini=%d\n",
+                               chan->channel,
+                               aniState->firstepLevel,
+                               level,
+                               ATH9K_ANI_FIRSTEP_LVL_NEW,
+                               value,
+                               aniState->iniDef.firstep);
+                       DBG2("ath9k: "
+                               "** ch %d: level %d=>%d[def:%d] firstep_low[level]=%d ini=%d\n",
+                               chan->channel,
+                               aniState->firstepLevel,
+                               level,
+                               ATH9K_ANI_FIRSTEP_LVL_NEW,
+                               value2,
+                               aniState->iniDef.firstepLow);
+                       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:{
+               u32 level = param;
+
+               if (level >= ARRAY_SIZE(cycpwrThr1_table)) {
+                       DBG("ath9k: "
+                               "ATH9K_ANI_SPUR_IMMUNITY_LEVEL: level out of range (%d > %zd)\n",
+                               level, ARRAY_SIZE(cycpwrThr1_table));
+                       return 0;
+               }
+               /*
+                * make register setting relative to default
+                * from INI file & cap value
+                */
+               value = cycpwrThr1_table[level] -
+                       cycpwrThr1_table[ATH9K_ANI_SPUR_IMMUNE_LVL_NEW] +
+                       aniState->iniDef.cycpwrThr1;
+               if (value < ATH9K_SIG_SPUR_IMM_SETTING_MIN)
+                       value = ATH9K_SIG_SPUR_IMM_SETTING_MIN;
+               if (value > ATH9K_SIG_SPUR_IMM_SETTING_MAX)
+                       value = ATH9K_SIG_SPUR_IMM_SETTING_MAX;
+               REG_RMW_FIELD(ah, AR_PHY_TIMING5,
+                             AR_PHY_TIMING5_CYCPWR_THR1,
+                             value);
+
+               /*
+                * set AR_PHY_EXT_CCA for extension channel
+                * make register setting relative to default
+                * from INI file & cap value
+                */
+               value2 = cycpwrThr1_table[level] -
+                        cycpwrThr1_table[ATH9K_ANI_SPUR_IMMUNE_LVL_NEW] +
+                        aniState->iniDef.cycpwrThr1Ext;
+               if (value2 < ATH9K_SIG_SPUR_IMM_SETTING_MIN)
+                       value2 = ATH9K_SIG_SPUR_IMM_SETTING_MIN;
+               if (value2 > ATH9K_SIG_SPUR_IMM_SETTING_MAX)
+                       value2 = ATH9K_SIG_SPUR_IMM_SETTING_MAX;
+               REG_RMW_FIELD(ah, AR_PHY_EXT_CCA,
+                             AR_PHY_EXT_CYCPWR_THR1, value2);
+
+               if (level != aniState->spurImmunityLevel) {
+                       DBG2("ath9k: "
+                               "** ch %d: level %d=>%d[def:%d] cycpwrThr1[level]=%d ini=%d\n",
+                               chan->channel,
+                               aniState->spurImmunityLevel,
+                               level,
+                               ATH9K_ANI_SPUR_IMMUNE_LVL_NEW,
+                               value,
+                               aniState->iniDef.cycpwrThr1);
+                       DBG2("ath9k: "
+                               "** ch %d: level %d=>%d[def:%d] cycpwrThr1Ext[level]=%d ini=%d\n",
+                               chan->channel,
+                               aniState->spurImmunityLevel,
+                               level,
+                               ATH9K_ANI_SPUR_IMMUNE_LVL_NEW,
+                               value2,
+                               aniState->iniDef.cycpwrThr1Ext);
+                       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_MRC_CCK:{
+               /*
+                * is_on == 1 means MRC CCK ON (default, less noise imm)
+                * is_on == 0 means MRC CCK is OFF (more noise imm)
+                */
+               int is_on = param ? 1 : 0;
+               REG_RMW_FIELD(ah, AR_PHY_MRC_CCK_CTRL,
+                             AR_PHY_MRC_CCK_ENABLE, is_on);
+               REG_RMW_FIELD(ah, AR_PHY_MRC_CCK_CTRL,
+                             AR_PHY_MRC_CCK_MUX_REG, is_on);
+               if (!is_on != aniState->mrcCCKOff) {
+                       DBG2("ath9k: "
+                               "** ch %d: MRC CCK: %s=>%s\n",
+                               chan->channel,
+                               !aniState->mrcCCKOff ? "on" : "off",
+                               is_on ? "on" : "off");
+               if (is_on)
+                       ah->stats.ast_ani_ccklow++;
+               else
+                       ah->stats.ast_ani_cckhigh++;
+               aniState->mrcCCKOff = !is_on;
+               }
+       break;
+       }
+       case ATH9K_ANI_PRESENT:
+               break;
+       default:
+               DBG2("ath9k: invalid cmd %d\n", cmd);
+               return 0;
+       }
+
+       DBG2("ath9k: "
+               "ANI parameters: SI=%d, ofdmWS=%s FS=%d MRCcck=%s listenTime=%d ofdmErrs=%d cckErrs=%d\n",
+               aniState->spurImmunityLevel,
+               !aniState->ofdmWeakSigDetectOff ? "on" : "off",
+               aniState->firstepLevel,
+               !aniState->mrcCCKOff ? "on" : "off",
+               aniState->listenTime,
+               aniState->ofdmPhyErrCount,
+               aniState->cckPhyErrCount);
+       return 1;
+}
+
+static void ar9003_hw_do_getnf(struct ath_hw *ah,
+                             int16_t nfarray[NUM_NF_READINGS])
+{
+#define AR_PHY_CH_MINCCA_PWR   0x1FF00000
+#define AR_PHY_CH_MINCCA_PWR_S 20
+#define AR_PHY_CH_EXT_MINCCA_PWR 0x01FF0000
+#define AR_PHY_CH_EXT_MINCCA_PWR_S 16
+
+       int16_t nf;
+       int i;
+
+       for (i = 0; i < AR9300_MAX_CHAINS; i++) {
+               if (ah->rxchainmask & BIT(i)) {
+                       nf = MS(REG_READ(ah, ah->nf_regs[i]),
+                                        AR_PHY_CH_MINCCA_PWR);
+                       nfarray[i] = sign_extend32(nf, 8);
+
+                       if (IS_CHAN_HT40(ah->curchan)) {
+                               u8 ext_idx = AR9300_MAX_CHAINS + i;
+
+                               nf = MS(REG_READ(ah, ah->nf_regs[ext_idx]),
+                                                AR_PHY_CH_EXT_MINCCA_PWR);
+                               nfarray[ext_idx] = sign_extend32(nf, 8);
+                       }
+               }
+       }
+}
+
+static 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_2g.nominal = AR_PHY_CCA_NOM_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;
+       ah->nf_5g.nominal = AR_PHY_CCA_NOM_VAL_9300_5GHZ;
+}
+
+/*
+ * Initialize the ANI register values with default (ini) values.
+ * This routine is called during a (full) hardware reset after
+ * all the registers are initialised from the INI.
+ */
+static void ar9003_hw_ani_cache_ini_regs(struct ath_hw *ah)
+{
+       struct ar5416AniState *aniState;
+       struct ath9k_channel *chan = ah->curchan;
+       struct ath9k_ani_default *iniDef;
+       u32 val;
+
+       aniState = &ah->curchan->ani;
+       iniDef = &aniState->iniDef;
+
+       DBG2("ath9k: "
+               "ver %d.%d chan %d Mhz/0x%x\n",
+               ah->hw_version.macVersion,
+               ah->hw_version.macRev,
+               chan->channel,
+               chan->channelFlags);
+
+       val = REG_READ(ah, AR_PHY_SFCORR);
+       iniDef->m1Thresh = MS(val, AR_PHY_SFCORR_M1_THRESH);
+       iniDef->m2Thresh = MS(val, AR_PHY_SFCORR_M2_THRESH);
+       iniDef->m2CountThr = MS(val, AR_PHY_SFCORR_M2COUNT_THR);
+
+       val = REG_READ(ah, AR_PHY_SFCORR_LOW);
+       iniDef->m1ThreshLow = MS(val, AR_PHY_SFCORR_LOW_M1_THRESH_LOW);
+       iniDef->m2ThreshLow = MS(val, AR_PHY_SFCORR_LOW_M2_THRESH_LOW);
+       iniDef->m2CountThrLow = MS(val, AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW);
+
+       val = REG_READ(ah, AR_PHY_SFCORR_EXT);
+       iniDef->m1ThreshExt = MS(val, AR_PHY_SFCORR_EXT_M1_THRESH);
+       iniDef->m2ThreshExt = MS(val, AR_PHY_SFCORR_EXT_M2_THRESH);
+       iniDef->m1ThreshLowExt = MS(val, AR_PHY_SFCORR_EXT_M1_THRESH_LOW);
+       iniDef->m2ThreshLowExt = MS(val, AR_PHY_SFCORR_EXT_M2_THRESH_LOW);
+       iniDef->firstep = REG_READ_FIELD(ah,
+                                        AR_PHY_FIND_SIG,
+                                        AR_PHY_FIND_SIG_FIRSTEP);
+       iniDef->firstepLow = REG_READ_FIELD(ah,
+                                           AR_PHY_FIND_SIG_LOW,
+                                           AR_PHY_FIND_SIG_LOW_FIRSTEP_LOW);
+       iniDef->cycpwrThr1 = REG_READ_FIELD(ah,
+                                           AR_PHY_TIMING5,
+                                           AR_PHY_TIMING5_CYCPWR_THR1);
+       iniDef->cycpwrThr1Ext = REG_READ_FIELD(ah,
+                                              AR_PHY_EXT_CCA,
+                                              AR_PHY_EXT_CYCPWR_THR1);
+
+       /* these levels just got reset to defaults by the INI */
+       aniState->spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL_NEW;
+       aniState->firstepLevel = ATH9K_ANI_FIRSTEP_LVL_NEW;
+       aniState->ofdmWeakSigDetectOff = !ATH9K_ANI_USE_OFDM_WEAK_SIG;
+       aniState->mrcCCKOff = !ATH9K_ANI_ENABLE_MRC_CCK;
+}
+
+static void ar9003_hw_set_radar_params(struct ath_hw *ah,
+                                      struct ath_hw_radar_conf *conf)
+{
+       u32 radar_0 = 0, radar_1 = 0;
+
+       if (!conf) {
+               REG_CLR_BIT(ah, AR_PHY_RADAR_0, AR_PHY_RADAR_0_ENA);
+               return;
+       }
+
+       radar_0 |= AR_PHY_RADAR_0_ENA | AR_PHY_RADAR_0_FFT_ENA;
+       radar_0 |= SM(conf->fir_power, AR_PHY_RADAR_0_FIRPWR);
+       radar_0 |= SM(conf->radar_rssi, AR_PHY_RADAR_0_RRSSI);
+       radar_0 |= SM(conf->pulse_height, AR_PHY_RADAR_0_HEIGHT);
+       radar_0 |= SM(conf->pulse_rssi, AR_PHY_RADAR_0_PRSSI);
+       radar_0 |= SM(conf->pulse_inband, AR_PHY_RADAR_0_INBAND);
+
+       radar_1 |= AR_PHY_RADAR_1_MAX_RRSSI;
+       radar_1 |= AR_PHY_RADAR_1_BLOCK_CHECK;
+       radar_1 |= SM(conf->pulse_maxlen, AR_PHY_RADAR_1_MAXLEN);
+       radar_1 |= SM(conf->pulse_inband_step, AR_PHY_RADAR_1_RELSTEP_THRESH);
+       radar_1 |= SM(conf->radar_inband, AR_PHY_RADAR_1_RELPWR_THRESH);
+
+       REG_WRITE(ah, AR_PHY_RADAR_0, radar_0);
+       REG_WRITE(ah, AR_PHY_RADAR_1, radar_1);
+       if (conf->ext_channel)
+               REG_SET_BIT(ah, AR_PHY_RADAR_EXT, AR_PHY_RADAR_EXT_ENA);
+       else
+               REG_CLR_BIT(ah, AR_PHY_RADAR_EXT, AR_PHY_RADAR_EXT_ENA);
+}
+
+static void ar9003_hw_set_radar_conf(struct ath_hw *ah)
+{
+       struct ath_hw_radar_conf *conf = &ah->radar_conf;
+
+       conf->fir_power = -28;
+       conf->radar_rssi = 0;
+       conf->pulse_height = 10;
+       conf->pulse_rssi = 24;
+       conf->pulse_inband = 8;
+       conf->pulse_maxlen = 255;
+       conf->pulse_inband_step = 12;
+       conf->radar_inband = 8;
+}
+
+static void ar9003_hw_antdiv_comb_conf_get(struct ath_hw *ah,
+                                  struct ath_hw_antcomb_conf *antconf)
+{
+       u32 regval;
+
+       regval = REG_READ(ah, AR_PHY_MC_GAIN_CTRL);
+       antconf->main_lna_conf = (regval & AR_PHY_9485_ANT_DIV_MAIN_LNACONF) >>
+                                 AR_PHY_9485_ANT_DIV_MAIN_LNACONF_S;
+       antconf->alt_lna_conf = (regval & AR_PHY_9485_ANT_DIV_ALT_LNACONF) >>
+                                AR_PHY_9485_ANT_DIV_ALT_LNACONF_S;
+       antconf->fast_div_bias = (regval & AR_PHY_9485_ANT_FAST_DIV_BIAS) >>
+                                 AR_PHY_9485_ANT_FAST_DIV_BIAS_S;
+       antconf->lna1_lna2_delta = -9;
+       antconf->div_group = 2;
+}
+
+static void ar9003_hw_antdiv_comb_conf_set(struct ath_hw *ah,
+                                  struct ath_hw_antcomb_conf *antconf)
+{
+       u32 regval;
+
+       regval = REG_READ(ah, AR_PHY_MC_GAIN_CTRL);
+       regval &= ~(AR_PHY_9485_ANT_DIV_MAIN_LNACONF |
+                   AR_PHY_9485_ANT_DIV_ALT_LNACONF |
+                   AR_PHY_9485_ANT_FAST_DIV_BIAS |
+                   AR_PHY_9485_ANT_DIV_MAIN_GAINTB |
+                   AR_PHY_9485_ANT_DIV_ALT_GAINTB);
+       regval |= ((antconf->main_lna_conf <<
+                                       AR_PHY_9485_ANT_DIV_MAIN_LNACONF_S)
+                  & AR_PHY_9485_ANT_DIV_MAIN_LNACONF);
+       regval |= ((antconf->alt_lna_conf << AR_PHY_9485_ANT_DIV_ALT_LNACONF_S)
+                  & AR_PHY_9485_ANT_DIV_ALT_LNACONF);
+       regval |= ((antconf->fast_div_bias << AR_PHY_9485_ANT_FAST_DIV_BIAS_S)
+                  & AR_PHY_9485_ANT_FAST_DIV_BIAS);
+       regval |= ((antconf->main_gaintb << AR_PHY_9485_ANT_DIV_MAIN_GAINTB_S)
+                  & AR_PHY_9485_ANT_DIV_MAIN_GAINTB);
+       regval |= ((antconf->alt_gaintb << AR_PHY_9485_ANT_DIV_ALT_GAINTB_S)
+                  & AR_PHY_9485_ANT_DIV_ALT_GAINTB);
+
+       REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, regval);
+}
+
+void ar9003_hw_attach_phy_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);
+       static 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,
+       };
+
+       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->set_diversity = ar9003_hw_set_diversity;
+       priv_ops->ani_control = ar9003_hw_ani_control;
+       priv_ops->do_getnf = ar9003_hw_do_getnf;
+       priv_ops->ani_cache_ini_regs = ar9003_hw_ani_cache_ini_regs;
+       priv_ops->set_radar_params = ar9003_hw_set_radar_params;
+
+       ops->antdiv_comb_conf_get = ar9003_hw_antdiv_comb_conf_get;
+       ops->antdiv_comb_conf_set = ar9003_hw_antdiv_comb_conf_set;
+
+       ar9003_hw_set_nf_limits(ah);
+       ar9003_hw_set_radar_conf(ah);
+       memcpy(ah->nf_regs, ar9300_cca_regs, sizeof(ah->nf_regs));
+}
+
+void ar9003_hw_disable_phy_restart(struct ath_hw *ah)
+{
+       u32 val;
+
+       val = REG_READ(ah, AR_PHY_RESTART);
+       val &= ~AR_PHY_RESTART_ENA;
+
+       REG_WRITE(ah, AR_PHY_RESTART, val);
+}
diff --git a/src/drivers/net/ath/ath9k/ath9k_calib.c b/src/drivers/net/ath/ath9k/ath9k_calib.c
new file mode 100644 (file)
index 0000000..6f3e07e
--- /dev/null
@@ -0,0 +1,403 @@
+/*
+ * Copyright (c) 2008-2011 Atheros Communications Inc.
+ *
+ * Modified for iPXE by Scott K Logan <logans@cottsay.net> July 2011
+ * Original from Linux kernel 3.0.1
+ *
+ * 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"
+
+/* Common calibration code */
+
+#define ATH9K_NF_TOO_HIGH      -60
+
+static int16_t ath9k_hw_get_nf_hist_mid(int16_t *nfCalBuffer)
+{
+       int16_t nfval;
+       int16_t sort[ATH9K_NF_CAL_HIST_MAX];
+       int i, j;
+
+       for (i = 0; i < ATH9K_NF_CAL_HIST_MAX; i++)
+               sort[i] = nfCalBuffer[i];
+
+       for (i = 0; i < ATH9K_NF_CAL_HIST_MAX - 1; i++) {
+               for (j = 1; j < ATH9K_NF_CAL_HIST_MAX - i; j++) {
+                       if (sort[j] > sort[j - 1]) {
+                               nfval = sort[j];
+                               sort[j] = sort[j - 1];
+                               sort[j - 1] = nfval;
+                       }
+               }
+       }
+       nfval = sort[(ATH9K_NF_CAL_HIST_MAX - 1) >> 1];
+
+       return nfval;
+}
+
+static struct ath_nf_limits *ath9k_hw_get_nf_limits(struct ath_hw *ah,
+                                                   struct ath9k_channel *chan)
+{
+       struct ath_nf_limits *limit;
+
+       if (!chan || IS_CHAN_2GHZ(chan))
+               limit = &ah->nf_2g;
+       else
+               limit = &ah->nf_5g;
+
+       return limit;
+}
+
+static s16 ath9k_hw_get_default_nf(struct ath_hw *ah,
+                                  struct ath9k_channel *chan)
+{
+       return ath9k_hw_get_nf_limits(ah, chan)->nominal;
+}
+
+
+static void ath9k_hw_update_nfcal_hist_buffer(struct ath_hw *ah,
+                                             struct ath9k_hw_cal_data *cal,
+                                             int16_t *nfarray)
+{
+       struct ath_nf_limits *limit;
+       struct ath9k_nfcal_hist *h;
+       int high_nf_mid = 0;
+       u8 chainmask = (ah->rxchainmask << 3) | ah->rxchainmask;
+       int i;
+
+       h = cal->nfCalHist;
+       limit = ath9k_hw_get_nf_limits(ah, ah->curchan);
+
+       for (i = 0; i < NUM_NF_READINGS; i++) {
+               if (!(chainmask & (1 << i)) ||
+                   (i >= AR5416_MAX_CHAINS))
+                       continue;
+
+               h[i].nfCalBuffer[h[i].currIndex] = nfarray[i];
+
+               if (++h[i].currIndex >= ATH9K_NF_CAL_HIST_MAX)
+                       h[i].currIndex = 0;
+
+               if (h[i].invalidNFcount > 0) {
+                       h[i].invalidNFcount--;
+                       h[i].privNF = nfarray[i];
+               } else {
+                       h[i].privNF =
+                               ath9k_hw_get_nf_hist_mid(h[i].nfCalBuffer);
+               }
+
+               if (!h[i].privNF)
+                       continue;
+
+               if (h[i].privNF > limit->max) {
+                       high_nf_mid = 1;
+
+                       DBG2("ath9k: "
+                               "NFmid[%d] (%d) > MAX (%d), %s\n",
+                               i, h[i].privNF, limit->max,
+                               (cal->nfcal_interference ?
+                                "not corrected (due to interference)" :
+                                "correcting to MAX"));
+
+                       /*
+                        * Normally we limit the average noise floor by the
+                        * hardware specific maximum here. However if we have
+                        * encountered stuck beacons because of interference,
+                        * we bypass this limit here in order to better deal
+                        * with our environment.
+                        */
+                       if (!cal->nfcal_interference)
+                               h[i].privNF = limit->max;
+               }
+       }
+
+       /*
+        * If the noise floor seems normal for all chains, assume that
+        * there is no significant interference in the environment anymore.
+        * Re-enable the enforcement of the NF maximum again.
+        */
+       if (!high_nf_mid)
+               cal->nfcal_interference = 0;
+}
+
+static int ath9k_hw_get_nf_thresh(struct ath_hw *ah,
+                                  int band,
+                                  int16_t *nft)
+{
+       switch (band) {
+       case NET80211_BAND_5GHZ:
+               *nft = (int8_t)ah->eep_ops->get_eeprom(ah, EEP_NFTHRESH_5);
+               break;
+       case NET80211_BAND_2GHZ:
+               *nft = (int8_t)ah->eep_ops->get_eeprom(ah, EEP_NFTHRESH_2);
+               break;
+       default:
+               return 0;
+       }
+
+       return 1;
+}
+
+void ath9k_hw_reset_calibration(struct ath_hw *ah,
+                               struct ath9k_cal_list *currCal)
+{
+       int i;
+
+       ath9k_hw_setup_calibration(ah, currCal);
+
+       currCal->calState = CAL_RUNNING;
+
+       for (i = 0; i < AR5416_MAX_CHAINS; i++) {
+               ah->meas0.sign[i] = 0;
+               ah->meas1.sign[i] = 0;
+               ah->meas2.sign[i] = 0;
+               ah->meas3.sign[i] = 0;
+       }
+
+       ah->cal_samples = 0;
+}
+
+/* This is done for the currently configured channel */
+int ath9k_hw_reset_calvalid(struct ath_hw *ah)
+{
+       struct ath9k_cal_list *currCal = ah->cal_list_curr;
+
+       if (!ah->caldata)
+               return 1;
+
+       if (!AR_SREV_9100(ah) && !AR_SREV_9160_10_OR_LATER(ah))
+               return 1;
+
+       if (currCal == NULL)
+               return 1;
+
+       if (currCal->calState != CAL_DONE) {
+               DBG("ath9k: "
+                       "Calibration state incorrect, %d\n",
+                       currCal->calState);
+               return 1;
+       }
+
+       if (!(ah->supp_cals & currCal->calData->calType))
+               return 1;
+
+       DBG("ath9k: "
+               "Resetting Cal %d state for channel %d\n",
+               currCal->calData->calType, (ah->dev->channels + ah->dev->channel)->center_freq);
+
+       ah->caldata->CalValid &= ~currCal->calData->calType;
+       currCal->calState = CAL_WAITING;
+
+       return 0;
+}
+
+void ath9k_hw_start_nfcal(struct ath_hw *ah, int update)
+{
+       if (ah->caldata)
+               ah->caldata->nfcal_pending = 1;
+
+       REG_SET_BIT(ah, AR_PHY_AGC_CONTROL,
+                   AR_PHY_AGC_CONTROL_ENABLE_NF);
+
+       if (update)
+               REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
+                   AR_PHY_AGC_CONTROL_NO_UPDATE_NF);
+       else
+               REG_SET_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);
+}
+
+void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)
+{
+       struct ath9k_nfcal_hist *h = NULL;
+       unsigned i, j;
+       int32_t val;
+       u8 chainmask = (ah->rxchainmask << 3) | ah->rxchainmask;
+       s16 default_nf = ath9k_hw_get_default_nf(ah, chan);
+
+       if (ah->caldata)
+               h = ah->caldata->nfCalHist;
+
+       for (i = 0; i < NUM_NF_READINGS; i++) {
+               if (chainmask & (1 << i)) {
+                       s16 nfval;
+
+                       if (i >= AR5416_MAX_CHAINS)
+                               continue;
+
+                       if (h)
+                               nfval = h[i].privNF;
+                       else
+                               nfval = default_nf;
+
+                       val = REG_READ(ah, ah->nf_regs[i]);
+                       val &= 0xFFFFFE00;
+                       val |= (((u32) nfval << 1) & 0x1ff);
+                       REG_WRITE(ah, ah->nf_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 < 10000; 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 == 10000) {
+               DBG("ath9k: "
+                       "Timeout while waiting for nf to load: AR_PHY_AGC_CONTROL=0x%x\n",
+                       REG_READ(ah, AR_PHY_AGC_CONTROL));
+               return;
+       }
+
+       /*
+        * 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.
+        */
+       ENABLE_REGWRITE_BUFFER(ah);
+       for (i = 0; i < NUM_NF_READINGS; i++) {
+               if (chainmask & (1 << i)) {
+                       if (i >= AR5416_MAX_CHAINS)
+                               continue;
+
+                       val = REG_READ(ah, ah->nf_regs[i]);
+                       val &= 0xFFFFFE00;
+                       val |= (((u32) (-50) << 1) & 0x1ff);
+                       REG_WRITE(ah, ah->nf_regs[i], val);
+               }
+       }
+       REGWRITE_BUFFER_FLUSH(ah);
+}
+
+
+static void ath9k_hw_nf_sanitize(struct ath_hw *ah, s16 *nf)
+{
+       struct ath_nf_limits *limit;
+       int i;
+
+       if (IS_CHAN_2GHZ(ah->curchan))
+               limit = &ah->nf_2g;
+       else
+               limit = &ah->nf_5g;
+
+       for (i = 0; i < NUM_NF_READINGS; i++) {
+               if (!nf[i])
+                       continue;
+
+               DBG2("ath9k: "
+                       "NF calibrated [%s] [chain %d] is %d\n",
+                       (i >= 3 ? "ext" : "ctl"), i % 3, nf[i]);
+
+               if (nf[i] > ATH9K_NF_TOO_HIGH) {
+                       DBG("ath9k: "
+                               "NF[%d] (%d) > MAX (%d), correcting to MAX\n",
+                               i, nf[i], ATH9K_NF_TOO_HIGH);
+                       nf[i] = limit->max;
+               } else if (nf[i] < limit->min) {
+                       DBG("ath9k: "
+                               "NF[%d] (%d) < MIN (%d), correcting to NOM\n",
+                               i, nf[i], limit->min);
+                       nf[i] = limit->nominal;
+               }
+       }
+}
+
+int ath9k_hw_getnf(struct ath_hw *ah, struct ath9k_channel *chan)
+{
+       int16_t nf, nfThresh;
+       int16_t nfarray[NUM_NF_READINGS] = { 0 };
+       struct ath9k_nfcal_hist *h;
+       struct net80211_channel *c = chan->chan;
+       struct ath9k_hw_cal_data *caldata = ah->caldata;
+
+       chan->channelFlags &= (~CHANNEL_CW_INT);
+       if (REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) {
+               DBG("ath9k: "
+                       "NF did not complete in calibration window\n");
+               return 0;
+       }
+
+       ath9k_hw_do_getnf(ah, nfarray);
+       ath9k_hw_nf_sanitize(ah, nfarray);
+       nf = nfarray[0];
+       if (ath9k_hw_get_nf_thresh(ah, c->band, &nfThresh)
+           && nf > nfThresh) {
+               DBG2("ath9k: "
+                       "noise floor failed detected; detected %d, threshold %d\n",
+                       nf, nfThresh);
+               chan->channelFlags |= CHANNEL_CW_INT;
+       }
+
+       if (!caldata) {
+               chan->noisefloor = nf;
+               return 0;
+       }
+
+       h = caldata->nfCalHist;
+       caldata->nfcal_pending = 0;
+       ath9k_hw_update_nfcal_hist_buffer(ah, caldata, nfarray);
+       chan->noisefloor = h[0].privNF;
+       return 1;
+}
+
+void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah,
+                                 struct ath9k_channel *chan)
+{
+       struct ath9k_nfcal_hist *h;
+       s16 default_nf;
+       int i, j;
+
+       ah->caldata->channel = chan->channel;
+       ah->caldata->channelFlags = chan->channelFlags & ~CHANNEL_CW_INT;
+       h = ah->caldata->nfCalHist;
+       default_nf = ath9k_hw_get_default_nf(ah, chan);
+       for (i = 0; i < NUM_NF_READINGS; i++) {
+               h[i].currIndex = 0;
+               h[i].privNF = default_nf;
+               h[i].invalidNFcount = AR_PHY_CCA_FILTERWINDOW_LENGTH;
+               for (j = 0; j < ATH9K_NF_CAL_HIST_MAX; j++) {
+                       h[i].nfCalBuffer[j] = default_nf;
+               }
+       }
+}
diff --git a/src/drivers/net/ath/ath9k/ath9k_common.c b/src/drivers/net/ath/ath9k/ath9k_common.c
new file mode 100644 (file)
index 0000000..ce33afb
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2009-2011 Atheros Communications Inc.
+ *
+ * Modified for iPXE by Scott K Logan <logans@cottsay.net> July 2011
+ * Original from Linux kernel 3.0.1
+ *
+ * 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.
+ */
+
+/*
+ * Module for common driver code between ath9k and ath9k_htc
+ */
+
+#include "common.h"
+
+/*
+ * Update internal channel flags.
+ */
+void ath9k_cmn_update_ichannel(struct ath9k_channel *ichan,
+                              struct net80211_channel *chan)
+{
+       ichan->channel = chan->center_freq;
+       ichan->chan = chan;
+
+       if (chan->band == NET80211_BAND_2GHZ) {
+               ichan->chanmode = CHANNEL_G;
+               ichan->channelFlags = CHANNEL_2GHZ | CHANNEL_OFDM;
+       } else {
+               ichan->chanmode = CHANNEL_A;
+               ichan->channelFlags = CHANNEL_5GHZ | CHANNEL_OFDM;
+       }
+}
+
+/*
+ * Get the internal channel reference.
+ */
+struct ath9k_channel *ath9k_cmn_get_curchannel(struct net80211_device *dev,
+                                              struct ath_hw *ah)
+{
+       struct net80211_channel *curchan = dev->channels + dev->channel;
+       struct ath9k_channel *channel;
+       u8 chan_idx;
+
+       chan_idx = curchan->hw_value;
+       channel = &ah->channels[chan_idx];
+       ath9k_cmn_update_ichannel(channel, curchan);
+
+       return channel;
+}
+
+void ath9k_cmn_update_txpow(struct ath_hw *ah, u16 cur_txpow,
+                           u16 new_txpow, u16 *txpower)
+{
+       if (cur_txpow != new_txpow) {
+               ath9k_hw_set_txpowerlimit(ah, new_txpow, 0);
+               /* read back in case value is clamped */
+               *txpower = ath9k_hw_regulatory(ah)->power_limit;
+       }
+}
diff --git a/src/drivers/net/ath/ath9k/ath9k_eeprom.c b/src/drivers/net/ath/ath9k/ath9k_eeprom.c
new file mode 100644 (file)
index 0000000..f552aca
--- /dev/null
@@ -0,0 +1,551 @@
+/*
+ * Copyright (c) 2008-2011 Atheros Communications Inc.
+ *
+ * Modified for iPXE by Scott K Logan <logans@cottsay.net> July 2011
+ * Original from Linux kernel 3.0.1
+ *
+ * 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 <ipxe/io.h>
+
+#include "hw.h"
+
+static inline u16 ath9k_hw_fbin2freq(u8 fbin, int is2GHz)
+{
+       if (fbin == AR5416_BCHAN_UNUSED)
+               return fbin;
+
+       return (u16) ((is2GHz) ? (2300 + fbin) : (4800 + 5 * fbin));
+}
+
+void ath9k_hw_analog_shift_regwrite(struct ath_hw *ah, u32 reg, u32 val)
+{
+        REG_WRITE(ah, reg, val);
+
+        if (ah->config.analog_shiftreg)
+               udelay(100);
+}
+
+void ath9k_hw_analog_shift_rmw(struct ath_hw *ah, u32 reg, u32 mask,
+                              u32 shift, u32 val)
+{
+       u32 regVal;
+
+       regVal = REG_READ(ah, reg) & ~mask;
+       regVal |= (val << shift) & mask;
+
+       REG_WRITE(ah, reg, regVal);
+
+       if (ah->config.analog_shiftreg)
+               udelay(100);
+}
+
+int16_t ath9k_hw_interpolate(u16 target, u16 srcLeft, u16 srcRight,
+                            int16_t targetLeft, int16_t targetRight)
+{
+       int16_t rv;
+
+       if (srcRight == srcLeft) {
+               rv = targetLeft;
+       } else {
+               rv = (int16_t) (((target - srcLeft) * targetRight +
+                                (srcRight - target) * targetLeft) /
+                               (srcRight - srcLeft));
+       }
+       return rv;
+}
+
+int ath9k_hw_get_lower_upper_index(u8 target, u8 *pList, u16 listSize,
+                                   u16 *indexL, u16 *indexR)
+{
+       u16 i;
+
+       if (target <= pList[0]) {
+               *indexL = *indexR = 0;
+               return 1;
+       }
+       if (target >= pList[listSize - 1]) {
+               *indexL = *indexR = (u16) (listSize - 1);
+               return 1;
+       }
+
+       for (i = 0; i < listSize - 1; i++) {
+               if (pList[i] == target) {
+                       *indexL = *indexR = i;
+                       return 1;
+               }
+               if (target < pList[i + 1]) {
+                       *indexL = i;
+                       *indexR = (u16) (i + 1);
+                       return 0;
+               }
+       }
+       return 0;
+}
+
+void ath9k_hw_usb_gen_fill_eeprom(struct ath_hw *ah, u16 *eep_data,
+                                 int eep_start_loc, int size)
+{
+       int i = 0, j, addr;
+       u32 addrdata[8];
+       u32 data[8];
+
+       for (addr = 0; addr < size; addr++) {
+               addrdata[i] = AR5416_EEPROM_OFFSET +
+                       ((addr + eep_start_loc) << AR5416_EEPROM_S);
+               i++;
+               if (i == 8) {
+                       REG_READ_MULTI(ah, addrdata, data, i);
+
+                       for (j = 0; j < i; j++) {
+                               *eep_data = data[j];
+                               eep_data++;
+                       }
+                       i = 0;
+               }
+       }
+
+       if (i != 0) {
+               REG_READ_MULTI(ah, addrdata, data, i);
+
+               for (j = 0; j < i; j++) {
+                       *eep_data = data[j];
+                       eep_data++;
+               }
+       }
+}
+
+int ath9k_hw_nvram_read(struct ath_common *common, u32 off, u16 *data)
+{
+       return common->bus_ops->eeprom_read(common, off, data);
+}
+
+void ath9k_hw_fill_vpd_table(u8 pwrMin, u8 pwrMax, u8 *pPwrList,
+                            u8 *pVpdList, u16 numIntercepts,
+                            u8 *pRetVpdList)
+{
+       u16 i, k;
+       u8 currPwr = pwrMin;
+       u16 idxL = 0, idxR = 0;
+
+       for (i = 0; i <= (pwrMax - pwrMin) / 2; i++) {
+               ath9k_hw_get_lower_upper_index(currPwr, pPwrList,
+                                              numIntercepts, &(idxL),
+                                              &(idxR));
+               if (idxR < 1)
+                       idxR = 1;
+               if (idxL == numIntercepts - 1)
+                       idxL = (u16) (numIntercepts - 2);
+               if (pPwrList[idxL] == pPwrList[idxR])
+                       k = pVpdList[idxL];
+               else
+                       k = (u16)(((currPwr - pPwrList[idxL]) * pVpdList[idxR] +
+                                  (pPwrList[idxR] - currPwr) * pVpdList[idxL]) /
+                                 (pPwrList[idxR] - pPwrList[idxL]));
+               pRetVpdList[i] = (u8) k;
+               currPwr += 2;
+       }
+}
+
+void ath9k_hw_get_legacy_target_powers(struct ath_hw *ah,
+                                      struct ath9k_channel *chan,
+                                      struct cal_target_power_leg *powInfo,
+                                      u16 numChannels,
+                                      struct cal_target_power_leg *pNewPower,
+                                      u16 numRates, int isExtTarget)
+{
+       struct chan_centers centers;
+       u16 clo, chi;
+       int i;
+       int matchIndex = -1, lowIndex = -1;
+       u16 freq;
+
+       ath9k_hw_get_channel_centers(ah, chan, &centers);
+       freq = (isExtTarget) ? centers.ext_center : centers.ctl_center;
+
+       if (freq <= ath9k_hw_fbin2freq(powInfo[0].bChannel,
+                                      IS_CHAN_2GHZ(chan))) {
+               matchIndex = 0;
+       } else {
+               for (i = 0; (i < numChannels) &&
+                            (powInfo[i].bChannel != AR5416_BCHAN_UNUSED); i++) {
+                       if (freq == ath9k_hw_fbin2freq(powInfo[i].bChannel,
+                                                      IS_CHAN_2GHZ(chan))) {
+                               matchIndex = i;
+                               break;
+                       } else if (freq < ath9k_hw_fbin2freq(powInfo[i].bChannel,
+                                               IS_CHAN_2GHZ(chan)) && i > 0 &&
+                                  freq > ath9k_hw_fbin2freq(powInfo[i - 1].bChannel,
+                                               IS_CHAN_2GHZ(chan))) {
+                               lowIndex = i - 1;
+                               break;
+                       }
+               }
+               if ((matchIndex == -1) && (lowIndex == -1))
+                       matchIndex = i - 1;
+       }
+
+       if (matchIndex != -1) {
+               *pNewPower = powInfo[matchIndex];
+       } else {
+               clo = ath9k_hw_fbin2freq(powInfo[lowIndex].bChannel,
+                                        IS_CHAN_2GHZ(chan));
+               chi = ath9k_hw_fbin2freq(powInfo[lowIndex + 1].bChannel,
+                                        IS_CHAN_2GHZ(chan));
+
+               for (i = 0; i < numRates; i++) {
+                       pNewPower->tPow2x[i] =
+                               (u8)ath9k_hw_interpolate(freq, clo, chi,
+                                               powInfo[lowIndex].tPow2x[i],
+                                               powInfo[lowIndex + 1].tPow2x[i]);
+               }
+       }
+}
+
+void ath9k_hw_get_target_powers(struct ath_hw *ah,
+                               struct ath9k_channel *chan,
+                               struct cal_target_power_ht *powInfo,
+                               u16 numChannels,
+                               struct cal_target_power_ht *pNewPower,
+                               u16 numRates, int isHt40Target)
+{
+       struct chan_centers centers;
+       u16 clo, chi;
+       int i;
+       int matchIndex = -1, lowIndex = -1;
+       u16 freq;
+
+       ath9k_hw_get_channel_centers(ah, chan, &centers);
+       freq = isHt40Target ? centers.synth_center : centers.ctl_center;
+
+       if (freq <= ath9k_hw_fbin2freq(powInfo[0].bChannel, IS_CHAN_2GHZ(chan))) {
+               matchIndex = 0;
+       } else {
+               for (i = 0; (i < numChannels) &&
+                            (powInfo[i].bChannel != AR5416_BCHAN_UNUSED); i++) {
+                       if (freq == ath9k_hw_fbin2freq(powInfo[i].bChannel,
+                                                      IS_CHAN_2GHZ(chan))) {
+                               matchIndex = i;
+                               break;
+                       } else
+                               if (freq < ath9k_hw_fbin2freq(powInfo[i].bChannel,
+                                               IS_CHAN_2GHZ(chan)) && i > 0 &&
+                                   freq > ath9k_hw_fbin2freq(powInfo[i - 1].bChannel,
+                                               IS_CHAN_2GHZ(chan))) {
+                                       lowIndex = i - 1;
+                                       break;
+                               }
+               }
+               if ((matchIndex == -1) && (lowIndex == -1))
+                       matchIndex = i - 1;
+       }
+
+       if (matchIndex != -1) {
+               *pNewPower = powInfo[matchIndex];
+       } else {
+               clo = ath9k_hw_fbin2freq(powInfo[lowIndex].bChannel,
+                                        IS_CHAN_2GHZ(chan));
+               chi = ath9k_hw_fbin2freq(powInfo[lowIndex + 1].bChannel,
+                                        IS_CHAN_2GHZ(chan));
+
+               for (i = 0; i < numRates; i++) {
+                       pNewPower->tPow2x[i] = (u8)ath9k_hw_interpolate(freq,
+                                               clo, chi,
+                                               powInfo[lowIndex].tPow2x[i],
+                                               powInfo[lowIndex + 1].tPow2x[i]);
+               }
+       }
+}
+
+u16 ath9k_hw_get_max_edge_power(u16 freq, struct cal_ctl_edges *pRdEdgesPower,
+                               int is2GHz, int num_band_edges)
+{
+       u16 twiceMaxEdgePower = MAX_RATE_POWER;
+       int i;
+
+       for (i = 0; (i < num_band_edges) &&
+                    (pRdEdgesPower[i].bChannel != AR5416_BCHAN_UNUSED); i++) {
+               if (freq == ath9k_hw_fbin2freq(pRdEdgesPower[i].bChannel, is2GHz)) {
+                       twiceMaxEdgePower = CTL_EDGE_TPOWER(pRdEdgesPower[i].ctl);
+                       break;
+               } else if ((i > 0) &&
+                          (freq < ath9k_hw_fbin2freq(pRdEdgesPower[i].bChannel,
+                                                     is2GHz))) {
+                       if (ath9k_hw_fbin2freq(pRdEdgesPower[i - 1].bChannel,
+                                              is2GHz) < freq &&
+                           CTL_EDGE_FLAGS(pRdEdgesPower[i - 1].ctl)) {
+                               twiceMaxEdgePower =
+                                       CTL_EDGE_TPOWER(pRdEdgesPower[i - 1].ctl);
+                       }
+                       break;
+               }
+       }
+
+       return twiceMaxEdgePower;
+}
+
+void ath9k_hw_update_regulatory_maxpower(struct ath_hw *ah)
+{
+       struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
+
+       switch (ar5416_get_ntxchains(ah->txchainmask)) {
+       case 1:
+               break;
+       case 2:
+               regulatory->max_power_level += INCREASE_MAXPOW_BY_TWO_CHAIN;
+               break;
+       case 3:
+               regulatory->max_power_level += INCREASE_MAXPOW_BY_THREE_CHAIN;
+               break;
+       default:
+               DBG2("ath9k: "
+                       "Invalid chainmask configuration\n");
+               break;
+       }
+}
+
+void ath9k_hw_get_gain_boundaries_pdadcs(struct ath_hw *ah,
+                               struct ath9k_channel *chan,
+                               void *pRawDataSet,
+                               u8 *bChans, u16 availPiers,
+                               u16 tPdGainOverlap,
+                               u16 *pPdGainBoundaries, u8 *pPDADCValues,
+                               u16 numXpdGains)
+{
+       int i, j, k;
+       int16_t ss;
+       u16 idxL = 0, idxR = 0, numPiers;
+       static u8 vpdTableL[AR5416_NUM_PD_GAINS]
+               [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
+       static u8 vpdTableR[AR5416_NUM_PD_GAINS]
+               [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
+       static u8 vpdTableI[AR5416_NUM_PD_GAINS]
+               [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
+
+       u8 *pVpdL, *pVpdR, *pPwrL, *pPwrR;
+       u8 minPwrT4[AR5416_NUM_PD_GAINS];
+       u8 maxPwrT4[AR5416_NUM_PD_GAINS];
+       int16_t vpdStep;
+       int16_t tmpVal;
+       u16 sizeCurrVpdTable, maxIndex, tgtIndex;
+       int match;
+       int16_t minDelta = 0;
+       struct chan_centers centers;
+       int pdgain_boundary_default;
+       struct cal_data_per_freq *data_def = pRawDataSet;
+       struct cal_data_per_freq_4k *data_4k = pRawDataSet;
+       struct cal_data_per_freq_ar9287 *data_9287 = pRawDataSet;
+       int eeprom_4k = AR_SREV_9285(ah) || AR_SREV_9271(ah);
+       int intercepts;
+
+       if (AR_SREV_9287(ah))
+               intercepts = AR9287_PD_GAIN_ICEPTS;
+       else
+               intercepts = AR5416_PD_GAIN_ICEPTS;
+
+       memset(&minPwrT4, 0, AR5416_NUM_PD_GAINS);
+       ath9k_hw_get_channel_centers(ah, chan, &centers);
+
+       for (numPiers = 0; numPiers < availPiers; numPiers++) {
+               if (bChans[numPiers] == AR5416_BCHAN_UNUSED)
+                       break;
+       }
+
+       match = ath9k_hw_get_lower_upper_index((u8)FREQ2FBIN(centers.synth_center,
+                                                            IS_CHAN_2GHZ(chan)),
+                                              bChans, numPiers, &idxL, &idxR);
+
+       if (match) {
+               if (AR_SREV_9287(ah)) {
+                       /* FIXME: array overrun? */
+                       for (i = 0; i < numXpdGains; i++) {
+                               minPwrT4[i] = data_9287[idxL].pwrPdg[i][0];
+                               maxPwrT4[i] = data_9287[idxL].pwrPdg[i][4];
+                               ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
+                                               data_9287[idxL].pwrPdg[i],
+                                               data_9287[idxL].vpdPdg[i],
+                                               intercepts,
+                                               vpdTableI[i]);
+                       }
+               } else if (eeprom_4k) {
+                       for (i = 0; i < numXpdGains; i++) {
+                               minPwrT4[i] = data_4k[idxL].pwrPdg[i][0];
+                               maxPwrT4[i] = data_4k[idxL].pwrPdg[i][4];
+                               ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
+                                               data_4k[idxL].pwrPdg[i],
+                                               data_4k[idxL].vpdPdg[i],
+                                               intercepts,
+                                               vpdTableI[i]);
+                       }
+               } else {
+                       for (i = 0; i < numXpdGains; i++) {
+                               minPwrT4[i] = data_def[idxL].pwrPdg[i][0];
+                               maxPwrT4[i] = data_def[idxL].pwrPdg[i][4];
+                               ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
+                                               data_def[idxL].pwrPdg[i],
+                                               data_def[idxL].vpdPdg[i],
+                                               intercepts,
+                                               vpdTableI[i]);
+                       }
+               }
+       } else {
+               for (i = 0; i < numXpdGains; i++) {
+                       if (AR_SREV_9287(ah)) {
+                               pVpdL = data_9287[idxL].vpdPdg[i];
+                               pPwrL = data_9287[idxL].pwrPdg[i];
+                               pVpdR = data_9287[idxR].vpdPdg[i];
+                               pPwrR = data_9287[idxR].pwrPdg[i];
+                       } else if (eeprom_4k) {
+                               pVpdL = data_4k[idxL].vpdPdg[i];
+                               pPwrL = data_4k[idxL].pwrPdg[i];
+                               pVpdR = data_4k[idxR].vpdPdg[i];
+                               pPwrR = data_4k[idxR].pwrPdg[i];
+                       } else {
+                               pVpdL = data_def[idxL].vpdPdg[i];
+                               pPwrL = data_def[idxL].pwrPdg[i];
+                               pVpdR = data_def[idxR].vpdPdg[i];
+                               pPwrR = data_def[idxR].pwrPdg[i];
+                       }
+
+                       minPwrT4[i] = max(pPwrL[0], pPwrR[0]);
+
+                       maxPwrT4[i] =
+                               min(pPwrL[intercepts - 1],
+                                   pPwrR[intercepts - 1]);
+
+
+                       ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
+                                               pPwrL, pVpdL,
+                                               intercepts,
+                                               vpdTableL[i]);
+                       ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
+                                               pPwrR, pVpdR,
+                                               intercepts,
+                                               vpdTableR[i]);
+
+                       for (j = 0; j <= (maxPwrT4[i] - minPwrT4[i]) / 2; j++) {
+                               vpdTableI[i][j] =
+                                       (u8)(ath9k_hw_interpolate((u16)
+                                            FREQ2FBIN(centers.
+                                                      synth_center,
+                                                      IS_CHAN_2GHZ
+                                                      (chan)),
+                                            bChans[idxL], bChans[idxR],
+                                            vpdTableL[i][j], vpdTableR[i][j]));
+                       }
+               }
+       }
+
+       k = 0;
+
+       for (i = 0; i < numXpdGains; i++) {
+               if (i == (numXpdGains - 1))
+                       pPdGainBoundaries[i] =
+                               (u16)(maxPwrT4[i] / 2);
+               else
+                       pPdGainBoundaries[i] =
+                               (u16)((maxPwrT4[i] + minPwrT4[i + 1]) / 4);
+
+               pPdGainBoundaries[i] =
+                       min((u16)MAX_RATE_POWER, pPdGainBoundaries[i]);
+
+               if ((i == 0) && !AR_SREV_5416_20_OR_LATER(ah)) {
+                       minDelta = pPdGainBoundaries[0] - 23;
+                       pPdGainBoundaries[0] = 23;
+               } else {
+                       minDelta = 0;
+               }
+
+               if (i == 0) {
+                       if (AR_SREV_9280_20_OR_LATER(ah))
+                               ss = (int16_t)(0 - (minPwrT4[i] / 2));
+                       else
+                               ss = 0;
+               } else {
+                       ss = (int16_t)((pPdGainBoundaries[i - 1] -
+                                       (minPwrT4[i] / 2)) -
+                                      tPdGainOverlap + 1 + minDelta);
+               }
+               vpdStep = (int16_t)(vpdTableI[i][1] - vpdTableI[i][0]);
+               vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
+
+               while ((ss < 0) && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
+                       tmpVal = (int16_t)(vpdTableI[i][0] + ss * vpdStep);
+                       pPDADCValues[k++] = (u8)((tmpVal < 0) ? 0 : tmpVal);
+                       ss++;
+               }
+
+               sizeCurrVpdTable = (u8) ((maxPwrT4[i] - minPwrT4[i]) / 2 + 1);
+               tgtIndex = (u8)(pPdGainBoundaries[i] + tPdGainOverlap -
+                               (minPwrT4[i] / 2));
+               maxIndex = (tgtIndex < sizeCurrVpdTable) ?
+                       tgtIndex : sizeCurrVpdTable;
+
+               while ((ss < maxIndex) && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
+                       pPDADCValues[k++] = vpdTableI[i][ss++];
+               }
+
+               vpdStep = (int16_t)(vpdTableI[i][sizeCurrVpdTable - 1] -
+                                   vpdTableI[i][sizeCurrVpdTable - 2]);
+               vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
+
+               if (tgtIndex >= maxIndex) {
+                       while ((ss <= tgtIndex) &&
+                              (k < (AR5416_NUM_PDADC_VALUES - 1))) {
+                               tmpVal = (int16_t)((vpdTableI[i][sizeCurrVpdTable - 1] +
+                                                   (ss - maxIndex + 1) * vpdStep));
+                               pPDADCValues[k++] = (u8)((tmpVal > 255) ?
+                                                        255 : tmpVal);
+                               ss++;
+                       }
+               }
+       }
+
+       if (eeprom_4k)
+               pdgain_boundary_default = 58;
+       else
+               pdgain_boundary_default = pPdGainBoundaries[i - 1];
+
+       while (i < AR5416_PD_GAINS_IN_MASK) {
+               pPdGainBoundaries[i] = pdgain_boundary_default;
+               i++;
+       }
+
+       while (k < AR5416_NUM_PDADC_VALUES) {
+               pPDADCValues[k] = pPDADCValues[k - 1];
+               k++;
+       }
+}
+
+int ath9k_hw_eeprom_init(struct ath_hw *ah)
+{
+       int status;
+
+       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_ops = &eep_4k_ops;
+       } else {
+               ah->eep_ops = &eep_def_ops;
+       }
+
+       if (!ah->eep_ops->fill_eeprom(ah))
+               return -EIO;
+
+       status = ah->eep_ops->check_eeprom(ah);
+
+       return status;
+}
diff --git a/src/drivers/net/ath/ath9k/ath9k_eeprom_4k.c b/src/drivers/net/ath/ath9k/ath9k_eeprom_4k.c
new file mode 100644 (file)
index 0000000..a42ad3d
--- /dev/null
@@ -0,0 +1,1078 @@
+/*
+ * Copyright (c) 2008-2011 Atheros Communications Inc.
+ *
+ * Modified for iPXE by Scott K Logan <logans@cottsay.net> July 2011
+ * Original from Linux kernel 3.0.1
+ *
+ * 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 <ipxe/io.h>
+
+#include "hw.h"
+#include "ar9002_phy.h"
+
+static int ath9k_hw_4k_get_eeprom_ver(struct ath_hw *ah)
+{
+       return ((ah->eeprom.map4k.baseEepHeader.version >> 12) & 0xF);
+}
+
+static int ath9k_hw_4k_get_eeprom_rev(struct ath_hw *ah)
+{
+       return ((ah->eeprom.map4k.baseEepHeader.version) & 0xFFF);
+}
+
+#define SIZE_EEPROM_4K (sizeof(struct ar5416_eeprom_4k) / sizeof(u16))
+
+static int __ath9k_hw_4k_fill_eeprom(struct ath_hw *ah)
+{
+       struct ath_common *common = ath9k_hw_common(ah);
+       u16 *eep_data = (u16 *)&ah->eeprom.map4k;
+       unsigned int addr;
+       int eep_start_loc = 64;
+
+       for (addr = 0; addr < SIZE_EEPROM_4K; addr++) {
+               if (!ath9k_hw_nvram_read(common, addr + eep_start_loc, eep_data)) {
+                       DBG("ath9k: "
+                               "Unable to read eeprom region\n");
+                       return 0;
+               }
+               eep_data++;
+       }
+
+       return 1;
+}
+
+static int __ath9k_hw_usb_4k_fill_eeprom(struct ath_hw *ah)
+{
+       u16 *eep_data = (u16 *)&ah->eeprom.map4k;
+
+       ath9k_hw_usb_gen_fill_eeprom(ah, eep_data, 64, SIZE_EEPROM_4K);
+
+       return 1;
+}
+
+static int ath9k_hw_4k_fill_eeprom(struct ath_hw *ah)
+{
+       struct ath_common *common = ath9k_hw_common(ah);
+
+       if (!ath9k_hw_use_flash(ah)) {
+               DBG2("ath9k: "
+                       "Reading from EEPROM, not flash\n");
+       }
+
+       if (common->bus_ops->ath_bus_type == ATH_USB)
+               return __ath9k_hw_usb_4k_fill_eeprom(ah);
+       else
+               return __ath9k_hw_4k_fill_eeprom(ah);
+}
+
+#undef SIZE_EEPROM_4K
+
+static int ath9k_hw_4k_check_eeprom(struct ath_hw *ah)
+{
+#define EEPROM_4K_SIZE (sizeof(struct ar5416_eeprom_4k) / sizeof(u16))
+       struct ath_common *common = ath9k_hw_common(ah);
+       struct ar5416_eeprom_4k *eep =
+               (struct ar5416_eeprom_4k *) &ah->eeprom.map4k;
+       u16 *eepdata, temp, magic, magic2;
+       u32 sum = 0, el;
+       int need_swap = 0;
+       unsigned int i, addr;
+
+
+       if (!ath9k_hw_use_flash(ah)) {
+               if (!ath9k_hw_nvram_read(common, AR5416_EEPROM_MAGIC_OFFSET,
+                                        &magic)) {
+                       DBG("ath9k: Reading Magic # failed\n");
+                       return 0;
+               }
+
+               DBG2("ath9k: "
+                       "Read Magic = 0x%04X\n", magic);
+
+               if (magic != AR5416_EEPROM_MAGIC) {
+                       magic2 = swab16(magic);
+
+                       if (magic2 == AR5416_EEPROM_MAGIC) {
+                               need_swap = 1;
+                               eepdata = (u16 *) (&ah->eeprom);
+
+                               for (addr = 0; addr < EEPROM_4K_SIZE; addr++) {
+                                       temp = swab16(*eepdata);
+                                       *eepdata = temp;
+                                       eepdata++;
+                               }
+                       } else {
+                               DBG("ath9k: "
+                                       "Invalid EEPROM Magic. Endianness mismatch.\n");
+                               return -EINVAL;
+                       }
+               }
+       }
+
+       DBG2("ath9k: need_swap = %s.\n",
+               need_swap ? "True" : "False");
+
+       if (need_swap)
+               el = swab16(ah->eeprom.map4k.baseEepHeader.length);
+       else
+               el = ah->eeprom.map4k.baseEepHeader.length;
+
+       if (el > sizeof(struct ar5416_eeprom_4k))
+               el = sizeof(struct ar5416_eeprom_4k) / sizeof(u16);
+       else
+               el = el / sizeof(u16);
+
+       eepdata = (u16 *)(&ah->eeprom);
+
+       for (i = 0; i < el; i++)
+               sum ^= *eepdata++;
+
+       if (need_swap) {
+               u32 integer;
+               u16 word;
+
+               DBG("ath9k: "
+                       "EEPROM Endianness is not native.. Changing\n");
+
+               word = swab16(eep->baseEepHeader.length);
+               eep->baseEepHeader.length = word;
+
+               word = swab16(eep->baseEepHeader.checksum);
+               eep->baseEepHeader.checksum = word;
+
+               word = swab16(eep->baseEepHeader.version);
+               eep->baseEepHeader.version = word;
+
+               word = swab16(eep->baseEepHeader.regDmn[0]);
+               eep->baseEepHeader.regDmn[0] = word;
+
+               word = swab16(eep->baseEepHeader.regDmn[1]);
+               eep->baseEepHeader.regDmn[1] = word;
+
+               word = swab16(eep->baseEepHeader.rfSilent);
+               eep->baseEepHeader.rfSilent = word;
+
+               word = swab16(eep->baseEepHeader.blueToothOptions);
+               eep->baseEepHeader.blueToothOptions = word;
+
+               word = swab16(eep->baseEepHeader.deviceCap);
+               eep->baseEepHeader.deviceCap = word;
+
+               integer = swab32(eep->modalHeader.antCtrlCommon);
+               eep->modalHeader.antCtrlCommon = integer;
+
+               for (i = 0; i < AR5416_EEP4K_MAX_CHAINS; i++) {
+                       integer = swab32(eep->modalHeader.antCtrlChain[i]);
+                       eep->modalHeader.antCtrlChain[i] = integer;
+               }
+
+               for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
+                       word = swab16(eep->modalHeader.spurChans[i].spurChan);
+                       eep->modalHeader.spurChans[i].spurChan = word;
+               }
+       }
+
+       if (sum != 0xffff || ah->eep_ops->get_eeprom_ver(ah) != AR5416_EEP_VER ||
+           ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_NO_BACK_VER) {
+               DBG("ath9k: Bad EEPROM checksum 0x%x or revision 0x%04x\n",
+                       sum, ah->eep_ops->get_eeprom_ver(ah));
+               return -EINVAL;
+       }
+
+       return 0;
+#undef EEPROM_4K_SIZE
+}
+
+static u32 ath9k_hw_4k_get_eeprom(struct ath_hw *ah,
+                                 enum eeprom_param param)
+{
+       struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k;
+       struct modal_eep_4k_header *pModal = &eep->modalHeader;
+       struct base_eep_header_4k *pBase = &eep->baseEepHeader;
+       u16 ver_minor;
+
+       ver_minor = pBase->version & AR5416_EEP_VER_MINOR_MASK;
+
+       switch (param) {
+       case EEP_NFTHRESH_2:
+               return pModal->noiseFloorThreshCh[0];
+       case EEP_MAC_LSW:
+               return pBase->macAddr[0] << 8 | pBase->macAddr[1];
+       case EEP_MAC_MID:
+               return pBase->macAddr[2] << 8 | pBase->macAddr[3];
+       case EEP_MAC_MSW:
+               return pBase->macAddr[4] << 8 | pBase->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;
+       case EEP_RF_SILENT:
+               return pBase->rfSilent;
+       case EEP_OB_2:
+               return pModal->ob_0;
+       case EEP_DB_2:
+               return pModal->db1_1;
+       case EEP_MINOR_REV:
+               return ver_minor;
+       case EEP_TX_MASK:
+               return pBase->txMask;
+       case EEP_RX_MASK:
+               return pBase->rxMask;
+       case EEP_FRAC_N_5G:
+               return 0;
+       case EEP_PWR_TABLE_OFFSET:
+               return AR5416_PWR_TABLE_OFFSET_DB;
+       case EEP_MODAL_VER:
+               return pModal->version;
+       case EEP_ANT_DIV_CTL1:
+               return pModal->antdiv_ctl1;
+       case EEP_TXGAIN_TYPE:
+               if (ver_minor >= AR5416_EEP_MINOR_VER_19)
+                       return pBase->txGainType;
+               else
+                       return AR5416_EEP_TXGAIN_ORIGINAL;
+       default:
+               return 0;
+       }
+}
+
+static void ath9k_hw_set_4k_power_cal_table(struct ath_hw *ah,
+                                 struct ath9k_channel *chan,
+                                 int16_t *pTxPowerIndexOffset)
+{
+       struct ar5416_eeprom_4k *pEepData = &ah->eeprom.map4k;
+       struct cal_data_per_freq_4k *pRawDataset;
+       u8 *pCalBChans = NULL;
+       u16 pdGainOverlap_t2;
+       static u8 pdadcValues[AR5416_NUM_PDADC_VALUES];
+       u16 gainBoundaries[AR5416_PD_GAINS_IN_MASK];
+       u16 numPiers, i, j;
+       u16 numXpdGain, xpdMask;
+       u16 xpdGainValues[AR5416_EEP4K_NUM_PD_GAINS] = { 0, 0 };
+       u32 reg32, regOffset, regChainOffset;
+
+       xpdMask = pEepData->modalHeader.xpdGain;
+
+       if ((pEepData->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
+           AR5416_EEP_MINOR_VER_2) {
+               pdGainOverlap_t2 =
+                       pEepData->modalHeader.pdGainOverlap;
+       } else {
+               pdGainOverlap_t2 = (u16)(MS(REG_READ(ah, AR_PHY_TPCRG5),
+                                           AR_PHY_TPCRG5_PD_GAIN_OVERLAP));
+       }
+
+       pCalBChans = pEepData->calFreqPier2G;
+       numPiers = AR5416_EEP4K_NUM_2G_CAL_PIERS;
+
+       numXpdGain = 0;
+
+       for (i = 1; i <= AR5416_PD_GAINS_IN_MASK; i++) {
+               if ((xpdMask >> (AR5416_PD_GAINS_IN_MASK - i)) & 1) {
+                       if (numXpdGain >= AR5416_EEP4K_NUM_PD_GAINS)
+                               break;
+                       xpdGainValues[numXpdGain] =
+                               (u16)(AR5416_PD_GAINS_IN_MASK - i);
+                       numXpdGain++;
+               }
+       }
+
+       REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_NUM_PD_GAIN,
+                     (numXpdGain - 1) & 0x3);
+       REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_1,
+                     xpdGainValues[0]);
+       REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_2,
+                     xpdGainValues[1]);
+       REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_3, 0);
+
+       for (i = 0; i < AR5416_EEP4K_MAX_CHAINS; i++) {
+               if (AR_SREV_5416_20_OR_LATER(ah) &&
+                   (ah->rxchainmask == 5 || ah->txchainmask == 5) &&
+                   (i != 0)) {
+                       regChainOffset = (i == 1) ? 0x2000 : 0x1000;
+               } else
+                       regChainOffset = i * 0x1000;
+
+               if (pEepData->baseEepHeader.txMask & (1 << i)) {
+                       pRawDataset = pEepData->calPierData2G[i];
+
+                       ath9k_hw_get_gain_boundaries_pdadcs(ah, chan,
+                                           pRawDataset, pCalBChans,
+                                           numPiers, pdGainOverlap_t2,
+                                           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,
+                                            AR_PHY_TPCRG5_PD_GAIN_OVERLAP)
+                                         | SM(gainBoundaries[0],
+                                              AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1)
+                                         | SM(gainBoundaries[1],
+                                              AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2)
+                                         | SM(gainBoundaries[2],
+                                              AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3)
+                                         | SM(gainBoundaries[3],
+                                      AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4));
+                       }
+
+                       regOffset = AR_PHY_BASE + (672 << 2) + regChainOffset;
+                       for (j = 0; j < 32; j++) {
+                               reg32 = ((pdadcValues[4 * j + 0] & 0xFF) << 0) |
+                                       ((pdadcValues[4 * j + 1] & 0xFF) << 8) |
+                                       ((pdadcValues[4 * j + 2] & 0xFF) << 16)|
+                                       ((pdadcValues[4 * j + 3] & 0xFF) << 24);
+                               REG_WRITE(ah, regOffset, reg32);
+
+                               DBG2("ath9k: "
+                                       "PDADC (%d,%4x): %4.4x %8.8x\n",
+                                       i, regChainOffset, regOffset,
+                                       reg32);
+                               DBG2("ath9k: "
+                                       "PDADC: Chain %d | "
+                                       "PDADC %3d Value %3d | "
+                                       "PDADC %3d Value %3d | "
+                                       "PDADC %3d Value %3d | "
+                                       "PDADC %3d Value %3d |\n",
+                                       i, 4 * j, pdadcValues[4 * j],
+                                       4 * j + 1, pdadcValues[4 * j + 1],
+                                       4 * j + 2, pdadcValues[4 * j + 2],
+                                       4 * j + 3, pdadcValues[4 * j + 3]);
+
+                               regOffset += 4;
+                       }
+
+                       REGWRITE_BUFFER_FLUSH(ah);
+               }
+       }
+
+       *pTxPowerIndexOffset = 0;
+}
+
+static void ath9k_hw_set_4k_power_per_rate_table(struct ath_hw *ah,
+                                                struct ath9k_channel *chan,
+                                                int16_t *ratesArray,
+                                                u16 cfgCtl,
+                                                u16 AntennaReduction,
+                                                u16 twiceMaxRegulatoryPower,
+                                                u16 powerLimit)
+{
+#define CMP_TEST_GRP \
+       (((cfgCtl & ~CTL_MODE_M)| (pCtlMode[ctlMode] & CTL_MODE_M)) ==  \
+        pEepData->ctlIndex[i])                                         \
+       || (((cfgCtl & ~CTL_MODE_M) | (pCtlMode[ctlMode] & CTL_MODE_M)) == \
+           ((pEepData->ctlIndex[i] & CTL_MODE_M) | SD_NO_CTL))
+
+       struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
+       unsigned int i;
+       int16_t twiceLargestAntenna;
+       u16 twiceMinEdgePower;
+       u16 twiceMaxEdgePower = MAX_RATE_POWER;
+       u16 scaledPower = 0, minCtlPower, maxRegAllowedPower;
+       u16 numCtlModes;
+       const u16 *pCtlMode;
+       u16 ctlMode, freq;
+       struct chan_centers centers;
+       struct cal_ctl_data_4k *rep;
+       struct ar5416_eeprom_4k *pEepData = &ah->eeprom.map4k;
+       static const u16 tpScaleReductionTable[5] =
+               { 0, 3, 6, 9, MAX_RATE_POWER };
+       struct cal_target_power_leg targetPowerOfdm, targetPowerCck = {
+               0, { 0, 0, 0, 0}
+       };
+       struct cal_target_power_leg targetPowerOfdmExt = {
+               0, { 0, 0, 0, 0} }, targetPowerCckExt = {
+               0, { 0, 0, 0, 0 }
+       };
+       struct cal_target_power_ht targetPowerHt20, targetPowerHt40 = {
+               0, {0, 0, 0, 0}
+       };
+       static const u16 ctlModesFor11g[] = {
+               CTL_11B, CTL_11G, CTL_2GHT20,
+               CTL_11B_EXT, CTL_11G_EXT, CTL_2GHT40
+       };
+
+       ath9k_hw_get_channel_centers(ah, chan, &centers);
+
+       twiceLargestAntenna = pEepData->modalHeader.antennaGainCh[0];
+       twiceLargestAntenna = (int16_t)min(AntennaReduction -
+                                          twiceLargestAntenna, 0);
+
+       maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna;
+       if (regulatory->tp_scale != ATH9K_TP_SCALE_MAX) {
+               maxRegAllowedPower -=
+                       (tpScaleReductionTable[(regulatory->tp_scale)] * 2);
+       }
+
+       scaledPower = min(powerLimit, maxRegAllowedPower);
+       scaledPower = max((u16)0, scaledPower);
+
+       numCtlModes = ARRAY_SIZE(ctlModesFor11g) - SUB_NUM_CTL_MODES_AT_2G_40;
+       pCtlMode = ctlModesFor11g;
+
+       ath9k_hw_get_legacy_target_powers(ah, chan,
+                       pEepData->calTargetPowerCck,
+                       AR5416_NUM_2G_CCK_TARGET_POWERS,
+                       &targetPowerCck, 4, 0);
+       ath9k_hw_get_legacy_target_powers(ah, chan,
+                       pEepData->calTargetPower2G,
+                       AR5416_NUM_2G_20_TARGET_POWERS,
+                       &targetPowerOfdm, 4, 0);
+       ath9k_hw_get_target_powers(ah, chan,
+                       pEepData->calTargetPower2GHT20,
+                       AR5416_NUM_2G_20_TARGET_POWERS,
+                       &targetPowerHt20, 8, 0);
+
+       if (IS_CHAN_HT40(chan)) {
+               numCtlModes = ARRAY_SIZE(ctlModesFor11g);
+               ath9k_hw_get_target_powers(ah, chan,
+                               pEepData->calTargetPower2GHT40,
+                               AR5416_NUM_2G_40_TARGET_POWERS,
+                               &targetPowerHt40, 8, 1);
+               ath9k_hw_get_legacy_target_powers(ah, chan,
+                               pEepData->calTargetPowerCck,
+                               AR5416_NUM_2G_CCK_TARGET_POWERS,
+                               &targetPowerCckExt, 4, 1);
+               ath9k_hw_get_legacy_target_powers(ah, chan,
+                               pEepData->calTargetPower2G,
+                               AR5416_NUM_2G_20_TARGET_POWERS,
+                               &targetPowerOfdmExt, 4, 1);
+       }
+
+       for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) {
+               int isHt40CtlMode = (pCtlMode[ctlMode] == CTL_5GHT40) ||
+                       (pCtlMode[ctlMode] == CTL_2GHT40);
+
+               if (isHt40CtlMode)
+                       freq = centers.synth_center;
+               else if (pCtlMode[ctlMode] & EXT_ADDITIVE)
+                       freq = centers.ext_center;
+               else
+                       freq = centers.ctl_center;
+
+               if (ah->eep_ops->get_eeprom_ver(ah) == 14 &&
+                   ah->eep_ops->get_eeprom_rev(ah) <= 2)
+                       twiceMaxEdgePower = MAX_RATE_POWER;
+
+               for (i = 0; (i < AR5416_EEP4K_NUM_CTLS) &&
+                            pEepData->ctlIndex[i]; i++) {
+
+                       if (CMP_TEST_GRP) {
+                               rep = &(pEepData->ctlData[i]);
+
+                               twiceMinEdgePower = ath9k_hw_get_max_edge_power(
+                                       freq,
+                                       rep->ctlEdges[
+                                       ar5416_get_ntxchains(ah->txchainmask) - 1],
+                                       IS_CHAN_2GHZ(chan),
+                                       AR5416_EEP4K_NUM_BAND_EDGES);
+
+                               if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL) {
+                                       twiceMaxEdgePower =
+                                               min(twiceMaxEdgePower,
+                                                   twiceMinEdgePower);
+                               } else {
+                                       twiceMaxEdgePower = twiceMinEdgePower;
+                                       break;
+                               }
+                       }
+               }
+
+               minCtlPower = (u8)min(twiceMaxEdgePower, scaledPower);
+
+               switch (pCtlMode[ctlMode]) {
+               case CTL_11B:
+                       for (i = 0; i < ARRAY_SIZE(targetPowerCck.tPow2x); i++) {
+                               targetPowerCck.tPow2x[i] =
+                                       min((u16)targetPowerCck.tPow2x[i],
+                                           minCtlPower);
+                       }
+                       break;
+               case CTL_11G:
+                       for (i = 0; i < ARRAY_SIZE(targetPowerOfdm.tPow2x); i++) {
+                               targetPowerOfdm.tPow2x[i] =
+                                       min((u16)targetPowerOfdm.tPow2x[i],
+                                           minCtlPower);
+                       }
+                       break;
+               case CTL_2GHT20:
+                       for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++) {
+                               targetPowerHt20.tPow2x[i] =
+                                       min((u16)targetPowerHt20.tPow2x[i],
+                                           minCtlPower);
+                       }
+                       break;
+               case CTL_11B_EXT:
+                       targetPowerCckExt.tPow2x[0] =
+                               min((u16)targetPowerCckExt.tPow2x[0],
+                                   minCtlPower);
+                       break;
+               case CTL_11G_EXT:
+                       targetPowerOfdmExt.tPow2x[0] =
+                               min((u16)targetPowerOfdmExt.tPow2x[0],
+                                   minCtlPower);
+                       break;
+               case CTL_2GHT40:
+                       for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++) {
+                               targetPowerHt40.tPow2x[i] =
+                                       min((u16)targetPowerHt40.tPow2x[i],
+                                           minCtlPower);
+                       }
+                       break;
+               default:
+                       break;
+               }
+       }
+
+       ratesArray[rate6mb] =
+       ratesArray[rate9mb] =
+       ratesArray[rate12mb] =
+       ratesArray[rate18mb] =
+       ratesArray[rate24mb] =
+       targetPowerOfdm.tPow2x[0];
+
+       ratesArray[rate36mb] = targetPowerOfdm.tPow2x[1];
+       ratesArray[rate48mb] = targetPowerOfdm.tPow2x[2];
+       ratesArray[rate54mb] = targetPowerOfdm.tPow2x[3];
+       ratesArray[rateXr] = targetPowerOfdm.tPow2x[0];
+
+       for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++)
+               ratesArray[rateHt20_0 + i] = targetPowerHt20.tPow2x[i];
+
+       ratesArray[rate1l] = targetPowerCck.tPow2x[0];
+       ratesArray[rate2s] = ratesArray[rate2l] = targetPowerCck.tPow2x[1];
+       ratesArray[rate5_5s] = ratesArray[rate5_5l] = targetPowerCck.tPow2x[2];
+       ratesArray[rate11s] = ratesArray[rate11l] = targetPowerCck.tPow2x[3];
+
+       if (IS_CHAN_HT40(chan)) {
+               for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++) {
+                       ratesArray[rateHt40_0 + i] =
+                               targetPowerHt40.tPow2x[i];
+               }
+               ratesArray[rateDupOfdm] = targetPowerHt40.tPow2x[0];
+               ratesArray[rateDupCck] = targetPowerHt40.tPow2x[0];
+               ratesArray[rateExtOfdm] = targetPowerOfdmExt.tPow2x[0];
+               ratesArray[rateExtCck] = targetPowerCckExt.tPow2x[0];
+       }
+
+#undef CMP_TEST_GRP
+}
+
+static void ath9k_hw_4k_set_txpower(struct ath_hw *ah,
+                                   struct ath9k_channel *chan,
+                                   u16 cfgCtl,
+                                   u8 twiceAntennaReduction,
+                                   u8 twiceMaxRegulatoryPower,
+                                   u8 powerLimit, int test)
+{
+       struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
+       struct ar5416_eeprom_4k *pEepData = &ah->eeprom.map4k;
+       struct modal_eep_4k_header *pModal = &pEepData->modalHeader;
+       int16_t ratesArray[Ar5416RateSize];
+       int16_t txPowerIndexOffset = 0;
+       u8 ht40PowerIncForPdadc = 2;
+       unsigned int i;
+
+       memset(ratesArray, 0, sizeof(ratesArray));
+
+       if ((pEepData->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
+           AR5416_EEP_MINOR_VER_2) {
+               ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc;
+       }
+
+       ath9k_hw_set_4k_power_per_rate_table(ah, chan,
+                                            &ratesArray[0], cfgCtl,
+                                            twiceAntennaReduction,
+                                            twiceMaxRegulatoryPower,
+                                            powerLimit);
+
+       ath9k_hw_set_4k_power_cal_table(ah, chan, &txPowerIndexOffset);
+
+       regulatory->max_power_level = 0;
+       for (i = 0; i < ARRAY_SIZE(ratesArray); i++) {
+               ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]);
+               if (ratesArray[i] > MAX_RATE_POWER)
+                       ratesArray[i] = MAX_RATE_POWER;
+
+               if (ratesArray[i] > regulatory->max_power_level)
+                       regulatory->max_power_level = ratesArray[i];
+       }
+
+       if (test)
+           return;
+
+       /* Update regulatory */
+       i = rate6mb;
+       if (IS_CHAN_HT40(chan))
+               i = rateHt40_0;
+       else if (IS_CHAN_HT20(chan))
+               i = rateHt20_0;
+
+       regulatory->max_power_level = ratesArray[i];
+
+       if (AR_SREV_9280_20_OR_LATER(ah)) {
+               for (i = 0; i < Ar5416RateSize; i++)
+                       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)
+                 | ATH9K_POW_SM(ratesArray[rate12mb], 16)
+                 | ATH9K_POW_SM(ratesArray[rate9mb], 8)
+                 | ATH9K_POW_SM(ratesArray[rate6mb], 0));
+       REG_WRITE(ah, AR_PHY_POWER_TX_RATE2,
+                 ATH9K_POW_SM(ratesArray[rate54mb], 24)
+                 | ATH9K_POW_SM(ratesArray[rate48mb], 16)
+                 | ATH9K_POW_SM(ratesArray[rate36mb], 8)
+                 | ATH9K_POW_SM(ratesArray[rate24mb], 0));
+
+       /* CCK power per rate */
+       REG_WRITE(ah, AR_PHY_POWER_TX_RATE3,
+                 ATH9K_POW_SM(ratesArray[rate2s], 24)
+                 | ATH9K_POW_SM(ratesArray[rate2l], 16)
+                 | ATH9K_POW_SM(ratesArray[rateXr], 8)
+                 | ATH9K_POW_SM(ratesArray[rate1l], 0));
+       REG_WRITE(ah, AR_PHY_POWER_TX_RATE4,
+                 ATH9K_POW_SM(ratesArray[rate11s], 24)
+                 | ATH9K_POW_SM(ratesArray[rate11l], 16)
+                 | ATH9K_POW_SM(ratesArray[rate5_5s], 8)
+                 | ATH9K_POW_SM(ratesArray[rate5_5l], 0));
+
+       /* HT20 power per rate */
+       REG_WRITE(ah, AR_PHY_POWER_TX_RATE5,
+                 ATH9K_POW_SM(ratesArray[rateHt20_3], 24)
+                 | ATH9K_POW_SM(ratesArray[rateHt20_2], 16)
+                 | ATH9K_POW_SM(ratesArray[rateHt20_1], 8)
+                 | ATH9K_POW_SM(ratesArray[rateHt20_0], 0));
+       REG_WRITE(ah, AR_PHY_POWER_TX_RATE6,
+                 ATH9K_POW_SM(ratesArray[rateHt20_7], 24)
+                 | ATH9K_POW_SM(ratesArray[rateHt20_6], 16)
+                 | ATH9K_POW_SM(ratesArray[rateHt20_5], 8)
+                 | ATH9K_POW_SM(ratesArray[rateHt20_4], 0));
+
+       /* HT40 power per rate */
+       if (IS_CHAN_HT40(chan)) {
+               REG_WRITE(ah, AR_PHY_POWER_TX_RATE7,
+                         ATH9K_POW_SM(ratesArray[rateHt40_3] +
+                                      ht40PowerIncForPdadc, 24)
+                         | ATH9K_POW_SM(ratesArray[rateHt40_2] +
+                                        ht40PowerIncForPdadc, 16)
+                         | ATH9K_POW_SM(ratesArray[rateHt40_1] +
+                                        ht40PowerIncForPdadc, 8)
+                         | ATH9K_POW_SM(ratesArray[rateHt40_0] +
+                                        ht40PowerIncForPdadc, 0));
+               REG_WRITE(ah, AR_PHY_POWER_TX_RATE8,
+                         ATH9K_POW_SM(ratesArray[rateHt40_7] +
+                                      ht40PowerIncForPdadc, 24)
+                         | ATH9K_POW_SM(ratesArray[rateHt40_6] +
+                                        ht40PowerIncForPdadc, 16)
+                         | ATH9K_POW_SM(ratesArray[rateHt40_5] +
+                                        ht40PowerIncForPdadc, 8)
+                         | ATH9K_POW_SM(ratesArray[rateHt40_4] +
+                                        ht40PowerIncForPdadc, 0));
+               REG_WRITE(ah, AR_PHY_POWER_TX_RATE9,
+                         ATH9K_POW_SM(ratesArray[rateExtOfdm], 24)
+                         | ATH9K_POW_SM(ratesArray[rateExtCck], 16)
+                         | ATH9K_POW_SM(ratesArray[rateDupOfdm], 8)
+                         | ATH9K_POW_SM(ratesArray[rateDupCck], 0));
+       }
+
+       REGWRITE_BUFFER_FLUSH(ah);
+}
+
+static void ath9k_hw_4k_set_addac(struct ath_hw *ah,
+                                 struct ath9k_channel *chan __unused)
+{
+       struct modal_eep_4k_header *pModal;
+       struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k;
+       u8 biaslevel;
+
+       if (ah->hw_version.macVersion != AR_SREV_VERSION_9160)
+               return;
+
+       if (ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_MINOR_VER_7)
+               return;
+
+       pModal = &eep->modalHeader;
+
+       if (pModal->xpaBiasLvl != 0xff) {
+               biaslevel = pModal->xpaBiasLvl;
+               INI_RA(&ah->iniAddac, 7, 1) =
+                 (INI_RA(&ah->iniAddac, 7, 1) & (~0x18)) | biaslevel << 3;
+       }
+}
+
+static void ath9k_hw_4k_set_gain(struct ath_hw *ah,
+                                struct modal_eep_4k_header *pModal,
+                                struct ar5416_eeprom_4k *eep,
+                                u8 txRxAttenLocal)
+{
+       REG_WRITE(ah, AR_PHY_SWITCH_CHAIN_0,
+                 pModal->antCtrlChain[0]);
+
+       REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0),
+                 (REG_READ(ah, AR_PHY_TIMING_CTRL4(0)) &
+                  ~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF |
+                    AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF)) |
+                 SM(pModal->iqCalICh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF) |
+                 SM(pModal->iqCalQCh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF));
+
+       if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
+           AR5416_EEP_MINOR_VER_3) {
+               txRxAttenLocal = pModal->txRxAttenCh[0];
+
+               REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ,
+                             AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN, pModal->bswMargin[0]);
+               REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ,
+                             AR_PHY_GAIN_2GHZ_XATTEN1_DB, pModal->bswAtten[0]);
+               REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ,
+                             AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN,
+                             pModal->xatten2Margin[0]);
+               REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ,
+                             AR_PHY_GAIN_2GHZ_XATTEN2_DB, pModal->xatten2Db[0]);
+
+               /* Set the block 1 value to block 0 value */
+               REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + 0x1000,
+                             AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN,
+                             pModal->bswMargin[0]);
+               REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + 0x1000,
+                             AR_PHY_GAIN_2GHZ_XATTEN1_DB, pModal->bswAtten[0]);
+               REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + 0x1000,
+                             AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN,
+                             pModal->xatten2Margin[0]);
+               REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + 0x1000,
+                             AR_PHY_GAIN_2GHZ_XATTEN2_DB,
+                             pModal->xatten2Db[0]);
+       }
+
+       REG_RMW_FIELD(ah, AR_PHY_RXGAIN,
+                     AR9280_PHY_RXGAIN_TXRX_ATTEN, txRxAttenLocal);
+       REG_RMW_FIELD(ah, AR_PHY_RXGAIN,
+                     AR9280_PHY_RXGAIN_TXRX_MARGIN, pModal->rxTxMarginCh[0]);
+
+       REG_RMW_FIELD(ah, AR_PHY_RXGAIN + 0x1000,
+                     AR9280_PHY_RXGAIN_TXRX_ATTEN, txRxAttenLocal);
+       REG_RMW_FIELD(ah, AR_PHY_RXGAIN + 0x1000,
+                     AR9280_PHY_RXGAIN_TXRX_MARGIN, pModal->rxTxMarginCh[0]);
+}
+
+/*
+ * Read EEPROM header info and program the device for correct operation
+ * given the channel value.
+ */
+static void ath9k_hw_4k_set_board_values(struct ath_hw *ah,
+                                        struct ath9k_channel *chan)
+{
+       struct modal_eep_4k_header *pModal;
+       struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k;
+       struct base_eep_header_4k *pBase = &eep->baseEepHeader;
+       u8 txRxAttenLocal;
+       u8 ob[5], db1[5], db2[5];
+       u8 ant_div_control1, ant_div_control2;
+       u32 regVal;
+
+       pModal = &eep->modalHeader;
+       txRxAttenLocal = 23;
+
+       REG_WRITE(ah, AR_PHY_SWITCH_COM, pModal->antCtrlCommon);
+
+       /* Single chain for 4K EEPROM*/
+       ath9k_hw_4k_set_gain(ah, pModal, eep, txRxAttenLocal);
+
+       /* Initialize Ant Diversity settings from EEPROM */
+       if (pModal->version >= 3) {
+               ant_div_control1 = pModal->antdiv_ctl1;
+               ant_div_control2 = pModal->antdiv_ctl2;
+
+               regVal = REG_READ(ah, AR_PHY_MULTICHAIN_GAIN_CTL);
+               regVal &= (~(AR_PHY_9285_ANT_DIV_CTL_ALL));
+
+               regVal |= SM(ant_div_control1,
+                            AR_PHY_9285_ANT_DIV_CTL);
+               regVal |= SM(ant_div_control2,
+                            AR_PHY_9285_ANT_DIV_ALT_LNACONF);
+               regVal |= SM((ant_div_control2 >> 2),
+                            AR_PHY_9285_ANT_DIV_MAIN_LNACONF);
+               regVal |= SM((ant_div_control1 >> 1),
+                            AR_PHY_9285_ANT_DIV_ALT_GAINTB);
+               regVal |= SM((ant_div_control1 >> 2),
+                            AR_PHY_9285_ANT_DIV_MAIN_GAINTB);
+
+
+               REG_WRITE(ah, AR_PHY_MULTICHAIN_GAIN_CTL, regVal);
+               regVal = REG_READ(ah, AR_PHY_MULTICHAIN_GAIN_CTL);
+               regVal = REG_READ(ah, AR_PHY_CCK_DETECT);
+               regVal &= (~AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV);
+               regVal |= SM((ant_div_control1 >> 3),
+                            AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV);
+
+               REG_WRITE(ah, AR_PHY_CCK_DETECT, regVal);
+               regVal = REG_READ(ah, AR_PHY_CCK_DETECT);
+       }
+
+       if (pModal->version >= 2) {
+               ob[0] = pModal->ob_0;
+               ob[1] = pModal->ob_1;
+               ob[2] = pModal->ob_2;
+               ob[3] = pModal->ob_3;
+               ob[4] = pModal->ob_4;
+
+               db1[0] = pModal->db1_0;
+               db1[1] = pModal->db1_1;
+               db1[2] = pModal->db1_2;
+               db1[3] = pModal->db1_3;
+               db1[4] = pModal->db1_4;
+
+               db2[0] = pModal->db2_0;
+               db2[1] = pModal->db2_1;
+               db2[2] = pModal->db2_2;
+               db2[3] = pModal->db2_3;
+               db2[4] = pModal->db2_4;
+       } else if (pModal->version == 1) {
+               ob[0] = pModal->ob_0;
+               ob[1] = ob[2] = ob[3] = ob[4] = pModal->ob_1;
+               db1[0] = pModal->db1_0;
+               db1[1] = db1[2] = db1[3] = db1[4] = pModal->db1_1;
+               db2[0] = pModal->db2_0;
+               db2[1] = db2[2] = db2[3] = db2[4] = pModal->db2_1;
+       } else {
+               int i;
+
+               for (i = 0; i < 5; i++) {
+                       ob[i] = pModal->ob_0;
+                       db1[i] = pModal->db1_0;
+                       db2[i] = pModal->db1_0;
+               }
+       }
+
+       if (AR_SREV_9271(ah)) {
+               ath9k_hw_analog_shift_rmw(ah,
+                                         AR9285_AN_RF2G3,
+                                         AR9271_AN_RF2G3_OB_cck,
+                                         AR9271_AN_RF2G3_OB_cck_S,
+                                         ob[0]);
+               ath9k_hw_analog_shift_rmw(ah,
+                                         AR9285_AN_RF2G3,
+                                         AR9271_AN_RF2G3_OB_psk,
+                                         AR9271_AN_RF2G3_OB_psk_S,
+                                         ob[1]);
+               ath9k_hw_analog_shift_rmw(ah,
+                                         AR9285_AN_RF2G3,
+                                         AR9271_AN_RF2G3_OB_qam,
+                                         AR9271_AN_RF2G3_OB_qam_S,
+                                         ob[2]);
+               ath9k_hw_analog_shift_rmw(ah,
+                                         AR9285_AN_RF2G3,
+                                         AR9271_AN_RF2G3_DB_1,
+                                         AR9271_AN_RF2G3_DB_1_S,
+                                         db1[0]);
+               ath9k_hw_analog_shift_rmw(ah,
+                                         AR9285_AN_RF2G4,
+                                         AR9271_AN_RF2G4_DB_2,
+                                         AR9271_AN_RF2G4_DB_2_S,
+                                         db2[0]);
+       } else {
+               ath9k_hw_analog_shift_rmw(ah,
+                                         AR9285_AN_RF2G3,
+                                         AR9285_AN_RF2G3_OB_0,
+                                         AR9285_AN_RF2G3_OB_0_S,
+                                         ob[0]);
+               ath9k_hw_analog_shift_rmw(ah,
+                                         AR9285_AN_RF2G3,
+                                         AR9285_AN_RF2G3_OB_1,
+                                         AR9285_AN_RF2G3_OB_1_S,
+                                         ob[1]);
+               ath9k_hw_analog_shift_rmw(ah,
+                                         AR9285_AN_RF2G3,
+                                         AR9285_AN_RF2G3_OB_2,
+                                         AR9285_AN_RF2G3_OB_2_S,
+                                         ob[2]);
+               ath9k_hw_analog_shift_rmw(ah,
+                                         AR9285_AN_RF2G3,
+                                         AR9285_AN_RF2G3_OB_3,
+                                         AR9285_AN_RF2G3_OB_3_S,
+                                         ob[3]);
+               ath9k_hw_analog_shift_rmw(ah,
+                                         AR9285_AN_RF2G3,
+                                         AR9285_AN_RF2G3_OB_4,
+                                         AR9285_AN_RF2G3_OB_4_S,
+                                         ob[4]);
+
+               ath9k_hw_analog_shift_rmw(ah,
+                                         AR9285_AN_RF2G3,
+                                         AR9285_AN_RF2G3_DB1_0,
+                                         AR9285_AN_RF2G3_DB1_0_S,
+                                         db1[0]);
+               ath9k_hw_analog_shift_rmw(ah,
+                                         AR9285_AN_RF2G3,
+                                         AR9285_AN_RF2G3_DB1_1,
+                                         AR9285_AN_RF2G3_DB1_1_S,
+                                         db1[1]);
+               ath9k_hw_analog_shift_rmw(ah,
+                                         AR9285_AN_RF2G3,
+                                         AR9285_AN_RF2G3_DB1_2,
+                                         AR9285_AN_RF2G3_DB1_2_S,
+                                         db1[2]);
+               ath9k_hw_analog_shift_rmw(ah,
+                                         AR9285_AN_RF2G4,
+                                         AR9285_AN_RF2G4_DB1_3,
+                                         AR9285_AN_RF2G4_DB1_3_S,
+                                         db1[3]);
+               ath9k_hw_analog_shift_rmw(ah,
+                                         AR9285_AN_RF2G4,
+                                         AR9285_AN_RF2G4_DB1_4,
+                                         AR9285_AN_RF2G4_DB1_4_S, db1[4]);
+
+               ath9k_hw_analog_shift_rmw(ah,
+                                         AR9285_AN_RF2G4,
+                                         AR9285_AN_RF2G4_DB2_0,
+                                         AR9285_AN_RF2G4_DB2_0_S,
+                                         db2[0]);
+               ath9k_hw_analog_shift_rmw(ah,
+                                         AR9285_AN_RF2G4,
+                                         AR9285_AN_RF2G4_DB2_1,
+                                         AR9285_AN_RF2G4_DB2_1_S,
+                                         db2[1]);
+               ath9k_hw_analog_shift_rmw(ah,
+                                         AR9285_AN_RF2G4,
+                                         AR9285_AN_RF2G4_DB2_2,
+                                         AR9285_AN_RF2G4_DB2_2_S,
+                                         db2[2]);
+               ath9k_hw_analog_shift_rmw(ah,
+                                         AR9285_AN_RF2G4,
+                                         AR9285_AN_RF2G4_DB2_3,
+                                         AR9285_AN_RF2G4_DB2_3_S,
+                                         db2[3]);
+               ath9k_hw_analog_shift_rmw(ah,
+                                         AR9285_AN_RF2G4,
+                                         AR9285_AN_RF2G4_DB2_4,
+                                         AR9285_AN_RF2G4_DB2_4_S,
+                                         db2[4]);
+       }
+
+
+       REG_RMW_FIELD(ah, AR_PHY_SETTLING, AR_PHY_SETTLING_SWITCH,
+                     pModal->switchSettling);
+       REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, AR_PHY_DESIRED_SZ_ADC,
+                     pModal->adcDesiredSize);
+
+       REG_WRITE(ah, AR_PHY_RF_CTL4,
+                 SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAA_OFF) |
+                 SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAB_OFF) |
+                 SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAA_ON)  |
+                 SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAB_ON));
+
+       REG_RMW_FIELD(ah, AR_PHY_RF_CTL3, AR_PHY_TX_END_TO_A2_RX_ON,
+                     pModal->txEndToRxOn);
+
+       if (AR_SREV_9271_10(ah))
+               REG_RMW_FIELD(ah, AR_PHY_RF_CTL3, AR_PHY_TX_END_TO_A2_RX_ON,
+                             pModal->txEndToRxOn);
+       REG_RMW_FIELD(ah, AR_PHY_CCA, AR9280_PHY_CCA_THRESH62,
+                     pModal->thresh62);
+       REG_RMW_FIELD(ah, AR_PHY_EXT_CCA0, AR_PHY_EXT_CCA0_THRESH62,
+                     pModal->thresh62);
+
+       if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
+                                               AR5416_EEP_MINOR_VER_2) {
+               REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, AR_PHY_TX_END_DATA_START,
+                             pModal->txFrameToDataStart);
+               REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, AR_PHY_TX_END_PA_ON,
+                             pModal->txFrameToPaOn);
+       }
+
+       if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
+                                               AR5416_EEP_MINOR_VER_3) {
+               if (IS_CHAN_HT40(chan))
+                       REG_RMW_FIELD(ah, AR_PHY_SETTLING,
+                                     AR_PHY_SETTLING_SWITCH,
+                                     pModal->swSettleHt40);
+       }
+       if (AR_SREV_9271(ah) || AR_SREV_9285(ah)) {
+               u8 bb_desired_scale = (pModal->bb_scale_smrt_antenna &
+                               EEP_4K_BB_DESIRED_SCALE_MASK);
+               if ((pBase->txGainType == 0) && (bb_desired_scale != 0)) {
+                       u32 pwrctrl, mask, clr;
+
+                       mask = BIT(0)|BIT(5)|BIT(10)|BIT(15)|BIT(20)|BIT(25);
+                       pwrctrl = mask * bb_desired_scale;
+                       clr = mask * 0x1f;
+                       REG_RMW(ah, AR_PHY_TX_PWRCTRL8, pwrctrl, clr);
+                       REG_RMW(ah, AR_PHY_TX_PWRCTRL10, pwrctrl, clr);
+                       REG_RMW(ah, AR_PHY_CH0_TX_PWRCTRL12, pwrctrl, clr);
+
+                       mask = BIT(0)|BIT(5)|BIT(15);
+                       pwrctrl = mask * bb_desired_scale;
+                       clr = mask * 0x1f;
+                       REG_RMW(ah, AR_PHY_TX_PWRCTRL9, pwrctrl, clr);
+
+                       mask = BIT(0)|BIT(5);
+                       pwrctrl = mask * bb_desired_scale;
+                       clr = mask * 0x1f;
+                       REG_RMW(ah, AR_PHY_CH0_TX_PWRCTRL11, pwrctrl, clr);
+                       REG_RMW(ah, AR_PHY_CH0_TX_PWRCTRL13, pwrctrl, clr);
+               }
+       }
+}
+
+static u16 ath9k_hw_4k_get_spur_channel(struct ath_hw *ah, u16 i, int is2GHz)
+{
+#define EEP_MAP4K_SPURCHAN \
+       (ah->eeprom.map4k.modalHeader.spurChans[i].spurChan)
+
+       u16 spur_val = AR_NO_SPUR;
+
+       DBG2("ath9k: "
+               "Getting spur idx:%d is2Ghz:%d val:%x\n",
+               i, is2GHz, ah->config.spurchans[i][is2GHz]);
+
+       switch (ah->config.spurmode) {
+       case SPUR_DISABLE:
+               break;
+       case SPUR_ENABLE_IOCTL:
+               spur_val = ah->config.spurchans[i][is2GHz];
+               DBG2("ath9k: "
+                       "Getting spur val from new loc. %d\n", spur_val);
+               break;
+       case SPUR_ENABLE_EEPROM:
+               spur_val = EEP_MAP4K_SPURCHAN;
+               break;
+       }
+
+       return spur_val;
+
+#undef EEP_MAP4K_SPURCHAN
+}
+
+const struct eeprom_ops eep_4k_ops = {
+       .check_eeprom           = ath9k_hw_4k_check_eeprom,
+       .get_eeprom             = ath9k_hw_4k_get_eeprom,
+       .fill_eeprom            = ath9k_hw_4k_fill_eeprom,
+       .get_eeprom_ver         = ath9k_hw_4k_get_eeprom_ver,
+       .get_eeprom_rev         = ath9k_hw_4k_get_eeprom_rev,
+       .set_board_values       = ath9k_hw_4k_set_board_values,
+       .set_addac              = ath9k_hw_4k_set_addac,
+       .set_txpower            = ath9k_hw_4k_set_txpower,
+       .get_spur_channel       = ath9k_hw_4k_get_spur_channel
+};
diff --git a/src/drivers/net/ath/ath9k/ath9k_eeprom_9287.c b/src/drivers/net/ath/ath9k/ath9k_eeprom_9287.c
new file mode 100644 (file)
index 0000000..ee16a6f
--- /dev/null
@@ -0,0 +1,1019 @@
+/*
+ * Copyright (c) 2008-2011 Atheros Communications Inc.
+ *
+ * Modified for iPXE by Scott K Logan <logans@cottsay.net> July 2011
+ * Original from Linux kernel 3.0.1
+ *
+ * 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 <ipxe/io.h>
+
+#include "hw.h"
+#include "ar9002_phy.h"
+
+#define SIZE_EEPROM_AR9287 (sizeof(struct ar9287_eeprom) / sizeof(u16))
+
+static int ath9k_hw_ar9287_get_eeprom_ver(struct ath_hw *ah)
+{
+       return (ah->eeprom.map9287.baseEepHeader.version >> 12) & 0xF;
+}
+
+static int ath9k_hw_ar9287_get_eeprom_rev(struct ath_hw *ah)
+{
+       return (ah->eeprom.map9287.baseEepHeader.version) & 0xFFF;
+}
+
+static int __ath9k_hw_ar9287_fill_eeprom(struct ath_hw *ah)
+{
+       struct ar9287_eeprom *eep = &ah->eeprom.map9287;
+       struct ath_common *common = ath9k_hw_common(ah);
+       u16 *eep_data;
+       unsigned int addr;
+       int eep_start_loc = AR9287_EEP_START_LOC;
+       eep_data = (u16 *)eep;
+
+       for (addr = 0; addr < SIZE_EEPROM_AR9287; addr++) {
+               if (!ath9k_hw_nvram_read(common, addr + eep_start_loc,
+                                        eep_data)) {
+                       DBG("ath9k: "
+                               "Unable to read eeprom region\n");
+                       return 0;
+               }
+               eep_data++;
+       }
+
+       return 1;
+}
+
+static int __ath9k_hw_usb_ar9287_fill_eeprom(struct ath_hw *ah)
+{
+       u16 *eep_data = (u16 *)&ah->eeprom.map9287;
+
+       ath9k_hw_usb_gen_fill_eeprom(ah, eep_data,
+                                    AR9287_HTC_EEP_START_LOC,
+                                    SIZE_EEPROM_AR9287);
+       return 1;
+}
+
+static int ath9k_hw_ar9287_fill_eeprom(struct ath_hw *ah)
+{
+       struct ath_common *common = ath9k_hw_common(ah);
+
+       if (!ath9k_hw_use_flash(ah)) {
+               DBG2("ath9k: "
+                       "Reading from EEPROM, not flash\n");
+       }
+
+       if (common->bus_ops->ath_bus_type == ATH_USB)
+               return __ath9k_hw_usb_ar9287_fill_eeprom(ah);
+       else
+               return __ath9k_hw_ar9287_fill_eeprom(ah);
+}
+
+static int ath9k_hw_ar9287_check_eeprom(struct ath_hw *ah)
+{
+       u32 sum = 0, el, integer;
+       u16 temp, word, magic, magic2, *eepdata;
+       unsigned int i, addr;
+       int need_swap = 0;
+       struct ar9287_eeprom *eep = &ah->eeprom.map9287;
+       struct ath_common *common = ath9k_hw_common(ah);
+
+       if (!ath9k_hw_use_flash(ah)) {
+               if (!ath9k_hw_nvram_read(common, AR5416_EEPROM_MAGIC_OFFSET,
+                                        &magic)) {
+                       DBG("ath9k: Reading Magic # failed\n");
+                       return 0;
+               }
+
+               DBG2("ath9k: "
+                       "Read Magic = 0x%04X\n", magic);
+
+               if (magic != AR5416_EEPROM_MAGIC) {
+                       magic2 = swab16(magic);
+
+                       if (magic2 == AR5416_EEPROM_MAGIC) {
+                               need_swap = 1;
+                               eepdata = (u16 *)(&ah->eeprom);
+
+                               for (addr = 0; addr < SIZE_EEPROM_AR9287; addr++) {
+                                       temp = swab16(*eepdata);
+                                       *eepdata = temp;
+                                       eepdata++;
+                               }
+                       } else {
+                               DBG("ath9k: "
+                                       "Invalid EEPROM Magic. Endianness mismatch.\n");
+                               return -EINVAL;
+                       }
+               }
+       }
+
+       DBG2("ath9k: need_swap = %s.\n",
+               need_swap ? "True" : "False");
+
+       if (need_swap)
+               el = swab16(ah->eeprom.map9287.baseEepHeader.length);
+       else
+               el = ah->eeprom.map9287.baseEepHeader.length;
+
+       if (el > sizeof(struct ar9287_eeprom))
+               el = sizeof(struct ar9287_eeprom) / sizeof(u16);
+       else
+               el = el / sizeof(u16);
+
+       eepdata = (u16 *)(&ah->eeprom);
+
+       for (i = 0; i < el; i++)
+               sum ^= *eepdata++;
+
+       if (need_swap) {
+               word = swab16(eep->baseEepHeader.length);
+               eep->baseEepHeader.length = word;
+
+               word = swab16(eep->baseEepHeader.checksum);
+               eep->baseEepHeader.checksum = word;
+
+               word = swab16(eep->baseEepHeader.version);
+               eep->baseEepHeader.version = word;
+
+               word = swab16(eep->baseEepHeader.regDmn[0]);
+               eep->baseEepHeader.regDmn[0] = word;
+
+               word = swab16(eep->baseEepHeader.regDmn[1]);
+               eep->baseEepHeader.regDmn[1] = word;
+
+               word = swab16(eep->baseEepHeader.rfSilent);
+               eep->baseEepHeader.rfSilent = word;
+
+               word = swab16(eep->baseEepHeader.blueToothOptions);
+               eep->baseEepHeader.blueToothOptions = word;
+
+               word = swab16(eep->baseEepHeader.deviceCap);
+               eep->baseEepHeader.deviceCap = word;
+
+               integer = swab32(eep->modalHeader.antCtrlCommon);
+               eep->modalHeader.antCtrlCommon = integer;
+
+               for (i = 0; i < AR9287_MAX_CHAINS; i++) {
+                       integer = swab32(eep->modalHeader.antCtrlChain[i]);
+                       eep->modalHeader.antCtrlChain[i] = integer;
+               }
+
+               for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
+                       word = swab16(eep->modalHeader.spurChans[i].spurChan);
+                       eep->modalHeader.spurChans[i].spurChan = word;
+               }
+       }
+
+       if (sum != 0xffff || ah->eep_ops->get_eeprom_ver(ah) != AR9287_EEP_VER
+           || ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_NO_BACK_VER) {
+               DBG("ath9k: Bad EEPROM checksum 0x%x or revision 0x%04x\n",
+                       sum, ah->eep_ops->get_eeprom_ver(ah));
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static u32 ath9k_hw_ar9287_get_eeprom(struct ath_hw *ah,
+                                     enum eeprom_param param)
+{
+       struct ar9287_eeprom *eep = &ah->eeprom.map9287;
+       struct modal_eep_ar9287_header *pModal = &eep->modalHeader;
+       struct base_eep_ar9287_header *pBase = &eep->baseEepHeader;
+       u16 ver_minor;
+
+       ver_minor = pBase->version & AR9287_EEP_VER_MINOR_MASK;
+
+       switch (param) {
+       case EEP_NFTHRESH_2:
+               return pModal->noiseFloorThreshCh[0];
+       case EEP_MAC_LSW:
+               return pBase->macAddr[0] << 8 | pBase->macAddr[1];
+       case EEP_MAC_MID:
+               return pBase->macAddr[2] << 8 | pBase->macAddr[3];
+       case EEP_MAC_MSW:
+               return pBase->macAddr[4] << 8 | pBase->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;
+       case EEP_RF_SILENT:
+               return pBase->rfSilent;
+       case EEP_MINOR_REV:
+               return ver_minor;
+       case EEP_TX_MASK:
+               return pBase->txMask;
+       case EEP_RX_MASK:
+               return pBase->rxMask;
+       case EEP_DEV_TYPE:
+               return pBase->deviceType;
+       case EEP_OL_PWRCTRL:
+               return pBase->openLoopPwrCntl;
+       case EEP_TEMPSENSE_SLOPE:
+               if (ver_minor >= AR9287_EEP_MINOR_VER_2)
+                       return pBase->tempSensSlope;
+               else
+                       return 0;
+       case EEP_TEMPSENSE_SLOPE_PAL_ON:
+               if (ver_minor >= AR9287_EEP_MINOR_VER_3)
+                       return pBase->tempSensSlopePalOn;
+               else
+                       return 0;
+       default:
+               return 0;
+       }
+}
+
+static void ar9287_eeprom_get_tx_gain_index(struct ath_hw *ah,
+                           struct ath9k_channel *chan,
+                           struct cal_data_op_loop_ar9287 *pRawDatasetOpLoop,
+                           u8 *pCalChans,  u16 availPiers, int8_t *pPwr)
+{
+       u16 idxL = 0, idxR = 0, numPiers;
+       int match;
+       struct chan_centers centers;
+
+       ath9k_hw_get_channel_centers(ah, chan, &centers);
+
+       for (numPiers = 0; numPiers < availPiers; numPiers++) {
+               if (pCalChans[numPiers] == AR5416_BCHAN_UNUSED)
+                       break;
+       }
+
+       match = ath9k_hw_get_lower_upper_index(
+               (u8)FREQ2FBIN(centers.synth_center, IS_CHAN_2GHZ(chan)),
+               pCalChans, numPiers, &idxL, &idxR);
+
+       if (match) {
+               *pPwr = (int8_t) pRawDatasetOpLoop[idxL].pwrPdg[0][0];
+       } else {
+               *pPwr = ((int8_t) pRawDatasetOpLoop[idxL].pwrPdg[0][0] +
+                        (int8_t) pRawDatasetOpLoop[idxR].pwrPdg[0][0])/2;
+       }
+
+}
+
+static void ar9287_eeprom_olpc_set_pdadcs(struct ath_hw *ah,
+                                         int32_t txPower, u16 chain)
+{
+       u32 tmpVal;
+       u32 a;
+
+       /* Enable OLPC for chain 0 */
+
+       tmpVal = REG_READ(ah, 0xa270);
+       tmpVal = tmpVal & 0xFCFFFFFF;
+       tmpVal = tmpVal | (0x3 << 24);
+       REG_WRITE(ah, 0xa270, tmpVal);
+
+       /* Enable OLPC for chain 1 */
+
+       tmpVal = REG_READ(ah, 0xb270);
+       tmpVal = tmpVal & 0xFCFFFFFF;
+       tmpVal = tmpVal | (0x3 << 24);
+       REG_WRITE(ah, 0xb270, tmpVal);
+
+       /* Write the OLPC ref power for chain 0 */
+
+       if (chain == 0) {
+               tmpVal = REG_READ(ah, 0xa398);
+               tmpVal = tmpVal & 0xff00ffff;
+               a = (txPower)&0xff;
+               tmpVal = tmpVal | (a << 16);
+               REG_WRITE(ah, 0xa398, tmpVal);
+       }
+
+       /* Write the OLPC ref power for chain 1 */
+
+       if (chain == 1) {
+               tmpVal = REG_READ(ah, 0xb398);
+               tmpVal = tmpVal & 0xff00ffff;
+               a = (txPower)&0xff;
+               tmpVal = tmpVal | (a << 16);
+               REG_WRITE(ah, 0xb398, tmpVal);
+       }
+}
+
+static void ath9k_hw_set_ar9287_power_cal_table(struct ath_hw *ah,
+                                               struct ath9k_channel *chan,
+                                               int16_t *pTxPowerIndexOffset)
+{
+       struct cal_data_per_freq_ar9287 *pRawDataset;
+       struct cal_data_op_loop_ar9287 *pRawDatasetOpenLoop;
+       u8 *pCalBChans = NULL;
+       u16 pdGainOverlap_t2;
+       u8 pdadcValues[AR5416_NUM_PDADC_VALUES];
+       u16 gainBoundaries[AR5416_PD_GAINS_IN_MASK];
+       u16 numPiers = 0, i, j;
+       u16 numXpdGain, xpdMask;
+       u16 xpdGainValues[AR5416_NUM_PD_GAINS] = {0, 0, 0, 0};
+       u32 reg32, regOffset, regChainOffset, regval;
+       int16_t diff = 0;
+       struct ar9287_eeprom *pEepData = &ah->eeprom.map9287;
+
+       xpdMask = pEepData->modalHeader.xpdGain;
+
+       if ((pEepData->baseEepHeader.version & AR9287_EEP_VER_MINOR_MASK) >=
+           AR9287_EEP_MINOR_VER_2)
+               pdGainOverlap_t2 = pEepData->modalHeader.pdGainOverlap;
+       else
+               pdGainOverlap_t2 = (u16)(MS(REG_READ(ah, AR_PHY_TPCRG5),
+                                           AR_PHY_TPCRG5_PD_GAIN_OVERLAP));
+
+       if (IS_CHAN_2GHZ(chan)) {
+               pCalBChans = pEepData->calFreqPier2G;
+               numPiers = AR9287_NUM_2G_CAL_PIERS;
+               if (ath9k_hw_ar9287_get_eeprom(ah, EEP_OL_PWRCTRL)) {
+                       pRawDatasetOpenLoop =
+                       (struct cal_data_op_loop_ar9287 *)pEepData->calPierData2G[0];
+                       ah->initPDADC = pRawDatasetOpenLoop->vpdPdg[0][0];
+               }
+       }
+
+       numXpdGain = 0;
+
+       /* Calculate the value of xpdgains from the xpdGain Mask */
+       for (i = 1; i <= AR5416_PD_GAINS_IN_MASK; i++) {
+               if ((xpdMask >> (AR5416_PD_GAINS_IN_MASK - i)) & 1) {
+                       if (numXpdGain >= AR5416_NUM_PD_GAINS)
+                               break;
+                       xpdGainValues[numXpdGain] =
+                               (u16)(AR5416_PD_GAINS_IN_MASK-i);
+                       numXpdGain++;
+               }
+       }
+
+       REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_NUM_PD_GAIN,
+                     (numXpdGain - 1) & 0x3);
+       REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_1,
+                     xpdGainValues[0]);
+       REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_2,
+                     xpdGainValues[1]);
+       REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_3,
+                     xpdGainValues[2]);
+
+       for (i = 0; i < AR9287_MAX_CHAINS; i++) {
+               regChainOffset = i * 0x1000;
+
+               if (pEepData->baseEepHeader.txMask & (1 << i)) {
+                       pRawDatasetOpenLoop =
+                       (struct cal_data_op_loop_ar9287 *)pEepData->calPierData2G[i];
+
+                       if (ath9k_hw_ar9287_get_eeprom(ah, EEP_OL_PWRCTRL)) {
+                               int8_t txPower;
+                               ar9287_eeprom_get_tx_gain_index(ah, chan,
+                                                       pRawDatasetOpenLoop,
+                                                       pCalBChans, numPiers,
+                                                       &txPower);
+                               ar9287_eeprom_olpc_set_pdadcs(ah, txPower, i);
+                       } else {
+                               pRawDataset =
+                                       (struct cal_data_per_freq_ar9287 *)
+                                       pEepData->calPierData2G[i];
+
+                               ath9k_hw_get_gain_boundaries_pdadcs(ah, chan,
+                                                          pRawDataset,
+                                                          pCalBChans, numPiers,
+                                                          pdGainOverlap_t2,
+                                                          gainBoundaries,
+                                                          pdadcValues,
+                                                          numXpdGain);
+                       }
+
+                       ENABLE_REGWRITE_BUFFER(ah);
+
+                       if (i == 0) {
+                               if (!ath9k_hw_ar9287_get_eeprom(ah,
+                                                       EEP_OL_PWRCTRL)) {
+
+                                       regval = SM(pdGainOverlap_t2,
+                                                   AR_PHY_TPCRG5_PD_GAIN_OVERLAP)
+                                               | SM(gainBoundaries[0],
+                                                    AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1)
+                                               | SM(gainBoundaries[1],
+                                                    AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2)
+                                               | SM(gainBoundaries[2],
+                                                    AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3)
+                                               | SM(gainBoundaries[3],
+                                                    AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4);
+
+                                       REG_WRITE(ah,
+                                                 AR_PHY_TPCRG5 + regChainOffset,
+                                                 regval);
+                               }
+                       }
+
+                       if ((int32_t)AR9287_PWR_TABLE_OFFSET_DB !=
+                           pEepData->baseEepHeader.pwrTableOffset) {
+                               diff = (u16)(pEepData->baseEepHeader.pwrTableOffset -
+                                            (int32_t)AR9287_PWR_TABLE_OFFSET_DB);
+                               diff *= 2;
+
+                               for (j = 0; j < ((u16)AR5416_NUM_PDADC_VALUES-diff); j++)
+                                       pdadcValues[j] = pdadcValues[j+diff];
+
+                               for (j = (u16)(AR5416_NUM_PDADC_VALUES-diff);
+                                    j < AR5416_NUM_PDADC_VALUES; j++)
+                                       pdadcValues[j] =
+                                         pdadcValues[AR5416_NUM_PDADC_VALUES-diff];
+                       }
+
+                       if (!ath9k_hw_ar9287_get_eeprom(ah, EEP_OL_PWRCTRL)) {
+                               regOffset = AR_PHY_BASE +
+                                       (672 << 2) + regChainOffset;
+
+                               for (j = 0; j < 32; j++) {
+                                       reg32 = ((pdadcValues[4*j + 0] & 0xFF) << 0)
+                                               | ((pdadcValues[4*j + 1] & 0xFF) << 8)
+                                               | ((pdadcValues[4*j + 2] & 0xFF) << 16)
+                                               | ((pdadcValues[4*j + 3] & 0xFF) << 24);
+
+                                       REG_WRITE(ah, regOffset, reg32);
+                                       regOffset += 4;
+                               }
+                       }
+                       REGWRITE_BUFFER_FLUSH(ah);
+               }
+       }
+
+       *pTxPowerIndexOffset = 0;
+}
+
+static void ath9k_hw_set_ar9287_power_per_rate_table(struct ath_hw *ah,
+                                                    struct ath9k_channel *chan,
+                                                    int16_t *ratesArray,
+                                                    u16 cfgCtl,
+                                                    u16 AntennaReduction,
+                                                    u16 twiceMaxRegulatoryPower,
+                                                    u16 powerLimit)
+{
+#define CMP_CTL \
+       (((cfgCtl & ~CTL_MODE_M) | (pCtlMode[ctlMode] & CTL_MODE_M)) == \
+        pEepData->ctlIndex[i])
+
+#define CMP_NO_CTL \
+       (((cfgCtl & ~CTL_MODE_M) | (pCtlMode[ctlMode] & CTL_MODE_M)) == \
+        ((pEepData->ctlIndex[i] & CTL_MODE_M) | SD_NO_CTL))
+
+#define REDUCE_SCALED_POWER_BY_TWO_CHAIN     6
+#define REDUCE_SCALED_POWER_BY_THREE_CHAIN   10
+
+       struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
+       u16 twiceMaxEdgePower = MAX_RATE_POWER;
+       static const u16 tpScaleReductionTable[5] =
+               { 0, 3, 6, 9, MAX_RATE_POWER };
+       unsigned int i;
+       int16_t twiceLargestAntenna;
+       struct cal_ctl_data_ar9287 *rep;
+       struct cal_target_power_leg targetPowerOfdm = {0, {0, 0, 0, 0} },
+                                   targetPowerCck = {0, {0, 0, 0, 0} };
+       struct cal_target_power_leg targetPowerOfdmExt = {0, {0, 0, 0, 0} },
+                                   targetPowerCckExt = {0, {0, 0, 0, 0} };
+       struct cal_target_power_ht targetPowerHt20,
+                                   targetPowerHt40 = {0, {0, 0, 0, 0} };
+       u16 scaledPower = 0, minCtlPower, maxRegAllowedPower;
+       static const u16 ctlModesFor11g[] = {
+               CTL_11B, CTL_11G, CTL_2GHT20,
+               CTL_11B_EXT, CTL_11G_EXT, CTL_2GHT40
+       };
+       u16 numCtlModes = 0;
+       const u16 *pCtlMode = NULL;
+       u16 ctlMode, freq;
+       struct chan_centers centers;
+       int tx_chainmask;
+       u16 twiceMinEdgePower;
+       struct ar9287_eeprom *pEepData = &ah->eeprom.map9287;
+       tx_chainmask = ah->txchainmask;
+
+       ath9k_hw_get_channel_centers(ah, chan, &centers);
+
+       /* Compute TxPower reduction due to Antenna Gain */
+       twiceLargestAntenna = max(pEepData->modalHeader.antennaGainCh[0],
+                                 pEepData->modalHeader.antennaGainCh[1]);
+       twiceLargestAntenna = (int16_t)min((AntennaReduction) -
+                                          twiceLargestAntenna, 0);
+
+       /*
+        * scaledPower is the minimum of the user input power level
+        * and the regulatory allowed power level.
+        */
+       maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna;
+
+       if (regulatory->tp_scale != ATH9K_TP_SCALE_MAX)
+               maxRegAllowedPower -=
+                       (tpScaleReductionTable[(regulatory->tp_scale)] * 2);
+
+       scaledPower = min(powerLimit, maxRegAllowedPower);
+
+       /*
+        * Reduce scaled Power by number of chains active
+        * to get the per chain tx power level.
+        */
+       switch (ar5416_get_ntxchains(tx_chainmask)) {
+       case 1:
+               break;
+       case 2:
+               if (scaledPower > REDUCE_SCALED_POWER_BY_TWO_CHAIN)
+                       scaledPower -= REDUCE_SCALED_POWER_BY_TWO_CHAIN;
+               else
+                       scaledPower = 0;
+               break;
+       case 3:
+               if (scaledPower > REDUCE_SCALED_POWER_BY_THREE_CHAIN)
+                       scaledPower -= REDUCE_SCALED_POWER_BY_THREE_CHAIN;
+               else
+                       scaledPower = 0;
+               break;
+       }
+       scaledPower = max((u16)0, scaledPower);
+
+       /*
+        * Get TX power from EEPROM.
+        */
+       if (IS_CHAN_2GHZ(chan)) {
+               /* CTL_11B, CTL_11G, CTL_2GHT20 */
+               numCtlModes =
+                       ARRAY_SIZE(ctlModesFor11g) - SUB_NUM_CTL_MODES_AT_2G_40;
+
+               pCtlMode = ctlModesFor11g;
+
+               ath9k_hw_get_legacy_target_powers(ah, chan,
+                                                 pEepData->calTargetPowerCck,
+                                                 AR9287_NUM_2G_CCK_TARGET_POWERS,
+                                                 &targetPowerCck, 4, 0);
+               ath9k_hw_get_legacy_target_powers(ah, chan,
+                                                 pEepData->calTargetPower2G,
+                                                 AR9287_NUM_2G_20_TARGET_POWERS,
+                                                 &targetPowerOfdm, 4, 0);
+               ath9k_hw_get_target_powers(ah, chan,
+                                          pEepData->calTargetPower2GHT20,
+                                          AR9287_NUM_2G_20_TARGET_POWERS,
+                                          &targetPowerHt20, 8, 0);
+
+               if (IS_CHAN_HT40(chan)) {
+                       /* All 2G CTLs */
+                       numCtlModes = ARRAY_SIZE(ctlModesFor11g);
+                       ath9k_hw_get_target_powers(ah, chan,
+                                                  pEepData->calTargetPower2GHT40,
+                                                  AR9287_NUM_2G_40_TARGET_POWERS,
+                                                  &targetPowerHt40, 8, 1);
+                       ath9k_hw_get_legacy_target_powers(ah, chan,
+                                                 pEepData->calTargetPowerCck,
+                                                 AR9287_NUM_2G_CCK_TARGET_POWERS,
+                                                 &targetPowerCckExt, 4, 1);
+                       ath9k_hw_get_legacy_target_powers(ah, chan,
+                                                 pEepData->calTargetPower2G,
+                                                 AR9287_NUM_2G_20_TARGET_POWERS,
+                                                 &targetPowerOfdmExt, 4, 1);
+               }
+       }
+
+       for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) {
+               int isHt40CtlMode =
+                       (pCtlMode[ctlMode] == CTL_2GHT40) ? 1 : 0;
+
+               if (isHt40CtlMode)
+                       freq = centers.synth_center;
+               else if (pCtlMode[ctlMode] & EXT_ADDITIVE)
+                       freq = centers.ext_center;
+               else
+                       freq = centers.ctl_center;
+
+               /* Walk through the CTL indices stored in EEPROM */
+               for (i = 0; (i < AR9287_NUM_CTLS) && pEepData->ctlIndex[i]; i++) {
+                       struct cal_ctl_edges *pRdEdgesPower;
+
+                       /*
+                        * Compare test group from regulatory channel list
+                        * with test mode from pCtlMode list
+                        */
+                       if (CMP_CTL || CMP_NO_CTL) {
+                               rep = &(pEepData->ctlData[i]);
+                               pRdEdgesPower =
+                               rep->ctlEdges[ar5416_get_ntxchains(tx_chainmask) - 1];
+
+                               twiceMinEdgePower = ath9k_hw_get_max_edge_power(freq,
+                                                               pRdEdgesPower,
+                                                               IS_CHAN_2GHZ(chan),
+                                                               AR5416_NUM_BAND_EDGES);
+
+                               if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL) {
+                                       twiceMaxEdgePower = min(twiceMaxEdgePower,
+                                                               twiceMinEdgePower);
+                               } else {
+                                       twiceMaxEdgePower = twiceMinEdgePower;
+                                       break;
+                               }
+                       }
+               }
+
+               minCtlPower = (u8)min(twiceMaxEdgePower, scaledPower);
+
+               /* Apply ctl mode to correct target power set */
+               switch (pCtlMode[ctlMode]) {
+               case CTL_11B:
+                       for (i = 0; i < ARRAY_SIZE(targetPowerCck.tPow2x); i++) {
+                               targetPowerCck.tPow2x[i] =
+                                       (u8)min((u16)targetPowerCck.tPow2x[i],
+                                               minCtlPower);
+                       }
+                       break;
+               case CTL_11A:
+               case CTL_11G:
+                       for (i = 0; i < ARRAY_SIZE(targetPowerOfdm.tPow2x); i++) {
+                               targetPowerOfdm.tPow2x[i] =
+                                       (u8)min((u16)targetPowerOfdm.tPow2x[i],
+                                               minCtlPower);
+                       }
+                       break;
+               case CTL_5GHT20:
+               case CTL_2GHT20:
+                       for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++) {
+                               targetPowerHt20.tPow2x[i] =
+                                       (u8)min((u16)targetPowerHt20.tPow2x[i],
+                                               minCtlPower);
+                       }
+                       break;
+               case CTL_11B_EXT:
+                       targetPowerCckExt.tPow2x[0] =
+                               (u8)min((u16)targetPowerCckExt.tPow2x[0],
+                                       minCtlPower);
+                       break;
+               case CTL_11A_EXT:
+               case CTL_11G_EXT:
+                       targetPowerOfdmExt.tPow2x[0] =
+                               (u8)min((u16)targetPowerOfdmExt.tPow2x[0],
+                                       minCtlPower);
+                       break;
+               case CTL_5GHT40:
+               case CTL_2GHT40:
+                       for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++) {
+                               targetPowerHt40.tPow2x[i] =
+                                       (u8)min((u16)targetPowerHt40.tPow2x[i],
+                                               minCtlPower);
+                       }
+                       break;
+               default:
+                       break;
+               }
+       }
+
+       /* Now set the rates array */
+
+       ratesArray[rate6mb] =
+       ratesArray[rate9mb] =
+       ratesArray[rate12mb] =
+       ratesArray[rate18mb] =
+       ratesArray[rate24mb] = targetPowerOfdm.tPow2x[0];
+
+       ratesArray[rate36mb] = targetPowerOfdm.tPow2x[1];
+       ratesArray[rate48mb] = targetPowerOfdm.tPow2x[2];
+       ratesArray[rate54mb] = targetPowerOfdm.tPow2x[3];
+       ratesArray[rateXr] = targetPowerOfdm.tPow2x[0];
+
+       for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++)
+               ratesArray[rateHt20_0 + i] = targetPowerHt20.tPow2x[i];
+
+       if (IS_CHAN_2GHZ(chan)) {
+               ratesArray[rate1l] = targetPowerCck.tPow2x[0];
+               ratesArray[rate2s] =
+               ratesArray[rate2l] = targetPowerCck.tPow2x[1];
+               ratesArray[rate5_5s] =
+               ratesArray[rate5_5l] = targetPowerCck.tPow2x[2];
+               ratesArray[rate11s] =
+               ratesArray[rate11l] = targetPowerCck.tPow2x[3];
+       }
+       if (IS_CHAN_HT40(chan)) {
+               for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++)
+                       ratesArray[rateHt40_0 + i] = targetPowerHt40.tPow2x[i];
+
+               ratesArray[rateDupOfdm] = targetPowerHt40.tPow2x[0];
+               ratesArray[rateDupCck]  = targetPowerHt40.tPow2x[0];
+               ratesArray[rateExtOfdm] = targetPowerOfdmExt.tPow2x[0];
+
+               if (IS_CHAN_2GHZ(chan))
+                       ratesArray[rateExtCck] = targetPowerCckExt.tPow2x[0];
+       }
+
+#undef CMP_CTL
+#undef CMP_NO_CTL
+#undef REDUCE_SCALED_POWER_BY_TWO_CHAIN
+#undef REDUCE_SCALED_POWER_BY_THREE_CHAIN
+}
+
+static void ath9k_hw_ar9287_set_txpower(struct ath_hw *ah,
+                                       struct ath9k_channel *chan, u16 cfgCtl,
+                                       u8 twiceAntennaReduction,
+                                       u8 twiceMaxRegulatoryPower,
+                                       u8 powerLimit, int test)
+{
+       struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
+       struct ar9287_eeprom *pEepData = &ah->eeprom.map9287;
+       struct modal_eep_ar9287_header *pModal = &pEepData->modalHeader;
+       int16_t ratesArray[Ar5416RateSize];
+       int16_t txPowerIndexOffset = 0;
+       u8 ht40PowerIncForPdadc = 2;
+       unsigned int i;
+
+       memset(ratesArray, 0, sizeof(ratesArray));
+
+       if ((pEepData->baseEepHeader.version & AR9287_EEP_VER_MINOR_MASK) >=
+           AR9287_EEP_MINOR_VER_2)
+               ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc;
+
+       ath9k_hw_set_ar9287_power_per_rate_table(ah, chan,
+                                                &ratesArray[0], cfgCtl,
+                                                twiceAntennaReduction,
+                                                twiceMaxRegulatoryPower,
+                                                powerLimit);
+
+       ath9k_hw_set_ar9287_power_cal_table(ah, chan, &txPowerIndexOffset);
+
+       regulatory->max_power_level = 0;
+       for (i = 0; i < ARRAY_SIZE(ratesArray); i++) {
+               ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]);
+               if (ratesArray[i] > MAX_RATE_POWER)
+                       ratesArray[i] = MAX_RATE_POWER;
+
+               if (ratesArray[i] > regulatory->max_power_level)
+                       regulatory->max_power_level = ratesArray[i];
+       }
+
+       if (test)
+               return;
+
+       if (IS_CHAN_2GHZ(chan))
+               i = rate1l;
+       else
+               i = rate6mb;
+
+       regulatory->max_power_level = ratesArray[i];
+
+       if (AR_SREV_9280_20_OR_LATER(ah)) {
+               for (i = 0; i < Ar5416RateSize; i++)
+                       ratesArray[i] -= AR9287_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)
+                 | ATH9K_POW_SM(ratesArray[rate12mb], 16)
+                 | ATH9K_POW_SM(ratesArray[rate9mb], 8)
+                 | ATH9K_POW_SM(ratesArray[rate6mb], 0));
+
+       REG_WRITE(ah, AR_PHY_POWER_TX_RATE2,
+                 ATH9K_POW_SM(ratesArray[rate54mb], 24)
+                 | ATH9K_POW_SM(ratesArray[rate48mb], 16)
+                 | ATH9K_POW_SM(ratesArray[rate36mb], 8)
+                 | ATH9K_POW_SM(ratesArray[rate24mb], 0));
+
+       /* CCK power per rate */
+       if (IS_CHAN_2GHZ(chan)) {
+               REG_WRITE(ah, AR_PHY_POWER_TX_RATE3,
+                         ATH9K_POW_SM(ratesArray[rate2s], 24)
+                         | ATH9K_POW_SM(ratesArray[rate2l], 16)
+                         | ATH9K_POW_SM(ratesArray[rateXr], 8)
+                         | ATH9K_POW_SM(ratesArray[rate1l], 0));
+               REG_WRITE(ah, AR_PHY_POWER_TX_RATE4,
+                         ATH9K_POW_SM(ratesArray[rate11s], 24)
+                         | ATH9K_POW_SM(ratesArray[rate11l], 16)
+                         | ATH9K_POW_SM(ratesArray[rate5_5s], 8)
+                         | ATH9K_POW_SM(ratesArray[rate5_5l], 0));
+       }
+
+       /* HT20 power per rate */
+       REG_WRITE(ah, AR_PHY_POWER_TX_RATE5,
+                 ATH9K_POW_SM(ratesArray[rateHt20_3], 24)
+                 | ATH9K_POW_SM(ratesArray[rateHt20_2], 16)
+                 | ATH9K_POW_SM(ratesArray[rateHt20_1], 8)
+                 | ATH9K_POW_SM(ratesArray[rateHt20_0], 0));
+
+       REG_WRITE(ah, AR_PHY_POWER_TX_RATE6,
+                 ATH9K_POW_SM(ratesArray[rateHt20_7], 24)
+                 | ATH9K_POW_SM(ratesArray[rateHt20_6], 16)
+                 | ATH9K_POW_SM(ratesArray[rateHt20_5], 8)
+                 | ATH9K_POW_SM(ratesArray[rateHt20_4], 0));
+
+       /* HT40 power per rate */
+       if (IS_CHAN_HT40(chan)) {
+               if (ath9k_hw_ar9287_get_eeprom(ah, EEP_OL_PWRCTRL)) {
+                       REG_WRITE(ah, AR_PHY_POWER_TX_RATE7,
+                                 ATH9K_POW_SM(ratesArray[rateHt40_3], 24)
+                                 | ATH9K_POW_SM(ratesArray[rateHt40_2], 16)
+                                 | ATH9K_POW_SM(ratesArray[rateHt40_1], 8)
+                                 | ATH9K_POW_SM(ratesArray[rateHt40_0], 0));
+
+                       REG_WRITE(ah, AR_PHY_POWER_TX_RATE8,
+                                 ATH9K_POW_SM(ratesArray[rateHt40_7], 24)
+                                 | ATH9K_POW_SM(ratesArray[rateHt40_6], 16)
+                                 | ATH9K_POW_SM(ratesArray[rateHt40_5], 8)
+                                 | ATH9K_POW_SM(ratesArray[rateHt40_4], 0));
+               } else {
+                       REG_WRITE(ah, AR_PHY_POWER_TX_RATE7,
+                                 ATH9K_POW_SM(ratesArray[rateHt40_3] +
+                                              ht40PowerIncForPdadc, 24)
+                                 | ATH9K_POW_SM(ratesArray[rateHt40_2] +
+                                                ht40PowerIncForPdadc, 16)
+                                 | ATH9K_POW_SM(ratesArray[rateHt40_1] +
+                                                ht40PowerIncForPdadc, 8)
+                                 | ATH9K_POW_SM(ratesArray[rateHt40_0] +
+                                                ht40PowerIncForPdadc, 0));
+
+                       REG_WRITE(ah, AR_PHY_POWER_TX_RATE8,
+                                 ATH9K_POW_SM(ratesArray[rateHt40_7] +
+                                              ht40PowerIncForPdadc, 24)
+                                 | ATH9K_POW_SM(ratesArray[rateHt40_6] +
+                                                ht40PowerIncForPdadc, 16)
+                                 | ATH9K_POW_SM(ratesArray[rateHt40_5] +
+                                                ht40PowerIncForPdadc, 8)
+                                 | ATH9K_POW_SM(ratesArray[rateHt40_4] +
+                                                ht40PowerIncForPdadc, 0));
+               }
+
+               /* Dup/Ext power per rate */
+               REG_WRITE(ah, AR_PHY_POWER_TX_RATE9,
+                         ATH9K_POW_SM(ratesArray[rateExtOfdm], 24)
+                         | ATH9K_POW_SM(ratesArray[rateExtCck], 16)
+                         | ATH9K_POW_SM(ratesArray[rateDupOfdm], 8)
+                         | ATH9K_POW_SM(ratesArray[rateDupCck], 0));
+       }
+       REGWRITE_BUFFER_FLUSH(ah);
+}
+
+static void ath9k_hw_ar9287_set_addac(struct ath_hw *ah __unused,
+                                     struct ath9k_channel *chan __unused)
+{
+}
+
+static void ath9k_hw_ar9287_set_board_values(struct ath_hw *ah,
+                                            struct ath9k_channel *chan)
+{
+       struct ar9287_eeprom *eep = &ah->eeprom.map9287;
+       struct modal_eep_ar9287_header *pModal = &eep->modalHeader;
+       u32 regChainOffset, regval;
+       u8 txRxAttenLocal;
+       int i;
+
+       pModal = &eep->modalHeader;
+
+       REG_WRITE(ah, AR_PHY_SWITCH_COM, pModal->antCtrlCommon);
+
+       for (i = 0; i < AR9287_MAX_CHAINS; i++) {
+               regChainOffset = i * 0x1000;
+
+               REG_WRITE(ah, AR_PHY_SWITCH_CHAIN_0 + regChainOffset,
+                         pModal->antCtrlChain[i]);
+
+               REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset,
+                         (REG_READ(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset)
+                          & ~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF |
+                              AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF)) |
+                         SM(pModal->iqCalICh[i],
+                            AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF) |
+                         SM(pModal->iqCalQCh[i],
+                            AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF));
+
+               txRxAttenLocal = pModal->txRxAttenCh[i];
+
+               REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
+                             AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN,
+                             pModal->bswMargin[i]);
+               REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
+                             AR_PHY_GAIN_2GHZ_XATTEN1_DB,
+                             pModal->bswAtten[i]);
+               REG_RMW_FIELD(ah, AR_PHY_RXGAIN + regChainOffset,
+                             AR9280_PHY_RXGAIN_TXRX_ATTEN,
+                             txRxAttenLocal);
+               REG_RMW_FIELD(ah, AR_PHY_RXGAIN + regChainOffset,
+                             AR9280_PHY_RXGAIN_TXRX_MARGIN,
+                             pModal->rxTxMarginCh[i]);
+       }
+
+
+       if (IS_CHAN_HT40(chan))
+               REG_RMW_FIELD(ah, AR_PHY_SETTLING,
+                             AR_PHY_SETTLING_SWITCH, pModal->swSettleHt40);
+       else
+               REG_RMW_FIELD(ah, AR_PHY_SETTLING,
+                             AR_PHY_SETTLING_SWITCH, pModal->switchSettling);
+
+       REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ,
+                     AR_PHY_DESIRED_SZ_ADC, pModal->adcDesiredSize);
+
+       REG_WRITE(ah, AR_PHY_RF_CTL4,
+                 SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAA_OFF)
+                 | SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAB_OFF)
+                 | SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAA_ON)
+                 | SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAB_ON));
+
+       REG_RMW_FIELD(ah, AR_PHY_RF_CTL3,
+                     AR_PHY_TX_END_TO_A2_RX_ON, pModal->txEndToRxOn);
+
+       REG_RMW_FIELD(ah, AR_PHY_CCA,
+                     AR9280_PHY_CCA_THRESH62, pModal->thresh62);
+       REG_RMW_FIELD(ah, AR_PHY_EXT_CCA0,
+                     AR_PHY_EXT_CCA0_THRESH62, pModal->thresh62);
+
+       regval = REG_READ(ah, AR9287_AN_RF2G3_CH0);
+       regval &= ~(AR9287_AN_RF2G3_DB1 |
+                   AR9287_AN_RF2G3_DB2 |
+                   AR9287_AN_RF2G3_OB_CCK |
+                   AR9287_AN_RF2G3_OB_PSK |
+                   AR9287_AN_RF2G3_OB_QAM |
+                   AR9287_AN_RF2G3_OB_PAL_OFF);
+       regval |= (SM(pModal->db1, AR9287_AN_RF2G3_DB1) |
+                  SM(pModal->db2, AR9287_AN_RF2G3_DB2) |
+                  SM(pModal->ob_cck, AR9287_AN_RF2G3_OB_CCK) |
+                  SM(pModal->ob_psk, AR9287_AN_RF2G3_OB_PSK) |
+                  SM(pModal->ob_qam, AR9287_AN_RF2G3_OB_QAM) |
+                  SM(pModal->ob_pal_off, AR9287_AN_RF2G3_OB_PAL_OFF));
+
+       ath9k_hw_analog_shift_regwrite(ah, AR9287_AN_RF2G3_CH0, regval);
+
+       regval = REG_READ(ah, AR9287_AN_RF2G3_CH1);
+       regval &= ~(AR9287_AN_RF2G3_DB1 |
+                   AR9287_AN_RF2G3_DB2 |
+                   AR9287_AN_RF2G3_OB_CCK |
+                   AR9287_AN_RF2G3_OB_PSK |
+                   AR9287_AN_RF2G3_OB_QAM |
+                   AR9287_AN_RF2G3_OB_PAL_OFF);
+       regval |= (SM(pModal->db1, AR9287_AN_RF2G3_DB1) |
+                  SM(pModal->db2, AR9287_AN_RF2G3_DB2) |
+                  SM(pModal->ob_cck, AR9287_AN_RF2G3_OB_CCK) |
+                  SM(pModal->ob_psk, AR9287_AN_RF2G3_OB_PSK) |
+                  SM(pModal->ob_qam, AR9287_AN_RF2G3_OB_QAM) |
+                  SM(pModal->ob_pal_off, AR9287_AN_RF2G3_OB_PAL_OFF));
+
+       ath9k_hw_analog_shift_regwrite(ah, AR9287_AN_RF2G3_CH1, regval);
+
+       REG_RMW_FIELD(ah, AR_PHY_RF_CTL2,
+                     AR_PHY_TX_END_DATA_START, pModal->txFrameToDataStart);
+       REG_RMW_FIELD(ah, AR_PHY_RF_CTL2,
+                     AR_PHY_TX_END_PA_ON, pModal->txFrameToPaOn);
+
+       ath9k_hw_analog_shift_rmw(ah, AR9287_AN_TOP2,
+                                 AR9287_AN_TOP2_XPABIAS_LVL,
+                                 AR9287_AN_TOP2_XPABIAS_LVL_S,
+                                 pModal->xpaBiasLvl);
+}
+
+static u16 ath9k_hw_ar9287_get_spur_channel(struct ath_hw *ah,
+                                           u16 i, int is2GHz)
+{
+#define EEP_MAP9287_SPURCHAN \
+       (ah->eeprom.map9287.modalHeader.spurChans[i].spurChan)
+
+       u16 spur_val = AR_NO_SPUR;
+
+       DBG2("ath9k: "
+               "Getting spur idx:%d is2Ghz:%d val:%x\n",
+               i, is2GHz, ah->config.spurchans[i][is2GHz]);
+
+       switch (ah->config.spurmode) {
+       case SPUR_DISABLE:
+               break;
+       case SPUR_ENABLE_IOCTL:
+               spur_val = ah->config.spurchans[i][is2GHz];
+               DBG2("ath9k: "
+                       "Getting spur val from new loc. %d\n", spur_val);
+               break;
+       case SPUR_ENABLE_EEPROM:
+               spur_val = EEP_MAP9287_SPURCHAN;
+               break;
+       }
+
+       return spur_val;
+
+#undef EEP_MAP9287_SPURCHAN
+}
+
+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,
+       .get_eeprom_ver         = ath9k_hw_ar9287_get_eeprom_ver,
+       .get_eeprom_rev         = ath9k_hw_ar9287_get_eeprom_rev,
+       .set_board_values       = ath9k_hw_ar9287_set_board_values,
+       .set_addac              = ath9k_hw_ar9287_set_addac,
+       .set_txpower            = ath9k_hw_ar9287_set_txpower,
+       .get_spur_channel       = ath9k_hw_ar9287_get_spur_channel
+};
diff --git a/src/drivers/net/ath/ath9k/ath9k_eeprom_def.c b/src/drivers/net/ath/ath9k/ath9k_eeprom_def.c
new file mode 100644 (file)
index 0000000..9b144d7
--- /dev/null
@@ -0,0 +1,1351 @@
+/*
+ * Copyright (c) 2008-2011 Atheros Communications Inc.
+ *
+ * Modified for iPXE by Scott K Logan <logans@cottsay.net> July 2011
+ * Original from Linux kernel 3.0.1
+ *
+ * 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 <ipxe/io.h>
+
+#include "hw.h"
+#include "ar9002_phy.h"
+
+static void ath9k_get_txgain_index(struct ath_hw *ah,
+               struct ath9k_channel *chan,
+               struct calDataPerFreqOpLoop *rawDatasetOpLoop,
+               u8 *calChans,  u16 availPiers, u8 *pwr, u8 *pcdacIdx)
+{
+       u8 pcdac, i = 0;
+       u16 idxL = 0, idxR = 0, numPiers;
+       int match;
+       struct chan_centers centers;
+
+       ath9k_hw_get_channel_centers(ah, chan, &centers);
+
+       for (numPiers = 0; numPiers < availPiers; numPiers++)
+               if (calChans[numPiers] == AR5416_BCHAN_UNUSED)
+                       break;
+
+       match = ath9k_hw_get_lower_upper_index(
+                       (u8)FREQ2FBIN(centers.synth_center, IS_CHAN_2GHZ(chan)),
+                       calChans, numPiers, &idxL, &idxR);
+       if (match) {
+               pcdac = rawDatasetOpLoop[idxL].pcdac[0][0];
+               *pwr = rawDatasetOpLoop[idxL].pwrPdg[0][0];
+       } else {
+               pcdac = rawDatasetOpLoop[idxR].pcdac[0][0];
+               *pwr = (rawDatasetOpLoop[idxL].pwrPdg[0][0] +
+                               rawDatasetOpLoop[idxR].pwrPdg[0][0])/2;
+       }
+
+       while (pcdac > ah->originalGain[i] &&
+                       i < (AR9280_TX_GAIN_TABLE_SIZE - 1))
+               i++;
+
+       *pcdacIdx = i;
+}
+
+static void ath9k_olc_get_pdadcs(struct ath_hw *ah,
+                               u32 initTxGain,
+                               int txPower,
+                               u8 *pPDADCValues)
+{
+       u32 i;
+       u32 offset;
+
+       REG_RMW_FIELD(ah, AR_PHY_TX_PWRCTRL6_0,
+                       AR_PHY_TX_PWRCTRL_ERR_EST_MODE, 3);
+       REG_RMW_FIELD(ah, AR_PHY_TX_PWRCTRL6_1,
+                       AR_PHY_TX_PWRCTRL_ERR_EST_MODE, 3);
+
+       REG_RMW_FIELD(ah, AR_PHY_TX_PWRCTRL7,
+                       AR_PHY_TX_PWRCTRL_INIT_TX_GAIN, initTxGain);
+
+       offset = txPower;
+       for (i = 0; i < AR5416_NUM_PDADC_VALUES; i++)
+               if (i < offset)
+                       pPDADCValues[i] = 0x0;
+               else
+                       pPDADCValues[i] = 0xFF;
+}
+
+static int ath9k_hw_def_get_eeprom_ver(struct ath_hw *ah)
+{
+       return ((ah->eeprom.def.baseEepHeader.version >> 12) & 0xF);
+}
+
+static int ath9k_hw_def_get_eeprom_rev(struct ath_hw *ah)
+{
+       return ((ah->eeprom.def.baseEepHeader.version) & 0xFFF);
+}
+
+#define SIZE_EEPROM_DEF (sizeof(struct ar5416_eeprom_def) / sizeof(u16))
+
+static int __ath9k_hw_def_fill_eeprom(struct ath_hw *ah)
+{
+       struct ath_common *common = ath9k_hw_common(ah);
+       u16 *eep_data = (u16 *)&ah->eeprom.def;
+       unsigned int addr;
+       int ar5416_eep_start_loc = 0x100;
+
+       for (addr = 0; addr < SIZE_EEPROM_DEF; addr++) {
+               if (!ath9k_hw_nvram_read(common, addr + ar5416_eep_start_loc,
+                                        eep_data)) {
+                       DBG("ath9k: "
+                               "Unable to read eeprom region\n");
+                       return 0;
+               }
+               eep_data++;
+       }
+       return 1;
+}
+
+static int __ath9k_hw_usb_def_fill_eeprom(struct ath_hw *ah)
+{
+       u16 *eep_data = (u16 *)&ah->eeprom.def;
+
+       ath9k_hw_usb_gen_fill_eeprom(ah, eep_data,
+                                    0x100, SIZE_EEPROM_DEF);
+       return 1;
+}
+
+static int ath9k_hw_def_fill_eeprom(struct ath_hw *ah)
+{
+       struct ath_common *common = ath9k_hw_common(ah);
+
+       if (!ath9k_hw_use_flash(ah)) {
+               DBG2("ath9k: "
+                       "Reading from EEPROM, not flash\n");
+       }
+
+       if (common->bus_ops->ath_bus_type == ATH_USB)
+               return __ath9k_hw_usb_def_fill_eeprom(ah);
+       else
+               return __ath9k_hw_def_fill_eeprom(ah);
+}
+
+#undef SIZE_EEPROM_DEF
+
+static int ath9k_hw_def_check_eeprom(struct ath_hw *ah)
+{
+       struct ar5416_eeprom_def *eep =
+               (struct ar5416_eeprom_def *) &ah->eeprom.def;
+       struct ath_common *common = ath9k_hw_common(ah);
+       u16 *eepdata, temp, magic, magic2;
+       u32 sum = 0, el;
+       int need_swap = 0;
+       unsigned int i, addr, size;
+
+       if (!ath9k_hw_nvram_read(common, AR5416_EEPROM_MAGIC_OFFSET, &magic)) {
+               DBG("ath9k: Reading Magic # failed\n");
+               return 0;
+       }
+
+       if (!ath9k_hw_use_flash(ah)) {
+               DBG2("ath9k: "
+                       "Read Magic = 0x%04X\n", magic);
+
+               if (magic != AR5416_EEPROM_MAGIC) {
+                       magic2 = swab16(magic);
+
+                       if (magic2 == AR5416_EEPROM_MAGIC) {
+                               size = sizeof(struct ar5416_eeprom_def);
+                               need_swap = 1;
+                               eepdata = (u16 *) (&ah->eeprom);
+
+                               for (addr = 0; addr < size / sizeof(u16); addr++) {
+                                       temp = swab16(*eepdata);
+                                       *eepdata = temp;
+                                       eepdata++;
+                               }
+                       } else {
+                               DBG("ath9k: "
+                                       "Invalid EEPROM Magic. Endianness mismatch.\n");
+                               return -EINVAL;
+                       }
+               }
+       }
+
+       DBG2("ath9k: need_swap = %s.\n",
+               need_swap ? "True" : "False");
+
+       if (need_swap)
+               el = swab16(ah->eeprom.def.baseEepHeader.length);
+       else
+               el = ah->eeprom.def.baseEepHeader.length;
+
+       if (el > sizeof(struct ar5416_eeprom_def))
+               el = sizeof(struct ar5416_eeprom_def) / sizeof(u16);
+       else
+               el = el / sizeof(u16);
+
+       eepdata = (u16 *)(&ah->eeprom);
+
+       for (i = 0; i < el; i++)
+               sum ^= *eepdata++;
+
+       if (need_swap) {
+               u32 integer, j;
+               u16 word;
+
+               DBG("ath9k: "
+                       "EEPROM Endianness is not native.. Changing.\n");
+
+               word = swab16(eep->baseEepHeader.length);
+               eep->baseEepHeader.length = word;
+
+               word = swab16(eep->baseEepHeader.checksum);
+               eep->baseEepHeader.checksum = word;
+
+               word = swab16(eep->baseEepHeader.version);
+               eep->baseEepHeader.version = word;
+
+               word = swab16(eep->baseEepHeader.regDmn[0]);
+               eep->baseEepHeader.regDmn[0] = word;
+
+               word = swab16(eep->baseEepHeader.regDmn[1]);
+               eep->baseEepHeader.regDmn[1] = word;
+
+               word = swab16(eep->baseEepHeader.rfSilent);
+               eep->baseEepHeader.rfSilent = word;
+
+               word = swab16(eep->baseEepHeader.blueToothOptions);
+               eep->baseEepHeader.blueToothOptions = word;
+
+               word = swab16(eep->baseEepHeader.deviceCap);
+               eep->baseEepHeader.deviceCap = word;
+
+               for (j = 0; j < ARRAY_SIZE(eep->modalHeader); j++) {
+                       struct modal_eep_header *pModal =
+                               &eep->modalHeader[j];
+                       integer = swab32(pModal->antCtrlCommon);
+                       pModal->antCtrlCommon = integer;
+
+                       for (i = 0; i < AR5416_MAX_CHAINS; i++) {
+                               integer = swab32(pModal->antCtrlChain[i]);
+                               pModal->antCtrlChain[i] = integer;
+                       }
+                       for (i = 0; i < 3; i++) {
+                               word = swab16(pModal->xpaBiasLvlFreq[i]);
+                               pModal->xpaBiasLvlFreq[i] = word;
+                       }
+
+                       for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
+                               word = swab16(pModal->spurChans[i].spurChan);
+                               pModal->spurChans[i].spurChan = word;
+                       }
+               }
+       }
+
+       if (sum != 0xffff || ah->eep_ops->get_eeprom_ver(ah) != AR5416_EEP_VER ||
+           ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_NO_BACK_VER) {
+               DBG("ath9k: Bad EEPROM checksum 0x%x or revision 0x%04x\n",
+                       sum, ah->eep_ops->get_eeprom_ver(ah));
+               return -EINVAL;
+       }
+
+       /* Enable fixup for AR_AN_TOP2 if necessary */
+       if ((ah->hw_version.devid == AR9280_DEVID_PCI) &&
+           ((eep->baseEepHeader.version & 0xff) > 0x0a) &&
+           (eep->baseEepHeader.pwdclkind == 0))
+               ah->need_an_top2_fixup = 1;
+
+       if ((common->bus_ops->ath_bus_type == ATH_USB) &&
+           (AR_SREV_9280(ah)))
+               eep->modalHeader[0].xpaBiasLvl = 0;
+
+       return 0;
+}
+
+static u32 ath9k_hw_def_get_eeprom(struct ath_hw *ah,
+                                  enum eeprom_param param)
+{
+       struct ar5416_eeprom_def *eep = &ah->eeprom.def;
+       struct modal_eep_header *pModal = eep->modalHeader;
+       struct base_eep_header *pBase = &eep->baseEepHeader;
+
+       switch (param) {
+       case EEP_NFTHRESH_5:
+               return pModal[0].noiseFloorThreshCh[0];
+       case EEP_NFTHRESH_2:
+               return pModal[1].noiseFloorThreshCh[0];
+       case EEP_MAC_LSW:
+               return pBase->macAddr[0] << 8 | pBase->macAddr[1];
+       case EEP_MAC_MID:
+               return pBase->macAddr[2] << 8 | pBase->macAddr[3];
+       case EEP_MAC_MSW:
+               return pBase->macAddr[4] << 8 | pBase->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;
+       case EEP_RF_SILENT:
+               return pBase->rfSilent;
+       case EEP_OB_5:
+               return pModal[0].ob;
+       case EEP_DB_5:
+               return pModal[0].db;
+       case EEP_OB_2:
+               return pModal[1].ob;
+       case EEP_DB_2:
+               return pModal[1].db;
+       case EEP_MINOR_REV:
+               return AR5416_VER_MASK;
+       case EEP_TX_MASK:
+               return pBase->txMask;
+       case EEP_RX_MASK:
+               return pBase->rxMask;
+       case EEP_FSTCLK_5G:
+               return pBase->fastClk5g;
+       case EEP_RXGAIN_TYPE:
+               return pBase->rxGainType;
+       case EEP_TXGAIN_TYPE:
+               return pBase->txGainType;
+       case EEP_OL_PWRCTRL:
+               if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_19)
+                       return pBase->openLoopPwrCntl ? 1 : 0;
+               else
+                       return 0;
+       case EEP_RC_CHAIN_MASK:
+               if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_19)
+                       return pBase->rcChainMask;
+               else
+                       return 0;
+       case EEP_DAC_HPWR_5G:
+               if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_20)
+                       return pBase->dacHiPwrMode_5G;
+               else
+                       return 0;
+       case EEP_FRAC_N_5G:
+               if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_22)
+                       return pBase->frac_n_5g;
+               else
+                       return 0;
+       case EEP_PWR_TABLE_OFFSET:
+               if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_21)
+                       return pBase->pwr_table_offset;
+               else
+                       return AR5416_PWR_TABLE_OFFSET_DB;
+       default:
+               return 0;
+       }
+}
+
+static void ath9k_hw_def_set_gain(struct ath_hw *ah,
+                                 struct modal_eep_header *pModal,
+                                 struct ar5416_eeprom_def *eep,
+                                 u8 txRxAttenLocal, int regChainOffset, int i)
+{
+       if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_3) {
+               txRxAttenLocal = pModal->txRxAttenCh[i];
+
+               if (AR_SREV_9280_20_OR_LATER(ah)) {
+                       REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
+                             AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN,
+                             pModal->bswMargin[i]);
+                       REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
+                             AR_PHY_GAIN_2GHZ_XATTEN1_DB,
+                             pModal->bswAtten[i]);
+                       REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
+                             AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN,
+                             pModal->xatten2Margin[i]);
+                       REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
+                             AR_PHY_GAIN_2GHZ_XATTEN2_DB,
+                             pModal->xatten2Db[i]);
+               } else {
+                       REG_WRITE(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
+                         (REG_READ(ah, AR_PHY_GAIN_2GHZ + regChainOffset) &
+                          ~AR_PHY_GAIN_2GHZ_BSW_MARGIN)
+                         | SM(pModal-> bswMargin[i],
+                              AR_PHY_GAIN_2GHZ_BSW_MARGIN));
+                       REG_WRITE(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
+                         (REG_READ(ah, AR_PHY_GAIN_2GHZ + regChainOffset) &
+                          ~AR_PHY_GAIN_2GHZ_BSW_ATTEN)
+                         | SM(pModal->bswAtten[i],
+                              AR_PHY_GAIN_2GHZ_BSW_ATTEN));
+               }
+       }
+
+       if (AR_SREV_9280_20_OR_LATER(ah)) {
+               REG_RMW_FIELD(ah,
+                     AR_PHY_RXGAIN + regChainOffset,
+                     AR9280_PHY_RXGAIN_TXRX_ATTEN, txRxAttenLocal);
+               REG_RMW_FIELD(ah,
+                     AR_PHY_RXGAIN + regChainOffset,
+                     AR9280_PHY_RXGAIN_TXRX_MARGIN, pModal->rxTxMarginCh[i]);
+       } else {
+               REG_WRITE(ah,
+                         AR_PHY_RXGAIN + regChainOffset,
+                         (REG_READ(ah, AR_PHY_RXGAIN + regChainOffset) &
+                          ~AR_PHY_RXGAIN_TXRX_ATTEN)
+                         | SM(txRxAttenLocal, AR_PHY_RXGAIN_TXRX_ATTEN));
+               REG_WRITE(ah,
+                         AR_PHY_GAIN_2GHZ + regChainOffset,
+                         (REG_READ(ah, AR_PHY_GAIN_2GHZ + regChainOffset) &
+                          ~AR_PHY_GAIN_2GHZ_RXTX_MARGIN) |
+                         SM(pModal->rxTxMarginCh[i], AR_PHY_GAIN_2GHZ_RXTX_MARGIN));
+       }
+}
+
+static void ath9k_hw_def_set_board_values(struct ath_hw *ah,
+                                         struct ath9k_channel *chan)
+{
+       struct modal_eep_header *pModal;
+       struct ar5416_eeprom_def *eep = &ah->eeprom.def;
+       int i, regChainOffset;
+       u8 txRxAttenLocal;
+
+       pModal = &(eep->modalHeader[IS_CHAN_2GHZ(chan)]);
+       txRxAttenLocal = IS_CHAN_2GHZ(chan) ? 23 : 44;
+
+       REG_WRITE(ah, AR_PHY_SWITCH_COM, pModal->antCtrlCommon & 0xffff);
+
+       for (i = 0; i < AR5416_MAX_CHAINS; i++) {
+               if (AR_SREV_9280(ah)) {
+                       if (i >= 2)
+                               break;
+               }
+
+               if (AR_SREV_5416_20_OR_LATER(ah) &&
+                   (ah->rxchainmask == 5 || ah->txchainmask == 5) && (i != 0))
+                       regChainOffset = (i == 1) ? 0x2000 : 0x1000;
+               else
+                       regChainOffset = i * 0x1000;
+
+               REG_WRITE(ah, AR_PHY_SWITCH_CHAIN_0 + regChainOffset,
+                         pModal->antCtrlChain[i]);
+
+               REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset,
+                         (REG_READ(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset) &
+                          ~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF |
+                            AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF)) |
+                         SM(pModal->iqCalICh[i],
+                            AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF) |
+                         SM(pModal->iqCalQCh[i],
+                            AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF));
+
+               if ((i == 0) || AR_SREV_5416_20_OR_LATER(ah))
+                       ath9k_hw_def_set_gain(ah, pModal, eep, txRxAttenLocal,
+                                             regChainOffset, i);
+       }
+
+       if (AR_SREV_9280_20_OR_LATER(ah)) {
+               if (IS_CHAN_2GHZ(chan)) {
+                       ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH0,
+                                                 AR_AN_RF2G1_CH0_OB,
+                                                 AR_AN_RF2G1_CH0_OB_S,
+                                                 pModal->ob);
+                       ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH0,
+                                                 AR_AN_RF2G1_CH0_DB,
+                                                 AR_AN_RF2G1_CH0_DB_S,
+                                                 pModal->db);
+                       ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH1,
+                                                 AR_AN_RF2G1_CH1_OB,
+                                                 AR_AN_RF2G1_CH1_OB_S,
+                                                 pModal->ob_ch1);
+                       ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH1,
+                                                 AR_AN_RF2G1_CH1_DB,
+                                                 AR_AN_RF2G1_CH1_DB_S,
+                                                 pModal->db_ch1);
+               } else {
+                       ath9k_hw_analog_shift_rmw(ah, AR_AN_RF5G1_CH0,
+                                                 AR_AN_RF5G1_CH0_OB5,
+                                                 AR_AN_RF5G1_CH0_OB5_S,
+                                                 pModal->ob);
+                       ath9k_hw_analog_shift_rmw(ah, AR_AN_RF5G1_CH0,
+                                                 AR_AN_RF5G1_CH0_DB5,
+                                                 AR_AN_RF5G1_CH0_DB5_S,
+                                                 pModal->db);
+                       ath9k_hw_analog_shift_rmw(ah, AR_AN_RF5G1_CH1,
+                                                 AR_AN_RF5G1_CH1_OB5,
+                                                 AR_AN_RF5G1_CH1_OB5_S,
+                                                 pModal->ob_ch1);
+                       ath9k_hw_analog_shift_rmw(ah, AR_AN_RF5G1_CH1,
+                                                 AR_AN_RF5G1_CH1_DB5,
+                                                 AR_AN_RF5G1_CH1_DB5_S,
+                                                 pModal->db_ch1);
+               }
+               ath9k_hw_analog_shift_rmw(ah, AR_AN_TOP2,
+                                         AR_AN_TOP2_XPABIAS_LVL,
+                                         AR_AN_TOP2_XPABIAS_LVL_S,
+                                         pModal->xpaBiasLvl);
+               ath9k_hw_analog_shift_rmw(ah, AR_AN_TOP2,
+                                         AR_AN_TOP2_LOCALBIAS,
+                                         AR_AN_TOP2_LOCALBIAS_S,
+                                         !!(pModal->lna_ctl &
+                                            LNA_CTL_LOCAL_BIAS));
+               REG_RMW_FIELD(ah, AR_PHY_XPA_CFG, AR_PHY_FORCE_XPA_CFG,
+                             !!(pModal->lna_ctl & LNA_CTL_FORCE_XPA));
+       }
+
+       REG_RMW_FIELD(ah, AR_PHY_SETTLING, AR_PHY_SETTLING_SWITCH,
+                     pModal->switchSettling);
+       REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, AR_PHY_DESIRED_SZ_ADC,
+                     pModal->adcDesiredSize);
+
+       if (!AR_SREV_9280_20_OR_LATER(ah))
+               REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ,
+                             AR_PHY_DESIRED_SZ_PGA,
+                             pModal->pgaDesiredSize);
+
+       REG_WRITE(ah, AR_PHY_RF_CTL4,
+                 SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAA_OFF)
+                 | SM(pModal->txEndToXpaOff,
+                      AR_PHY_RF_CTL4_TX_END_XPAB_OFF)
+                 | SM(pModal->txFrameToXpaOn,
+                      AR_PHY_RF_CTL4_FRAME_XPAA_ON)
+                 | SM(pModal->txFrameToXpaOn,
+                      AR_PHY_RF_CTL4_FRAME_XPAB_ON));
+
+       REG_RMW_FIELD(ah, AR_PHY_RF_CTL3, AR_PHY_TX_END_TO_A2_RX_ON,
+                     pModal->txEndToRxOn);
+
+       if (AR_SREV_9280_20_OR_LATER(ah)) {
+               REG_RMW_FIELD(ah, AR_PHY_CCA, AR9280_PHY_CCA_THRESH62,
+                             pModal->thresh62);
+               REG_RMW_FIELD(ah, AR_PHY_EXT_CCA0,
+                             AR_PHY_EXT_CCA0_THRESH62,
+                             pModal->thresh62);
+       } else {
+               REG_RMW_FIELD(ah, AR_PHY_CCA, AR_PHY_CCA_THRESH62,
+                             pModal->thresh62);
+               REG_RMW_FIELD(ah, AR_PHY_EXT_CCA,
+                             AR_PHY_EXT_CCA_THRESH62,
+                             pModal->thresh62);
+       }
+
+       if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_2) {
+               REG_RMW_FIELD(ah, AR_PHY_RF_CTL2,
+                             AR_PHY_TX_END_DATA_START,
+                             pModal->txFrameToDataStart);
+               REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, AR_PHY_TX_END_PA_ON,
+                             pModal->txFrameToPaOn);
+       }
+
+       if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_3) {
+               if (IS_CHAN_HT40(chan))
+                       REG_RMW_FIELD(ah, AR_PHY_SETTLING,
+                                     AR_PHY_SETTLING_SWITCH,
+                                     pModal->swSettleHt40);
+       }
+
+       if (AR_SREV_9280_20_OR_LATER(ah) &&
+           AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_19)
+               REG_RMW_FIELD(ah, AR_PHY_CCK_TX_CTRL,
+                             AR_PHY_CCK_TX_CTRL_TX_DAC_SCALE_CCK,
+                             pModal->miscBits);
+
+
+       if (AR_SREV_9280_20(ah) && AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_20) {
+               if (IS_CHAN_2GHZ(chan))
+                       REG_RMW_FIELD(ah, AR_AN_TOP1, AR_AN_TOP1_DACIPMODE,
+                                       eep->baseEepHeader.dacLpMode);
+               else if (eep->baseEepHeader.dacHiPwrMode_5G)
+                       REG_RMW_FIELD(ah, AR_AN_TOP1, AR_AN_TOP1_DACIPMODE, 0);
+               else
+                       REG_RMW_FIELD(ah, AR_AN_TOP1, AR_AN_TOP1_DACIPMODE,
+                                     eep->baseEepHeader.dacLpMode);
+
+               udelay(100);
+
+               REG_RMW_FIELD(ah, AR_PHY_FRAME_CTL, AR_PHY_FRAME_CTL_TX_CLIP,
+                             pModal->miscBits >> 2);
+
+               REG_RMW_FIELD(ah, AR_PHY_TX_PWRCTRL9,
+                             AR_PHY_TX_DESIRED_SCALE_CCK,
+                             eep->baseEepHeader.desiredScaleCCK);
+       }
+}
+
+static void ath9k_hw_def_set_addac(struct ath_hw *ah,
+                                  struct ath9k_channel *chan)
+{
+#define XPA_LVL_FREQ(cnt) (pModal->xpaBiasLvlFreq[cnt])
+       struct modal_eep_header *pModal;
+       struct ar5416_eeprom_def *eep = &ah->eeprom.def;
+       u8 biaslevel;
+
+       if (ah->hw_version.macVersion != AR_SREV_VERSION_9160)
+               return;
+
+       if (ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_MINOR_VER_7)
+               return;
+
+       pModal = &(eep->modalHeader[IS_CHAN_2GHZ(chan)]);
+
+       if (pModal->xpaBiasLvl != 0xff) {
+               biaslevel = pModal->xpaBiasLvl;
+       } else {
+               u16 resetFreqBin, freqBin, freqCount = 0;
+               struct chan_centers centers;
+
+               ath9k_hw_get_channel_centers(ah, chan, &centers);
+
+               resetFreqBin = FREQ2FBIN(centers.synth_center,
+                                        IS_CHAN_2GHZ(chan));
+               freqBin = XPA_LVL_FREQ(0) & 0xff;
+               biaslevel = (u8) (XPA_LVL_FREQ(0) >> 14);
+
+               freqCount++;
+
+               while (freqCount < 3) {
+                       if (XPA_LVL_FREQ(freqCount) == 0x0)
+                               break;
+
+                       freqBin = XPA_LVL_FREQ(freqCount) & 0xff;
+                       if (resetFreqBin >= freqBin)
+                               biaslevel = (u8)(XPA_LVL_FREQ(freqCount) >> 14);
+                       else
+                               break;
+                       freqCount++;
+               }
+       }
+
+       if (IS_CHAN_2GHZ(chan)) {
+               INI_RA(&ah->iniAddac, 7, 1) = (INI_RA(&ah->iniAddac,
+                                       7, 1) & (~0x18)) | biaslevel << 3;
+       } else {
+               INI_RA(&ah->iniAddac, 6, 1) = (INI_RA(&ah->iniAddac,
+                                       6, 1) & (~0xc0)) | biaslevel << 6;
+       }
+#undef XPA_LVL_FREQ
+}
+
+static int16_t ath9k_change_gain_boundary_setting(struct ath_hw *ah,
+                               u16 *gb,
+                               u16 numXpdGain,
+                               u16 pdGainOverlap_t2,
+                               int8_t pwr_table_offset,
+                               int16_t *diff)
+
+{
+       u16 k;
+
+       /* Prior to writing the boundaries or the pdadc vs. power table
+        * into the chip registers the default starting point on the pdadc
+        * vs. power table needs to be checked and the curve boundaries
+        * adjusted accordingly
+        */
+       if (AR_SREV_9280_20_OR_LATER(ah)) {
+               u16 gb_limit;
+
+               if (AR5416_PWR_TABLE_OFFSET_DB != pwr_table_offset) {
+                       /* get the difference in dB */
+                       *diff = (u16)(pwr_table_offset - AR5416_PWR_TABLE_OFFSET_DB);
+                       /* get the number of half dB steps */
+                       *diff *= 2;
+                       /* change the original gain boundary settings
+                        * by the number of half dB steps
+                        */
+                       for (k = 0; k < numXpdGain; k++)
+                               gb[k] = (u16)(gb[k] - *diff);
+               }
+               /* Because of a hardware limitation, ensure the gain boundary
+                * is not larger than (63 - overlap)
+                */
+               gb_limit = (u16)(MAX_RATE_POWER - pdGainOverlap_t2);
+
+               for (k = 0; k < numXpdGain; k++)
+                       gb[k] = (u16)min(gb_limit, gb[k]);
+       }
+
+       return *diff;
+}
+
+static void ath9k_adjust_pdadc_values(struct ath_hw *ah,
+                                     int8_t pwr_table_offset,
+                                     int16_t diff,
+                                     u8 *pdadcValues)
+{
+#define NUM_PDADC(diff) (AR5416_NUM_PDADC_VALUES - diff)
+       u16 k;
+
+       /* If this is a board that has a pwrTableOffset that differs from
+        * the default AR5416_PWR_TABLE_OFFSET_DB then the start of the
+        * pdadc vs pwr table needs to be adjusted prior to writing to the
+        * chip.
+        */
+       if (AR_SREV_9280_20_OR_LATER(ah)) {
+               if (AR5416_PWR_TABLE_OFFSET_DB != pwr_table_offset) {
+                       /* shift the table to start at the new offset */
+                       for (k = 0; k < (u16)NUM_PDADC(diff); k++ ) {
+                               pdadcValues[k] = pdadcValues[k + diff];
+                       }
+
+                       /* fill the back of the table */
+                       for (k = (u16)NUM_PDADC(diff); k < NUM_PDADC(0); k++) {
+                               pdadcValues[k] = pdadcValues[NUM_PDADC(diff)];
+                       }
+               }
+       }
+#undef NUM_PDADC
+}
+
+static void ath9k_hw_set_def_power_cal_table(struct ath_hw *ah,
+                                 struct ath9k_channel *chan,
+                                 int16_t *pTxPowerIndexOffset)
+{
+#define SM_PD_GAIN(x) SM(0x38, AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_##x)
+#define SM_PDGAIN_B(x, y) \
+               SM((gainBoundaries[x]), AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_##y)
+       struct ar5416_eeprom_def *pEepData = &ah->eeprom.def;
+       struct cal_data_per_freq *pRawDataset;
+       u8 *pCalBChans = NULL;
+       u16 pdGainOverlap_t2;
+       static u8 pdadcValues[AR5416_NUM_PDADC_VALUES];
+       u16 gainBoundaries[AR5416_PD_GAINS_IN_MASK];
+       u16 numPiers, i, j;
+       int16_t diff = 0;
+       u16 numXpdGain, xpdMask;
+       u16 xpdGainValues[AR5416_NUM_PD_GAINS] = { 0, 0, 0, 0 };
+       u32 reg32, regOffset, regChainOffset;
+       int16_t modalIdx;
+       int8_t pwr_table_offset;
+
+       modalIdx = IS_CHAN_2GHZ(chan) ? 1 : 0;
+       xpdMask = pEepData->modalHeader[modalIdx].xpdGain;
+
+       pwr_table_offset = ah->eep_ops->get_eeprom(ah, EEP_PWR_TABLE_OFFSET);
+
+       if ((pEepData->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
+           AR5416_EEP_MINOR_VER_2) {
+               pdGainOverlap_t2 =
+                       pEepData->modalHeader[modalIdx].pdGainOverlap;
+       } else {
+               pdGainOverlap_t2 = (u16)(MS(REG_READ(ah, AR_PHY_TPCRG5),
+                                           AR_PHY_TPCRG5_PD_GAIN_OVERLAP));
+       }
+
+       if (IS_CHAN_2GHZ(chan)) {
+               pCalBChans = pEepData->calFreqPier2G;
+               numPiers = AR5416_NUM_2G_CAL_PIERS;
+       } else {
+               pCalBChans = pEepData->calFreqPier5G;
+               numPiers = AR5416_NUM_5G_CAL_PIERS;
+       }
+
+       if (OLC_FOR_AR9280_20_LATER && IS_CHAN_2GHZ(chan)) {
+               pRawDataset = pEepData->calPierData2G[0];
+               ah->initPDADC = ((struct calDataPerFreqOpLoop *)
+                                pRawDataset)->vpdPdg[0][0];
+       }
+
+       numXpdGain = 0;
+
+       for (i = 1; i <= AR5416_PD_GAINS_IN_MASK; i++) {
+               if ((xpdMask >> (AR5416_PD_GAINS_IN_MASK - i)) & 1) {
+                       if (numXpdGain >= AR5416_NUM_PD_GAINS)
+                               break;
+                       xpdGainValues[numXpdGain] =
+                               (u16)(AR5416_PD_GAINS_IN_MASK - i);
+                       numXpdGain++;
+               }
+       }
+
+       REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_NUM_PD_GAIN,
+                     (numXpdGain - 1) & 0x3);
+       REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_1,
+                     xpdGainValues[0]);
+       REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_2,
+                     xpdGainValues[1]);
+       REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_3,
+                     xpdGainValues[2]);
+
+       for (i = 0; i < AR5416_MAX_CHAINS; i++) {
+               if (AR_SREV_5416_20_OR_LATER(ah) &&
+                   (ah->rxchainmask == 5 || ah->txchainmask == 5) &&
+                   (i != 0)) {
+                       regChainOffset = (i == 1) ? 0x2000 : 0x1000;
+               } else
+                       regChainOffset = i * 0x1000;
+
+               if (pEepData->baseEepHeader.txMask & (1 << i)) {
+                       if (IS_CHAN_2GHZ(chan))
+                               pRawDataset = pEepData->calPierData2G[i];
+                       else
+                               pRawDataset = pEepData->calPierData5G[i];
+
+
+                       if (OLC_FOR_AR9280_20_LATER) {
+                               u8 pcdacIdx;
+                               u8 txPower;
+
+                               ath9k_get_txgain_index(ah, chan,
+                               (struct calDataPerFreqOpLoop *)pRawDataset,
+                               pCalBChans, numPiers, &txPower, &pcdacIdx);
+                               ath9k_olc_get_pdadcs(ah, pcdacIdx,
+                                                    txPower/2, pdadcValues);
+                       } else {
+                               ath9k_hw_get_gain_boundaries_pdadcs(ah,
+                                                       chan, pRawDataset,
+                                                       pCalBChans, numPiers,
+                                                       pdGainOverlap_t2,
+                                                       gainBoundaries,
+                                                       pdadcValues,
+                                                       numXpdGain);
+                       }
+
+                       diff = ath9k_change_gain_boundary_setting(ah,
+                                                          gainBoundaries,
+                                                          numXpdGain,
+                                                          pdGainOverlap_t2,
+                                                          pwr_table_offset,
+                                                          &diff);
+
+                       ENABLE_REGWRITE_BUFFER(ah);
+
+                       if ((i == 0) || AR_SREV_5416_20_OR_LATER(ah)) {
+                               if (OLC_FOR_AR9280_20_LATER) {
+                                       REG_WRITE(ah,
+                                               AR_PHY_TPCRG5 + regChainOffset,
+                                               SM(0x6,
+                                               AR_PHY_TPCRG5_PD_GAIN_OVERLAP) |
+                                               SM_PD_GAIN(1) | SM_PD_GAIN(2) |
+                                               SM_PD_GAIN(3) | SM_PD_GAIN(4));
+                               } else {
+                                       REG_WRITE(ah,
+                                               AR_PHY_TPCRG5 + regChainOffset,
+                                               SM(pdGainOverlap_t2,
+                                               AR_PHY_TPCRG5_PD_GAIN_OVERLAP)|
+                                               SM_PDGAIN_B(0, 1) |
+                                               SM_PDGAIN_B(1, 2) |
+                                               SM_PDGAIN_B(2, 3) |
+                                               SM_PDGAIN_B(3, 4));
+                               }
+                       }
+
+
+                       ath9k_adjust_pdadc_values(ah, pwr_table_offset,
+                                                 diff, pdadcValues);
+
+                       regOffset = AR_PHY_BASE + (672 << 2) + regChainOffset;
+                       for (j = 0; j < 32; j++) {
+                               reg32 = ((pdadcValues[4 * j + 0] & 0xFF) << 0) |
+                                       ((pdadcValues[4 * j + 1] & 0xFF) << 8) |
+                                       ((pdadcValues[4 * j + 2] & 0xFF) << 16)|
+                                       ((pdadcValues[4 * j + 3] & 0xFF) << 24);
+                               REG_WRITE(ah, regOffset, reg32);
+
+                               DBG2("ath9k: "
+                                       "PDADC (%d,%4x): %4.4x %8.8x\n",
+                                       i, regChainOffset, regOffset,
+                                       reg32);
+                               DBG2("ath9k: "
+                                       "PDADC: Chain %d | PDADC %3d "
+                                       "Value %3d | PDADC %3d Value %3d | "
+                                       "PDADC %3d Value %3d | PDADC %3d "
+                                       "Value %3d |\n",
+                                       i, 4 * j, pdadcValues[4 * j],
+                                       4 * j + 1, pdadcValues[4 * j + 1],
+                                       4 * j + 2, pdadcValues[4 * j + 2],
+                                       4 * j + 3, pdadcValues[4 * j + 3]);
+
+                               regOffset += 4;
+                       }
+                       REGWRITE_BUFFER_FLUSH(ah);
+               }
+       }
+
+       *pTxPowerIndexOffset = 0;
+#undef SM_PD_GAIN
+#undef SM_PDGAIN_B
+}
+
+static void ath9k_hw_set_def_power_per_rate_table(struct ath_hw *ah,
+                                                 struct ath9k_channel *chan,
+                                                 int16_t *ratesArray,
+                                                 u16 cfgCtl,
+                                                 u16 AntennaReduction,
+                                                 u16 twiceMaxRegulatoryPower,
+                                                 u16 powerLimit)
+{
+#define REDUCE_SCALED_POWER_BY_TWO_CHAIN     6  /* 10*log10(2)*2 */
+#define REDUCE_SCALED_POWER_BY_THREE_CHAIN   9 /* 10*log10(3)*2 */
+
+       struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
+       struct ar5416_eeprom_def *pEepData = &ah->eeprom.def;
+       u16 twiceMaxEdgePower = MAX_RATE_POWER;
+       static const u16 tpScaleReductionTable[5] =
+               { 0, 3, 6, 9, MAX_RATE_POWER };
+
+       unsigned int i;
+       int16_t twiceLargestAntenna;
+       struct cal_ctl_data *rep;
+       struct cal_target_power_leg targetPowerOfdm, targetPowerCck = {
+               0, { 0, 0, 0, 0}
+       };
+       struct cal_target_power_leg targetPowerOfdmExt = {
+               0, { 0, 0, 0, 0} }, targetPowerCckExt = {
+               0, { 0, 0, 0, 0 }
+       };
+       struct cal_target_power_ht targetPowerHt20, targetPowerHt40 = {
+               0, {0, 0, 0, 0}
+       };
+       u16 scaledPower = 0, minCtlPower, maxRegAllowedPower;
+       static const u16 ctlModesFor11a[] = {
+               CTL_11A, CTL_5GHT20, CTL_11A_EXT, CTL_5GHT40
+       };
+       static const u16 ctlModesFor11g[] = {
+               CTL_11B, CTL_11G, CTL_2GHT20,
+               CTL_11B_EXT, CTL_11G_EXT, CTL_2GHT40
+       };
+       u16 numCtlModes;
+       const u16 *pCtlMode;
+       u16 ctlMode, freq;
+       struct chan_centers centers;
+       int tx_chainmask;
+       u16 twiceMinEdgePower;
+
+       tx_chainmask = ah->txchainmask;
+
+       ath9k_hw_get_channel_centers(ah, chan, &centers);
+
+       twiceLargestAntenna = max(
+               pEepData->modalHeader
+                       [IS_CHAN_2GHZ(chan)].antennaGainCh[0],
+               pEepData->modalHeader
+                       [IS_CHAN_2GHZ(chan)].antennaGainCh[1]);
+
+       twiceLargestAntenna = max((u8)twiceLargestAntenna,
+                                 pEepData->modalHeader
+                                 [IS_CHAN_2GHZ(chan)].antennaGainCh[2]);
+
+       twiceLargestAntenna = (int16_t)min(AntennaReduction -
+                                          twiceLargestAntenna, 0);
+
+       maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna;
+
+       if (regulatory->tp_scale != ATH9K_TP_SCALE_MAX) {
+               maxRegAllowedPower -=
+                       (tpScaleReductionTable[(regulatory->tp_scale)] * 2);
+       }
+
+       scaledPower = min(powerLimit, maxRegAllowedPower);
+
+       switch (ar5416_get_ntxchains(tx_chainmask)) {
+       case 1:
+               break;
+       case 2:
+               if (scaledPower > REDUCE_SCALED_POWER_BY_TWO_CHAIN)
+                       scaledPower -= REDUCE_SCALED_POWER_BY_TWO_CHAIN;
+               else
+                       scaledPower = 0;
+               break;
+       case 3:
+               if (scaledPower > REDUCE_SCALED_POWER_BY_THREE_CHAIN)
+                       scaledPower -= REDUCE_SCALED_POWER_BY_THREE_CHAIN;
+               else
+                       scaledPower = 0;
+               break;
+       }
+
+       if (IS_CHAN_2GHZ(chan)) {
+               numCtlModes = ARRAY_SIZE(ctlModesFor11g) -
+                       SUB_NUM_CTL_MODES_AT_2G_40;
+               pCtlMode = ctlModesFor11g;
+
+               ath9k_hw_get_legacy_target_powers(ah, chan,
+                       pEepData->calTargetPowerCck,
+                       AR5416_NUM_2G_CCK_TARGET_POWERS,
+                       &targetPowerCck, 4, 0);
+               ath9k_hw_get_legacy_target_powers(ah, chan,
+                       pEepData->calTargetPower2G,
+                       AR5416_NUM_2G_20_TARGET_POWERS,
+                       &targetPowerOfdm, 4, 0);
+               ath9k_hw_get_target_powers(ah, chan,
+                       pEepData->calTargetPower2GHT20,
+                       AR5416_NUM_2G_20_TARGET_POWERS,
+                       &targetPowerHt20, 8, 0);
+
+               if (IS_CHAN_HT40(chan)) {
+                       numCtlModes = ARRAY_SIZE(ctlModesFor11g);
+                       ath9k_hw_get_target_powers(ah, chan,
+                               pEepData->calTargetPower2GHT40,
+                               AR5416_NUM_2G_40_TARGET_POWERS,
+                               &targetPowerHt40, 8, 1);
+                       ath9k_hw_get_legacy_target_powers(ah, chan,
+                               pEepData->calTargetPowerCck,
+                               AR5416_NUM_2G_CCK_TARGET_POWERS,
+                               &targetPowerCckExt, 4, 1);
+                       ath9k_hw_get_legacy_target_powers(ah, chan,
+                               pEepData->calTargetPower2G,
+                               AR5416_NUM_2G_20_TARGET_POWERS,
+                               &targetPowerOfdmExt, 4, 1);
+               }
+       } else {
+               numCtlModes = ARRAY_SIZE(ctlModesFor11a) -
+                       SUB_NUM_CTL_MODES_AT_5G_40;
+               pCtlMode = ctlModesFor11a;
+
+               ath9k_hw_get_legacy_target_powers(ah, chan,
+                       pEepData->calTargetPower5G,
+                       AR5416_NUM_5G_20_TARGET_POWERS,
+                       &targetPowerOfdm, 4, 0);
+               ath9k_hw_get_target_powers(ah, chan,
+                       pEepData->calTargetPower5GHT20,
+                       AR5416_NUM_5G_20_TARGET_POWERS,
+                       &targetPowerHt20, 8, 0);
+
+               if (IS_CHAN_HT40(chan)) {
+                       numCtlModes = ARRAY_SIZE(ctlModesFor11a);
+                       ath9k_hw_get_target_powers(ah, chan,
+                               pEepData->calTargetPower5GHT40,
+                               AR5416_NUM_5G_40_TARGET_POWERS,
+                               &targetPowerHt40, 8, 1);
+                       ath9k_hw_get_legacy_target_powers(ah, chan,
+                               pEepData->calTargetPower5G,
+                               AR5416_NUM_5G_20_TARGET_POWERS,
+                               &targetPowerOfdmExt, 4, 1);
+               }
+       }
+
+       for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) {
+               int isHt40CtlMode = (pCtlMode[ctlMode] == CTL_5GHT40) ||
+                       (pCtlMode[ctlMode] == CTL_2GHT40);
+               if (isHt40CtlMode)
+                       freq = centers.synth_center;
+               else if (pCtlMode[ctlMode] & EXT_ADDITIVE)
+                       freq = centers.ext_center;
+               else
+                       freq = centers.ctl_center;
+
+               if (ah->eep_ops->get_eeprom_ver(ah) == 14 &&
+                   ah->eep_ops->get_eeprom_rev(ah) <= 2)
+                       twiceMaxEdgePower = MAX_RATE_POWER;
+
+               for (i = 0; (i < AR5416_NUM_CTLS) && pEepData->ctlIndex[i]; i++) {
+                       if ((((cfgCtl & ~CTL_MODE_M) |
+                             (pCtlMode[ctlMode] & CTL_MODE_M)) ==
+                            pEepData->ctlIndex[i]) ||
+                           (((cfgCtl & ~CTL_MODE_M) |
+                             (pCtlMode[ctlMode] & CTL_MODE_M)) ==
+                            ((pEepData->ctlIndex[i] & CTL_MODE_M) | SD_NO_CTL))) {
+                               rep = &(pEepData->ctlData[i]);
+
+                               twiceMinEdgePower = ath9k_hw_get_max_edge_power(freq,
+                               rep->ctlEdges[ar5416_get_ntxchains(tx_chainmask) - 1],
+                               IS_CHAN_2GHZ(chan), AR5416_NUM_BAND_EDGES);
+
+                               if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL) {
+                                       twiceMaxEdgePower = min(twiceMaxEdgePower,
+                                                               twiceMinEdgePower);
+                               } else {
+                                       twiceMaxEdgePower = twiceMinEdgePower;
+                                       break;
+                               }
+                       }
+               }
+
+               minCtlPower = min(twiceMaxEdgePower, scaledPower);
+
+               switch (pCtlMode[ctlMode]) {
+               case CTL_11B:
+                       for (i = 0; i < ARRAY_SIZE(targetPowerCck.tPow2x); i++) {
+                               targetPowerCck.tPow2x[i] =
+                                       min((u16)targetPowerCck.tPow2x[i],
+                                           minCtlPower);
+                       }
+                       break;
+               case CTL_11A:
+               case CTL_11G:
+                       for (i = 0; i < ARRAY_SIZE(targetPowerOfdm.tPow2x); i++) {
+                               targetPowerOfdm.tPow2x[i] =
+                                       min((u16)targetPowerOfdm.tPow2x[i],
+                                           minCtlPower);
+                       }
+                       break;
+               case CTL_5GHT20:
+               case CTL_2GHT20:
+                       for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++) {
+                               targetPowerHt20.tPow2x[i] =
+                                       min((u16)targetPowerHt20.tPow2x[i],
+                                           minCtlPower);
+                       }
+                       break;
+               case CTL_11B_EXT:
+                       targetPowerCckExt.tPow2x[0] = min((u16)
+                                       targetPowerCckExt.tPow2x[0],
+                                       minCtlPower);
+                       break;
+               case CTL_11A_EXT:
+               case CTL_11G_EXT:
+                       targetPowerOfdmExt.tPow2x[0] = min((u16)
+                                       targetPowerOfdmExt.tPow2x[0],
+                                       minCtlPower);
+                       break;
+               case CTL_5GHT40:
+               case CTL_2GHT40:
+                       for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++) {
+                               targetPowerHt40.tPow2x[i] =
+                                       min((u16)targetPowerHt40.tPow2x[i],
+                                           minCtlPower);
+                       }
+                       break;
+               default:
+                       break;
+               }
+       }
+
+       ratesArray[rate6mb] = ratesArray[rate9mb] = ratesArray[rate12mb] =
+               ratesArray[rate18mb] = ratesArray[rate24mb] =
+               targetPowerOfdm.tPow2x[0];
+       ratesArray[rate36mb] = targetPowerOfdm.tPow2x[1];
+       ratesArray[rate48mb] = targetPowerOfdm.tPow2x[2];
+       ratesArray[rate54mb] = targetPowerOfdm.tPow2x[3];
+       ratesArray[rateXr] = targetPowerOfdm.tPow2x[0];
+
+       for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++)
+               ratesArray[rateHt20_0 + i] = targetPowerHt20.tPow2x[i];
+
+       if (IS_CHAN_2GHZ(chan)) {
+               ratesArray[rate1l] = targetPowerCck.tPow2x[0];
+               ratesArray[rate2s] = ratesArray[rate2l] =
+                       targetPowerCck.tPow2x[1];
+               ratesArray[rate5_5s] = ratesArray[rate5_5l] =
+                       targetPowerCck.tPow2x[2];
+               ratesArray[rate11s] = ratesArray[rate11l] =
+                       targetPowerCck.tPow2x[3];
+       }
+       if (IS_CHAN_HT40(chan)) {
+               for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++) {
+                       ratesArray[rateHt40_0 + i] =
+                               targetPowerHt40.tPow2x[i];
+               }
+               ratesArray[rateDupOfdm] = targetPowerHt40.tPow2x[0];
+               ratesArray[rateDupCck] = targetPowerHt40.tPow2x[0];
+               ratesArray[rateExtOfdm] = targetPowerOfdmExt.tPow2x[0];
+               if (IS_CHAN_2GHZ(chan)) {
+                       ratesArray[rateExtCck] =
+                               targetPowerCckExt.tPow2x[0];
+               }
+       }
+}
+
+static void ath9k_hw_def_set_txpower(struct ath_hw *ah,
+                                   struct ath9k_channel *chan,
+                                   u16 cfgCtl,
+                                   u8 twiceAntennaReduction,
+                                   u8 twiceMaxRegulatoryPower,
+                                   u8 powerLimit, int test)
+{
+#define RT_AR_DELTA(x) (ratesArray[x] - cck_ofdm_delta)
+       struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
+       struct ar5416_eeprom_def *pEepData = &ah->eeprom.def;
+       struct modal_eep_header *pModal =
+               &(pEepData->modalHeader[IS_CHAN_2GHZ(chan)]);
+       int16_t ratesArray[Ar5416RateSize];
+       int16_t txPowerIndexOffset = 0;
+       u8 ht40PowerIncForPdadc = 2;
+       unsigned int i, cck_ofdm_delta = 0;
+
+       memset(ratesArray, 0, sizeof(ratesArray));
+
+       if ((pEepData->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
+           AR5416_EEP_MINOR_VER_2) {
+               ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc;
+       }
+
+       ath9k_hw_set_def_power_per_rate_table(ah, chan,
+                                              &ratesArray[0], cfgCtl,
+                                              twiceAntennaReduction,
+                                              twiceMaxRegulatoryPower,
+                                              powerLimit);
+
+       ath9k_hw_set_def_power_cal_table(ah, chan, &txPowerIndexOffset);
+
+       regulatory->max_power_level = 0;
+       for (i = 0; i < ARRAY_SIZE(ratesArray); i++) {
+               ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]);
+               if (ratesArray[i] > MAX_RATE_POWER)
+                       ratesArray[i] = MAX_RATE_POWER;
+               if (ratesArray[i] > regulatory->max_power_level)
+                       regulatory->max_power_level = ratesArray[i];
+       }
+
+       if (!test) {
+               i = rate6mb;
+
+               if (IS_CHAN_HT40(chan))
+                       i = rateHt40_0;
+               else if (IS_CHAN_HT20(chan))
+                       i = rateHt20_0;
+
+               regulatory->max_power_level = ratesArray[i];
+       }
+
+       switch(ar5416_get_ntxchains(ah->txchainmask)) {
+       case 1:
+               break;
+       case 2:
+               regulatory->max_power_level += INCREASE_MAXPOW_BY_TWO_CHAIN;
+               break;
+       case 3:
+               regulatory->max_power_level += INCREASE_MAXPOW_BY_THREE_CHAIN;
+               break;
+       default:
+               DBG2("ath9k: "
+                       "Invalid chainmask configuration\n");
+               break;
+       }
+
+       if (test)
+               return;
+
+       if (AR_SREV_9280_20_OR_LATER(ah)) {
+               for (i = 0; i < Ar5416RateSize; i++) {
+                       int8_t pwr_table_offset;
+
+                       pwr_table_offset = ah->eep_ops->get_eeprom(ah,
+                                                       EEP_PWR_TABLE_OFFSET);
+                       ratesArray[i] -= pwr_table_offset * 2;
+               }
+       }
+
+       ENABLE_REGWRITE_BUFFER(ah);
+
+       REG_WRITE(ah, AR_PHY_POWER_TX_RATE1,
+                 ATH9K_POW_SM(ratesArray[rate18mb], 24)
+                 | ATH9K_POW_SM(ratesArray[rate12mb], 16)
+                 | ATH9K_POW_SM(ratesArray[rate9mb], 8)
+                 | ATH9K_POW_SM(ratesArray[rate6mb], 0));
+       REG_WRITE(ah, AR_PHY_POWER_TX_RATE2,
+                 ATH9K_POW_SM(ratesArray[rate54mb], 24)
+                 | ATH9K_POW_SM(ratesArray[rate48mb], 16)
+                 | ATH9K_POW_SM(ratesArray[rate36mb], 8)
+                 | ATH9K_POW_SM(ratesArray[rate24mb], 0));
+
+       if (IS_CHAN_2GHZ(chan)) {
+               if (OLC_FOR_AR9280_20_LATER) {
+                       cck_ofdm_delta = 2;
+                       REG_WRITE(ah, AR_PHY_POWER_TX_RATE3,
+                               ATH9K_POW_SM(RT_AR_DELTA(rate2s), 24)
+                               | ATH9K_POW_SM(RT_AR_DELTA(rate2l), 16)
+                               | ATH9K_POW_SM(ratesArray[rateXr], 8)
+                               | ATH9K_POW_SM(RT_AR_DELTA(rate1l), 0));
+                       REG_WRITE(ah, AR_PHY_POWER_TX_RATE4,
+                               ATH9K_POW_SM(RT_AR_DELTA(rate11s), 24)
+                               | ATH9K_POW_SM(RT_AR_DELTA(rate11l), 16)
+                               | ATH9K_POW_SM(RT_AR_DELTA(rate5_5s), 8)
+                               | ATH9K_POW_SM(RT_AR_DELTA(rate5_5l), 0));
+               } else {
+                       REG_WRITE(ah, AR_PHY_POWER_TX_RATE3,
+                               ATH9K_POW_SM(ratesArray[rate2s], 24)
+                               | ATH9K_POW_SM(ratesArray[rate2l], 16)
+                               | ATH9K_POW_SM(ratesArray[rateXr], 8)
+                               | ATH9K_POW_SM(ratesArray[rate1l], 0));
+                       REG_WRITE(ah, AR_PHY_POWER_TX_RATE4,
+                               ATH9K_POW_SM(ratesArray[rate11s], 24)
+                               | ATH9K_POW_SM(ratesArray[rate11l], 16)
+                               | ATH9K_POW_SM(ratesArray[rate5_5s], 8)
+                               | ATH9K_POW_SM(ratesArray[rate5_5l], 0));
+               }
+       }
+
+       REG_WRITE(ah, AR_PHY_POWER_TX_RATE5,
+                 ATH9K_POW_SM(ratesArray[rateHt20_3], 24)
+                 | ATH9K_POW_SM(ratesArray[rateHt20_2], 16)
+                 | ATH9K_POW_SM(ratesArray[rateHt20_1], 8)
+                 | ATH9K_POW_SM(ratesArray[rateHt20_0], 0));
+       REG_WRITE(ah, AR_PHY_POWER_TX_RATE6,
+                 ATH9K_POW_SM(ratesArray[rateHt20_7], 24)
+                 | ATH9K_POW_SM(ratesArray[rateHt20_6], 16)
+                 | ATH9K_POW_SM(ratesArray[rateHt20_5], 8)
+                 | ATH9K_POW_SM(ratesArray[rateHt20_4], 0));
+
+       if (IS_CHAN_HT40(chan)) {
+               REG_WRITE(ah, AR_PHY_POWER_TX_RATE7,
+                         ATH9K_POW_SM(ratesArray[rateHt40_3] +
+                                      ht40PowerIncForPdadc, 24)
+                         | ATH9K_POW_SM(ratesArray[rateHt40_2] +
+                                        ht40PowerIncForPdadc, 16)
+                         | ATH9K_POW_SM(ratesArray[rateHt40_1] +
+                                        ht40PowerIncForPdadc, 8)
+                         | ATH9K_POW_SM(ratesArray[rateHt40_0] +
+                                        ht40PowerIncForPdadc, 0));
+               REG_WRITE(ah, AR_PHY_POWER_TX_RATE8,
+                         ATH9K_POW_SM(ratesArray[rateHt40_7] +
+                                      ht40PowerIncForPdadc, 24)
+                         | ATH9K_POW_SM(ratesArray[rateHt40_6] +
+                                        ht40PowerIncForPdadc, 16)
+                         | ATH9K_POW_SM(ratesArray[rateHt40_5] +
+                                        ht40PowerIncForPdadc, 8)
+                         | ATH9K_POW_SM(ratesArray[rateHt40_4] +
+                                        ht40PowerIncForPdadc, 0));
+               if (OLC_FOR_AR9280_20_LATER) {
+                       REG_WRITE(ah, AR_PHY_POWER_TX_RATE9,
+                               ATH9K_POW_SM(ratesArray[rateExtOfdm], 24)
+                               | ATH9K_POW_SM(RT_AR_DELTA(rateExtCck), 16)
+                               | ATH9K_POW_SM(ratesArray[rateDupOfdm], 8)
+                               | ATH9K_POW_SM(RT_AR_DELTA(rateDupCck), 0));
+               } else {
+                       REG_WRITE(ah, AR_PHY_POWER_TX_RATE9,
+                               ATH9K_POW_SM(ratesArray[rateExtOfdm], 24)
+                               | ATH9K_POW_SM(ratesArray[rateExtCck], 16)
+                               | ATH9K_POW_SM(ratesArray[rateDupOfdm], 8)
+                               | ATH9K_POW_SM(ratesArray[rateDupCck], 0));
+               }
+       }
+
+       REG_WRITE(ah, AR_PHY_POWER_TX_SUB,
+                 ATH9K_POW_SM(pModal->pwrDecreaseFor3Chain, 6)
+                 | ATH9K_POW_SM(pModal->pwrDecreaseFor2Chain, 0));
+
+       REGWRITE_BUFFER_FLUSH(ah);
+}
+
+static u16 ath9k_hw_def_get_spur_channel(struct ath_hw *ah, u16 i, int is2GHz)
+{
+#define EEP_DEF_SPURCHAN \
+       (ah->eeprom.def.modalHeader[is2GHz].spurChans[i].spurChan)
+
+       u16 spur_val = AR_NO_SPUR;
+
+       DBG2("ath9k: "
+               "Getting spur idx:%d is2Ghz:%d val:%x\n",
+               i, is2GHz, ah->config.spurchans[i][is2GHz]);
+
+       switch (ah->config.spurmode) {
+       case SPUR_DISABLE:
+               break;
+       case SPUR_ENABLE_IOCTL:
+               spur_val = ah->config.spurchans[i][is2GHz];
+               DBG2("ath9k: "
+                       "Getting spur val from new loc. %d\n", spur_val);
+               break;
+       case SPUR_ENABLE_EEPROM:
+               spur_val = EEP_DEF_SPURCHAN;
+               break;
+       }
+
+       return spur_val;
+
+#undef EEP_DEF_SPURCHAN
+}
+
+const struct eeprom_ops eep_def_ops = {
+       .check_eeprom           = ath9k_hw_def_check_eeprom,
+       .get_eeprom             = ath9k_hw_def_get_eeprom,
+       .fill_eeprom            = ath9k_hw_def_fill_eeprom,
+       .get_eeprom_ver         = ath9k_hw_def_get_eeprom_ver,
+       .get_eeprom_rev         = ath9k_hw_def_get_eeprom_rev,
+       .set_board_values       = ath9k_hw_def_set_board_values,
+       .set_addac              = ath9k_hw_def_set_addac,
+       .set_txpower            = ath9k_hw_def_set_txpower,
+       .get_spur_channel       = ath9k_hw_def_get_spur_channel
+};
diff --git a/src/drivers/net/ath/ath9k/ath9k_hw.c b/src/drivers/net/ath/ath9k/ath9k_hw.c
new file mode 100644 (file)
index 0000000..554e9be
--- /dev/null
@@ -0,0 +1,2067 @@
+/*
+ * Copyright (c) 2008-2011 Atheros Communications Inc.
+ *
+ * Modified for iPXE by Scott K Logan <logans@cottsay.net> July 2011
+ * Original from Linux kernel 3.0.1
+ *
+ * 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 <ipxe/vsprintf.h>
+#include <ipxe/io.h>
+
+#include "hw.h"
+#include "hw-ops.h"
+#include "ar9003_mac.h"
+
+static int ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type);
+
+/* 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 u32 ath9k_hw_compute_pll_control(struct ath_hw *ah,
+                                       struct ath9k_channel *chan)
+{
+       return ath9k_hw_private_ops(ah)->compute_pll_control(ah, chan);
+}
+
+static void ath9k_hw_init_mode_gain_regs(struct ath_hw *ah)
+{
+       if (!ath9k_hw_private_ops(ah)->init_mode_gain_regs)
+               return;
+
+       ath9k_hw_private_ops(ah)->init_mode_gain_regs(ah);
+}
+
+static void ath9k_hw_ani_cache_ini_regs(struct ath_hw *ah)
+{
+       /* You will not have this callback if using the old ANI */
+       if (!ath9k_hw_private_ops(ah)->ani_cache_ini_regs)
+               return;
+
+       ath9k_hw_private_ops(ah)->ani_cache_ini_regs(ah);
+}
+
+/********************/
+/* Helper Functions */
+/********************/
+
+static void ath9k_hw_set_clockrate(struct ath_hw *ah)
+{
+       struct ath_common *common = ath9k_hw_common(ah);
+       struct net80211_device *dev = common->dev;
+       unsigned int clockrate;
+
+       if (!ah->curchan) /* should really check for CCK instead */
+               clockrate = ATH9K_CLOCK_RATE_CCK;
+       else if ((dev->channels + dev->channel)->band == NET80211_BAND_2GHZ)
+               clockrate = ATH9K_CLOCK_RATE_2GHZ_OFDM;
+       else if (ah->caps.hw_caps & ATH9K_HW_CAP_FASTCLOCK)
+               clockrate = ATH9K_CLOCK_FAST_RATE_5GHZ_OFDM;
+       else
+               clockrate = ATH9K_CLOCK_RATE_5GHZ_OFDM;
+
+       common->clockrate = clockrate;
+}
+
+static u32 ath9k_hw_mac_to_clks(struct ath_hw *ah, u32 usecs)
+{
+       struct ath_common *common = ath9k_hw_common(ah);
+
+       return usecs * common->clockrate;
+}
+
+int ath9k_hw_wait(struct ath_hw *ah, u32 reg, u32 mask, u32 val, u32 timeout)
+{
+       unsigned int i;
+
+       for (i = 0; i < (timeout / AH_TIME_QUANTUM); i++) {
+               if ((REG_READ(ah, reg) & mask) == val)
+                       return 1;
+
+               udelay(AH_TIME_QUANTUM);
+       }
+
+       DBG("ath9k: "
+               "timeout (%d us) on reg 0x%x: 0x%08x & 0x%08x != 0x%08x\n",
+               timeout, reg, REG_READ(ah, reg), mask, val);
+
+       return 0;
+}
+
+void ath9k_hw_write_array(struct ath_hw *ah, struct ar5416IniArray *array,
+                         int column, unsigned int *writecnt)
+{
+       unsigned int r;
+
+       ENABLE_REGWRITE_BUFFER(ah);
+       for (r = 0; r < array->ia_rows; r++) {
+               REG_WRITE(ah, INI_RA(array, r, 0),
+                         INI_RA(array, r, column));
+               DO_DELAY(*writecnt);
+       }
+       REGWRITE_BUFFER_FLUSH(ah);
+}
+
+u32 ath9k_hw_reverse_bits(u32 val, u32 n)
+{
+       u32 retval;
+       unsigned int i;
+
+       for (i = 0, retval = 0; i < n; i++) {
+               retval = (retval << 1) | (val & 1);
+               val >>= 1;
+       }
+       return retval;
+}
+
+u16 ath9k_hw_computetxtime(struct ath_hw *ah,
+                          u8 phy, int kbps,
+                          u32 frameLen, u16 rateix,
+                          int shortPreamble)
+{
+       u32 bitsPerSymbol, numBits, numSymbols, phyTime, txTime;
+
+       if (kbps == 0)
+               return 0;
+
+       switch (phy) {
+       case CHANNEL_CCK:
+               phyTime = CCK_PREAMBLE_BITS + CCK_PLCP_BITS;
+               if (shortPreamble)
+                       phyTime >>= 1;
+               numBits = frameLen << 3;
+               txTime = CCK_SIFS_TIME + phyTime + ((numBits * 1000) / kbps);
+               break;
+       case CHANNEL_OFDM:
+               if (ah->curchan && IS_CHAN_QUARTER_RATE(ah->curchan)) {
+                       bitsPerSymbol = (kbps * OFDM_SYMBOL_TIME_QUARTER) / 1000;
+                       numBits = OFDM_PLCP_BITS + (frameLen << 3);
+                       numSymbols = DIV_ROUND_UP(numBits, bitsPerSymbol);
+                       txTime = OFDM_SIFS_TIME_QUARTER
+                               + OFDM_PREAMBLE_TIME_QUARTER
+                               + (numSymbols * OFDM_SYMBOL_TIME_QUARTER);
+               } else if (ah->curchan &&
+                          IS_CHAN_HALF_RATE(ah->curchan)) {
+                       bitsPerSymbol = (kbps * OFDM_SYMBOL_TIME_HALF) / 1000;
+                       numBits = OFDM_PLCP_BITS + (frameLen << 3);
+                       numSymbols = DIV_ROUND_UP(numBits, bitsPerSymbol);
+                       txTime = OFDM_SIFS_TIME_HALF +
+                               OFDM_PREAMBLE_TIME_HALF
+                               + (numSymbols * OFDM_SYMBOL_TIME_HALF);
+               } else {
+                       bitsPerSymbol = (kbps * OFDM_SYMBOL_TIME) / 1000;
+                       numBits = OFDM_PLCP_BITS + (frameLen << 3);
+                       numSymbols = DIV_ROUND_UP(numBits, bitsPerSymbol);
+                       txTime = OFDM_SIFS_TIME + OFDM_PREAMBLE_TIME
+                               + (numSymbols * OFDM_SYMBOL_TIME);
+               }
+               break;
+       default:
+               DBG("ath9k: "
+                       "Unknown phy %d (rate ix %d)\n", phy, rateix);
+               txTime = 0;
+               break;
+       }
+
+       return txTime;
+}
+
+void ath9k_hw_get_channel_centers(struct ath_hw *ah __unused,
+                                 struct ath9k_channel *chan,
+                                 struct chan_centers *centers)
+{
+       int8_t extoff;
+
+       if (!IS_CHAN_HT40(chan)) {
+               centers->ctl_center = centers->ext_center =
+                       centers->synth_center = chan->channel;
+               return;
+       }
+
+       if ((chan->chanmode == CHANNEL_A_HT40PLUS) ||
+           (chan->chanmode == CHANNEL_G_HT40PLUS)) {
+               centers->synth_center =
+                       chan->channel + HT40_CHANNEL_CENTER_SHIFT;
+               extoff = 1;
+       } else {
+               centers->synth_center =
+                       chan->channel - HT40_CHANNEL_CENTER_SHIFT;
+               extoff = -1;
+       }
+
+       centers->ctl_center =
+               centers->synth_center - (extoff * HT40_CHANNEL_CENTER_SHIFT);
+       /* 25 MHz spacing is supported by hw but not on upper layers */
+       centers->ext_center =
+               centers->synth_center + (extoff * HT40_CHANNEL_CENTER_SHIFT);
+}
+
+/******************/
+/* Chip Revisions */
+/******************/
+
+static void ath9k_hw_read_revisions(struct ath_hw *ah)
+{
+       u32 val;
+
+       switch (ah->hw_version.devid) {
+       case AR5416_AR9100_DEVID:
+               ah->hw_version.macVersion = AR_SREV_VERSION_9100;
+               break;
+       case AR9300_DEVID_AR9340:
+               ah->hw_version.macVersion = AR_SREV_VERSION_9340;
+               val = REG_READ(ah, AR_SREV);
+               ah->hw_version.macRev = MS(val, AR_SREV_REVISION2);
+               return;
+       }
+
+       val = REG_READ(ah, AR_SREV) & AR_SREV_ID;
+
+       if (val == 0xFF) {
+               val = REG_READ(ah, AR_SREV);
+               ah->hw_version.macVersion =
+                       (val & AR_SREV_VERSION2) >> AR_SREV_TYPE2_S;
+               ah->hw_version.macRev = MS(val, AR_SREV_REVISION2);
+               ah->is_pciexpress = (val & AR_SREV_TYPE2_HOST_MODE) ? 0 : 1;
+       } else {
+               if (!AR_SREV_9100(ah))
+                       ah->hw_version.macVersion = MS(val, AR_SREV_VERSION);
+
+               ah->hw_version.macRev = val & AR_SREV_REVISION;
+
+               if (ah->hw_version.macVersion == AR_SREV_VERSION_5416_PCIE)
+                       ah->is_pciexpress = 1;
+       }
+}
+
+/************************************/
+/* HW Attach, Detach, Init Routines */
+/************************************/
+
+static void ath9k_hw_disablepcie(struct ath_hw *ah)
+{
+       if (!AR_SREV_5416(ah))
+               return;
+
+       REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fc00);
+       REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924);
+       REG_WRITE(ah, AR_PCIE_SERDES, 0x28000029);
+       REG_WRITE(ah, AR_PCIE_SERDES, 0x57160824);
+       REG_WRITE(ah, AR_PCIE_SERDES, 0x25980579);
+       REG_WRITE(ah, AR_PCIE_SERDES, 0x00000000);
+       REG_WRITE(ah, AR_PCIE_SERDES, 0x1aaabe40);
+       REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554);
+       REG_WRITE(ah, AR_PCIE_SERDES, 0x000e1007);
+
+       REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
+}
+
+/* This should work for all families including legacy */
+static int ath9k_hw_chip_test(struct ath_hw *ah)
+{
+       u32 regAddr[2] = { AR_STA_ID0 };
+       u32 regHold[2];
+       static const u32 patternData[4] = {
+               0x55555555, 0xaaaaaaaa, 0x66666666, 0x99999999
+       };
+       int i, j, loop_max;
+
+       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;
+
+               regHold[i] = REG_READ(ah, addr);
+               for (j = 0; j < 0x100; j++) {
+                       wrData = (j << 16) | j;
+                       REG_WRITE(ah, addr, wrData);
+                       rdData = REG_READ(ah, addr);
+                       if (rdData != wrData) {
+                               DBG("ath9k: "
+                                       "address test failed addr: 0x%08x - wr:0x%08x != rd:0x%08x\n",
+                                       addr, wrData, rdData);
+                               return 0;
+                       }
+               }
+               for (j = 0; j < 4; j++) {
+                       wrData = patternData[j];
+                       REG_WRITE(ah, addr, wrData);
+                       rdData = REG_READ(ah, addr);
+                       if (wrData != rdData) {
+                               DBG("ath9k: "
+                                       "address test failed addr: 0x%08x - wr:0x%08x != rd:0x%08x\n",
+                                       addr, wrData, rdData);
+                               return 0;
+                       }
+               }
+               REG_WRITE(ah, regAddr[i], regHold[i]);
+       }
+       udelay(100);
+
+       return 1;
+}
+
+static void ath9k_hw_init_config(struct ath_hw *ah)
+{
+       int i;
+
+       ah->config.dma_beacon_response_time = 2;
+       ah->config.sw_beacon_response_time = 10;
+       ah->config.additional_swba_backoff = 0;
+       ah->config.ack_6mb = 0x0;
+       ah->config.cwm_ignore_extcca = 0;
+       ah->config.pcie_powersave_enable = 0;
+       ah->config.pcie_clock_req = 0;
+       ah->config.pcie_waen = 0;
+       ah->config.analog_shiftreg = 1;
+       ah->config.enable_ani = 1;
+
+       for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
+               ah->config.spurchans[i][0] = AR_NO_SPUR;
+               ah->config.spurchans[i][1] = AR_NO_SPUR;
+       }
+
+       /* PAPRD needs some more work to be enabled */
+       ah->config.paprd_disable = 1;
+
+       ah->config.rx_intr_mitigation = 1;
+       ah->config.pcieSerDesWrite = 1;
+}
+
+static void ath9k_hw_init_defaults(struct ath_hw *ah)
+{
+       struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
+
+       regulatory->country_code = CTRY_DEFAULT;
+       regulatory->power_limit = MAX_RATE_POWER;
+       regulatory->tp_scale = ATH9K_TP_SCALE_MAX;
+
+       ah->hw_version.magic = AR5416_MAGIC;
+       ah->hw_version.subvendorid = 0;
+
+       ah->atim_window = 0;
+       ah->sta_id1_defaults =
+               AR_STA_ID1_CRPT_MIC_ENABLE |
+               AR_STA_ID1_MCAST_KSRCH;
+       if (AR_SREV_9100(ah))
+               ah->sta_id1_defaults |= AR_STA_ID1_AR9100_BA_FIX;
+       ah->enable_32kHz_clock = DONT_USE_32KHZ;
+       ah->slottime = 20;
+       ah->globaltxtimeout = (u32) -1;
+       ah->power_mode = ATH9K_PM_UNDEFINED;
+}
+
+static int ath9k_hw_init_macaddr(struct ath_hw *ah)
+{
+       struct ath_common *common = ath9k_hw_common(ah);
+       u32 sum;
+       int i;
+       u16 eeval;
+       static const 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, EEP_MAC[i]);
+               sum += eeval;
+               common->macaddr[2 * i] = eeval >> 8;
+               common->macaddr[2 * i + 1] = eeval & 0xff;
+       }
+       if (sum == 0 || sum == 0xffff * 3)
+               return -EADDRNOTAVAIL;
+
+       return 0;
+}
+
+static int ath9k_hw_post_init(struct ath_hw *ah)
+{
+       struct ath_common *common = ath9k_hw_common(ah);
+       int ecode;
+
+       if (common->bus_ops->ath_bus_type != ATH_USB) {
+               if (!ath9k_hw_chip_test(ah))
+                       return -ENODEV;
+       }
+
+       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)
+               return ecode;
+
+       DBG("ath9k: "
+               "Eeprom VER: %d, REV: %d\n",
+               ah->eep_ops->get_eeprom_ver(ah),
+               ah->eep_ops->get_eeprom_rev(ah));
+
+       ecode = ath9k_hw_rf_alloc_ext_banks(ah);
+       if (ecode) {
+               DBG("ath9k: "
+                       "Failed allocating banks for external radio\n");
+               ath9k_hw_rf_free_ext_banks(ah);
+               return ecode;
+       }
+
+       if (!AR_SREV_9100(ah) && !AR_SREV_9340(ah)) {
+               ath9k_hw_ani_setup(ah);
+               ath9k_hw_ani_init(ah);
+       }
+
+       return 0;
+}
+
+static void ath9k_hw_attach_ops(struct ath_hw *ah)
+{
+       if (AR_SREV_9300_20_OR_LATER(ah))
+               ar9003_hw_attach_ops(ah);
+       else
+               ar9002_hw_attach_ops(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;
+
+       ath9k_hw_read_revisions(ah);
+
+       /*
+        * Read back AR_WA into a permanent copy and set bits 14 and 17.
+        * We need to do this to avoid RMW of this register. We cannot
+        * read the reg when chip is asleep.
+        */
+       ah->WARegVal = REG_READ(ah, AR_WA);
+       ah->WARegVal |= (AR_WA_D3_L1_DISABLE |
+                        AR_WA_ASPM_TIMER_BASED_DISABLE);
+
+       if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_POWER_ON)) {
+               DBG("ath9k: Couldn't reset chip\n");
+               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)) {
+               DBG("ath9k: Couldn't wakeup chip\n");
+               return -EIO;
+       }
+
+       if (ah->config.serialize_regmode == SER_REG_MODE_AUTO) {
+               if (ah->hw_version.macVersion == AR_SREV_VERSION_5416_PCI ||
+                   ((AR_SREV_9160(ah) || AR_SREV_9280(ah)) &&
+                    !ah->is_pciexpress)) {
+                       ah->config.serialize_regmode =
+                               SER_REG_MODE_ON;
+               } else {
+                       ah->config.serialize_regmode =
+                               SER_REG_MODE_OFF;
+               }
+       }
+
+       DBG2("ath9k: serialize_regmode is %d\n",
+               ah->config.serialize_regmode);
+
+       if (AR_SREV_9285(ah) || AR_SREV_9271(ah))
+               ah->config.max_txtrig_level = MAX_TX_FIFO_THRESHOLD >> 1;
+       else
+               ah->config.max_txtrig_level = MAX_TX_FIFO_THRESHOLD;
+
+       switch (ah->hw_version.macVersion) {
+       case AR_SREV_VERSION_5416_PCI:
+       case AR_SREV_VERSION_5416_PCIE:
+       case AR_SREV_VERSION_9160:
+       case AR_SREV_VERSION_9100:
+       case AR_SREV_VERSION_9280:
+       case AR_SREV_VERSION_9285:
+       case AR_SREV_VERSION_9287:
+       case AR_SREV_VERSION_9271:
+       case AR_SREV_VERSION_9300:
+       case AR_SREV_VERSION_9485:
+       case AR_SREV_VERSION_9340:
+               break;
+       default:
+               DBG("ath9k: "
+                       "Mac Chip Rev 0x%02x.%x is not supported by this driver\n",
+                       ah->hw_version.macVersion, ah->hw_version.macRev);
+               return -EOPNOTSUPP;
+       }
+
+       if (AR_SREV_9271(ah) || AR_SREV_9100(ah) || AR_SREV_9340(ah))
+               ah->is_pciexpress = 0;
+
+       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_20_OR_LATER(ah) && !AR_SREV_9300_20_OR_LATER(ah))
+               ah->ani_function &= ~ATH9K_ANI_NOISE_IMMUNITY_LEVEL;
+       if (!AR_SREV_9300_20_OR_LATER(ah))
+               ah->ani_function &= ~ATH9K_ANI_MRC_CCK;
+
+       ath9k_hw_init_mode_regs(ah);
+
+
+       if (ah->is_pciexpress)
+               ath9k_hw_configpcipowersave(ah, 0, 0);
+       else
+               ath9k_hw_disablepcie(ah);
+
+       if (!AR_SREV_9300_20_OR_LATER(ah))
+               ar9002_hw_cck_chan14_spread(ah);
+
+       r = ath9k_hw_post_init(ah);
+       if (r)
+               return r;
+
+       ath9k_hw_init_mode_gain_regs(ah);
+       r = ath9k_hw_fill_cap_info(ah);
+       if (r)
+               return r;
+
+       r = ath9k_hw_init_macaddr(ah);
+       if (r) {
+               DBG("ath9k: Failed to initialize MAC address\n");
+               return r;
+       }
+
+       if (AR_SREV_9285(ah) || AR_SREV_9271(ah))
+               ah->tx_trig_level = (AR_FTRIG_256B >> AR_FTRIG_S);
+       else
+               ah->tx_trig_level = (AR_FTRIG_512B >> AR_FTRIG_S);
+
+       common->state = ATH_HW_INITIALIZED;
+
+       return 0;
+}
+
+int ath9k_hw_init(struct ath_hw *ah)
+{
+       int ret;
+       struct ath_common *common = ath9k_hw_common(ah);
+
+       /* 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:
+       case AR9300_DEVID_AR9485_PCIE:
+       case AR9300_DEVID_AR9340:
+               break;
+       default:
+               if (common->bus_ops->ath_bus_type == ATH_USB)
+                       break;
+               DBG("ath9k: Hardware device ID 0x%04x not supported\n",
+                       ah->hw_version.devid);
+               return -EOPNOTSUPP;
+       }
+
+       ret = __ath9k_hw_init(ah);
+       if (ret) {
+               DBG("ath9k: "
+                       "Unable to initialize hardware; initialization status: %d\n",
+                       ret);
+               return ret;
+       }
+
+       return 0;
+}
+
+u32 ar9003_get_pll_sqsum_dvc(struct ath_hw *ah)
+{
+       REG_CLR_BIT(ah, PLL3, PLL3_DO_MEAS_MASK);
+       udelay(100);
+       REG_SET_BIT(ah, PLL3, PLL3_DO_MEAS_MASK);
+
+       while ((REG_READ(ah, PLL4) & PLL4_MEAS_DONE) == 0)
+               udelay(100);
+
+       return (REG_READ(ah, PLL3) & SQSUM_DVC_MASK) >> 3;
+}
+
+static void ath9k_hw_init_pll(struct ath_hw *ah,
+                             struct ath9k_channel *chan)
+{
+       u32 pll;
+
+       if (AR_SREV_9485(ah)) {
+
+               /* program BB PLL ki and kd value, ki=0x4, kd=0x40 */
+               REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2,
+                             AR_CH0_BB_DPLL2_PLL_PWD, 0x1);
+               REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2,
+                             AR_CH0_DPLL2_KD, 0x40);
+               REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2,
+                             AR_CH0_DPLL2_KI, 0x4);
+
+               REG_RMW_FIELD(ah, AR_CH0_BB_DPLL1,
+                             AR_CH0_BB_DPLL1_REFDIV, 0x5);
+               REG_RMW_FIELD(ah, AR_CH0_BB_DPLL1,
+                             AR_CH0_BB_DPLL1_NINI, 0x58);
+               REG_RMW_FIELD(ah, AR_CH0_BB_DPLL1,
+                             AR_CH0_BB_DPLL1_NFRAC, 0x0);
+
+               REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2,
+                             AR_CH0_BB_DPLL2_OUTDIV, 0x1);
+               REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2,
+                             AR_CH0_BB_DPLL2_LOCAL_PLL, 0x1);
+               REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2,
+                             AR_CH0_BB_DPLL2_EN_NEGTRIG, 0x1);
+
+               /* program BB PLL phase_shift to 0x6 */
+               REG_RMW_FIELD(ah, AR_CH0_BB_DPLL3,
+                             AR_CH0_BB_DPLL3_PHASE_SHIFT, 0x6);
+
+               REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2,
+                             AR_CH0_BB_DPLL2_PLL_PWD, 0x0);
+               udelay(1000);
+       } else if (AR_SREV_9340(ah)) {
+               u32 regval, pll2_divint, pll2_divfrac, refdiv;
+
+               REG_WRITE(ah, AR_RTC_PLL_CONTROL, 0x1142c);
+               udelay(1000);
+
+               REG_SET_BIT(ah, AR_PHY_PLL_MODE, 0x1 << 16);
+               udelay(100);
+
+               if (ah->is_clk_25mhz) {
+                       pll2_divint = 0x54;
+                       pll2_divfrac = 0x1eb85;
+                       refdiv = 3;
+               } else {
+                       pll2_divint = 88;
+                       pll2_divfrac = 0;
+                       refdiv = 5;
+               }
+
+               regval = REG_READ(ah, AR_PHY_PLL_MODE);
+               regval |= (0x1 << 16);
+               REG_WRITE(ah, AR_PHY_PLL_MODE, regval);
+               udelay(100);
+
+               REG_WRITE(ah, AR_PHY_PLL_CONTROL, (refdiv << 27) |
+                         (pll2_divint << 18) | pll2_divfrac);
+               udelay(100);
+
+               regval = REG_READ(ah, AR_PHY_PLL_MODE);
+               regval = (regval & 0x80071fff) | (0x1 << 30) | (0x1 << 13) |
+                        (0x4 << 26) | (0x18 << 19);
+               REG_WRITE(ah, AR_PHY_PLL_MODE, regval);
+               REG_WRITE(ah, AR_PHY_PLL_MODE,
+                         REG_READ(ah, AR_PHY_PLL_MODE) & 0xfffeffff);
+               udelay(1000);
+       }
+
+       pll = ath9k_hw_compute_pll_control(ah, chan);
+
+       REG_WRITE(ah, AR_RTC_PLL_CONTROL, pll);
+
+       if (AR_SREV_9485(ah) || AR_SREV_9340(ah))
+               udelay(1000);
+
+       /* Switch the core clock for ar9271 to 117Mhz */
+       if (AR_SREV_9271(ah)) {
+               udelay(500);
+               REG_WRITE(ah, 0x50040, 0x304);
+       }
+
+       udelay(RTC_PLL_SETTLE_DELAY);
+
+       REG_WRITE(ah, AR_RTC_SLEEP_CLK, AR_RTC_FORCE_DERIVED_CLK);
+
+       if (AR_SREV_9340(ah)) {
+               if (ah->is_clk_25mhz) {
+                       REG_WRITE(ah, AR_RTC_DERIVED_CLK, 0x17c << 1);
+                       REG_WRITE(ah, AR_SLP32_MODE, 0x0010f3d7);
+                       REG_WRITE(ah,  AR_SLP32_INC, 0x0001e7ae);
+               } else {
+                       REG_WRITE(ah, AR_RTC_DERIVED_CLK, 0x261 << 1);
+                       REG_WRITE(ah, AR_SLP32_MODE, 0x0010f400);
+                       REG_WRITE(ah,  AR_SLP32_INC, 0x0001e800);
+               }
+               udelay(100);
+       }
+}
+
+static void ath9k_hw_init_interrupt_masks(struct ath_hw *ah)
+{
+       u32 sync_default = AR_INTR_SYNC_DEFAULT;
+       u32 imr_reg = AR_IMR_TXERR |
+               AR_IMR_TXURN |
+               AR_IMR_RXERR |
+               AR_IMR_RXORN;;
+
+       if (AR_SREV_9340(ah))
+               sync_default &= ~AR_INTR_SYNC_HOST1_FATAL;
+
+       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;
+
+       } 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;
+
+       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);
+
+       if (!AR_SREV_9100(ah)) {
+               REG_WRITE(ah, AR_INTR_SYNC_CAUSE, 0xFFFFFFFF);
+               REG_WRITE(ah, AR_INTR_SYNC_ENABLE, sync_default);
+               REG_WRITE(ah, AR_INTR_SYNC_MASK, 0);
+       }
+
+       REGWRITE_BUFFER_FLUSH(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)
+{
+       u32 val = ath9k_hw_mac_to_clks(ah, us);
+       val = min(val, (u32) 0xFFFF);
+       REG_WRITE(ah, AR_D_GBL_IFS_SLOT, val);
+}
+
+static void ath9k_hw_set_ack_timeout(struct ath_hw *ah, u32 us)
+{
+       u32 val = ath9k_hw_mac_to_clks(ah, us);
+       val = min(val, (u32) MS(0xFFFFFFFF, AR_TIME_OUT_ACK));
+       REG_RMW_FIELD(ah, AR_TIME_OUT, AR_TIME_OUT_ACK, val);
+}
+
+static void ath9k_hw_set_cts_timeout(struct ath_hw *ah, u32 us)
+{
+       u32 val = ath9k_hw_mac_to_clks(ah, us);
+       val = min(val, (u32) MS(0xFFFFFFFF, AR_TIME_OUT_CTS));
+       REG_RMW_FIELD(ah, AR_TIME_OUT, AR_TIME_OUT_CTS, val);
+}
+
+static int ath9k_hw_set_global_txtimeout(struct ath_hw *ah, u32 tu)
+{
+       if (tu > 0xFFFF) {
+               DBG("ath9k: "
+                       "bad global tx timeout %d\n", tu);
+               ah->globaltxtimeout = (u32) -1;
+               return 0;
+       } else {
+               REG_RMW_FIELD(ah, AR_GTXTO, AR_GTXTO_TIMEOUT_LIMIT, tu);
+               ah->globaltxtimeout = tu;
+               return 1;
+       }
+}
+
+void ath9k_hw_init_global_settings(struct ath_hw *ah)
+{
+       int acktimeout;
+       int slottime;
+       int sifstime;
+
+       DBG2("ath9k: ah->misc_mode 0x%x\n",
+               ah->misc_mode);
+
+       if (ah->misc_mode != 0)
+               REG_SET_BIT(ah, AR_PCU_MISC, ah->misc_mode);
+
+       if ((ah->dev->channels + ah->dev->channel)->band == NET80211_BAND_5GHZ)
+               sifstime = 16;
+       else
+               sifstime = 10;
+
+       /* As defined by IEEE 802.11-2007 17.3.8.6 */
+       slottime = ah->slottime + 3 * ah->coverage_class;
+       acktimeout = slottime + sifstime;
+
+       /*
+        * Workaround for early ACK timeouts, add an offset to match the
+        * initval's 64us ack timeout value.
+        * This was initially only meant to work around an issue with delayed
+        * BA frames in some implementations, but it has been found to fix ACK
+        * timeout issues in other cases as well.
+        */
+       if ((ah->dev->channels + ah->dev->channel)->band == NET80211_BAND_2GHZ)
+               acktimeout += 64 - sifstime - ah->slottime;
+
+       ath9k_hw_setslottime(ah, ah->slottime);
+       ath9k_hw_set_ack_timeout(ah, acktimeout);
+       ath9k_hw_set_cts_timeout(ah, acktimeout);
+       if (ah->globaltxtimeout != (u32) -1)
+               ath9k_hw_set_global_txtimeout(ah, ah->globaltxtimeout);
+}
+
+void ath9k_hw_deinit(struct ath_hw *ah)
+{
+       struct ath_common *common = ath9k_hw_common(ah);
+
+       if (common->state < ATH_HW_INITIALIZED)
+               goto free_hw;
+
+       ath9k_hw_setpower(ah, ATH9K_PM_FULL_SLEEP);
+
+free_hw:
+       ath9k_hw_rf_free_ext_banks(ah);
+}
+
+/*******/
+/* INI */
+/*******/
+
+u32 ath9k_regd_get_ctl(struct ath_regulatory *reg, struct ath9k_channel *chan)
+{
+       u32 ctl = ath_regd_get_band_ctl(reg, chan->chan->band);
+
+       if (IS_CHAN_B(chan))
+               ctl |= CTL_11B;
+       else if (IS_CHAN_G(chan))
+               ctl |= CTL_11G;
+       else
+               ctl |= CTL_11A;
+
+       return ctl;
+}
+
+/****************************************/
+/* Reset and Channel Switching Routines */
+/****************************************/
+
+static inline void ath9k_hw_set_dma(struct ath_hw *ah)
+{
+       struct ath_common *common = ath9k_hw_common(ah);
+
+       ENABLE_REGWRITE_BUFFER(ah);
+
+       /*
+        * set AHB_MODE not to do cacheline prefetches
+       */
+       if (!AR_SREV_9300_20_OR_LATER(ah))
+               REG_SET_BIT(ah, AR_AHB_MODE, AR_AHB_PREFETCH_RD_EN);
+
+       /*
+        * let mac dma reads be in 128 byte chunks
+        */
+       REG_RMW(ah, AR_TXCFG, AR_TXCFG_DMASZ_128B, AR_TXCFG_DMASZ_MASK);
+
+       REGWRITE_BUFFER_FLUSH(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.
+        */
+       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
+        */
+       REG_RMW(ah, AR_RXCFG, AR_RXCFG_DMASZ_128B, AR_RXCFG_DMASZ_MASK);
+
+       /*
+        * Setup receive FIFO threshold to hold off TX activities
+        */
+       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.
+        */
+       if (AR_SREV_9285(ah)) {
+               /* For AR9285 the number of Fifos are reduced to half.
+                * So set the usable tx buf size also to half to
+                * avoid data/delimiter underruns
+                */
+               REG_WRITE(ah, AR_PCU_TXBUF_CTRL,
+                         AR_9285_PCU_TXBUF_CTRL_USABLE_SIZE);
+       } else if (!AR_SREV_9271(ah)) {
+               REG_WRITE(ah, AR_PCU_TXBUF_CTRL,
+                         AR_PCU_TXBUF_CTRL_USABLE_SIZE);
+       }
+
+       REGWRITE_BUFFER_FLUSH(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)
+{
+       u32 mask = AR_STA_ID1_STA_AP | AR_STA_ID1_ADHOC;
+       u32 set = AR_STA_ID1_KSRCH_MODE;
+
+       REG_CLR_BIT(ah, AR_CFG, AR_CFG_AP_ADHOC_INDICATION);
+
+       REG_RMW(ah, AR_STA_ID1, set, mask);
+}
+
+void ath9k_hw_get_delta_slope_vals(struct ath_hw *ah __unused, u32 coef_scaled,
+                                  u32 *coef_mantissa, u32 *coef_exponent)
+{
+       u32 coef_exp, coef_man;
+
+       for (coef_exp = 31; coef_exp > 0; coef_exp--)
+               if ((coef_scaled >> coef_exp) & 0x1)
+                       break;
+
+       coef_exp = 14 - (coef_exp - COEF_SCALE_S);
+
+       coef_man = coef_scaled + (1 << (COEF_SCALE_S - coef_exp - 1));
+
+       *coef_mantissa = coef_man >> (COEF_SCALE_S - coef_exp);
+       *coef_exponent = coef_exp - 16;
+}
+
+static int ath9k_hw_set_reset(struct ath_hw *ah, int type)
+{
+       u32 rst_flags;
+       u32 tmpReg;
+
+       if (AR_SREV_9100(ah)) {
+               REG_RMW_FIELD(ah, AR_RTC_DERIVED_CLK,
+                             AR_RTC_DERIVED_CLK_PERIOD, 1);
+               (void)REG_READ(ah, AR_RTC_DERIVED_CLK);
+       }
+
+       ENABLE_REGWRITE_BUFFER(ah);
+
+       if (AR_SREV_9300_20_OR_LATER(ah)) {
+               REG_WRITE(ah, AR_WA, ah->WARegVal);
+               udelay(10);
+       }
+
+       REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN |
+                 AR_RTC_FORCE_WAKE_ON_INT);
+
+       if (AR_SREV_9100(ah)) {
+               rst_flags = AR_RTC_RC_MAC_WARM | AR_RTC_RC_MAC_COLD |
+                       AR_RTC_RC_COLD_RESET | AR_RTC_RC_WARM_RESET;
+       } else {
+               tmpReg = REG_READ(ah, AR_INTR_SYNC_CAUSE);
+               if (tmpReg &
+                   (AR_INTR_SYNC_LOCAL_TIMEOUT |
+                    AR_INTR_SYNC_RADM_CPL_TIMEOUT)) {
+                       u32 val;
+                       REG_WRITE(ah, AR_INTR_SYNC_ENABLE, 0);
+
+                       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)
+                       rst_flags |= AR_RTC_RC_MAC_COLD;
+       }
+
+       REG_WRITE(ah, AR_RTC_RC, rst_flags);
+
+       REGWRITE_BUFFER_FLUSH(ah);
+
+       udelay(50);
+
+       REG_WRITE(ah, AR_RTC_RC, 0);
+       if (!ath9k_hw_wait(ah, AR_RTC_RC, AR_RTC_RC_M, 0, AH_WAIT_TIMEOUT)) {
+               DBG("ath9k: "
+                       "RTC stuck in MAC reset\n");
+               return 0;
+       }
+
+       if (!AR_SREV_9100(ah))
+               REG_WRITE(ah, AR_RC, 0);
+
+       if (AR_SREV_9100(ah))
+               udelay(50);
+
+       return 1;
+}
+
+static int ath9k_hw_set_reset_power_on(struct ath_hw *ah)
+{
+       ENABLE_REGWRITE_BUFFER(ah);
+
+       if (AR_SREV_9300_20_OR_LATER(ah)) {
+               REG_WRITE(ah, AR_WA, ah->WARegVal);
+               udelay(10);
+       }
+
+       REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN |
+                 AR_RTC_FORCE_WAKE_ON_INT);
+
+       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);
+
+       REGWRITE_BUFFER_FLUSH(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);
+
+       if (!ath9k_hw_wait(ah,
+                          AR_RTC_STATUS,
+                          AR_RTC_STATUS_M,
+                          AR_RTC_STATUS_ON,
+                          AH_WAIT_TIMEOUT)) {
+               DBG("ath9k: "
+                       "RTC not waking up\n");
+               return 0;
+       }
+
+       return ath9k_hw_set_reset(ah, ATH9K_RESET_WARM);
+}
+
+static int ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type)
+{
+       if (AR_SREV_9300_20_OR_LATER(ah)) {
+               REG_WRITE(ah, AR_WA, ah->WARegVal);
+               udelay(10);
+       }
+
+       REG_WRITE(ah, AR_RTC_FORCE_WAKE,
+                 AR_RTC_FORCE_WAKE_EN | AR_RTC_FORCE_WAKE_ON_INT);
+
+       switch (type) {
+       case ATH9K_RESET_POWER_ON:
+               return ath9k_hw_set_reset_power_on(ah);
+       case ATH9K_RESET_WARM:
+       case ATH9K_RESET_COLD:
+               return ath9k_hw_set_reset(ah, type);
+       default:
+               return 0;
+       }
+}
+
+static int ath9k_hw_chip_reset(struct ath_hw *ah,
+                               struct ath9k_channel *chan)
+{
+       if (AR_SREV_9280(ah) && ah->eep_ops->get_eeprom(ah, EEP_OL_PWRCTRL)) {
+               if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_POWER_ON))
+                       return 0;
+       } else if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_WARM))
+               return 0;
+
+       if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
+               return 0;
+
+       ah->chip_fullsleep = 0;
+       ath9k_hw_init_pll(ah, chan);
+       ath9k_hw_set_rfmode(ah, chan);
+
+       return 1;
+}
+
+static int ath9k_hw_channel_change(struct ath_hw *ah,
+                                   struct ath9k_channel *chan)
+{
+       struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
+       struct net80211_channel *channel = chan->chan;
+       u32 qnum;
+       int r;
+
+       for (qnum = 0; qnum < AR_NUM_QCU; qnum++) {
+               if (ath9k_hw_numtxpending(ah, qnum)) {
+                       DBG("ath9k: "
+                               "Transmit frames pending on queue %d\n", qnum);
+                       return 0;
+               }
+       }
+
+       if (!ath9k_hw_rfbus_req(ah)) {
+               DBG("ath9k: Could not kill baseband RX\n");
+               return 0;
+       }
+
+       ath9k_hw_set_channel_regs(ah, chan);
+
+       r = ath9k_hw_rf_set_freq(ah, chan);
+       if (r) {
+               DBG("ath9k: Failed to set channel\n");
+               return 0;
+       }
+       ath9k_hw_set_clockrate(ah);
+
+       ah->eep_ops->set_txpower(ah, chan,
+                            ath9k_regd_get_ctl(regulatory, chan),
+                            0,
+                            channel->maxpower * 2,
+                            min((u32) MAX_RATE_POWER,
+                            (u32) regulatory->power_limit), 0);
+
+       ath9k_hw_rfbus_done(ah);
+
+       if (IS_CHAN_OFDM(chan) || IS_CHAN_HT(chan))
+               ath9k_hw_set_delta_slope(ah, chan);
+
+       ath9k_hw_spur_mitigate_freq(ah, chan);
+
+       return 1;
+}
+
+static void ath9k_hw_apply_gpio_override(struct ath_hw *ah)
+{
+       u32 gpio_mask = ah->gpio_mask;
+       int i;
+
+       for (i = 0; gpio_mask; i++, gpio_mask >>= 1) {
+               if (!(gpio_mask & 1))
+                       continue;
+
+               ath9k_hw_cfg_output(ah, i, AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
+               ath9k_hw_set_gpio(ah, i, !!(ah->gpio_val & BIT(i)));
+       }
+}
+
+int ath9k_hw_check_alive(struct ath_hw *ah)
+{
+       int count = 50;
+       u32 reg;
+
+       if (AR_SREV_9285_12_OR_LATER(ah))
+               return 1;
+
+       do {
+               reg = REG_READ(ah, AR_OBS_BUS_1);
+
+               if ((reg & 0x7E7FFFEF) == 0x00702400)
+                       continue;
+
+               switch (reg & 0x7E000B00) {
+               case 0x1E000000:
+               case 0x52000B00:
+               case 0x18000B00:
+                       continue;
+               default:
+                       return 1;
+               }
+       } while (count-- > 0);
+
+       return 0;
+}
+
+int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
+                  struct ath9k_hw_cal_data *caldata, int bChannelChange)
+{
+       struct ath_common *common = ath9k_hw_common(ah);
+       u32 saveLedState;
+       struct ath9k_channel *curchan = ah->curchan;
+       u32 saveDefAntenna;
+       u32 macStaId1;
+       int i, r;
+
+       ah->txchainmask = common->tx_chainmask;
+       ah->rxchainmask = common->rx_chainmask;
+
+       if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
+               return -EIO;
+
+       if (curchan && !ah->chip_fullsleep)
+               ath9k_hw_getnf(ah, curchan);
+
+       ah->caldata = caldata;
+       if (caldata &&
+           (chan->channel != caldata->channel ||
+            (chan->channelFlags & ~CHANNEL_CW_INT) !=
+            (caldata->channelFlags & ~CHANNEL_CW_INT))) {
+               /* Operating channel changed, reset channel calibration data */
+               memset(caldata, 0, sizeof(*caldata));
+               ath9k_init_nfcal_hist_buffer(ah, chan);
+       }
+
+       if (bChannelChange &&
+           (ah->chip_fullsleep != 1) &&
+           (ah->curchan != NULL) &&
+           (chan->channel != ah->curchan->channel) &&
+           ((chan->channelFlags & CHANNEL_ALL) ==
+            (ah->curchan->channelFlags & CHANNEL_ALL)) &&
+           (!AR_SREV_9280(ah) || AR_DEVID_7010(ah))) {
+
+               if (ath9k_hw_channel_change(ah, chan)) {
+                       ath9k_hw_loadnf(ah, ah->curchan);
+                       ath9k_hw_start_nfcal(ah, 1);
+                       if (AR_SREV_9271(ah))
+                               ar9002_hw_load_ani_reg(ah, chan);
+                       return 0;
+               }
+       }
+
+       saveDefAntenna = REG_READ(ah, AR_DEF_ANTENNA);
+       if (saveDefAntenna == 0)
+               saveDefAntenna = 1;
+
+       macStaId1 = REG_READ(ah, AR_STA_ID1) & AR_STA_ID1_BASE_RATE_11B;
+
+       saveLedState = REG_READ(ah, AR_CFG_LED) &
+               (AR_CFG_LED_ASSOC_CTL | AR_CFG_LED_MODE_SEL |
+                AR_CFG_LED_BLINK_THRESH_SEL | AR_CFG_LED_BLINK_SLOW);
+
+       ath9k_hw_mark_phy_inactive(ah);
+
+       ah->paprd_table_write_done = 0;
+
+       /* Only required on the first reset */
+       if (AR_SREV_9271(ah) && ah->htc_reset_init) {
+               REG_WRITE(ah,
+                         AR9271_RESET_POWER_DOWN_CONTROL,
+                         AR9271_RADIO_RF_RST);
+               udelay(50);
+       }
+
+       if (!ath9k_hw_chip_reset(ah, chan)) {
+               DBG("ath9k: Chip reset failed\n");
+               return -EINVAL;
+       }
+
+       /* Only required on the first reset */
+       if (AR_SREV_9271(ah) && ah->htc_reset_init) {
+               ah->htc_reset_init = 0;
+               REG_WRITE(ah,
+                         AR9271_RESET_POWER_DOWN_CONTROL,
+                         AR9271_GATE_MAC_CTL);
+               udelay(50);
+       }
+
+       if (AR_SREV_9280_20_OR_LATER(ah))
+               REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL, AR_GPIO_JTAG_DISABLE);
+
+       if (!AR_SREV_9300_20_OR_LATER(ah))
+               ar9002_hw_enable_async_fifo(ah);
+
+       r = ath9k_hw_process_ini(ah, chan);
+       if (r)
+               return r;
+
+       /* Setup MFP options for CCMP */
+       if (AR_SREV_9280_20_OR_LATER(ah)) {
+               /* Mask Retry(b11), PwrMgt(b12), MoreData(b13) to 0 in mgmt
+                * frames when constructing CCMP AAD. */
+               REG_RMW_FIELD(ah, AR_AES_MUTE_MASK1, AR_AES_MUTE_MASK1_FC_MGMT,
+                             0xc7ff);
+               ah->sw_mgmt_crypto = 0;
+       } else if (AR_SREV_9160_10_OR_LATER(ah)) {
+               /* Disable hardware crypto for management frames */
+               REG_CLR_BIT(ah, AR_PCU_MISC_MODE2,
+                           AR_PCU_MISC_MODE2_MGMT_CRYPTO_ENABLE);
+               REG_SET_BIT(ah, AR_PCU_MISC_MODE2,
+                           AR_PCU_MISC_MODE2_NO_CRYPTO_FOR_NON_DATA_PKT);
+               ah->sw_mgmt_crypto = 1;
+       } else
+               ah->sw_mgmt_crypto = 1;
+
+       if (IS_CHAN_OFDM(chan) || IS_CHAN_HT(chan))
+               ath9k_hw_set_delta_slope(ah, chan);
+
+       ath9k_hw_spur_mitigate_freq(ah, chan);
+       ah->eep_ops->set_board_values(ah, chan);
+
+       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
+                 | AR_STA_ID1_RTS_USE_DEF
+                 | (ah->config.
+                    ack_6mb ? AR_STA_ID1_ACKCTS_6MB : 0)
+                 | ah->sta_id1_defaults);
+       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);
+
+       REGWRITE_BUFFER_FLUSH(ah);
+
+       ath9k_hw_set_operating_mode(ah);
+
+       r = ath9k_hw_rf_set_freq(ah, chan);
+       if (r)
+               return r;
+
+       ath9k_hw_set_clockrate(ah);
+
+       ENABLE_REGWRITE_BUFFER(ah);
+
+       for (i = 0; i < AR_NUM_DCU; i++)
+               REG_WRITE(ah, AR_DQCUMASK(i), 1 << i);
+
+       REGWRITE_BUFFER_FLUSH(ah);
+
+       ah->intr_txqs = 0;
+       for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
+               ath9k_hw_resettxqueue(ah, i);
+
+       ath9k_hw_init_interrupt_masks(ah);
+       ath9k_hw_ani_cache_ini_regs(ah);
+
+       if (ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
+               ath9k_hw_cfg_gpio_input(ah, ah->rfkill_gpio);
+
+       ath9k_hw_init_global_settings(ah);
+
+       if (!AR_SREV_9300_20_OR_LATER(ah)) {
+               ar9002_hw_update_async_fifo(ah);
+               ar9002_hw_enable_wep_aggregation(ah);
+       }
+
+       REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PRESERVE_SEQNUM);
+
+       ath9k_hw_set_dma(ah);
+
+       REG_WRITE(ah, AR_OBS, 8);
+
+       if (ah->config.rx_intr_mitigation) {
+               REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_LAST, 500);
+               REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_FIRST, 2000);
+       }
+
+       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;
+
+       ENABLE_REGWRITE_BUFFER(ah);
+
+       ath9k_hw_restore_chainmask(ah);
+       REG_WRITE(ah, AR_CFG_LED, saveLedState | AR_CFG_SCLK_32KHZ);
+
+       REGWRITE_BUFFER_FLUSH(ah);
+
+       /*
+        * For big endian systems turn on swapping for descriptors
+        */
+       if (AR_SREV_9100(ah)) {
+               u32 mask;
+               mask = REG_READ(ah, AR_CFG);
+               if (mask & (AR_CFG_SWRB | AR_CFG_SWTB | AR_CFG_SWRG)) {
+                       DBG2("ath9k: "
+                               "CFG Byte Swap Set 0x%x\n", mask);
+               } else {
+                       mask =
+                               INIT_CONFIG_STATUS | AR_CFG_SWRB | AR_CFG_SWTB;
+                       REG_WRITE(ah, AR_CFG, mask);
+                       DBG2("ath9k: "
+                               "Setting CFG 0x%x\n", REG_READ(ah, AR_CFG));
+               }
+       } else {
+               if (common->bus_ops->ath_bus_type == ATH_USB) {
+                       /* Configure AR9271 target WLAN */
+                       if (AR_SREV_9271(ah))
+                               REG_WRITE(ah, AR_CFG, AR_CFG_SWRB | AR_CFG_SWTB);
+                       else
+                               REG_WRITE(ah, AR_CFG, AR_CFG_SWTD | AR_CFG_SWRD);
+               }
+#if __BYTE_ORDER == __BIG_ENDIAN
+               else if (AR_SREV_9340(ah))
+                       REG_RMW(ah, AR_CFG, AR_CFG_SWRB | AR_CFG_SWTB, 0);
+               else
+                       REG_WRITE(ah, AR_CFG, AR_CFG_SWTD | AR_CFG_SWRD);
+#endif
+       }
+
+       if (AR_SREV_9300_20_OR_LATER(ah)) {
+               ar9003_hw_disable_phy_restart(ah);
+       }
+
+       ath9k_hw_apply_gpio_override(ah);
+
+       return 0;
+}
+
+/******************************/
+/* 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) && !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);
+       }
+
+       /* Clear Bit 14 of AR_WA after putting chip into Full Sleep mode. */
+       if (AR_SREV_9300_20_OR_LATER(ah))
+               REG_WRITE(ah, AR_WA,
+                         ah->WARegVal & ~AR_WA_D3_L1_DISABLE);
+}
+
+static int ath9k_hw_set_power_awake(struct ath_hw *ah, int setChip)
+{
+       u32 val;
+       int i;
+
+       /* Set Bits 14 and 17 of AR_WA before powering on the chip. */
+       if (AR_SREV_9300_20_OR_LATER(ah)) {
+               REG_WRITE(ah, AR_WA, ah->WARegVal);
+               udelay(10);
+       }
+
+       if (setChip) {
+               if ((REG_READ(ah, AR_RTC_STATUS) &
+                    AR_RTC_STATUS_M) == AR_RTC_STATUS_SHUTDOWN) {
+                       if (ath9k_hw_set_reset_reg(ah,
+                                          ATH9K_RESET_POWER_ON) != 1) {
+                               return 0;
+                       }
+                       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,
+                                   AR_RTC_RESET_EN);
+
+               REG_SET_BIT(ah, AR_RTC_FORCE_WAKE,
+                           AR_RTC_FORCE_WAKE_EN);
+               udelay(50);
+
+               for (i = POWER_UP_TIME / 50; i > 0; i--) {
+                       val = REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M;
+                       if (val == AR_RTC_STATUS_ON)
+                               break;
+                       udelay(50);
+                       REG_SET_BIT(ah, AR_RTC_FORCE_WAKE,
+                                   AR_RTC_FORCE_WAKE_EN);
+               }
+               if (i == 0) {
+                       DBG("ath9k: "
+                               "Failed to wakeup in %dus\n",
+                               POWER_UP_TIME / 20);
+                       return 0;
+               }
+       }
+
+       REG_CLR_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV);
+
+       return 1;
+}
+
+int ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode)
+{
+       int status = 1, setChip = 1;
+       static const char *modes[] = {
+               "AWAKE",
+               "FULL-SLEEP",
+               "NETWORK SLEEP",
+               "UNDEFINED"
+       };
+
+       if (ah->power_mode == mode)
+               return status;
+
+       DBG2("ath9k: %s -> %s\n",
+               modes[ah->power_mode], modes[mode]);
+
+       switch (mode) {
+       case ATH9K_PM_AWAKE:
+               status = ath9k_hw_set_power_awake(ah, setChip);
+               break;
+       case ATH9K_PM_FULL_SLEEP:
+               ath9k_set_power_sleep(ah, setChip);
+               ah->chip_fullsleep = 1;
+               break;
+       default:
+               DBG("ath9k: Unknown power mode %d\n", mode);
+               return 0;
+       }
+       ah->power_mode = mode;
+
+       return status;
+}
+
+/*******************/
+/* HW Capabilities */
+/*******************/
+
+int ath9k_hw_fill_cap_info(struct ath_hw *ah)
+{
+       struct ath9k_hw_capabilities *pCap = &ah->caps;
+       struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
+       struct ath_common *common = ath9k_hw_common(ah);
+
+       u16 eeval;
+       u8 ant_div_ctl1, tx_chainmask, rx_chainmask;
+
+       eeval = ah->eep_ops->get_eeprom(ah, EEP_REG_0);
+       regulatory->current_rd = eeval;
+
+       eeval = ah->eep_ops->get_eeprom(ah, EEP_REG_1);
+       if (AR_SREV_9285_12_OR_LATER(ah))
+               eeval |= AR9285_RDEXT_DEFAULT;
+       regulatory->current_rd_ext = eeval;
+
+       if (ah->hw_version.subvendorid == AR_SUBVENDOR_ID_NEW_A) {
+               if (regulatory->current_rd == 0x64 ||
+                   regulatory->current_rd == 0x65)
+                       regulatory->current_rd += 5;
+               else if (regulatory->current_rd == 0x41)
+                       regulatory->current_rd = 0x43;
+               DBG2("ath9k: "
+                       "regdomain mapped to 0x%x\n", regulatory->current_rd);
+       }
+
+       eeval = ah->eep_ops->get_eeprom(ah, EEP_OP_MODE);
+       if ((eeval & (AR5416_OPFLAGS_11G | AR5416_OPFLAGS_11A)) == 0) {
+               DBG("ath9k: "
+                       "no band has been marked as supported in EEPROM\n");
+               return -EINVAL;
+       }
+
+       if (eeval & AR5416_OPFLAGS_11A)
+               pCap->hw_caps |= ATH9K_HW_CAP_5GHZ;
+
+       if (eeval & AR5416_OPFLAGS_11G)
+               pCap->hw_caps |= ATH9K_HW_CAP_2GHZ;
+
+       pCap->tx_chainmask = ah->eep_ops->get_eeprom(ah, EEP_TX_MASK);
+       /*
+        * For AR9271 we will temporarilly uses the rx chainmax as read from
+        * the EEPROM.
+        */
+       if ((ah->hw_version.devid == AR5416_DEVID_PCI) &&
+           !(eeval & AR5416_OPFLAGS_11A) &&
+           !(AR_SREV_9271(ah)))
+               /* CB71: GPIO 0 is pulled down to indicate 3 rx chains */
+               pCap->rx_chainmask = ath9k_hw_gpio_get(ah, 0) ? 0x5 : 0x7;
+       else if (AR_SREV_9100(ah))
+               pCap->rx_chainmask = 0x7;
+       else
+               /* Use rx_chainmask from EEPROM. */
+               pCap->rx_chainmask = ah->eep_ops->get_eeprom(ah, EEP_RX_MASK);
+
+       ah->misc_mode |= AR_PCU_MIC_NEW_LOC_ENA;
+
+       /* enable key search for every frame in an aggregate */
+       if (AR_SREV_9300_20_OR_LATER(ah))
+               ah->misc_mode |= AR_PCU_ALWAYS_PERFORM_KEYSEARCH;
+
+       common->crypt_caps |= ATH_CRYPT_CAP_CIPHER_AESCCM;
+
+       pCap->hw_caps &= ~ATH9K_HW_CAP_HT;
+
+       if (AR_SREV_9271(ah))
+               pCap->num_gpio_pins = AR9271_NUM_GPIO;
+       else if (AR_DEVID_7010(ah))
+               pCap->num_gpio_pins = AR7010_NUM_GPIO;
+       else if (AR_SREV_9285_12_OR_LATER(ah))
+               pCap->num_gpio_pins = AR9285_NUM_GPIO;
+       else if (AR_SREV_9280_20_OR_LATER(ah))
+               pCap->num_gpio_pins = AR928X_NUM_GPIO;
+       else
+               pCap->num_gpio_pins = AR_NUM_GPIO;
+
+       if (AR_SREV_9160_10_OR_LATER(ah) || AR_SREV_9100(ah)) {
+               pCap->hw_caps |= ATH9K_HW_CAP_CST;
+               pCap->rts_aggr_limit = ATH_AMPDU_LIMIT_MAX;
+       } else {
+               pCap->rts_aggr_limit = (8 * 1024);
+       }
+
+       ah->rfsilent = ah->eep_ops->get_eeprom(ah, EEP_RF_SILENT);
+       if (ah->rfsilent & EEP_RFSILENT_ENABLED) {
+               ah->rfkill_gpio =
+                       MS(ah->rfsilent, EEP_RFSILENT_GPIO_SEL);
+               ah->rfkill_polarity =
+                       MS(ah->rfsilent, EEP_RFSILENT_POLARITY);
+
+               pCap->hw_caps |= ATH9K_HW_CAP_RFSILENT;
+       }
+
+       pCap->hw_caps &= ~ATH9K_HW_CAP_AUTOSLEEP;
+
+       if (AR_SREV_9280(ah) || AR_SREV_9285(ah))
+               pCap->hw_caps &= ~ATH9K_HW_CAP_4KB_SPLITTRANS;
+       else
+               pCap->hw_caps |= ATH9K_HW_CAP_4KB_SPLITTRANS;
+
+       if (AR_SREV_9300_20_OR_LATER(ah)) {
+               pCap->hw_caps |= ATH9K_HW_CAP_FASTCLOCK;
+               if (!AR_SREV_9485(ah))
+                       pCap->hw_caps |= 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);
+               if (!ah->config.paprd_disable &&
+                   ah->eep_ops->get_eeprom(ah, EEP_PAPRD))
+                       pCap->hw_caps |= ATH9K_HW_CAP_PAPRD;
+       } else {
+               pCap->tx_desc_len = sizeof(struct ath_desc);
+               if (AR_SREV_9280_20(ah) &&
+                   ((ah->eep_ops->get_eeprom(ah, EEP_MINOR_REV) <=
+                     AR5416_EEP_MINOR_VER_16) ||
+                    ah->eep_ops->get_eeprom(ah, EEP_FSTCLK_5G)))
+                       pCap->hw_caps |= ATH9K_HW_CAP_FASTCLOCK;
+       }
+
+       if (AR_SREV_9300_20_OR_LATER(ah))
+               pCap->hw_caps |= ATH9K_HW_CAP_RAC_SUPPORTED;
+
+       if (AR_SREV_9300_20_OR_LATER(ah))
+               ah->ent_mode = REG_READ(ah, AR_ENT_OTP);
+
+       if (AR_SREV_9287_11_OR_LATER(ah) || AR_SREV_9271(ah))
+               pCap->hw_caps |= ATH9K_HW_CAP_SGI_20;
+
+       if (AR_SREV_9285(ah))
+               if (ah->eep_ops->get_eeprom(ah, EEP_MODAL_VER) >= 3) {
+                       ant_div_ctl1 =
+                               ah->eep_ops->get_eeprom(ah, EEP_ANT_DIV_CTL1);
+                       if ((ant_div_ctl1 & 0x1) && ((ant_div_ctl1 >> 3) & 0x1))
+                               pCap->hw_caps |= ATH9K_HW_CAP_ANT_DIV_COMB;
+               }
+       if (AR_SREV_9300_20_OR_LATER(ah)) {
+               if (ah->eep_ops->get_eeprom(ah, EEP_CHAIN_MASK_REDUCE))
+                       pCap->hw_caps |= ATH9K_HW_CAP_APM;
+       }
+
+
+       if (AR_SREV_9485(ah)) {
+               ant_div_ctl1 = ah->eep_ops->get_eeprom(ah, EEP_ANT_DIV_CTL1);
+               /*
+                * enable the diversity-combining algorithm only when
+                * both enable_lna_div and enable_fast_div are set
+                *              Table for Diversity
+                * ant_div_alt_lnaconf          bit 0-1
+                * ant_div_main_lnaconf         bit 2-3
+                * ant_div_alt_gaintb           bit 4
+                * ant_div_main_gaintb          bit 5
+                * enable_ant_div_lnadiv        bit 6
+                * enable_ant_fast_div          bit 7
+                */
+               if ((ant_div_ctl1 >> 0x6) == 0x3)
+                       pCap->hw_caps |= ATH9K_HW_CAP_ANT_DIV_COMB;
+       }
+
+       if (AR_SREV_9485_10(ah)) {
+               pCap->pcie_lcr_extsync_en = 1;
+               pCap->pcie_lcr_offset = 0x80;
+       }
+
+       tx_chainmask = pCap->tx_chainmask;
+       rx_chainmask = pCap->rx_chainmask;
+       while (tx_chainmask || rx_chainmask) {
+               if (tx_chainmask & BIT(0))
+                       pCap->max_txchains++;
+               if (rx_chainmask & BIT(0))
+                       pCap->max_rxchains++;
+
+               tx_chainmask >>= 1;
+               rx_chainmask >>= 1;
+       }
+
+       return 0;
+}
+
+/****************************/
+/* GPIO / RFKILL / Antennae */
+/****************************/
+
+static void ath9k_hw_gpio_cfg_output_mux(struct ath_hw *ah,
+                                        u32 gpio, u32 type)
+{
+       int addr;
+       u32 gpio_shift, tmp;
+
+       if (gpio > 11)
+               addr = AR_GPIO_OUTPUT_MUX3;
+       else if (gpio > 5)
+               addr = AR_GPIO_OUTPUT_MUX2;
+       else
+               addr = AR_GPIO_OUTPUT_MUX1;
+
+       gpio_shift = (gpio % 6) * 5;
+
+       if (AR_SREV_9280_20_OR_LATER(ah)
+           || (addr != AR_GPIO_OUTPUT_MUX1)) {
+               REG_RMW(ah, addr, (type << gpio_shift),
+                       (0x1f << gpio_shift));
+       } else {
+               tmp = REG_READ(ah, addr);
+               tmp = ((tmp & 0x1F0) << 1) | (tmp & ~0x1F0);
+               tmp &= ~(0x1f << gpio_shift);
+               tmp |= (type << gpio_shift);
+               REG_WRITE(ah, addr, tmp);
+       }
+}
+
+void ath9k_hw_cfg_gpio_input(struct ath_hw *ah, u32 gpio)
+{
+       u32 gpio_shift;
+
+       if (AR_DEVID_7010(ah)) {
+               gpio_shift = gpio;
+               REG_RMW(ah, AR7010_GPIO_OE,
+                       (AR7010_GPIO_OE_AS_INPUT << gpio_shift),
+                       (AR7010_GPIO_OE_MASK << gpio_shift));
+               return;
+       }
+
+       gpio_shift = gpio << 1;
+       REG_RMW(ah,
+               AR_GPIO_OE_OUT,
+               (AR_GPIO_OE_OUT_DRV_NO << gpio_shift),
+               (AR_GPIO_OE_OUT_DRV << gpio_shift));
+}
+
+u32 ath9k_hw_gpio_get(struct ath_hw *ah, u32 gpio)
+{
+#define MS_REG_READ(x, y) \
+       (MS(REG_READ(ah, AR_GPIO_IN_OUT), x##_GPIO_IN_VAL) & (AR_GPIO_BIT(y)))
+
+       if (gpio >= ah->caps.num_gpio_pins)
+               return 0xffffffff;
+
+       if (AR_DEVID_7010(ah)) {
+               u32 val;
+               val = REG_READ(ah, AR7010_GPIO_IN);
+               return (MS(val, AR7010_GPIO_IN_VAL) & AR_GPIO_BIT(gpio)) == 0;
+       } else if (AR_SREV_9300_20_OR_LATER(ah))
+               return (MS(REG_READ(ah, AR_GPIO_IN), AR9300_GPIO_IN_VAL) &
+                       AR_GPIO_BIT(gpio)) != 0;
+       else if (AR_SREV_9271(ah))
+               return MS_REG_READ(AR9271, gpio) != 0;
+       else if (AR_SREV_9287_11_OR_LATER(ah))
+               return MS_REG_READ(AR9287, gpio) != 0;
+       else if (AR_SREV_9285_12_OR_LATER(ah))
+               return MS_REG_READ(AR9285, gpio) != 0;
+       else if (AR_SREV_9280_20_OR_LATER(ah))
+               return MS_REG_READ(AR928X, gpio) != 0;
+       else
+               return MS_REG_READ(AR, gpio) != 0;
+}
+
+void ath9k_hw_cfg_output(struct ath_hw *ah, u32 gpio,
+                        u32 ah_signal_type)
+{
+       u32 gpio_shift;
+
+       if (AR_DEVID_7010(ah)) {
+               gpio_shift = gpio;
+               REG_RMW(ah, AR7010_GPIO_OE,
+                       (AR7010_GPIO_OE_AS_OUTPUT << gpio_shift),
+                       (AR7010_GPIO_OE_MASK << gpio_shift));
+               return;
+       }
+
+       ath9k_hw_gpio_cfg_output_mux(ah, gpio, ah_signal_type);
+       gpio_shift = 2 * gpio;
+       REG_RMW(ah,
+               AR_GPIO_OE_OUT,
+               (AR_GPIO_OE_OUT_DRV_ALL << gpio_shift),
+               (AR_GPIO_OE_OUT_DRV << gpio_shift));
+}
+
+void ath9k_hw_set_gpio(struct ath_hw *ah, u32 gpio, u32 val)
+{
+       if (AR_DEVID_7010(ah)) {
+               val = val ? 0 : 1;
+               REG_RMW(ah, AR7010_GPIO_OUT, ((val&1) << gpio),
+                       AR_GPIO_BIT(gpio));
+               return;
+       }
+
+       if (AR_SREV_9271(ah))
+               val = ~val;
+
+       REG_RMW(ah, AR_GPIO_IN_OUT, ((val & 1) << gpio),
+               AR_GPIO_BIT(gpio));
+}
+
+u32 ath9k_hw_getdefantenna(struct ath_hw *ah)
+{
+       return REG_READ(ah, AR_DEF_ANTENNA) & 0x7;
+}
+
+void ath9k_hw_setantenna(struct ath_hw *ah, u32 antenna)
+{
+       REG_WRITE(ah, AR_DEF_ANTENNA, (antenna & 0x7));
+}
+
+/*********************/
+/* General Operation */
+/*********************/
+
+u32 ath9k_hw_getrxfilter(struct ath_hw *ah)
+{
+       u32 bits = REG_READ(ah, AR_RX_FILTER);
+       u32 phybits = REG_READ(ah, AR_PHY_ERR);
+
+       if (phybits & AR_PHY_ERR_RADAR)
+               bits |= ATH9K_RX_FILTER_PHYRADAR;
+       if (phybits & (AR_PHY_ERR_OFDM_TIMING | AR_PHY_ERR_CCK_TIMING))
+               bits |= ATH9K_RX_FILTER_PHYERR;
+
+       return bits;
+}
+
+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;
+       if (bits & ATH9K_RX_FILTER_PHYRADAR)
+               phybits |= AR_PHY_ERR_RADAR;
+       if (bits & ATH9K_RX_FILTER_PHYERR)
+               phybits |= AR_PHY_ERR_OFDM_TIMING | AR_PHY_ERR_CCK_TIMING;
+       REG_WRITE(ah, AR_PHY_ERR, phybits);
+
+       if (phybits)
+               REG_SET_BIT(ah, AR_RXCFG, AR_RXCFG_ZLFDMA);
+       else
+               REG_CLR_BIT(ah, AR_RXCFG, AR_RXCFG_ZLFDMA);
+
+       REGWRITE_BUFFER_FLUSH(ah);
+}
+
+int ath9k_hw_phy_disable(struct ath_hw *ah)
+{
+       if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_WARM))
+               return 0;
+
+       ath9k_hw_init_pll(ah, NULL);
+       return 1;
+}
+
+int ath9k_hw_disable(struct ath_hw *ah)
+{
+       if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
+               return 0;
+
+       if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_COLD))
+               return 0;
+
+       ath9k_hw_init_pll(ah, NULL);
+       return 1;
+}
+
+void ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit, int test)
+{
+       struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
+       struct ath9k_channel *chan = ah->curchan;
+       struct net80211_channel *channel = chan->chan;
+
+       regulatory->power_limit = min(limit, (u32) MAX_RATE_POWER);
+
+       ah->eep_ops->set_txpower(ah, chan,
+                                ath9k_regd_get_ctl(regulatory, chan),
+                                0,
+                                channel->maxpower * 2,
+                                min((u32) MAX_RATE_POWER,
+                                (u32) regulatory->power_limit), test);
+}
+
+void ath9k_hw_setopmode(struct ath_hw *ah)
+{
+       ath9k_hw_set_operating_mode(ah);
+}
+
+void ath9k_hw_setmcastfilter(struct ath_hw *ah, u32 filter0, u32 filter1)
+{
+       REG_WRITE(ah, AR_MCAST_FIL0, filter0);
+       REG_WRITE(ah, AR_MCAST_FIL1, filter1);
+}
+
+void ath9k_hw_write_associd(struct ath_hw *ah)
+{
+       struct ath_common *common = ath9k_hw_common(ah);
+
+       REG_WRITE(ah, AR_BSS_ID0, get_unaligned_le32(common->curbssid));
+       REG_WRITE(ah, AR_BSS_ID1, get_unaligned_le16(common->curbssid + 4) |
+                 ((common->curaid & 0x3fff) << AR_BSS_ID1_AID_S));
+}
+
+void ath9k_hw_set11nmac2040(struct ath_hw *ah)
+{
+       u32 macmode;
+
+       macmode = 0;
+
+       REG_WRITE(ah, AR_2040_MODE, macmode);
+}
+
+static struct {
+       u32 version;
+       const char * name;
+} ath_mac_bb_names[] = {
+       /* Devices with external radios */
+       { AR_SREV_VERSION_5416_PCI,     "5416" },
+       { AR_SREV_VERSION_5416_PCIE,    "5418" },
+       { AR_SREV_VERSION_9100,         "9100" },
+       { AR_SREV_VERSION_9160,         "9160" },
+       /* Single-chip solutions */
+       { AR_SREV_VERSION_9280,         "9280" },
+       { AR_SREV_VERSION_9285,         "9285" },
+       { AR_SREV_VERSION_9287,         "9287" },
+       { AR_SREV_VERSION_9271,         "9271" },
+       { AR_SREV_VERSION_9300,         "9300" },
+       { AR_SREV_VERSION_9485,         "9485" },
+};
+
+/* For devices with external radios */
+static struct {
+       u16 version;
+       const char * name;
+} ath_rf_names[] = {
+       { 0,                            "5133" },
+       { AR_RAD5133_SREV_MAJOR,        "5133" },
+       { AR_RAD5122_SREV_MAJOR,        "5122" },
+       { AR_RAD2133_SREV_MAJOR,        "2133" },
+       { AR_RAD2122_SREV_MAJOR,        "2122" }
+};
+
+/*
+ * Return the MAC/BB name. "????" is returned if the MAC/BB is unknown.
+ */
+static const char *ath9k_hw_mac_bb_name(u32 mac_bb_version)
+{
+       unsigned int i;
+
+       for (i=0; i<ARRAY_SIZE(ath_mac_bb_names); i++) {
+               if (ath_mac_bb_names[i].version == mac_bb_version) {
+                       return ath_mac_bb_names[i].name;
+               }
+       }
+
+       return "????";
+}
+
+/*
+ * Return the RF name. "????" is returned if the RF is unknown.
+ * Used for devices with external radios.
+ */
+static const char *ath9k_hw_rf_name(u16 rf_version)
+{
+       unsigned int i;
+
+       for (i=0; i<ARRAY_SIZE(ath_rf_names); i++) {
+               if (ath_rf_names[i].version == rf_version) {
+                       return ath_rf_names[i].name;
+               }
+       }
+
+       return "????";
+}
+
+void ath9k_hw_name(struct ath_hw *ah, char *hw_name, size_t len)
+{
+       int used;
+
+       /* chipsets >= AR9280 are single-chip */
+       if (AR_SREV_9280_20_OR_LATER(ah)) {
+               used = snprintf(hw_name, len,
+                              "Atheros AR%s Rev:%x",
+                              ath9k_hw_mac_bb_name(ah->hw_version.macVersion),
+                              ah->hw_version.macRev);
+       }
+       else {
+               used = snprintf(hw_name, len,
+                              "Atheros AR%s MAC/BB Rev:%x AR%s RF Rev:%x",
+                              ath9k_hw_mac_bb_name(ah->hw_version.macVersion),
+                              ah->hw_version.macRev,
+                              ath9k_hw_rf_name((ah->hw_version.analog5GhzRev &
+                                               AR_RADIO_SREV_MAJOR)),
+                              ah->hw_version.phyRev);
+       }
+
+       hw_name[used] = '\0';
+}
diff --git a/src/drivers/net/ath/ath9k/ath9k_init.c b/src/drivers/net/ath/ath9k/ath9k_init.c
new file mode 100644 (file)
index 0000000..93fbe77
--- /dev/null
@@ -0,0 +1,593 @@
+/*
+ * Copyright (c) 2008-2011 Atheros Communications Inc.
+ *
+ * Modified for iPXE by Scott K Logan <logans@cottsay.net> July 2011
+ * Original from Linux kernel 3.0.1
+ *
+ * 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 <ipxe/malloc.h>
+#include <ipxe/pci_io.h>
+#include <ipxe/pci.h>
+
+#include "ath9k.h"
+
+int is_ath9k_unloaded;
+/* We use the hw_value as an index into our private channel structure */
+
+#define CHAN2G(_freq, _idx)  { \
+       .band = NET80211_BAND_2GHZ, \
+       .center_freq = (_freq), \
+       .hw_value = (_idx), \
+       .maxpower = 20, \
+}
+
+#define CHAN5G(_freq, _idx) { \
+       .band = NET80211_BAND_5GHZ, \
+       .center_freq = (_freq), \
+       .hw_value = (_idx), \
+       .maxpower = 20, \
+}
+
+/* Some 2 GHz radios are actually tunable on 2312-2732
+ * on 5 MHz steps, we support the channels which we know
+ * we have calibration data for all cards though to make
+ * this static */
+static const struct net80211_channel ath9k_2ghz_chantable[] = {
+       CHAN2G(2412, 0), /* Channel 1 */
+       CHAN2G(2417, 1), /* Channel 2 */
+       CHAN2G(2422, 2), /* Channel 3 */
+       CHAN2G(2427, 3), /* Channel 4 */
+       CHAN2G(2432, 4), /* Channel 5 */
+       CHAN2G(2437, 5), /* Channel 6 */
+       CHAN2G(2442, 6), /* Channel 7 */
+       CHAN2G(2447, 7), /* Channel 8 */
+       CHAN2G(2452, 8), /* Channel 9 */
+       CHAN2G(2457, 9), /* Channel 10 */
+       CHAN2G(2462, 10), /* Channel 11 */
+       CHAN2G(2467, 11), /* Channel 12 */
+       CHAN2G(2472, 12), /* Channel 13 */
+       CHAN2G(2484, 13), /* Channel 14 */
+};
+
+/* Some 5 GHz radios are actually tunable on XXXX-YYYY
+ * on 5 MHz steps, we support the channels which we know
+ * we have calibration data for all cards though to make
+ * this static */
+static const struct net80211_channel ath9k_5ghz_chantable[] = {
+       /* _We_ call this UNII 1 */
+       CHAN5G(5180, 14), /* Channel 36 */
+       CHAN5G(5200, 15), /* Channel 40 */
+       CHAN5G(5220, 16), /* Channel 44 */
+       CHAN5G(5240, 17), /* Channel 48 */
+       /* _We_ call this UNII 2 */
+       CHAN5G(5260, 18), /* Channel 52 */
+       CHAN5G(5280, 19), /* Channel 56 */
+       CHAN5G(5300, 20), /* Channel 60 */
+       CHAN5G(5320, 21), /* Channel 64 */
+       /* _We_ call this "Middle band" */
+       CHAN5G(5500, 22), /* Channel 100 */
+       CHAN5G(5520, 23), /* Channel 104 */
+       CHAN5G(5540, 24), /* Channel 108 */
+       CHAN5G(5560, 25), /* Channel 112 */
+       CHAN5G(5580, 26), /* Channel 116 */
+       CHAN5G(5600, 27), /* Channel 120 */
+       CHAN5G(5620, 28), /* Channel 124 */
+       CHAN5G(5640, 29), /* Channel 128 */
+       CHAN5G(5660, 30), /* Channel 132 */
+       CHAN5G(5680, 31), /* Channel 136 */
+       CHAN5G(5700, 32), /* Channel 140 */
+       /* _We_ call this UNII 3 */
+       CHAN5G(5745, 33), /* Channel 149 */
+       CHAN5G(5765, 34), /* Channel 153 */
+       CHAN5G(5785, 35), /* Channel 157 */
+       CHAN5G(5805, 36), /* Channel 161 */
+       CHAN5G(5825, 37), /* Channel 165 */
+};
+
+/* Atheros hardware rate code addition for short premble */
+#define SHPCHECK(__hw_rate, __flags) \
+       ((__flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) ? (__hw_rate | 0x04 ) : 0)
+
+#define RATE(_bitrate, _hw_rate, _flags) {              \
+       .bitrate        = (_bitrate),                   \
+       .flags          = (_flags),                     \
+       .hw_value       = (_hw_rate),                   \
+       .hw_value_short = (SHPCHECK(_hw_rate, _flags))  \
+}
+
+static struct ath9k_legacy_rate ath9k_legacy_rates[] = {
+       RATE(10, 0x1b, 0),
+       RATE(20, 0x1a, IEEE80211_TX_RC_USE_SHORT_PREAMBLE),
+       RATE(55, 0x19, IEEE80211_TX_RC_USE_SHORT_PREAMBLE),
+       RATE(110, 0x18, IEEE80211_TX_RC_USE_SHORT_PREAMBLE),
+       RATE(60, 0x0b, 0),
+       RATE(90, 0x0f, 0),
+       RATE(120, 0x0a, 0),
+       RATE(180, 0x0e, 0),
+       RATE(240, 0x09, 0),
+       RATE(360, 0x0d, 0),
+       RATE(480, 0x08, 0),
+       RATE(540, 0x0c, 0),
+};
+
+static void ath9k_deinit_softc(struct ath_softc *sc);
+
+/*
+ * Read and write, they both share the same lock. We do this to serialize
+ * reads and writes on Atheros 802.11n PCI devices only. This is required
+ * as the FIFO on these devices can only accept sanely 2 requests.
+ */
+
+static void ath9k_iowrite32(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 ath_softc *sc = (struct ath_softc *) common->priv;
+
+       writel(val, sc->mem + reg_offset);
+}
+
+static unsigned int ath9k_ioread32(void *hw_priv, u32 reg_offset)
+{
+       struct ath_hw *ah = (struct ath_hw *) hw_priv;
+       struct ath_common *common = ath9k_hw_common(ah);
+       struct ath_softc *sc = (struct ath_softc *) common->priv;
+       u32 val;
+
+       val = readl(sc->mem + reg_offset);
+       return val;
+}
+
+static unsigned int ath9k_reg_rmw(void *hw_priv, u32 reg_offset, u32 set, u32 clr)
+{
+       struct ath_hw *ah = (struct ath_hw *) hw_priv;
+       struct ath_common *common = ath9k_hw_common(ah);
+       struct ath_softc *sc = (struct ath_softc *) common->priv;
+       u32 val;
+
+       val = readl(sc->mem + reg_offset);
+       val &= ~clr;
+       val |= set;
+       writel(val, sc->mem + reg_offset);
+
+       return val;
+}
+
+/**************************/
+/*     Initialization     */
+/**************************/
+
+/*
+ *  This function will allocate both the DMA descriptor structure, and the
+ *  buffers it contains.  These are used to contain the descriptors used
+ *  by the system.
+*/
+int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
+                     struct list_head *head, const char *name,
+                     int nbuf, int ndesc, int is_tx)
+{
+#define        DS2PHYS(_dd, _ds)                                               \
+       ((_dd)->dd_desc_paddr + ((char *)(_ds) - (char *)(_dd)->dd_desc))
+#define ATH_DESC_4KB_BOUND_CHECK(_daddr) ((((_daddr) & 0xFFF) > 0xF9F) ? 1 : 0)
+       u8 *ds;
+       struct ath_buf *bf;
+       int i, bsize, error, desc_len;
+
+       DBG2("ath9k: %s DMA: %d buffers %d 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 ((desc_len % 4) != 0) {
+               DBG("ath9k: ath_desc not DWORD aligned\n");
+               error = -ENOMEM;
+               goto fail;
+       }
+
+       dd->dd_desc_len = desc_len * nbuf * ndesc;
+
+       /*
+        * Need additional DMA memory because we can't use
+        * descriptors that cross the 4K page boundary.
+        * However, iPXE only utilizes 16 buffers, which
+        * will never make up more than half of one page,
+        * so we will only ever skip 1 descriptor, if that.
+        */
+       if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_4KB_SPLITTRANS)) {
+               u32 ndesc_skipped = 1;
+               u32 dma_len;
+
+               dma_len = ndesc_skipped * desc_len;
+               dd->dd_desc_len += dma_len;
+       }
+
+       /* allocate descriptors */
+       dd->dd_desc = malloc_dma(dd->dd_desc_len, 16);
+       if (dd->dd_desc == NULL) {
+               error = -ENOMEM;
+               goto fail;
+       }
+       dd->dd_desc_paddr = virt_to_bus(dd->dd_desc);
+       ds = (u8 *) dd->dd_desc;
+       DBG2("ath9k: %s DMA map: %p (%d) -> %llx (%d)\n",
+               name, ds, (u32) dd->dd_desc_len,
+               ito64(dd->dd_desc_paddr), /*XXX*/(u32) dd->dd_desc_len);
+
+       /* allocate buffers */
+       bsize = sizeof(struct ath_buf) * nbuf;
+       bf = zalloc(bsize);
+       if (bf == NULL) {
+               error = -ENOMEM;
+               goto fail2;
+       }
+       dd->dd_bufptr = bf;
+
+       for (i = 0; i < nbuf; i++, bf++, ds += (desc_len * ndesc)) {
+               bf->bf_desc = ds;
+               bf->bf_daddr = DS2PHYS(dd, ds);
+
+               if (!(sc->sc_ah->caps.hw_caps &
+                     ATH9K_HW_CAP_4KB_SPLITTRANS)) {
+                       /*
+                        * Skip descriptor addresses which can cause 4KB
+                        * boundary crossing (addr + length) with a 32 dword
+                        * descriptor fetch.
+                        */
+                       while (ATH_DESC_4KB_BOUND_CHECK(bf->bf_daddr)) {
+                               ds += (desc_len * ndesc);
+                               bf->bf_desc = ds;
+                               bf->bf_daddr = DS2PHYS(dd, ds);
+                       }
+               }
+               list_add_tail(&bf->list, head);
+       }
+       return 0;
+fail2:
+       free_dma(dd->dd_desc, dd->dd_desc_len);
+fail:
+       memset(dd, 0, sizeof(*dd));
+       return error;
+#undef ATH_DESC_4KB_BOUND_CHECK
+#undef DS2PHYS
+}
+
+void ath9k_init_crypto(struct ath_softc *sc)
+{
+       struct ath_common *common = ath9k_hw_common(sc->sc_ah);
+       unsigned int i = 0;
+
+       /* Get the hardware key cache size. */
+       common->keymax = AR_KEYTABLE_SIZE;
+
+       /*
+        * Reset the key cache since some parts do not
+        * reset the contents on initial power up.
+        */
+       for (i = 0; i < common->keymax; i++)
+               ath_hw_keyreset(common, (u16) i);
+
+       /*
+        * Check whether the separate key cache entries
+        * are required to handle both tx+rx MIC keys.
+        * With split mic keys the number of stations is limited
+        * to 27 otherwise 59.
+        */
+       if (sc->sc_ah->misc_mode & AR_PCU_MIC_NEW_LOC_ENA)
+               common->crypt_caps |= ATH_CRYPT_CAP_MIC_COMBINED;
+}
+
+static int ath9k_init_queues(struct ath_softc *sc)
+{
+       int i = 0;
+
+       for (i = 0; i < WME_NUM_AC; i++) {
+               sc->tx.txq_map[i] = ath_txq_setup(sc, ATH9K_TX_QUEUE_DATA, i);
+               sc->tx.txq_map[i]->mac80211_qnum = i;
+       }
+       return 0;
+}
+
+static int ath9k_init_channels_rates(struct ath_softc *sc)
+{
+       unsigned int i;
+
+       memcpy(&sc->rates, ath9k_legacy_rates, sizeof(ath9k_legacy_rates));
+
+       if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ) {
+               memcpy(&sc->hwinfo->channels[sc->hwinfo->nr_channels], ath9k_2ghz_chantable, sizeof(ath9k_2ghz_chantable));
+
+               sc->hwinfo->nr_channels += ARRAY_SIZE(ath9k_2ghz_chantable);
+
+               for (i = 0; i < ARRAY_SIZE(ath9k_legacy_rates); i++)
+                       sc->hwinfo->rates[NET80211_BAND_2GHZ][i] = ath9k_legacy_rates[i].bitrate;
+               sc->hwinfo->nr_rates[NET80211_BAND_2GHZ] = ARRAY_SIZE(ath9k_legacy_rates);
+       }
+
+       if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ) {
+               memcpy(&sc->hwinfo->channels[sc->hwinfo->nr_channels], ath9k_5ghz_chantable, sizeof(ath9k_5ghz_chantable));
+
+               sc->hwinfo->nr_channels += ARRAY_SIZE(ath9k_5ghz_chantable);
+
+               for (i = 4; i < ARRAY_SIZE(ath9k_legacy_rates); i++)
+                       sc->hwinfo->rates[NET80211_BAND_5GHZ][i - 4] = ath9k_legacy_rates[i].bitrate;
+               sc->hwinfo->nr_rates[NET80211_BAND_5GHZ] = ARRAY_SIZE(ath9k_legacy_rates) - 4;
+       }
+       return 0;
+}
+
+static void ath9k_init_misc(struct ath_softc *sc)
+{
+       struct ath_common *common = ath9k_hw_common(sc->sc_ah);
+
+       common->ani.timer = 0;
+
+       sc->config.txpowlimit = ATH_TXPOWER_MAX;
+
+       common->tx_chainmask = sc->sc_ah->caps.tx_chainmask;
+       common->rx_chainmask = sc->sc_ah->caps.rx_chainmask;
+
+       ath9k_hw_set_diversity(sc->sc_ah, 1);
+       sc->rx.defant = ath9k_hw_getdefantenna(sc->sc_ah);
+
+       memcpy(common->bssidmask, ath_bcast_mac, ETH_ALEN);
+}
+
+static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid,
+                           const struct ath_bus_ops *bus_ops)
+{
+       struct ath_hw *ah = NULL;
+       struct ath_common *common;
+       int ret = 0, i;
+       int csz = 0;
+
+       ah = zalloc(sizeof(struct ath_hw));
+       if (!ah)
+               return -ENOMEM;
+
+       ah->dev = sc->dev;
+       ah->hw_version.devid = devid;
+       ah->hw_version.subsysid = subsysid;
+       ah->reg_ops.read = ath9k_ioread32;
+       ah->reg_ops.write = ath9k_iowrite32;
+       ah->reg_ops.rmw = ath9k_reg_rmw;
+       sc->sc_ah = ah;
+
+       sc->hwinfo = zalloc(sizeof(*sc->hwinfo));
+       if (!sc->hwinfo) {
+               DBG("ath9k: cannot allocate 802.11 hardware info structure\n");
+               return -ENOMEM;
+       }
+
+       ah->ah_flags |= AH_USE_EEPROM;
+       sc->sc_ah->led_pin = -1;
+
+       common = ath9k_hw_common(ah);
+       common->ops = &ah->reg_ops;
+       common->bus_ops = bus_ops;
+       common->ah = ah;
+       common->dev = sc->dev;
+       common->priv = sc;
+
+       sc->intr_tq = ath9k_tasklet;
+
+       /*
+        * Cache line size is used to size and align various
+        * structures used to communicate with the hardware.
+        */
+       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)
+               goto err_hw;
+
+       memcpy(sc->hwinfo->hwaddr, common->macaddr, ETH_ALEN);
+
+       ret = ath9k_init_queues(sc);
+       if (ret)
+               goto err_queues;
+
+       ret = ath9k_init_channels_rates(sc);
+       if (ret)
+               goto err_btcoex;
+
+       ath9k_init_crypto(sc);
+       ath9k_init_misc(sc);
+
+       return 0;
+
+err_btcoex:
+       for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
+               if (ATH_TXQ_SETUP(sc, i))
+                       ath_tx_cleanupq(sc, &sc->tx.txq[i]);
+err_queues:
+       ath9k_hw_deinit(ah);
+err_hw:
+       free(sc->hwinfo);
+       sc->hwinfo = NULL;
+
+       free(ah);
+       sc->sc_ah = NULL;
+
+       return ret;
+}
+
+static void ath9k_init_band_txpower(struct ath_softc *sc, int band)
+{
+       struct net80211_channel *chan;
+       struct ath_hw *ah = sc->sc_ah;
+       struct ath_regulatory *reg = ath9k_hw_regulatory(ah);
+       int i;
+
+       for (i = 0; i < sc->hwinfo->nr_channels; i++) {
+               chan = &sc->hwinfo->channels[i];
+               if(chan->band != band)
+                       continue;
+               ah->curchan = &ah->channels[chan->hw_value];
+               ath9k_hw_set_txpowerlimit(ah, MAX_RATE_POWER, 1);
+               chan->maxpower = reg->max_power_level / 2;
+       }
+}
+
+static void ath9k_init_txpower_limits(struct ath_softc *sc)
+{
+       struct ath_hw *ah = sc->sc_ah;
+       struct ath9k_channel *curchan = ah->curchan;
+
+       if (ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ)
+               ath9k_init_band_txpower(sc, NET80211_BAND_2GHZ);
+       if (ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ)
+               ath9k_init_band_txpower(sc, NET80211_BAND_5GHZ);
+
+       ah->curchan = curchan;
+}
+
+void ath9k_set_hw_capab(struct ath_softc *sc, struct net80211_device *dev __unused)
+{
+       sc->hwinfo->flags = NET80211_HW_RX_HAS_FCS;
+       sc->hwinfo->signal_type = NET80211_SIGNAL_DB;
+       sc->hwinfo->signal_max = 40; /* 35dB should give perfect 54Mbps */
+       sc->hwinfo->channel_change_time = 5000;
+
+       if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ)
+       {
+               sc->hwinfo->bands |= NET80211_BAND_BIT_2GHZ;
+               sc->hwinfo->modes |= NET80211_MODE_B | NET80211_MODE_G;
+       }
+       if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ)
+       {
+               sc->hwinfo->bands |= NET80211_BAND_BIT_5GHZ;
+               sc->hwinfo->modes |= NET80211_MODE_A;
+       }
+}
+
+int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid,
+                   const struct ath_bus_ops *bus_ops)
+{
+       struct net80211_device *dev = sc->dev;
+       /*struct ath_common *common;
+       struct ath_hw *ah;*/
+       int error = 0;
+       /*struct ath_regulatory *reg;*/
+
+       /* Bring up device */
+       error = ath9k_init_softc(devid, sc, subsysid, bus_ops);
+       if (error != 0)
+               goto error_init;
+
+       /*ah = sc->sc_ah;
+       common = ath9k_hw_common(ah);*/
+       ath9k_set_hw_capab(sc, dev);
+       /* TODO Cottsay: reg */
+       /* Initialize regulatory */
+       /*error = ath_regd_init(&common->regulatory, sc->dev->wiphy,
+                             ath9k_reg_notifier);
+       if (error)
+               goto error_regd;
+
+       reg = &common->regulatory;*/
+
+       /* Setup TX DMA */
+       error = ath_tx_init(sc, ATH_TXBUF);
+       if (error != 0)
+               goto error_tx;
+
+       /* Setup RX DMA */
+       error = ath_rx_init(sc, ATH_RXBUF);
+       if (error != 0)
+               goto error_rx;
+
+       ath9k_init_txpower_limits(sc);
+
+       /* Register with mac80211 */
+       error = net80211_register(dev, &ath9k_ops, sc->hwinfo);
+       if (error)
+               goto error_register;
+
+       /* TODO Cottsay: reg */
+       /* Handle world regulatory */
+       /*if (!ath_is_world_regd(reg)) {
+               error = regulatory_hint(hw->wiphy, reg->alpha2);
+               if (error)
+                       goto error_world;
+       }*/
+
+       sc->hw_pll_work = ath_hw_pll_work;
+       sc->last_rssi = ATH_RSSI_DUMMY_MARKER;
+
+       /* TODO Cottsay: rfkill */
+       /*ath_start_rfkill_poll(sc);*/
+
+       return 0;
+
+//error_world:
+//     net80211_unregister(dev);
+error_register:
+       ath_rx_cleanup(sc);
+error_rx:
+       ath_tx_cleanup(sc);
+error_tx:
+       ath9k_deinit_softc(sc);
+error_init:
+       return error;
+}
+
+/*****************************/
+/*     De-Initialization     */
+/*****************************/
+
+static void ath9k_deinit_softc(struct ath_softc *sc)
+{
+       int i = 0;
+
+       for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
+               if (ATH_TXQ_SETUP(sc, i))
+                       ath_tx_cleanupq(sc, &sc->tx.txq[i]);
+
+       ath9k_hw_deinit(sc->sc_ah);
+
+       free(sc->hwinfo);
+       sc->hwinfo = NULL;
+       free(sc->sc_ah);
+       sc->sc_ah = NULL;
+}
+
+void ath9k_deinit_device(struct ath_softc *sc)
+{
+       struct net80211_device *dev = sc->dev;
+
+       net80211_unregister(dev);
+       ath_rx_cleanup(sc);
+       ath_tx_cleanup(sc);
+       ath9k_deinit_softc(sc);
+}
+
+void ath_descdma_cleanup(struct ath_softc *sc __unused,
+                        struct ath_descdma *dd,
+                        struct list_head *head)
+{
+       free_dma(dd->dd_desc, dd->dd_desc_len);
+
+       INIT_LIST_HEAD(head);
+       free(dd->dd_bufptr);
+       memset(dd, 0, sizeof(*dd));
+}
diff --git a/src/drivers/net/ath/ath9k/ath9k_mac.c b/src/drivers/net/ath/ath9k/ath9k_mac.c
new file mode 100644 (file)
index 0000000..fbb3c33
--- /dev/null
@@ -0,0 +1,733 @@
+/*
+ * Copyright (c) 2008-2011 Atheros Communications Inc.
+ *
+ * Modified for iPXE by Scott K Logan <logans@cottsay.net> July 2011
+ * Original from Linux kernel 3.0.1
+ *
+ * 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 <ipxe/io.h>
+
+#include "hw.h"
+#include "hw-ops.h"
+
+static void ath9k_hw_set_txq_interrupts(struct ath_hw *ah,
+                                       struct ath9k_tx_queue_info *qi __unused)
+{
+       DBG2("ath9k: "
+               "tx ok 0x%x err 0x%x desc 0x%x eol 0x%x urn 0x%x\n",
+               ah->txok_interrupt_mask, ah->txerr_interrupt_mask,
+               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));
+       REG_WRITE(ah, AR_IMR_S1,
+                 SM(ah->txerr_interrupt_mask, AR_IMR_S1_QCU_TXERR)
+                 | SM(ah->txeol_interrupt_mask, AR_IMR_S1_QCU_TXEOL));
+
+       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);
+}
+
+void ath9k_hw_puttxbuf(struct ath_hw *ah, u32 q, u32 txdp)
+{
+       REG_WRITE(ah, AR_QTXDP(q), txdp);
+}
+
+void ath9k_hw_txstart(struct ath_hw *ah, u32 q)
+{
+       DBG2("ath9k: "
+               "Enable TXE on queue: %d\n", q);
+       REG_WRITE(ah, AR_Q_TXE, 1 << q);
+}
+
+u32 ath9k_hw_numtxpending(struct ath_hw *ah, u32 q)
+{
+       u32 npend;
+
+       npend = REG_READ(ah, AR_QSTS(q)) & AR_Q_STS_PEND_FR_CNT;
+       if (npend == 0) {
+
+               if (REG_READ(ah, AR_Q_TXE) & (1 << q))
+                       npend = 1;
+       }
+
+       return npend;
+}
+
+/**
+ * ath9k_hw_updatetxtriglevel - adjusts the frame trigger level
+ *
+ * @ah: atheros hardware struct
+ * @bIncTrigLevel: whether or not the frame trigger level should be updated
+ *
+ * The frame trigger level specifies the minimum number of bytes,
+ * in units of 64 bytes, that must be DMA'ed into the PCU TX FIFO
+ * before the PCU will initiate sending the frame on the air. This can
+ * mean we initiate transmit before a full frame is on the PCU TX FIFO.
+ * Resets to 0x1 (meaning 64 bytes or a full frame, whichever occurs
+ * first)
+ *
+ * Caution must be taken to ensure to set the frame trigger level based
+ * on the DMA request size. For example if the DMA request size is set to
+ * 128 bytes the trigger level cannot exceed 6 * 64 = 384. This is because
+ * there need to be enough space in the tx FIFO for the requested transfer
+ * size. Hence the tx FIFO will stop with 512 - 128 = 384 bytes. If we set
+ * the threshold to a value beyond 6, then the transmit will hang.
+ *
+ * Current dual   stream devices have a PCU TX FIFO size of 8 KB.
+ * Current single stream devices have a PCU TX FIFO size of 4 KB, however,
+ * there is a hardware issue which forces us to use 2 KB instead so the
+ * frame trigger level must not exceed 2 KB for these chipsets.
+ */
+int ath9k_hw_updatetxtriglevel(struct ath_hw *ah, int bIncTrigLevel)
+{
+       u32 txcfg, curLevel, newLevel;
+
+       if (ah->tx_trig_level >= ah->config.max_txtrig_level)
+               return 0;
+
+       ath9k_hw_disable_interrupts(ah);
+
+       txcfg = REG_READ(ah, AR_TXCFG);
+       curLevel = MS(txcfg, AR_FTRIG);
+       newLevel = curLevel;
+       if (bIncTrigLevel) {
+               if (curLevel < ah->config.max_txtrig_level)
+                       newLevel++;
+       } else if (curLevel > MIN_TX_FIFO_THRESHOLD)
+               newLevel--;
+       if (newLevel != curLevel)
+               REG_WRITE(ah, AR_TXCFG,
+                         (txcfg & ~AR_FTRIG) | SM(newLevel, AR_FTRIG));
+
+       ath9k_hw_enable_interrupts(ah);
+
+       ah->tx_trig_level = newLevel;
+
+       return newLevel != curLevel;
+}
+
+void ath9k_hw_abort_tx_dma(struct ath_hw *ah)
+{
+       int i, q;
+
+       REG_WRITE(ah, AR_Q_TXD, AR_Q_TXD_M);
+
+       REG_SET_BIT(ah, AR_PCU_MISC, AR_PCU_FORCE_QUIET_COLL | AR_PCU_CLEAR_VMF);
+       REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH);
+       REG_SET_BIT(ah, AR_D_GBL_IFS_MISC, AR_D_GBL_IFS_MISC_IGNORE_BACKOFF);
+
+       for (q = 0; q < AR_NUM_QCU; q++) {
+               for (i = 0; i < 1000; i++) {
+                       if (i)
+                               udelay(5);
+
+                       if (!ath9k_hw_numtxpending(ah, q))
+                               break;
+               }
+       }
+
+       REG_CLR_BIT(ah, AR_PCU_MISC, AR_PCU_FORCE_QUIET_COLL | AR_PCU_CLEAR_VMF);
+       REG_CLR_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH);
+       REG_CLR_BIT(ah, AR_D_GBL_IFS_MISC, AR_D_GBL_IFS_MISC_IGNORE_BACKOFF);
+
+       REG_WRITE(ah, AR_Q_TXD, 0);
+}
+
+void ath9k_hw_gettxintrtxqs(struct ath_hw *ah, u32 *txqs)
+{
+       *txqs &= ah->intr_txqs;
+       ah->intr_txqs &= ~(*txqs);
+}
+
+int ath9k_hw_set_txq_props(struct ath_hw *ah, int q,
+                           const struct ath9k_tx_queue_info *qinfo)
+{
+       u32 cw;
+       struct ath9k_tx_queue_info *qi;
+
+       qi = &ah->txq[q];
+       if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
+               DBG("ath9k: "
+                       "Set TXQ properties, inactive queue: %d\n", q);
+               return 0;
+       }
+
+       DBG2("ath9k: Set queue properties for: %d\n", q);
+
+       qi->tqi_ver = qinfo->tqi_ver;
+       qi->tqi_subtype = qinfo->tqi_subtype;
+       qi->tqi_qflags = qinfo->tqi_qflags;
+       qi->tqi_priority = qinfo->tqi_priority;
+       if (qinfo->tqi_aifs != ATH9K_TXQ_USEDEFAULT)
+               qi->tqi_aifs = min(qinfo->tqi_aifs, 255U);
+       else
+               qi->tqi_aifs = INIT_AIFS;
+       if (qinfo->tqi_cwmin != ATH9K_TXQ_USEDEFAULT) {
+               cw = min(qinfo->tqi_cwmin, 1024U);
+               qi->tqi_cwmin = 1;
+               while (qi->tqi_cwmin < cw)
+                       qi->tqi_cwmin = (qi->tqi_cwmin << 1) | 1;
+       } else
+               qi->tqi_cwmin = qinfo->tqi_cwmin;
+       if (qinfo->tqi_cwmax != ATH9K_TXQ_USEDEFAULT) {
+               cw = min(qinfo->tqi_cwmax, 1024U);
+               qi->tqi_cwmax = 1;
+               while (qi->tqi_cwmax < cw)
+                       qi->tqi_cwmax = (qi->tqi_cwmax << 1) | 1;
+       } else
+               qi->tqi_cwmax = INIT_CWMAX;
+
+       if (qinfo->tqi_shretry != 0)
+               qi->tqi_shretry = min((u32) qinfo->tqi_shretry, 15U);
+       else
+               qi->tqi_shretry = INIT_SH_RETRY;
+       if (qinfo->tqi_lgretry != 0)
+               qi->tqi_lgretry = min((u32) qinfo->tqi_lgretry, 15U);
+       else
+               qi->tqi_lgretry = INIT_LG_RETRY;
+       qi->tqi_cbrPeriod = qinfo->tqi_cbrPeriod;
+       qi->tqi_cbrOverflowLimit = qinfo->tqi_cbrOverflowLimit;
+       qi->tqi_burstTime = qinfo->tqi_burstTime;
+       qi->tqi_readyTime = qinfo->tqi_readyTime;
+
+       return 1;
+}
+
+int ath9k_hw_setuptxqueue(struct ath_hw *ah, enum ath9k_tx_queue type,
+                         const struct ath9k_tx_queue_info *qinfo)
+{
+       struct ath9k_tx_queue_info *qi;
+       int q;
+
+       for (q = 0; q < ATH9K_NUM_TX_QUEUES; q++)
+               if (ah->txq[q].tqi_type ==
+                   ATH9K_TX_QUEUE_INACTIVE)
+                       break;
+       if (q == ATH9K_NUM_TX_QUEUES) {
+               DBG("No available TX queue\n");
+               return -1;
+       }
+
+       DBG2("ath9K: Setup TX queue: %d\n", q);
+
+       qi = &ah->txq[q];
+       if (qi->tqi_type != ATH9K_TX_QUEUE_INACTIVE) {
+               DBG("ath9k: TX queue: %d already active\n", q);
+               return -1;
+       }
+       memset(qi, 0, sizeof(struct ath9k_tx_queue_info));
+       qi->tqi_type = type;
+       if (qinfo == NULL) {
+               qi->tqi_qflags =
+                       TXQ_FLAG_TXOKINT_ENABLE
+                       | TXQ_FLAG_TXERRINT_ENABLE
+                       | TXQ_FLAG_TXDESCINT_ENABLE | TXQ_FLAG_TXURNINT_ENABLE;
+               qi->tqi_aifs = INIT_AIFS;
+               qi->tqi_cwmin = ATH9K_TXQ_USEDEFAULT;
+               qi->tqi_cwmax = INIT_CWMAX;
+               qi->tqi_shretry = INIT_SH_RETRY;
+               qi->tqi_lgretry = INIT_LG_RETRY;
+               qi->tqi_physCompBuf = 0;
+       } else {
+               qi->tqi_physCompBuf = qinfo->tqi_physCompBuf;
+               (void) ath9k_hw_set_txq_props(ah, q, qinfo);
+       }
+
+       return q;
+}
+
+int ath9k_hw_releasetxqueue(struct ath_hw *ah, u32 q)
+{
+       struct ath9k_tx_queue_info *qi;
+
+       qi = &ah->txq[q];
+       if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
+               DBG("ath9k: "
+                       "Release TXQ, inactive queue: %d\n", q);
+               return 0;
+       }
+
+       DBG2("ath9k: Release TX queue: %d\n", q);
+
+       qi->tqi_type = ATH9K_TX_QUEUE_INACTIVE;
+       ah->txok_interrupt_mask &= ~(1 << q);
+       ah->txerr_interrupt_mask &= ~(1 << q);
+       ah->txdesc_interrupt_mask &= ~(1 << q);
+       ah->txeol_interrupt_mask &= ~(1 << q);
+       ah->txurn_interrupt_mask &= ~(1 << q);
+       ath9k_hw_set_txq_interrupts(ah, qi);
+
+       return 1;
+}
+
+int ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
+{
+       struct ath9k_channel *chan = ah->curchan;
+       struct ath9k_tx_queue_info *qi;
+       u32 cwMin, chanCwMin, value __unused;
+
+       qi = &ah->txq[q];
+       if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
+               DBG("ath9k: "
+                       "Reset TXQ, inactive queue: %d\n", q);
+               return 1;
+       }
+
+       DBG2("ath9k: Reset TX queue: %d\n", q);
+
+       if (qi->tqi_cwmin == ATH9K_TXQ_USEDEFAULT) {
+               if (chan && IS_CHAN_B(chan))
+                       chanCwMin = INIT_CWMIN_11B;
+               else
+                       chanCwMin = INIT_CWMIN;
+
+               for (cwMin = 1; cwMin < chanCwMin; cwMin = (cwMin << 1) | 1);
+       } 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) |
+                 SM(qi->tqi_aifs, AR_D_LCL_IFS_AIFS));
+
+       REG_WRITE(ah, AR_DRETRY_LIMIT(q),
+                 SM(INIT_SSH_RETRY, AR_D_RETRY_LIMIT_STA_SH) |
+                 SM(INIT_SLG_RETRY, AR_D_RETRY_LIMIT_STA_LG) |
+                 SM(qi->tqi_shretry, AR_D_RETRY_LIMIT_FR_SH));
+
+       REG_WRITE(ah, AR_QMISC(q), AR_Q_MISC_DCU_EARLY_TERM_REQ);
+
+       if (AR_SREV_9340(ah))
+               REG_WRITE(ah, AR_DMISC(q),
+                         AR_D_MISC_CW_BKOFF_EN | AR_D_MISC_FRAG_WAIT_EN | 0x1);
+       else
+               REG_WRITE(ah, AR_DMISC(q),
+                         AR_D_MISC_CW_BKOFF_EN | AR_D_MISC_FRAG_WAIT_EN | 0x2);
+
+       if (qi->tqi_cbrPeriod) {
+               REG_WRITE(ah, AR_QCBRCFG(q),
+                         SM(qi->tqi_cbrPeriod, AR_Q_CBRCFG_INTERVAL) |
+                         SM(qi->tqi_cbrOverflowLimit, AR_Q_CBRCFG_OVF_THRESH));
+               REG_SET_BIT(ah, AR_QMISC(q), AR_Q_MISC_FSP_CBR |
+                           (qi->tqi_cbrOverflowLimit ?
+                            AR_Q_MISC_CBR_EXP_CNTR_LIMIT_EN : 0));
+       }
+       if (qi->tqi_readyTime) {
+               REG_WRITE(ah, AR_QRDYTIMECFG(q),
+                         SM(qi->tqi_readyTime, AR_Q_RDYTIMECFG_DURATION) |
+                         AR_Q_RDYTIMECFG_EN);
+       }
+
+       REG_WRITE(ah, AR_DCHNTIME(q),
+                 SM(qi->tqi_burstTime, AR_D_CHNTIME_DUR) |
+                 (qi->tqi_burstTime ? AR_D_CHNTIME_EN : 0));
+
+       if (qi->tqi_burstTime
+           && (qi->tqi_qflags & TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE))
+               REG_SET_BIT(ah, AR_QMISC(q), AR_Q_MISC_RDYTIME_EXP_POLICY);
+
+       if (qi->tqi_qflags & TXQ_FLAG_BACKOFF_DISABLE)
+               REG_SET_BIT(ah, AR_DMISC(q), AR_D_MISC_POST_FR_BKOFF_DIS);
+
+       REGWRITE_BUFFER_FLUSH(ah);
+
+       if (qi->tqi_qflags & TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE)
+               REG_SET_BIT(ah, AR_DMISC(q), AR_D_MISC_FRAG_BKOFF_EN);
+
+       if (qi->tqi_intFlags & ATH9K_TXQ_USE_LOCKOUT_BKOFF_DIS) {
+               REG_SET_BIT(ah, AR_DMISC(q),
+                           SM(AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL,
+                              AR_D_MISC_ARB_LOCKOUT_CNTRL) |
+                           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
+               ah->txok_interrupt_mask &= ~(1 << q);
+       if (qi->tqi_qflags & TXQ_FLAG_TXERRINT_ENABLE)
+               ah->txerr_interrupt_mask |= 1 << q;
+       else
+               ah->txerr_interrupt_mask &= ~(1 << q);
+       if (qi->tqi_qflags & TXQ_FLAG_TXDESCINT_ENABLE)
+               ah->txdesc_interrupt_mask |= 1 << q;
+       else
+               ah->txdesc_interrupt_mask &= ~(1 << q);
+       if (qi->tqi_qflags & TXQ_FLAG_TXEOLINT_ENABLE)
+               ah->txeol_interrupt_mask |= 1 << q;
+       else
+               ah->txeol_interrupt_mask &= ~(1 << q);
+       if (qi->tqi_qflags & TXQ_FLAG_TXURNINT_ENABLE)
+               ah->txurn_interrupt_mask |= 1 << q;
+       else
+               ah->txurn_interrupt_mask &= ~(1 << q);
+       ath9k_hw_set_txq_interrupts(ah, qi);
+
+       return 1;
+}
+
+int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds,
+                       struct ath_rx_status *rs, u64 tsf __unused)
+{
+       struct ar5416_desc ads;
+       struct ar5416_desc *adsp = AR5416DESC(ds);
+       u32 phyerr;
+
+       if ((adsp->ds_rxstatus8 & AR_RxDone) == 0)
+               return -EINPROGRESS;
+
+       ads.u.rx = adsp->u.rx;
+
+       rs->rs_status = 0;
+       rs->rs_flags = 0;
+
+       rs->rs_datalen = ads.ds_rxstatus1 & AR_DataLen;
+       rs->rs_tstamp = ads.AR_RcvTimestamp;
+
+       if (ads.ds_rxstatus8 & AR_PostDelimCRCErr) {
+               rs->rs_rssi = ATH9K_RSSI_BAD;
+               rs->rs_rssi_ctl0 = ATH9K_RSSI_BAD;
+               rs->rs_rssi_ctl1 = ATH9K_RSSI_BAD;
+               rs->rs_rssi_ctl2 = ATH9K_RSSI_BAD;
+               rs->rs_rssi_ext0 = ATH9K_RSSI_BAD;
+               rs->rs_rssi_ext1 = ATH9K_RSSI_BAD;
+               rs->rs_rssi_ext2 = ATH9K_RSSI_BAD;
+       } else {
+               rs->rs_rssi = MS(ads.ds_rxstatus4, AR_RxRSSICombined);
+               rs->rs_rssi_ctl0 = MS(ads.ds_rxstatus0,
+                                               AR_RxRSSIAnt00);
+               rs->rs_rssi_ctl1 = MS(ads.ds_rxstatus0,
+                                               AR_RxRSSIAnt01);
+               rs->rs_rssi_ctl2 = MS(ads.ds_rxstatus0,
+                                               AR_RxRSSIAnt02);
+               rs->rs_rssi_ext0 = MS(ads.ds_rxstatus4,
+                                               AR_RxRSSIAnt10);
+               rs->rs_rssi_ext1 = MS(ads.ds_rxstatus4,
+                                               AR_RxRSSIAnt11);
+               rs->rs_rssi_ext2 = MS(ads.ds_rxstatus4,
+                                               AR_RxRSSIAnt12);
+       }
+       if (ads.ds_rxstatus8 & AR_RxKeyIdxValid)
+               rs->rs_keyix = MS(ads.ds_rxstatus8, AR_KeyIdx);
+       else
+               rs->rs_keyix = ATH9K_RXKEYIX_INVALID;
+
+       rs->rs_rate = RXSTATUS_RATE(ah, (&ads));
+       rs->rs_more = (ads.ds_rxstatus1 & AR_RxMore) ? 1 : 0;
+
+       rs->rs_isaggr = (ads.ds_rxstatus8 & AR_RxAggr) ? 1 : 0;
+       rs->rs_moreaggr =
+               (ads.ds_rxstatus8 & AR_RxMoreAggr) ? 1 : 0;
+       rs->rs_antenna = MS(ads.ds_rxstatus3, AR_RxAntenna);
+       rs->rs_flags =
+               (ads.ds_rxstatus3 & AR_GI) ? ATH9K_RX_GI : 0;
+       rs->rs_flags |=
+               (ads.ds_rxstatus3 & AR_2040) ? ATH9K_RX_2040 : 0;
+
+       if (ads.ds_rxstatus8 & AR_PreDelimCRCErr)
+               rs->rs_flags |= ATH9K_RX_DELIM_CRC_PRE;
+       if (ads.ds_rxstatus8 & AR_PostDelimCRCErr)
+               rs->rs_flags |= ATH9K_RX_DELIM_CRC_POST;
+       if (ads.ds_rxstatus8 & AR_DecryptBusyErr)
+               rs->rs_flags |= ATH9K_RX_DECRYPT_BUSY;
+
+       if ((ads.ds_rxstatus8 & AR_RxFrameOK) == 0) {
+               /*
+                * Treat these errors as mutually exclusive to avoid spurious
+                * extra error reports from the hardware. If a CRC error is
+                * reported, then decryption and MIC errors are irrelevant,
+                * the frame is going to be dropped either way
+                */
+               if (ads.ds_rxstatus8 & AR_CRCErr)
+                       rs->rs_status |= ATH9K_RXERR_CRC;
+               else if (ads.ds_rxstatus8 & AR_PHYErr) {
+                       rs->rs_status |= ATH9K_RXERR_PHY;
+                       phyerr = MS(ads.ds_rxstatus8, AR_PHYErrCode);
+                       rs->rs_phyerr = phyerr;
+               } else if (ads.ds_rxstatus8 & AR_DecryptCRCErr)
+                       rs->rs_status |= ATH9K_RXERR_DECRYPT;
+               else if (ads.ds_rxstatus8 & AR_MichaelErr)
+                       rs->rs_status |= ATH9K_RXERR_MIC;
+               else if (ads.ds_rxstatus8 & AR_KeyMiss)
+                       rs->rs_status |= ATH9K_RXERR_DECRYPT;
+       }
+
+       return 0;
+}
+
+/*
+ * This can stop or re-enables RX.
+ *
+ * If bool is set this will kill any frame which is currently being
+ * transferred between the MAC and baseband and also prevent any new
+ * frames from getting started.
+ */
+int ath9k_hw_setrxabort(struct ath_hw *ah, int set)
+{
+       u32 reg;
+
+       if (set) {
+               REG_SET_BIT(ah, AR_DIAG_SW,
+                           (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
+
+               if (!ath9k_hw_wait(ah, AR_OBS_BUS_1, AR_OBS_BUS_1_RX_STATE,
+                                  0, AH_WAIT_TIMEOUT)) {
+                       REG_CLR_BIT(ah, AR_DIAG_SW,
+                                   (AR_DIAG_RX_DIS |
+                                    AR_DIAG_RX_ABORT));
+
+                       reg = REG_READ(ah, AR_OBS_BUS_1);
+                       DBG("ath9k: "
+                               "RX failed to go idle in 10 ms RXSM=0x%x\n",
+                               reg);
+
+                       return 0;
+               }
+       } else {
+               REG_CLR_BIT(ah, AR_DIAG_SW,
+                           (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
+       }
+
+       return 1;
+}
+
+void ath9k_hw_putrxbuf(struct ath_hw *ah, u32 rxdp)
+{
+       REG_WRITE(ah, AR_RXDP, rxdp);
+}
+
+void ath9k_hw_startpcureceive(struct ath_hw *ah, int is_scanning)
+{
+       ath9k_ani_reset(ah, is_scanning);
+
+       REG_CLR_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
+}
+
+void ath9k_hw_abortpcurecv(struct ath_hw *ah)
+{
+       REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_ABORT | AR_DIAG_RX_DIS);
+}
+
+int ath9k_hw_stopdmarecv(struct ath_hw *ah, int *reset)
+{
+#define AH_RX_STOP_DMA_TIMEOUT 10000   /* usec */
+       u32 mac_status, last_mac_status = 0;
+       int i;
+
+       /* Enable access to the DMA observation bus */
+       REG_WRITE(ah, AR_MACMISC,
+                 ((AR_MACMISC_DMA_OBS_LINE_8 << AR_MACMISC_DMA_OBS_S) |
+                  (AR_MACMISC_MISC_OBS_BUS_1 <<
+                   AR_MACMISC_MISC_OBS_BUS_MSB_S)));
+
+       REG_WRITE(ah, AR_CR, AR_CR_RXD);
+
+       /* Wait for rx enable bit to go low */
+       for (i = AH_RX_STOP_DMA_TIMEOUT / AH_TIME_QUANTUM; i != 0; i--) {
+               if ((REG_READ(ah, AR_CR) & AR_CR_RXE) == 0)
+                       break;
+
+               if (!AR_SREV_9300_20_OR_LATER(ah)) {
+                       mac_status = REG_READ(ah, AR_DMADBG_7) & 0x7f0;
+                       if (mac_status == 0x1c0 && mac_status == last_mac_status) {
+                               *reset = 1;
+                               break;
+                       }
+
+                       last_mac_status = mac_status;
+               }
+
+               udelay(AH_TIME_QUANTUM);
+       }
+
+       if (i == 0) {
+               DBG("ath9k: "
+                       "DMA failed to stop in %d ms AR_CR=0x%08x AR_DIAG_SW=0x%08x DMADBG_7=0x%08x\n",
+                       AH_RX_STOP_DMA_TIMEOUT / 1000,
+                       REG_READ(ah, AR_CR),
+                       REG_READ(ah, AR_DIAG_SW),
+                       REG_READ(ah, AR_DMADBG_7));
+               return 0;
+       } else {
+               return 1;
+       }
+
+#undef AH_RX_STOP_DMA_TIMEOUT
+}
+
+int ath9k_hw_intrpend(struct ath_hw *ah)
+{
+       u32 host_isr;
+
+       if (AR_SREV_9100(ah) || !(ah->ah_ier & AR_IER_ENABLE))
+               return 1;
+
+       host_isr = REG_READ(ah, AR_INTR_ASYNC_CAUSE);
+       if ((host_isr & AR_INTR_MAC_IRQ) && (host_isr != AR_INTR_SPURIOUS))
+               return 1;
+
+       host_isr = REG_READ(ah, AR_INTR_SYNC_CAUSE);
+       if ((host_isr & AR_INTR_SYNC_DEFAULT)
+           && (host_isr != AR_INTR_SPURIOUS))
+               return 1;
+
+       return 0;
+}
+
+void ath9k_hw_disable_interrupts(struct ath_hw *ah)
+{
+       DBG2("ath9k: disable IER\n");
+       REG_WRITE(ah, AR_IER, ah->ah_ier);
+       (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);
+       }
+}
+
+void ath9k_hw_enable_interrupts(struct ath_hw *ah)
+{
+       u32 sync_default = AR_INTR_SYNC_DEFAULT;
+
+       if (!(ah->imask & ATH9K_INT_GLOBAL))
+               return;
+
+       if (AR_SREV_9340(ah))
+               sync_default &= ~AR_INTR_SYNC_HOST1_FATAL;
+
+       DBG2("ath9k: enable IER\n");
+       REG_WRITE(ah, AR_IER, ah->ah_ier);
+       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, sync_default);
+               REG_WRITE(ah, AR_INTR_SYNC_MASK, sync_default);
+       }
+       DBG2("ath9k: AR_IMR 0x%x IER 0x%x\n",
+               REG_READ(ah, AR_IMR), REG_READ(ah, AR_IER));
+}
+
+void 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;
+
+       if (!(ints & ATH9K_INT_GLOBAL))
+               ath9k_hw_disable_interrupts(ah);
+
+       DBG2("ath9k: 0x%x => 0x%x\n", omask, ints);
+
+       /* 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;
+               else {
+                       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_GENTIMER)
+               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;
+       }
+
+       DBG2("ath9k: 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)
+               ath9k_hw_enable_interrupts(ah);
+
+       return;
+}
diff --git a/src/drivers/net/ath/ath9k/ath9k_main.c b/src/drivers/net/ath/ath9k/ath9k_main.c
new file mode 100644 (file)
index 0000000..0a17b9b
--- /dev/null
@@ -0,0 +1,916 @@
+/*
+ * Copyright (c) 2008-2011 Atheros Communications Inc.
+ *
+ * Modified for iPXE by Scott K Logan <logans@cottsay.net> July 2011
+ * Original from Linux kernel 3.0.1
+ *
+ * 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 <ipxe/io.h>
+
+#include "ath9k.h"
+
+static void ath9k_bss_info_changed(struct net80211_device *dev, u32 changed);
+
+int ath9k_setpower(struct ath_softc *sc, enum ath9k_power_mode mode)
+{
+       int ret;
+
+       ret = ath9k_hw_setpower(sc->sc_ah, mode);
+
+       return ret;
+}
+
+static void ath_start_ani(struct ath_common *common)
+{
+       struct ath_hw *ah = common->ah;
+       unsigned long timestamp = ( currticks() * 1000 ) / TICKS_PER_SEC;
+       struct ath_softc *sc = (struct ath_softc *) common->priv;
+
+       if (!(sc->sc_flags & SC_OP_ANI_RUN))
+               return;
+
+       if (sc->sc_flags & SC_OP_OFFCHANNEL)
+               return;
+
+       common->ani.longcal_timer = timestamp;
+       common->ani.shortcal_timer = timestamp;
+       common->ani.checkani_timer = timestamp;
+
+       common->ani.timer = timestamp + ah->config.ani_poll_interval;
+}
+
+static void ath_update_survey_nf(struct ath_softc *sc, int channel)
+{
+       struct ath_hw *ah = sc->sc_ah;
+       struct ath9k_channel *chan = &ah->channels[channel];
+       struct survey_info *survey = &sc->survey[channel];
+
+       if (chan->noisefloor) {
+               survey->filled |= SURVEY_INFO_NOISE_DBM;
+               survey->noise = chan->noisefloor;
+       }
+}
+
+/*
+ * Updates the survey statistics and returns the busy time since last
+ * update in %, if the measurement duration was long enough for the
+ * result to be useful, -1 otherwise.
+ */
+static int ath_update_survey_stats(struct ath_softc *sc)
+{
+       struct ath_hw *ah = sc->sc_ah;
+       struct ath_common *common = ath9k_hw_common(ah);
+       int pos = ah->curchan - &ah->channels[0];
+       struct survey_info *survey = &sc->survey[pos];
+       struct ath_cycle_counters *cc = &common->cc_survey;
+       unsigned int div = common->clockrate * 1000;
+       int ret = 0;
+
+       if (!ah->curchan)
+               return -1;
+
+       if (ah->power_mode == ATH9K_PM_AWAKE)
+               ath_hw_cycle_counters_update(common);
+
+       if (cc->cycles > 0) {
+               survey->filled |= SURVEY_INFO_CHANNEL_TIME |
+                       SURVEY_INFO_CHANNEL_TIME_BUSY |
+                       SURVEY_INFO_CHANNEL_TIME_RX |
+                       SURVEY_INFO_CHANNEL_TIME_TX;
+               survey->channel_time += cc->cycles / div;
+               survey->channel_time_busy += cc->rx_busy / div;
+               survey->channel_time_rx += cc->rx_frame / div;
+               survey->channel_time_tx += cc->tx_frame / div;
+       }
+
+       if (cc->cycles < div)
+               return -1;
+
+       if (cc->cycles > 0)
+               ret = cc->rx_busy * 100 / cc->cycles;
+
+       memset(cc, 0, sizeof(*cc));
+
+       ath_update_survey_nf(sc, pos);
+
+       return ret;
+}
+
+/*
+ * Set/change channels.  If the channel is really being changed, it's done
+ * by reseting the chip.  To accomplish this we must first cleanup any pending
+ * DMA, then restart stuff.
+*/
+int ath_set_channel(struct ath_softc *sc, struct net80211_device *dev,
+                   struct ath9k_channel *hchan)
+{
+       struct ath_hw *ah = sc->sc_ah;
+       struct ath_common *common = ath9k_hw_common(ah);
+       int fastcc __unused = 1, stopped __unused;
+       struct net80211_channel *channel = dev->channels + dev->channel;
+       struct ath9k_hw_cal_data *caldata = NULL;
+       int r;
+
+       if (sc->sc_flags & SC_OP_INVALID)
+               return -EIO;
+
+       sc->hw_busy_count = 0;
+
+       common->ani.timer = 0;
+       sc->tx_complete_work_timer = 0;
+       sc->hw_pll_work_timer = 0;
+
+       /*
+        * This is only performed if the channel settings have
+        * actually changed.
+        *
+        * To switch channels clear any pending DMA operations;
+        * wait long enough for the RX fifo to drain, reset the
+        * hardware at the new frequency, and then re-enable
+        * the relevant bits of the h/w.
+        */
+       ath9k_hw_disable_interrupts(ah);
+       stopped = ath_drain_all_txq(sc, 0);
+
+       if (!ath_stoprecv(sc))
+               stopped = 0;
+
+       if (!ath9k_hw_check_alive(ah))
+               stopped = 0;
+
+       /* XXX: do not flush receive queue here. We don't want
+        * to flush data frames already in queue because of
+        * changing channel. */
+
+       if (!(sc->sc_flags & SC_OP_OFFCHANNEL))
+               caldata = &sc->caldata;
+
+       DBG2("ath9k: "
+               "(%d MHz) -> (%d MHz)\n",
+               sc->sc_ah->curchan->channel,
+               channel->center_freq);
+
+       r = ath9k_hw_reset(ah, hchan, caldata, fastcc);
+       if (r) {
+               DBG("ath9k: "
+                       "Unable to reset channel (%d MHz), reset status %d\n",
+                       channel->center_freq, r);
+               goto ps_restore;
+       }
+
+       if (ath_startrecv(sc) != 0) {
+               DBG("ath9k: Unable to restart recv logic\n");
+               r = -EIO;
+               goto ps_restore;
+       }
+
+       ath9k_cmn_update_txpow(ah, sc->curtxpow,
+                              sc->config.txpowlimit, &sc->curtxpow);
+       ath9k_hw_set_interrupts(ah, ah->imask);
+
+       if (!(sc->sc_flags & (SC_OP_OFFCHANNEL))) {
+               sc->tx_complete_work(sc);
+               sc->hw_pll_work_timer = (currticks() * 1000 ) / TICKS_PER_SEC + 500;
+               ath_start_ani(common);
+       }
+
+ ps_restore:
+       return r;
+}
+
+/*
+ *  This routine performs the periodic noise floor calibration function
+ *  that is used to adjust and optimize the chip performance.  This
+ *  takes environmental changes (location, temperature) into account.
+ *  When the task is complete, it reschedules itself depending on the
+ *  appropriate interval that was calculated.
+ */
+void ath_ani_calibrate(struct ath_softc *sc)
+{
+       struct ath_hw *ah = sc->sc_ah;
+       struct ath_common *common = ath9k_hw_common(ah);
+       int longcal = 0;
+       int shortcal = 0;
+       int aniflag = 0;
+       unsigned int timestamp = (currticks() * 1000 ) / TICKS_PER_SEC;
+       u32 cal_interval, short_cal_interval, long_cal_interval;
+
+       if (ah->caldata && ah->caldata->nfcal_interference)
+               long_cal_interval = ATH_LONG_CALINTERVAL_INT;
+       else
+               long_cal_interval = ATH_LONG_CALINTERVAL;
+
+       short_cal_interval = ATH_STA_SHORT_CALINTERVAL;
+
+       /* Only calibrate if awake */
+       if (sc->sc_ah->power_mode != ATH9K_PM_AWAKE)
+               goto set_timer;
+
+       /* Long calibration runs independently of short calibration. */
+       if ((timestamp - common->ani.longcal_timer) >= long_cal_interval) {
+               longcal = 1;
+               DBG2("ath9k: longcal @%d\n", timestamp);
+               common->ani.longcal_timer = timestamp;
+       }
+
+       /* Short calibration applies only while caldone is false */
+       if (!common->ani.caldone) {
+               if ((timestamp - common->ani.shortcal_timer) >= short_cal_interval) {
+                       shortcal = 1;
+                       DBG2("ath9k: "
+                               "shortcal @%d\n", timestamp);
+                       common->ani.shortcal_timer = timestamp;
+                       common->ani.resetcal_timer = timestamp;
+               }
+       } else {
+               if ((timestamp - common->ani.resetcal_timer) >=
+                   ATH_RESTART_CALINTERVAL) {
+                       common->ani.caldone = ath9k_hw_reset_calvalid(ah);
+                       if (common->ani.caldone)
+                               common->ani.resetcal_timer = timestamp;
+               }
+       }
+
+       /* Verify whether we must check ANI */
+       if ((timestamp - common->ani.checkani_timer) >=
+            ah->config.ani_poll_interval) {
+               aniflag = 1;
+               common->ani.checkani_timer = timestamp;
+       }
+
+       /* Skip all processing if there's nothing to do. */
+       if (longcal || shortcal || aniflag) {
+               /* Call ANI routine if necessary */
+               if (aniflag) {
+                       ath9k_hw_ani_monitor(ah, ah->curchan);
+                       ath_update_survey_stats(sc);
+               }
+
+               /* Perform calibration if necessary */
+               if (longcal || shortcal) {
+                       common->ani.caldone =
+                               ath9k_hw_calibrate(ah,
+                                                  ah->curchan,
+                                                  common->rx_chainmask,
+                                                  longcal);
+               }
+       }
+
+set_timer:
+       /*
+       * Set timer interval based on previous results.
+       * The interval must be the shortest necessary to satisfy ANI,
+       * short calibration and long calibration.
+       */
+       cal_interval = ATH_LONG_CALINTERVAL;
+       if (sc->sc_ah->config.enable_ani)
+               cal_interval = min(cal_interval,
+                                  (u32)ah->config.ani_poll_interval);
+       if (!common->ani.caldone)
+               cal_interval = min(cal_interval, (u32)short_cal_interval);
+
+       common->ani.timer = timestamp + cal_interval;
+}
+
+void ath_hw_check(struct ath_softc *sc)
+{
+       int busy;
+
+       if (ath9k_hw_check_alive(sc->sc_ah))
+               goto out;
+
+       busy = ath_update_survey_stats(sc);
+
+       DBG("ath9k: Possible baseband hang, "
+               "busy=%d (try %d)\n", busy, sc->hw_busy_count + 1);
+       if (busy >= 99) {
+               if (++sc->hw_busy_count >= 3)
+                       ath_reset(sc, 1);
+       } else if (busy >= 0)
+               sc->hw_busy_count = 0;
+
+out:
+       return;
+}
+
+static void ath_hw_pll_rx_hang_check(struct ath_softc *sc, u32 pll_sqsum)
+{
+       static int count;
+
+       if (pll_sqsum >= 0x40000) {
+               count++;
+               if (count == 3) {
+                       /* Rx is hung for more than 500ms. Reset it */
+                       DBG("ath9k: "
+                               "Possible RX hang, resetting");
+                       ath_reset(sc, 1);
+                       count = 0;
+               }
+       } else
+               count = 0;
+}
+
+void ath_hw_pll_work(struct ath_softc *sc)
+{
+       u32 pll_sqsum;
+
+       if (AR_SREV_9485(sc->sc_ah)) {
+               pll_sqsum = ar9003_get_pll_sqsum_dvc(sc->sc_ah);
+
+               ath_hw_pll_rx_hang_check(sc, pll_sqsum);
+
+               sc->hw_pll_work_timer = (currticks() * 1000 ) / TICKS_PER_SEC + 200;
+       }
+}
+
+
+void ath9k_tasklet(struct ath_softc *sc)
+{
+       struct ath_hw *ah = sc->sc_ah;
+
+       u32 status = sc->intrstatus;
+       u32 rxmask;
+
+       if ((status & ATH9K_INT_FATAL) ||
+           (status & ATH9K_INT_BB_WATCHDOG)) {
+               ath_reset(sc, 1);
+               return;
+       }
+
+       rxmask = (ATH9K_INT_RX | ATH9K_INT_RXEOL | ATH9K_INT_RXORN);
+
+       if (status & rxmask) {
+               ath_rx_tasklet(sc, 0, 0);
+       }
+
+       if (status & ATH9K_INT_TX) {
+               ath_tx_tasklet(sc);
+       }
+
+       /* re-enable hardware interrupt */
+       ath9k_hw_enable_interrupts(ah);
+}
+
+void ath_isr(struct net80211_device *dev)
+{
+#define SCHED_INTR (                           \
+               ATH9K_INT_FATAL |               \
+               ATH9K_INT_BB_WATCHDOG |         \
+               ATH9K_INT_RXORN |               \
+               ATH9K_INT_RXEOL |               \
+               ATH9K_INT_RX |                  \
+               ATH9K_INT_RXLP |                \
+               ATH9K_INT_RXHP |                \
+               ATH9K_INT_TX |                  \
+               ATH9K_INT_BMISS |               \
+               ATH9K_INT_CST |                 \
+               ATH9K_INT_TSFOOR |              \
+               ATH9K_INT_GENTIMER)
+
+       struct ath_softc *sc = dev->priv;
+       struct ath_hw *ah = sc->sc_ah;
+       struct ath_common *common = ath9k_hw_common(ah);
+       enum ath9k_int status;
+       unsigned long timestamp = (currticks() * 1000 ) / TICKS_PER_SEC;
+       int sched = 0;
+
+       /*
+        * The hardware is not ready/present, don't
+        * touch anything. Note this can happen early
+        * on if the IRQ is shared.
+        */
+       if (sc->sc_flags & SC_OP_INVALID)
+               return;
+
+
+       /* Check calibration */
+       if(timestamp >= (unsigned int)common->ani.timer && common->ani.timer)
+               ath_ani_calibrate(sc);
+
+       /* Check tx_complete_work */
+       if(timestamp >= (unsigned int)sc->tx_complete_work_timer && sc->tx_complete_work_timer)
+               sc->tx_complete_work(sc);
+
+       /* Check hw_pll_work */
+       if(timestamp >= (unsigned int)sc->hw_pll_work_timer && sc->hw_pll_work_timer)
+               sc->hw_pll_work(sc);
+
+       /* shared irq, not for us */
+
+       if (!ath9k_hw_intrpend(ah))
+               return;
+
+       /*
+        * Figure out the reason(s) for the interrupt.  Note
+        * that the hal returns a pseudo-ISR that may include
+        * bits we haven't explicitly enabled so we mask the
+        * value to insure we only process bits we requested.
+        */
+       ath9k_hw_getisr(ah, &status);   /* NB: clears ISR too */
+       status &= ah->imask;    /* discard unasked-for bits */
+
+       /*
+        * If there are no status bits set, then this interrupt was not
+        * for me (should have been caught above).
+        */
+       if (!status)
+               return;
+
+       /* Cache the status */
+       sc->intrstatus = status;
+
+       if (status & SCHED_INTR)
+               sched = 1;
+
+       /*
+        * If a FATAL or RXORN interrupt is received, we have to reset the
+        * chip immediately.
+        */
+       if ((status & ATH9K_INT_FATAL) || (status & ATH9K_INT_RXORN))
+               goto chip_reset;
+
+       if (status & ATH9K_INT_TXURN)
+               ath9k_hw_updatetxtriglevel(ah, 1);
+
+       if (!(ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP))
+               if (status & ATH9K_INT_TIM_TIMER) {
+                       if (sc->ps_idle)
+                               goto chip_reset;
+                       /* Clear RxAbort bit so that we can
+                        * receive frames */
+                       ath9k_setpower(sc, ATH9K_PM_AWAKE);
+                       ath9k_hw_setrxabort(sc->sc_ah, 0);
+                       sc->ps_flags |= PS_WAIT_FOR_BEACON;
+               }
+
+chip_reset:
+
+       if (sched) {
+               /* turn off every interrupt */
+               ath9k_hw_disable_interrupts(ah);
+               sc->intr_tq(sc);
+       }
+
+       return;
+
+#undef SCHED_INTR
+}
+
+void ath_radio_disable(struct ath_softc *sc, struct net80211_device *dev)
+{
+       struct ath_hw *ah = sc->sc_ah;
+       struct net80211_channel *channel = dev->channels + dev->channel;
+       int r;
+
+       sc->hw_pll_work_timer = 0;
+
+       /*
+        * Keep the LED on when the radio is disabled
+        * during idle unassociated state.
+        */
+       if (!sc->ps_idle) {
+               ath9k_hw_set_gpio(ah, ah->led_pin, 1);
+               ath9k_hw_cfg_gpio_input(ah, ah->led_pin);
+       }
+
+       /* Disable interrupts */
+       ath9k_hw_disable_interrupts(ah);
+
+       ath_drain_all_txq(sc, 0);       /* clear pending tx frames */
+
+       ath_stoprecv(sc);               /* turn off frame recv */
+       ath_flushrecv(sc);              /* flush recv queue */
+
+       if (!ah->curchan)
+               ah->curchan = ath9k_cmn_get_curchannel(dev, ah);
+
+       r = ath9k_hw_reset(ah, ah->curchan, ah->caldata, 0);
+       if (r) {
+               DBG("ath9k: "
+                       "Unable to reset channel (%d MHz), reset status %d\n",
+                       channel->center_freq, r);
+       }
+
+       ath9k_hw_phy_disable(ah);
+
+       ath9k_hw_configpcipowersave(ah, 1, 1);
+}
+
+int ath_reset(struct ath_softc *sc, int retry_tx)
+{
+       struct ath_hw *ah = sc->sc_ah;
+       struct ath_common *common = ath9k_hw_common(ah);
+       int r;
+
+       sc->hw_busy_count = 0;
+
+       /* Stop ANI */
+       common->ani.timer = 0;
+
+       ath9k_hw_disable_interrupts(ah);
+       ath_drain_all_txq(sc, retry_tx);
+
+       ath_stoprecv(sc);
+       ath_flushrecv(sc);
+
+       r = ath9k_hw_reset(ah, sc->sc_ah->curchan, ah->caldata, 0);
+       if (r)
+               DBG("ath9k: "
+                       "Unable to reset hardware; reset status %d\n", r);
+
+       if (ath_startrecv(sc) != 0)
+               DBG("ath9k: Unable to start recv logic\n");
+
+       /*
+        * We may be doing a reset in response to a request
+        * that changes the channel so update any state that
+        * might change as a result.
+        */
+       ath9k_cmn_update_txpow(ah, sc->curtxpow,
+                              sc->config.txpowlimit, &sc->curtxpow);
+
+       ath9k_hw_set_interrupts(ah, ah->imask);
+
+       if (retry_tx) {
+               int i;
+               for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
+                       if (ATH_TXQ_SETUP(sc, i)) {
+                               ath_txq_schedule(sc, &sc->tx.txq[i]);
+                       }
+               }
+       }
+
+       /* Start ANI */
+       ath_start_ani(common);
+
+       return r;
+}
+
+/**********************/
+/* mac80211 callbacks */
+/**********************/
+
+static int ath9k_start(struct net80211_device *dev)
+{
+       struct ath_softc *sc = dev->priv;
+       struct ath_hw *ah = sc->sc_ah;
+       struct ath_common *common = ath9k_hw_common(ah);
+       struct net80211_channel *curchan = dev->channels + dev->channel;
+       struct ath9k_channel *init_channel;
+       int r;
+
+       DBG("ath9k: "
+               "Starting driver with initial channel: %d MHz\n",
+               curchan->center_freq);
+
+       /* setup initial channel */
+       sc->chan_idx = curchan->hw_value;
+
+       init_channel = ath9k_cmn_get_curchannel(dev, ah);
+
+       /* Reset SERDES registers */
+       ath9k_hw_configpcipowersave(ah, 0, 0);
+
+       /*
+        * The basic interface to setting the hardware in a good
+        * state is ``reset''.  On return the hardware is known to
+        * be powered up and with interrupts disabled.  This must
+        * be followed by initialization of the appropriate bits
+        * and then setup of the interrupt mask.
+        */
+       r = ath9k_hw_reset(ah, init_channel, ah->caldata, 0);
+       if (r) {
+               DBG("ath9k: "
+                       "Unable to reset hardware; reset status %d (freq %d MHz)\n",
+                       r, curchan->center_freq);
+               goto mutex_unlock;
+       }
+
+       /*
+        * This is needed only to setup initial state
+        * but it's best done after a reset.
+        */
+       ath9k_cmn_update_txpow(ah, sc->curtxpow,
+                       sc->config.txpowlimit, &sc->curtxpow);
+
+       /*
+        * Setup the hardware after reset:
+        * The receive engine is set going.
+        * Frame transmit is handled entirely
+        * in the frame output path; there's nothing to do
+        * here except setup the interrupt mask.
+        */
+       if (ath_startrecv(sc) != 0) {
+               DBG("ath9k: Unable to start recv logic\n");
+               r = -EIO;
+               goto mutex_unlock;
+       }
+
+       /* Setup our intr mask. */
+       ah->imask = ATH9K_INT_TX | ATH9K_INT_RXEOL |
+                   ATH9K_INT_RXORN | ATH9K_INT_FATAL |
+                   ATH9K_INT_GLOBAL;
+
+       ah->imask |= ATH9K_INT_RX;
+
+       sc->sc_flags &= ~SC_OP_INVALID;
+       sc->sc_ah->is_monitoring = 0;
+
+       ath9k_hw_set_interrupts(ah, ah->imask);
+
+       sc->tx_complete_work(sc);
+
+       if (ah->caps.pcie_lcr_extsync_en && common->bus_ops->extn_synch_en)
+               common->bus_ops->extn_synch_en(common);
+
+mutex_unlock:
+       return r;
+}
+
+static int ath9k_tx(struct net80211_device *dev, struct io_buffer *iob)
+{
+       struct ath_softc *sc = dev->priv;
+       struct ath_tx_control txctl;
+       int ret = 0;
+
+       memset(&txctl, 0, sizeof(struct ath_tx_control));
+       txctl.txq = sc->tx.txq_map[0];
+
+       DBGIO("ath9k: transmitting packet, iob: %p\n", iob);
+
+       ret = ath_tx_start(dev, iob, &txctl);
+       if (ret) {
+               DBG("ath9k: TX failed\n");
+               goto exit;
+       }
+
+       return ret;
+exit:
+       free_iob(iob);
+       return ret;
+}
+
+static void ath9k_stop(struct net80211_device *dev)
+{
+       struct ath_softc *sc = dev->priv;
+       struct ath_hw *ah = sc->sc_ah;
+
+       sc->tx_complete_work_timer = 0;
+       sc->hw_pll_work_timer = 0;
+
+       if (sc->sc_flags & SC_OP_INVALID) {
+               DBG("ath9k: Device not present\n");
+               return;
+       }
+
+       /* prevent tasklets to enable interrupts once we disable them */
+       ah->imask &= ~ATH9K_INT_GLOBAL;
+
+       /* make sure h/w will not generate any interrupt
+        * before setting the invalid flag. */
+       ath9k_hw_disable_interrupts(ah);
+
+       if (!(sc->sc_flags & SC_OP_INVALID)) {
+               ath_drain_all_txq(sc, 0);
+               ath_stoprecv(sc);
+               ath9k_hw_phy_disable(ah);
+       } else
+               sc->rx.rxlink = NULL;
+
+       if (sc->rx.frag) {
+               free_iob(sc->rx.frag);
+               sc->rx.frag = NULL;
+       }
+
+       /* disable HAL and put h/w to sleep */
+       ath9k_hw_disable(ah);
+       ath9k_hw_configpcipowersave(ah, 1, 1);
+
+       ath_radio_disable(sc, dev);
+
+       sc->sc_flags |= SC_OP_INVALID;
+
+       DBG("ath9k: Driver halt\n");
+}
+
+static int ath9k_config(struct net80211_device *dev, int changed)
+{
+       struct ath_softc *sc = dev->priv;
+       struct ath_hw *ah = sc->sc_ah;
+
+       if ((changed & NET80211_CFG_RATE) ||
+                       (changed & NET80211_CFG_PHY_PARAMS)) {
+               int spmbl = (sc->sc_flags & SC_OP_PREAMBLE_SHORT) ? IEEE80211_TX_RC_USE_SHORT_PREAMBLE : 0;
+               u16 rate = dev->rates[dev->rate];
+               u16 slowrate = dev->rates[dev->rtscts_rate];
+               int i;
+
+               for (i = 0; i < NET80211_MAX_RATES; i++) {
+                       if (sc->rates[i].bitrate == rate &&
+                           (sc->rates[i].flags & spmbl))
+                               sc->hw_rix = i;
+
+                       if (sc->rates[i].bitrate == slowrate &&
+                           (sc->rates[i].flags & spmbl))
+                               sc->hw_rix = i;
+               }
+       }
+
+       ath9k_bss_info_changed(dev, changed);
+
+       if (changed & NET80211_CFG_CHANNEL) {
+               struct net80211_channel *curchan = dev->channels + dev->channel;
+               int pos = curchan->hw_value;
+               int old_pos = -1;
+
+               if (ah->curchan)
+                       old_pos = ah->curchan - &ah->channels[0];
+
+               sc->sc_flags &= ~SC_OP_OFFCHANNEL;
+
+               DBG2("ath9k: "
+                       "Set channel: %d MHz\n",
+                       curchan->center_freq);
+
+               ath9k_cmn_update_ichannel(&sc->sc_ah->channels[pos],
+                                         curchan);
+
+               /* update survey stats for the old channel before switching */
+               ath_update_survey_stats(sc);
+
+               /*
+                * If the operating channel changes, change the survey in-use flags
+                * along with it.
+                * Reset the survey data for the new channel, unless we're switching
+                * back to the operating channel from an off-channel operation.
+                */
+               if (sc->cur_survey != &sc->survey[pos]) {
+
+                       if (sc->cur_survey)
+                               sc->cur_survey->filled &= ~SURVEY_INFO_IN_USE;
+
+                       sc->cur_survey = &sc->survey[pos];
+
+                       memset(sc->cur_survey, 0, sizeof(struct survey_info));
+                       sc->cur_survey->filled |= SURVEY_INFO_IN_USE;
+               } else if (!(sc->survey[pos].filled & SURVEY_INFO_IN_USE)) {
+                       memset(&sc->survey[pos], 0, sizeof(struct survey_info));
+               }
+
+               if (ath_set_channel(sc, dev, &sc->sc_ah->channels[pos]) < 0) {
+                       DBG("ath9k: Unable to set channel\n");
+                       return -EINVAL;
+               }
+
+               /*
+                * The most recent snapshot of channel->noisefloor for the old
+                * channel is only available after the hardware reset. Copy it to
+                * the survey stats now.
+                */
+               if (old_pos >= 0)
+                       ath_update_survey_nf(sc, old_pos);
+       }
+
+       if (changed & NET80211_CFG_CHANNEL) {
+               DBG2("ath9k: "
+                       "Set power: %d\n", (dev->channels + dev->channel)->maxpower);
+               sc->config.txpowlimit = 2 * (dev->channels + dev->channel)->maxpower;
+               ath9k_cmn_update_txpow(ah, sc->curtxpow,
+                                      sc->config.txpowlimit, &sc->curtxpow);
+       }
+
+       return 0;
+}
+
+static void ath9k_bss_iter(struct ath_softc *sc)
+{
+       struct ath_common *common = ath9k_hw_common(sc->sc_ah);
+
+       if (common->dev->state & NET80211_ASSOCIATED) {
+               sc->sc_flags |= SC_OP_PRIM_STA_VIF;
+               memcpy(common->curbssid, common->dev->bssid, ETH_ALEN);
+               common->curaid = common->dev->aid;
+               ath9k_hw_write_associd(sc->sc_ah);
+               DBG("ath9k: "
+                       "Bss Info ASSOC %d, bssid: %pM\n",
+                       common->dev->aid, common->curbssid);
+
+               /*
+                * Request a re-configuration of Beacon related timers
+                * on the receipt of the first Beacon frame (i.e.,
+                * after time sync with the AP).
+                */
+               sc->ps_flags |= PS_BEACON_SYNC | PS_WAIT_FOR_BEACON;
+               /* Reset rssi stats */
+               sc->last_rssi = ATH_RSSI_DUMMY_MARKER;
+               sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER;
+
+               sc->sc_flags |= SC_OP_ANI_RUN;
+               ath_start_ani(common);
+       }
+}
+
+static void ath9k_config_bss(struct ath_softc *sc)
+{
+       struct ath_common *common = ath9k_hw_common(sc->sc_ah);
+       struct net80211_device *dev = common->dev;
+
+       /* Reconfigure bss info */
+       if (!(dev->state & NET80211_ASSOCIATED)) {
+               DBG2("ath9k: "
+                       "ath9k: Bss Info DISASSOC %d, bssid %pM\n",
+                       common->curaid, common->curbssid);
+               sc->sc_flags &= ~(SC_OP_PRIM_STA_VIF | SC_OP_BEACONS);
+               memset(common->curbssid, 0, ETH_ALEN);
+               common->curaid = 0;
+       }
+
+       ath9k_bss_iter(sc);
+
+       /*
+        * None of station vifs are associated.
+        * Clear bssid & aid
+        */
+       if (!(sc->sc_flags & SC_OP_PRIM_STA_VIF)) {
+               ath9k_hw_write_associd(sc->sc_ah);
+               /* Stop ANI */
+               sc->sc_flags &= ~SC_OP_ANI_RUN;
+               common->ani.timer = 0;
+       }
+}
+
+static void ath9k_bss_info_changed(struct net80211_device *dev,
+                                  u32 changed)
+{
+       struct ath_softc *sc = dev->priv;
+       struct ath_hw *ah = sc->sc_ah;
+       struct ath_common *common = ath9k_hw_common(ah);
+       int slottime;
+
+       if (changed & NET80211_CFG_ASSOC) {
+               ath9k_config_bss(sc);
+
+               DBG2("ath9k: BSSID: %pM aid: 0x%x\n",
+                       common->curbssid, common->curaid);
+       }
+
+       if (changed & NET80211_CFG_PHY_PARAMS) {
+               if (dev->phy_flags & NET80211_PHY_USE_PROTECTION)
+                       slottime = 9;
+               else
+                       slottime = 20;
+               ah->slottime = slottime;
+               ath9k_hw_init_global_settings(ah);
+
+               DBG2("ath9k: BSS Changed PREAMBLE %d\n",
+                               !!(dev->phy_flags & NET80211_PHY_USE_SHORT_PREAMBLE));
+               if (dev->phy_flags & NET80211_PHY_USE_SHORT_PREAMBLE)
+                       sc->sc_flags |= SC_OP_PREAMBLE_SHORT;
+               else
+                       sc->sc_flags &= ~SC_OP_PREAMBLE_SHORT;
+
+               DBG2("ath9k: BSS Changed CTS PROT %d\n",
+                       !!(dev->phy_flags & NET80211_PHY_USE_PROTECTION));
+               if ((dev->phy_flags & NET80211_PHY_USE_PROTECTION) &&
+                   (dev->channels + dev->channel)->band != NET80211_BAND_5GHZ)
+                       sc->sc_flags |= SC_OP_PROTECT_ENABLE;
+               else
+                       sc->sc_flags &= ~SC_OP_PROTECT_ENABLE;
+       }
+}
+
+static void ath9k_poll(struct net80211_device *dev)
+{
+       ath_isr(dev);
+}
+
+static void ath9k_irq(struct net80211_device *dev, int enable)
+{
+       struct ath_softc *sc = dev->priv;
+       struct ath_hw *ah = sc->sc_ah;
+
+       ah->ah_ier = enable ? AR_IER_ENABLE : AR_IER_DISABLE;
+
+       ath9k_hw_set_interrupts(ah, ah->imask);
+}
+
+struct net80211_device_operations ath9k_ops = {
+       .transmit       = ath9k_tx,
+       .open           = ath9k_start,
+       .close          = ath9k_stop,
+       .config         = ath9k_config,
+       .poll           = ath9k_poll,
+       .irq            = ath9k_irq,
+};
diff --git a/src/drivers/net/ath/ath9k/ath9k_recv.c b/src/drivers/net/ath/ath9k/ath9k_recv.c
new file mode 100644 (file)
index 0000000..ba363c6
--- /dev/null
@@ -0,0 +1,521 @@
+/*
+ * Copyright (c) 2008-2011 Atheros Communications Inc.
+ *
+ * Modified for iPXE by Scott K Logan <logans@cottsay.net> July 2011
+ * Original from Linux kernel 3.0.1
+ *
+ * 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 <ipxe/io.h>
+
+#include "ath9k.h"
+#include "ar9003_mac.h"
+
+/*
+ * Setup and link descriptors.
+ *
+ * 11N: we can no longer afford to self link the last descriptor.
+ * MAC acknowledges BA status as long as it copies frames to host
+ * buffer (or rx fifo). This can incorrectly acknowledge packets
+ * to a sender if last desc is self-linked.
+ */
+static void ath_rx_buf_link(struct ath_softc *sc, struct ath_buf *bf)
+{
+       struct ath_hw *ah = sc->sc_ah;
+       struct ath_common *common = ath9k_hw_common(ah);
+       struct ath_desc *ds;
+//     struct io_buffer *iob;
+
+       ATH_RXBUF_RESET(bf);
+
+       ds = bf->bf_desc;
+       ds->ds_link = 0; /* link to null */
+       ds->ds_data = bf->bf_buf_addr;
+
+//     /* virtual addr of the beginning of the buffer. */
+//     iob = bf->bf_mpdu;
+//     ds->ds_vdata = iob->data;
+
+       /*
+        * setup rx descriptors. The rx_bufsize here tells the hardware
+        * how much data it can DMA to us and that we are prepared
+        * to process
+        */
+       ath9k_hw_setuprxdesc(ah, ds,
+                            common->rx_bufsize,
+                            0);
+
+       if (sc->rx.rxlink == NULL)
+               ath9k_hw_putrxbuf(ah, bf->bf_daddr);
+       else
+               *sc->rx.rxlink = bf->bf_daddr;
+
+       sc->rx.rxlink = &ds->ds_link;
+}
+
+static void ath_setdefantenna(struct ath_softc *sc, u32 antenna)
+{
+       /* XXX block beacon interrupts */
+       ath9k_hw_setantenna(sc->sc_ah, antenna);
+       sc->rx.defant = antenna;
+       sc->rx.rxotherant = 0;
+}
+
+static void ath_opmode_init(struct ath_softc *sc)
+{
+       struct ath_hw *ah = sc->sc_ah;
+       struct ath_common *common = ath9k_hw_common(ah);
+
+       u32 rfilt, mfilt[2];
+
+       /* configure rx filter */
+       rfilt = ath_calcrxfilter(sc);
+       ath9k_hw_setrxfilter(ah, rfilt);
+
+       /* configure bssid mask */
+       ath_hw_setbssidmask(common);
+
+       /* configure operational mode */
+       ath9k_hw_setopmode(ah);
+
+       /* calculate and install multicast filter */
+       mfilt[0] = mfilt[1] = ~0;
+       ath9k_hw_setmcastfilter(ah, mfilt[0], mfilt[1]);
+}
+
+int ath_rx_init(struct ath_softc *sc, int nbufs)
+{
+       struct ath_common *common = ath9k_hw_common(sc->sc_ah);
+       struct io_buffer *iob;
+       u32 *iob_addr = NULL;
+       struct ath_buf *bf;
+       int error = 0;
+
+       sc->sc_flags &= ~SC_OP_RXFLUSH;
+
+       common->rx_bufsize = IEEE80211_MAX_MPDU_LEN / 2 +
+                            sc->sc_ah->caps.rx_status_len;
+
+       DBG2("ath9k: cachelsz %d rxbufsize %d\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) {
+               DBG("ath9k: "
+                       "failed to allocate rx descriptors: %d\n",
+                       error);
+               goto err;
+       }
+
+       list_for_each_entry(bf, &sc->rx.rxbuf, list) {
+               iob = ath_rxbuf_alloc(common, common->rx_bufsize,
+                                     iob_addr);
+               if (iob == NULL) {
+                       error = -ENOMEM;
+                       goto err;
+               }
+
+               bf->bf_mpdu = iob;
+               bf->bf_buf_addr = *iob_addr;
+       }
+       sc->rx.rxlink = NULL;
+
+err:
+       if (error)
+               ath_rx_cleanup(sc);
+
+       return error;
+}
+
+void ath_rx_cleanup(struct ath_softc *sc)
+{
+       struct io_buffer *iob;
+       struct ath_buf *bf;
+
+       list_for_each_entry(bf, &sc->rx.rxbuf, list) {
+               iob = bf->bf_mpdu;
+               if (iob) {
+                       free_iob(iob);
+                       bf->bf_buf_addr = 0;
+                       bf->bf_mpdu = NULL;
+               }
+       }
+
+       if (sc->rx.rxdma.dd_desc_len != 0)
+               ath_descdma_cleanup(sc, &sc->rx.rxdma, &sc->rx.rxbuf);
+}
+
+/*
+ * Calculate the receive filter according to the
+ * operating mode and state:
+ *
+ * o always accept unicast, broadcast, and multicast traffic
+ * o maintain current state of phy error reception (the hal
+ *   may enable phy error frames for noise immunity work)
+ * o probe request frames are accepted only when operating in
+ *   hostap, adhoc, or monitor modes
+ * o enable promiscuous mode according to the interface state
+ * o accept beacons:
+ *   - when operating in adhoc mode so the 802.11 layer creates
+ *     node table entries for peers,
+ *   - when operating in station mode for collecting rssi data when
+ *     the station is otherwise quiet, or
+ *   - when operating as a repeater so we see repeater-sta beacons
+ *   - when scanning
+ */
+
+u32 ath_calcrxfilter(struct ath_softc *sc)
+{
+#define        RX_FILTER_PRESERVE (ATH9K_RX_FILTER_PHYERR | ATH9K_RX_FILTER_PHYRADAR)
+
+       u32 rfilt;
+
+       rfilt = (ath9k_hw_getrxfilter(sc->sc_ah) & RX_FILTER_PRESERVE)
+               | ATH9K_RX_FILTER_UCAST | ATH9K_RX_FILTER_BCAST
+               | ATH9K_RX_FILTER_MCAST | ATH9K_RX_FILTER_BEACON;
+
+       return rfilt;
+
+#undef RX_FILTER_PRESERVE
+}
+
+int ath_startrecv(struct ath_softc *sc)
+{
+       struct ath_hw *ah = sc->sc_ah;
+       struct ath_buf *bf, *tbf;
+
+       if (list_empty(&sc->rx.rxbuf))
+               goto start_recv;
+
+       sc->rx.rxlink = NULL;
+       list_for_each_entry_safe(bf, tbf, &sc->rx.rxbuf, list) {
+               ath_rx_buf_link(sc, bf);
+       }
+
+       /* We could have deleted elements so the list may be empty now */
+       if (list_empty(&sc->rx.rxbuf))
+               goto start_recv;
+
+       bf = list_first_entry(&sc->rx.rxbuf, struct ath_buf, list);
+       ath9k_hw_putrxbuf(ah, bf->bf_daddr);
+       ath9k_hw_rxena(ah);
+
+start_recv:
+       ath_opmode_init(sc);
+       ath9k_hw_startpcureceive(ah, (sc->sc_flags & SC_OP_OFFCHANNEL));
+
+       return 0;
+}
+
+int ath_stoprecv(struct ath_softc *sc)
+{
+       struct ath_hw *ah = sc->sc_ah;
+       int stopped, reset = 0;
+
+       ath9k_hw_abortpcurecv(ah);
+       ath9k_hw_setrxfilter(ah, 0);
+       stopped = ath9k_hw_stopdmarecv(ah, &reset);
+
+       sc->rx.rxlink = NULL;
+
+       if (!(ah->ah_flags & AH_UNPLUGGED) &&
+           !stopped) {
+               DBG("ath9k: "
+                       "Could not stop RX, we could be "
+                       "confusing the DMA engine when we start RX up\n");
+       }
+       return stopped && !reset;
+}
+
+void ath_flushrecv(struct ath_softc *sc)
+{
+       sc->sc_flags |= SC_OP_RXFLUSH;
+       ath_rx_tasklet(sc, 1, 0);
+       sc->sc_flags &= ~SC_OP_RXFLUSH;
+}
+
+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_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 ((&bf->list)->next == &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;
+
+       return bf;
+}
+
+/* Assumes you've already done the endian to CPU conversion */
+static int ath9k_rx_accept(struct ath_common *common,
+                           struct ath_rx_status *rx_stats,
+                           int *decrypt_error)
+{
+       struct ath_hw *ah = common->ah;
+       u8 rx_status_len = ah->caps.rx_status_len;
+
+
+       if (!rx_stats->rs_datalen)
+               return 0;
+        /*
+         * rs_status follows rs_datalen so if rs_datalen is too large
+         * we can take a hint that hardware corrupted it, so ignore
+         * those frames.
+         */
+       if (rx_stats->rs_datalen > (common->rx_bufsize - rx_status_len))
+               return 0;
+
+       /* Only use error bits from the last fragment */
+       if (rx_stats->rs_more)
+               return 1;
+
+       /*
+        * The rx_stats->rs_status will not be set until the end of the
+        * chained descriptors so it can be ignored if rs_more is set. The
+        * rs_more will be false at the last element of the chained
+        * descriptors.
+        */
+       if (rx_stats->rs_status != 0) {
+               if (rx_stats->rs_status & ATH9K_RXERR_PHY)
+                       return 0;
+
+               if (rx_stats->rs_status & ATH9K_RXERR_DECRYPT) {
+                       *decrypt_error = 1;
+               }
+               /*
+                * Reject error frames with the exception of
+                * decryption and MIC failures. For monitor mode,
+                * we also ignore the CRC error.
+                */
+               if (ah->is_monitoring) {
+                       if (rx_stats->rs_status &
+                           ~(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC |
+                             ATH9K_RXERR_CRC))
+                               return 0;
+               } else {
+                       if (rx_stats->rs_status &
+                           ~(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC)) {
+                               return 0;
+                       }
+               }
+       }
+       return 1;
+}
+
+static int ath9k_process_rate(struct ath_common *common __unused,
+                             struct net80211_device *dev,
+                             struct ath_rx_status *rx_stats,
+                             int *rix)
+{
+       struct ath_softc *sc = (struct ath_softc *)dev->priv;
+       int band;
+       int i = 0;
+
+       band = (dev->channels + sc->dev->channel)->band;
+
+       for (i = 0; i < sc->hwinfo->nr_rates[band]; i++) {
+               if (sc->rates[i].hw_value == rx_stats->rs_rate) {
+                       *rix = i;
+                       return 0;
+               }
+               if (sc->rates[i].hw_value_short == rx_stats->rs_rate) {
+                       *rix = i;
+                       return 0;
+               }
+       }
+
+       /*
+        * No valid hardware bitrate found -- we should not get here
+        * because hardware has already validated this frame as OK.
+        */
+       DBG("ath9k: "
+               "unsupported hw bitrate detected 0x%02x using 1 Mbit\n",
+               rx_stats->rs_rate);
+
+       return -EINVAL;
+}
+
+/*
+ * For Decrypt or Demic errors, we only mark packet status here and always push
+ * up the frame up to let mac80211 handle the actual error case, be it no
+ * decryption key or real decryption error. This let us keep statistics there.
+ */
+static int ath9k_rx_iob_preprocess(struct ath_common *common,
+                                  struct net80211_device *dev,
+                                  struct ath_rx_status *rx_stats,
+                                  int *rix,
+                                  int *decrypt_error)
+{
+       /*
+        * everything but the rate is checked here, the rate check is done
+        * separately to avoid doing two lookups for a rate for each frame.
+        */
+       if (!ath9k_rx_accept(common, rx_stats, decrypt_error))
+               return -EINVAL;
+
+       /* Only use status info from the last fragment */
+       if (rx_stats->rs_more)
+               return 0;
+
+       if (ath9k_process_rate(common, dev, rx_stats, rix))
+               return -EINVAL;
+
+       return 0;
+}
+
+int ath_rx_tasklet(struct ath_softc *sc, int flush, int hp __unused)
+{
+       struct ath_buf *bf;
+       struct io_buffer *iob = NULL, *requeue_iob;
+       u32 *requeue_iob_addr = NULL;
+       struct ath_hw *ah = sc->sc_ah;
+       struct ath_common *common = ath9k_hw_common(ah);
+       /*
+        * The hw can technically differ from common->hw when using ath9k
+        * virtual wiphy so to account for that we iterate over the active
+        * wiphys and find the appropriate wiphy and therefore hw.
+        */
+       struct net80211_device *dev = sc->dev;
+       int retval;
+       int decrypt_error = 0;
+       struct ath_rx_status rs;
+       int rix = 0;
+
+       do {
+               /* If handling rx interrupt and flush is in progress => exit */
+               if ((sc->sc_flags & SC_OP_RXFLUSH) && (flush == 0))
+                       break;
+
+               memset(&rs, 0, sizeof(rs));
+               bf = ath_get_next_rx_buf(sc, &rs);
+
+               if (!bf)
+                       break;
+
+               iob = bf->bf_mpdu;
+               if (!iob)
+                       continue;
+
+               /*
+                * If we're asked to flush receive queue, directly
+                * chain it back at the queue without processing it.
+                */
+               if (flush)
+                       goto requeue_drop_frag;
+
+               retval = ath9k_rx_iob_preprocess(common, dev, &rs,
+                                                &rix, &decrypt_error);
+               if (retval)
+                       goto requeue_drop_frag;
+
+               /* Ensure we always have an iob to requeue once we are done
+                * processing the current buffer's iob */
+               requeue_iob = ath_rxbuf_alloc(common, common->rx_bufsize, requeue_iob_addr);
+
+               /* If there is no memory we ignore the current RX'd frame,
+                * tell hardware it can give us a new frame using the old
+                * iob and put it at the tail of the sc->rx.rxbuf list for
+                * processing. */
+               if (!requeue_iob)
+                       goto requeue_drop_frag;
+
+               iob_put(iob, rs.rs_datalen + ah->caps.rx_status_len);
+               if (ah->caps.rx_status_len)
+                       iob_pull(iob, ah->caps.rx_status_len);
+
+               /* We will now give hardware our shiny new allocated iob */
+               bf->bf_mpdu = requeue_iob;
+               bf->bf_buf_addr = *requeue_iob_addr;
+
+               /*
+                * change the default rx antenna if rx diversity chooses the
+                * other antenna 3 times in a row.
+                */
+               if (sc->rx.defant != rs.rs_antenna) {
+                       if (++sc->rx.rxotherant >= 3)
+                               ath_setdefantenna(sc, rs.rs_antenna);
+               } else {
+                       sc->rx.rxotherant = 0;
+               }
+
+               DBGIO("ath9k: rx %d bytes, signal %d, bitrate %d, hw_value %d\n", rs.rs_datalen,
+                                               rs.rs_rssi, sc->rates[rix].bitrate, rs.rs_rate);
+
+               net80211_rx(dev, iob, rs.rs_rssi,
+                               sc->rates[rix].bitrate);
+
+requeue_drop_frag:
+               list_del(&bf->list);
+               list_add_tail(&bf->list, &sc->rx.rxbuf);
+               ath_rx_buf_link(sc, bf);
+               ath9k_hw_rxena(ah);
+       } while (1);
+
+       return 0;
+}
diff --git a/src/drivers/net/ath/ath9k/ath9k_xmit.c b/src/drivers/net/ath/ath9k/ath9k_xmit.c
new file mode 100644 (file)
index 0000000..7f4f28a
--- /dev/null
@@ -0,0 +1,813 @@
+/*
+ * Copyright (c) 2008-2011 Atheros Communications Inc.
+ *
+ * Modified for iPXE by Scott K Logan <logans@cottsay.net> July 2011
+ * Original from Linux kernel 3.0.1
+ *
+ * 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 <ipxe/io.h>
+
+#include "ath9k.h"
+#include "ar9003_mac.h"
+
+#define BITS_PER_BYTE           8
+#define OFDM_PLCP_BITS          22
+#define HT_RC_2_STREAMS(_rc)    ((((_rc) & 0x78) >> 3) + 1)
+#define L_STF                   8
+#define L_LTF                   8
+#define L_SIG                   4
+#define HT_SIG                  8
+#define HT_STF                  4
+#define HT_LTF(_ns)             (4 * (_ns))
+#define SYMBOL_TIME(_ns)        ((_ns) << 2) /* ns * 4 us */
+#define SYMBOL_TIME_HALFGI(_ns) (((_ns) * 18 + 4) / 5)  /* ns * 3.6 us */
+#define NUM_SYMBOLS_PER_USEC(_usec) (_usec >> 2)
+#define NUM_SYMBOLS_PER_USEC_HALFGI(_usec) (((_usec*5)-4)/18)
+
+
+#define IS_HT_RATE(_rate)     ((_rate) & 0x80)
+
+static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq,
+                              struct ath_atx_tid *tid,
+                              struct list_head *bf_head);
+static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
+                               struct ath_txq *txq, struct list_head *bf_q,
+                               struct ath_tx_status *ts, int txok, int sendbar);
+static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq,
+                            struct list_head *head);
+static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, int len);
+
+enum {
+       MCS_HT20,
+       MCS_HT20_SGI,
+       MCS_HT40,
+       MCS_HT40_SGI,
+};
+
+/*********************/
+/* Aggregation logic */
+/*********************/
+
+static void ath_tx_queue_tid(struct ath_txq *txq, struct ath_atx_tid *tid)
+{
+       struct ath_atx_ac *ac = tid->ac;
+
+       if (tid->paused)
+               return;
+
+       if (tid->sched)
+               return;
+
+       tid->sched = 1;
+       list_add_tail(&tid->list, &ac->tid_q);
+
+       if (ac->sched)
+               return;
+
+       ac->sched = 1;
+       list_add_tail(&ac->list, &txq->axq_acq);
+}
+
+static struct ath_buf *ath_tx_get_buffer(struct ath_softc *sc)
+{
+       struct ath_buf *bf = NULL;
+
+       if (list_empty(&sc->tx.txbuf)) {
+               return NULL;
+       }
+
+       bf = list_first_entry(&sc->tx.txbuf, struct ath_buf, list);
+       list_del(&bf->list);
+
+       return bf;
+}
+
+static void ath_tx_return_buffer(struct ath_softc *sc, struct ath_buf *bf)
+{
+       list_add_tail(&bf->list, &sc->tx.txbuf);
+}
+
+/********************/
+/* Queue Management */
+/********************/
+
+struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype)
+{
+       struct ath_hw *ah = sc->sc_ah;
+       struct ath9k_tx_queue_info qi;
+       static const int subtype_txq_to_hwq[] = {
+               [WME_AC_BE] = ATH_TXQ_AC_BE,
+       };
+       int axq_qnum, i;
+
+       memset(&qi, 0, sizeof(qi));
+       qi.tqi_subtype = subtype_txq_to_hwq[subtype];
+       qi.tqi_aifs = ATH9K_TXQ_USEDEFAULT;
+       qi.tqi_cwmin = ATH9K_TXQ_USEDEFAULT;
+       qi.tqi_cwmax = ATH9K_TXQ_USEDEFAULT;
+       qi.tqi_physCompBuf = 0;
+
+       /*
+        * Enable interrupts only for EOL and DESC conditions.
+        * We mark tx descriptors to receive a DESC interrupt
+        * when a tx queue gets deep; otherwise waiting for the
+        * EOL to reap descriptors.  Note that this is done to
+        * reduce interrupt load and this only defers reaping
+        * descriptors, never transmitting frames.  Aside from
+        * reducing interrupts this also permits more concurrency.
+        * The only potential downside is if the tx queue backs
+        * up in which case the top half of the kernel may backup
+        * due to a lack of tx descriptors.
+        *
+        * The UAPSD queue is an exception, since we take a desc-
+        * based intr on the EOSP frames.
+        */
+       qi.tqi_qflags = TXQ_FLAG_TXEOLINT_ENABLE |
+                       TXQ_FLAG_TXDESCINT_ENABLE;
+
+       axq_qnum = ath9k_hw_setuptxqueue(ah, qtype, &qi);
+       if (axq_qnum == -1) {
+               /*
+                * NB: don't print a message, this happens
+                * normally on parts with too few tx queues
+                */
+               return NULL;
+       }
+       if ((unsigned int)axq_qnum >= ARRAY_SIZE(sc->tx.txq)) {
+               DBG("ath9k: qnum %d out of range, max %zd!\n",
+                       axq_qnum, ARRAY_SIZE(sc->tx.txq));
+               ath9k_hw_releasetxqueue(ah, axq_qnum);
+               return NULL;
+       }
+       if (!ATH_TXQ_SETUP(sc, axq_qnum)) {
+               struct ath_txq *txq = &sc->tx.txq[axq_qnum];
+
+               txq->axq_qnum = axq_qnum;
+               txq->mac80211_qnum = -1;
+               txq->axq_link = NULL;
+               INIT_LIST_HEAD(&txq->axq_q);
+               INIT_LIST_HEAD(&txq->axq_acq);
+               txq->axq_depth = 0;
+               txq->axq_ampdu_depth = 0;
+               txq->axq_tx_inprogress = 0;
+               sc->tx.txqsetup |= 1<<axq_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[axq_qnum];
+}
+
+/*
+ * Drain a given TX queue (could be Beacon or Data)
+ *
+ * This assumes output has been stopped and
+ * we do not need to block ath_tx_tasklet.
+ */
+void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, int retry_tx __unused)
+{
+       struct ath_buf *bf, *lastbf __unused;
+       struct list_head bf_head;
+       struct ath_tx_status ts;
+
+       memset(&ts, 0, sizeof(ts));
+       INIT_LIST_HEAD(&bf_head);
+
+       for (;;) {
+               if (list_empty(&txq->axq_q)) {
+                       txq->axq_link = NULL;
+                       break;
+               }
+               bf = list_first_entry(&txq->axq_q, struct ath_buf,
+                                     list);
+
+               if (bf->bf_stale) {
+                       list_del(&bf->list);
+
+                       ath_tx_return_buffer(sc, bf);
+                       continue;
+               }
+
+               lastbf = bf->bf_lastbf;
+
+               list_cut_position(&bf_head, &txq->axq_q, &lastbf->list);
+
+               txq->axq_depth--;
+               ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0, 0);
+       }
+
+       txq->axq_tx_inprogress = 0;
+}
+
+int ath_drain_all_txq(struct ath_softc *sc, int retry_tx)
+{
+       struct ath_hw *ah = sc->sc_ah;
+       struct ath_txq *txq;
+       int i, npend = 0;
+
+       if (sc->sc_flags & SC_OP_INVALID)
+               return 1;
+
+       ath9k_hw_abort_tx_dma(ah);
+
+       /* Check if any queue remains active */
+       for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
+               if (!ATH_TXQ_SETUP(sc, i))
+                       continue;
+
+               npend += ath9k_hw_numtxpending(ah, sc->tx.txq[i].axq_qnum);
+       }
+
+       if (npend)
+               DBG("ath9k: Failed to stop TX DMA!\n");
+
+       for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
+               if (!ATH_TXQ_SETUP(sc, i))
+                       continue;
+
+               /*
+                * The caller will resume queues with ieee80211_wake_queues.
+                * Mark the queue as not stopped to prevent ath_tx_complete
+                * from waking the queue too early.
+                */
+               txq = &sc->tx.txq[i];
+               txq->stopped = 0;
+               ath_draintxq(sc, txq, retry_tx);
+       }
+
+       return !npend;
+}
+
+void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq)
+{
+       ath9k_hw_releasetxqueue(sc->sc_ah, txq->axq_qnum);
+       sc->tx.txqsetup &= ~(1<<txq->axq_qnum);
+}
+
+/* For each axq_acq entry, for each tid, try to schedule packets
+ * for transmit until ampdu_depth has reached min Q depth.
+ */
+void ath_txq_schedule(struct ath_softc *sc __unused, struct ath_txq *txq)
+{
+       struct ath_atx_ac *ac, *ac_tmp, *last_ac;
+       struct ath_atx_tid *tid, *last_tid;
+
+       if (list_empty(&txq->axq_acq) ||
+           txq->axq_ampdu_depth >= ATH_AGGR_MIN_QDEPTH)
+               return;
+
+       ac = list_first_entry(&txq->axq_acq, struct ath_atx_ac, list);
+       last_ac = list_entry(txq->axq_acq.prev, struct ath_atx_ac, list);
+
+       list_for_each_entry_safe(ac, ac_tmp, &txq->axq_acq, list) {
+               last_tid = list_entry(ac->tid_q.prev, struct ath_atx_tid, list);
+               list_del(&ac->list);
+               ac->sched = 0;
+
+               while (!list_empty(&ac->tid_q)) {
+                       tid = list_first_entry(&ac->tid_q, struct ath_atx_tid,
+                                              list);
+                       list_del(&tid->list);
+                       tid->sched = 0;
+
+                       if (tid->paused)
+                               continue;
+
+                       /*
+                        * add tid to round-robin queue if more frames
+                        * are pending for the tid
+                        */
+                       if (!list_empty(&tid->buf_q))
+                               ath_tx_queue_tid(txq, tid);
+
+                       if (tid == last_tid ||
+                           txq->axq_ampdu_depth >= ATH_AGGR_MIN_QDEPTH)
+                               break;
+               }
+
+               if (!list_empty(&ac->tid_q)) {
+                       if (!ac->sched) {
+                               ac->sched = 1;
+                               list_add_tail(&ac->list, &txq->axq_acq);
+                       }
+               }
+
+               if (ac == last_ac ||
+                   txq->axq_ampdu_depth >= ATH_AGGR_MIN_QDEPTH)
+                       return;
+       }
+}
+
+/***********/
+/* TX, DMA */
+/***********/
+
+/*
+ * Insert a chain of ath_buf (descriptors) on a txq and
+ * assume the descriptors are already chained together by caller.
+ */
+static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq,
+                            struct list_head *head)
+{
+       struct ath_hw *ah = sc->sc_ah;
+       struct ath_buf *bf;
+
+       /*
+        * Insert the frame on the outbound list and
+        * pass it on to the hardware.
+        */
+
+       if (list_empty(head))
+               return;
+
+       bf = list_first_entry(head, struct ath_buf, list);
+
+       DBGIO("ath9k: "
+               "qnum: %d, txq depth: %d\n", txq->axq_qnum, txq->axq_depth);
+
+       list_splice_tail_init(head, &txq->axq_q);
+
+       if (txq->axq_link == NULL) {
+               ath9k_hw_puttxbuf(ah, txq->axq_qnum, bf->bf_daddr);
+               DBGIO("ath9k: TXDP[%d] = %llx (%p)\n",
+                       txq->axq_qnum, ito64(bf->bf_daddr),
+                       bf->bf_desc);
+       } else {
+               *txq->axq_link = bf->bf_daddr;
+               DBGIO("ath9k: "
+                       "link[%d] (%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);
+
+       txq->axq_depth++;
+}
+
+static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq,
+                              struct ath_atx_tid *tid,
+                              struct list_head *bf_head)
+{
+       struct ath_buf *bf;
+
+       bf = list_first_entry(bf_head, struct ath_buf, list);
+       bf->bf_state.bf_type &= ~BUF_AMPDU;
+
+       /* update starting sequence number for subsequent ADDBA request */
+       if (tid)
+               INCR(tid->seq_start, IEEE80211_SEQ_MAX);
+
+       bf->bf_lastbf = bf;
+       ath_buf_set_rate(sc, bf, iob_len(bf->bf_mpdu) + FCS_LEN);
+       ath_tx_txqaddbuf(sc, txq, bf_head);
+}
+
+static enum ath9k_pkt_type get_hw_packet_type(struct io_buffer *iob)
+{
+       struct ieee80211_frame *hdr;
+       enum ath9k_pkt_type htype;
+       u16 fc;
+
+       hdr = (struct ieee80211_frame *)iob->data;
+       fc = hdr->fc;
+
+       if ((fc & (IEEE80211_FC_TYPE | IEEE80211_FC_SUBTYPE)) == (IEEE80211_TYPE_MGMT | IEEE80211_STYPE_BEACON))
+               htype = ATH9K_PKT_TYPE_BEACON;
+       else if ((fc & (IEEE80211_FC_TYPE | IEEE80211_FC_SUBTYPE)) == (IEEE80211_TYPE_MGMT | IEEE80211_STYPE_PROBE_RESP))
+               htype = ATH9K_PKT_TYPE_PROBE_RESP;
+       else
+               htype = ATH9K_PKT_TYPE_NORMAL;
+
+       return htype;
+}
+
+static int setup_tx_flags(struct io_buffer *iob __unused)
+{
+       int flags = 0;
+
+       flags |= ATH9K_TXDESC_INTREQ;
+
+       return flags;
+}
+
+u8 ath_txchainmask_reduction(struct ath_softc *sc, u8 chainmask, u32 rate)
+{
+       struct ath_hw *ah = sc->sc_ah;
+       struct ath9k_channel *curchan = ah->curchan;
+       if ((sc->sc_flags & SC_OP_ENABLE_APM) &&
+                       (curchan->channelFlags & CHANNEL_5GHZ) &&
+                       (chainmask == 0x7) && (rate < 0x90))
+               return 0x3;
+       else
+               return chainmask;
+}
+
+static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, int len)
+{
+       struct ath_common *common = ath9k_hw_common(sc->sc_ah);
+       struct ath9k_11n_rate_series series[4];
+       const struct ath9k_legacy_rate *rate;
+       int i, flags = 0;
+       u8 rix = 0, ctsrate = 0;
+       int is_pspoll;
+
+       memset(series, 0, sizeof(struct ath9k_11n_rate_series) * 4);
+
+       is_pspoll = 0;
+
+       /*
+        * We check if Short Preamble is needed for the CTS rate by
+        * checking the BSS's global flag.
+        * But for the rate series, IEEE80211_TX_RC_USE_SHORT_PREAMBLE is used.
+        */
+       rate = &sc->rates[sc->hw_rix];
+       ctsrate = rate->hw_value;
+       if (sc->sc_flags & SC_OP_PREAMBLE_SHORT)
+               ctsrate |= rate->hw_value_short;
+
+       for (i = 0; i < 4; i++) {
+               int is_40 __unused, is_sgi __unused, is_sp;
+               int phy;
+
+               rix = sc->hw_rix;
+               series[i].Tries = ATH_TXMAXTRY;
+
+               if (sc->sc_flags & SC_OP_PROTECT_ENABLE) {
+                       series[i].RateFlags |= ATH9K_RATESERIES_RTS_CTS;
+                       flags |= ATH9K_TXDESC_CTSENA;
+               }
+
+               is_sp = !!(rate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE);
+
+               /* legacy rates */
+               if ((sc->dev->channels + sc->dev->channel)->band == NET80211_BAND_2GHZ)
+                       phy = CHANNEL_CCK;
+               else
+                       phy = CHANNEL_OFDM;
+
+               series[i].Rate = rate->hw_value;
+               if (rate->hw_value_short && (sc->sc_flags & SC_OP_PREAMBLE_SHORT)) {
+                       if (rate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
+                               series[i].Rate |= rate->hw_value_short;
+               } else {
+                       is_sp = 0;
+               }
+
+               if (bf->bf_state.bfs_paprd)
+                       series[i].ChSel = common->tx_chainmask;
+               else
+                       series[i].ChSel = ath_txchainmask_reduction(sc,
+                                       common->tx_chainmask, series[i].Rate);
+
+               series[i].PktDuration = ath9k_hw_computetxtime(sc->sc_ah,
+                       phy, rate->bitrate * 100, len, rix, is_sp);
+       }
+
+       /* For AR5416 - RTS cannot be followed by a frame larger than 8K */
+       if (bf_isaggr(bf) && (len > sc->sc_ah->caps.rts_aggr_limit))
+               flags &= ~ATH9K_TXDESC_RTSENA;
+
+       /* ATH9K_TXDESC_RTSENA and ATH9K_TXDESC_CTSENA are mutually exclusive. */
+       if (flags & ATH9K_TXDESC_RTSENA)
+               flags &= ~ATH9K_TXDESC_CTSENA;
+
+       /* set dur_update_en for l-sig computation except for PS-Poll frames */
+       ath9k_hw_set11n_ratescenario(sc->sc_ah, bf->bf_desc,
+                                    bf->bf_lastbf->bf_desc,
+                                    !is_pspoll, ctsrate,
+                                    0, series, 4, flags);
+
+}
+
+static struct ath_buf *ath_tx_setup_buffer(struct net80211_device *dev,
+                                          struct ath_txq *txq,
+                                          struct io_buffer *iob)
+{
+       struct ath_softc *sc = dev->priv;
+       struct ath_hw *ah = sc->sc_ah;
+       struct ath_buf *bf;
+       struct ath_desc *ds;
+       int frm_type;
+       static const enum ath9k_key_type net80211_keytype_to_ath[] = {
+                       [NET80211_CRYPT_NONE] = ATH9K_KEY_TYPE_CLEAR,
+                       [NET80211_CRYPT_WEP] = ATH9K_KEY_TYPE_WEP,
+                       [NET80211_CRYPT_TKIP] = ATH9K_KEY_TYPE_TKIP,
+                       [NET80211_CRYPT_CCMP] = ATH9K_KEY_TYPE_AES,
+                       [NET80211_CRYPT_UNKNOWN] = ATH9K_KEY_TYPE_CLEAR,
+       };
+
+       bf = ath_tx_get_buffer(sc);
+       if (!bf) {
+               DBG("ath9k: TX buffers are full\n");
+               return NULL;
+       }
+
+       ATH_TXBUF_RESET(bf);
+
+       bf->bf_flags = setup_tx_flags(iob);
+       bf->bf_mpdu = iob;
+
+       bf->bf_buf_addr = virt_to_bus(iob->data);
+
+       frm_type = get_hw_packet_type(iob);
+
+       ds = bf->bf_desc;
+       ath9k_hw_set_desc_link(ah, ds, 0);
+
+       ath9k_hw_set11n_txdesc(ah, ds, iob_len(iob) + FCS_LEN, frm_type, MAX_RATE_POWER,
+                              ATH9K_TXKEYIX_INVALID, net80211_keytype_to_ath[dev->crypto->algorithm], bf->bf_flags);
+
+       ath9k_hw_filltxdesc(ah, ds,
+                           iob_len(iob),       /* segment length */
+                           1,          /* first segment */
+                           1,          /* last segment */
+                           ds,         /* first descriptor */
+                           bf->bf_buf_addr,
+                           txq->axq_qnum);
+
+
+       return bf;
+}
+
+/* FIXME: tx power */
+static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf,
+                            struct ath_tx_control *txctl)
+{
+       struct list_head bf_head;
+       struct ath_atx_tid *tid = NULL;
+
+       INIT_LIST_HEAD(&bf_head);
+       list_add_tail(&bf->list, &bf_head);
+
+       bf->bf_state.bfs_paprd = txctl->paprd;
+
+       if (txctl->paprd)
+               bf->bf_state.bfs_paprd_timestamp = ( currticks() * 1000 ) / TICKS_PER_SEC;
+
+       ath9k_hw_set_clrdmask(sc->sc_ah, bf->bf_desc, 1);
+
+       ath_tx_send_normal(sc, txctl->txq, tid, &bf_head);
+}
+
+/* Upon failure caller should free iob */
+int ath_tx_start(struct net80211_device *dev, struct io_buffer *iob,
+                struct ath_tx_control *txctl)
+{
+       struct ath_softc *sc = dev->priv;
+       struct ath_txq *txq = txctl->txq;
+       struct ath_buf *bf;
+       int q;
+
+       /*
+        * At this point, the vif, hw_key and sta pointers in the tx control
+        * info are no longer valid (overwritten by the ath_frame_info data.
+        */
+
+       bf = ath_tx_setup_buffer(dev, txctl->txq, iob);
+       if (!bf)
+               return -ENOMEM;
+
+       q = 0;
+       if (txq == sc->tx.txq_map[q] &&
+           ++txq->pending_frames > ATH_MAX_QDEPTH && !txq->stopped) {
+               txq->stopped = 1;
+       }
+
+       ath_tx_start_dma(sc, bf, txctl);
+
+       return 0;
+}
+
+/*****************/
+/* TX Completion */
+/*****************/
+
+static void ath_tx_complete(struct ath_softc *sc, struct io_buffer *iob,
+                           int tx_flags __unused, struct ath_tx_status *ts, struct ath_txq *txq)
+{
+       struct net80211_device *dev = sc->dev;
+       int q, padpos __unused, padsize __unused;
+
+       DBGIO("ath9k: TX complete: iob: %p\n", iob);
+
+       q = 0;
+       if (txq == sc->tx.txq_map[q]) {
+               if (--txq->pending_frames < 0)
+                       txq->pending_frames = 0;
+
+               if (txq->stopped && txq->pending_frames < ATH_MAX_QDEPTH) {
+                       txq->stopped = 0;
+               }
+       }
+
+       net80211_tx_complete(dev, iob, ts->ts_longretry,
+                       (ts->ts_status & ATH9K_TXERR_MASK) ? EIO : 0);
+}
+
+static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
+                               struct ath_txq *txq, struct list_head *bf_q,
+                               struct ath_tx_status *ts, int txok, int sendbar)
+{
+       struct io_buffer *iob = bf->bf_mpdu;
+       int tx_flags = 0;
+
+       if (sendbar)
+               tx_flags = ATH_TX_BAR;
+
+       if (!txok) {
+               tx_flags |= ATH_TX_ERROR;
+
+               if (bf_isxretried(bf))
+                       tx_flags |= ATH_TX_XRETRY;
+       }
+
+       bf->bf_buf_addr = 0;
+
+       ath_tx_complete(sc, iob, tx_flags,
+                       ts, txq);
+
+       /* At this point, iob (bf->bf_mpdu) is consumed...make sure we don't
+        * accidentally reference it later.
+        */
+       bf->bf_mpdu = NULL;
+
+       /*
+        * Return the list of ath_buf of this mpdu to free queue
+        */
+       list_splice_tail_init(bf_q, &sc->tx.txbuf);
+}
+
+static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
+{
+       struct ath_hw *ah = sc->sc_ah;
+       struct ath_buf *bf, *lastbf, *bf_held = NULL;
+       struct list_head bf_head;
+       struct ath_desc *ds;
+       struct ath_tx_status ts;
+       int txok;
+       int status;
+
+       DBGIO("ath9k: tx queue %d (%x), link %p\n",
+               txq->axq_qnum, ath9k_hw_gettxbuf(sc->sc_ah, txq->axq_qnum),
+               txq->axq_link);
+
+       for (;;) {
+               if (list_empty(&txq->axq_q)) {
+                       txq->axq_link = NULL;
+                       if (sc->sc_flags & SC_OP_TXAGGR)
+                               ath_txq_schedule(sc, txq);
+                       break;
+               }
+               bf = list_first_entry(&txq->axq_q, struct ath_buf, list);
+
+               /*
+                * There is a race condition that a BH gets scheduled
+                * after sw writes TxE and before hw re-load the last
+                * descriptor to get the newly chained one.
+                * Software must keep the last DONE descriptor as a
+                * holding descriptor - software does so by marking
+                * it with the STALE flag.
+                */
+               bf_held = NULL;
+               if (bf->bf_stale) {
+                       bf_held = bf;
+                       if (list_is_last(&bf_held->list, &txq->axq_q)) {
+                               break;
+                       } else {
+                               bf = list_entry(bf_held->list.next,
+                                               struct ath_buf, list);
+                       }
+               }
+
+               lastbf = bf->bf_lastbf;
+               ds = lastbf->bf_desc;
+
+               memset(&ts, 0, sizeof(ts));
+               status = ath9k_hw_txprocdesc(ah, ds, &ts);
+               if (status == -EINPROGRESS) {
+                       break;
+               }
+
+               /*
+                * Remove ath_buf's of the same transmit unit from txq,
+                * however leave the last descriptor back as the holding
+                * descriptor for hw.
+                */
+               lastbf->bf_stale = 1;
+               INIT_LIST_HEAD(&bf_head);
+               if (!list_is_singular(&lastbf->list))
+                       list_cut_position(&bf_head,
+                               &txq->axq_q, lastbf->list.prev);
+
+               txq->axq_depth--;
+               txok = !(ts.ts_status & ATH9K_TXERR_MASK);
+               txq->axq_tx_inprogress = 0;
+               if (bf_held)
+                       list_del(&bf_held->list);
+
+               if (bf_held)
+                       ath_tx_return_buffer(sc, bf_held);
+
+               /*
+                * This frame is sent out as a single frame.
+                * Use hardware retry status for this frame.
+                */
+               if (ts.ts_status & ATH9K_TXERR_XRETRY)
+                       bf->bf_state.bf_type |= BUF_XRETRY;
+
+               ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, txok, 0);
+
+               if (sc->sc_flags & SC_OP_TXAGGR)
+                       ath_txq_schedule(sc, txq);
+       }
+}
+
+static void ath_tx_complete_poll_work(struct ath_softc *sc)
+{
+       struct ath_txq *txq;
+       int i;
+       int needreset = 0;
+
+       for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
+               if (ATH_TXQ_SETUP(sc, i)) {
+                       txq = &sc->tx.txq[i];
+                       if (txq->axq_depth) {
+                               if (txq->axq_tx_inprogress) {
+                                       needreset = 1;
+                                       break;
+                               } else {
+                                       txq->axq_tx_inprogress = 1;
+                               }
+                       }
+               }
+
+       if (needreset) {
+               DBG("ath9k: "
+                       "tx hung, resetting the chip\n");
+               ath_reset(sc, 1);
+       }
+
+       sc->tx_complete_work_timer = ( currticks() * 1000 ) / TICKS_PER_SEC + ATH_TX_COMPLETE_POLL_INT;
+}
+
+
+
+void ath_tx_tasklet(struct ath_softc *sc)
+{
+       int i;
+       u32 qcumask = ((1 << ATH9K_NUM_TX_QUEUES) - 1);
+
+       ath9k_hw_gettxintrtxqs(sc->sc_ah, &qcumask);
+
+       for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
+               if (ATH_TXQ_SETUP(sc, i) && (qcumask & (1 << i)))
+                       ath_tx_processq(sc, &sc->tx.txq[i]);
+       }
+}
+
+/*****************/
+/* Init, Cleanup */
+/*****************/
+
+int ath_tx_init(struct ath_softc *sc, int nbufs)
+{
+       int error = 0;
+
+       error = ath_descdma_setup(sc, &sc->tx.txdma, &sc->tx.txbuf,
+                                 "tx", nbufs, 1, 1);
+       if (error != 0) {
+               DBG("ath9k: "
+                       "Failed to allocate tx descriptors: %d\n", error);
+               goto err;
+       }
+
+       sc->tx_complete_work = ath_tx_complete_poll_work;
+
+err:
+       if (error != 0)
+               ath_tx_cleanup(sc);
+
+       return error;
+}
+
+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);
+}
diff --git a/src/drivers/net/ath/ath9k/calib.h b/src/drivers/net/ath/ath9k/calib.h
new file mode 100644 (file)
index 0000000..5bf50f4
--- /dev/null
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2008-2011 Atheros Communications Inc.
+ *
+ * Modified for iPXE by Scott K Logan <logans@cottsay.net> July 2011
+ * Original from Linux kernel 3.0.1
+ *
+ * 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 CALIB_H
+#define CALIB_H
+
+#include "hw.h"
+
+#define AR_PHY_CCA_FILTERWINDOW_LENGTH_INIT     3
+#define AR_PHY_CCA_FILTERWINDOW_LENGTH          5
+
+#define NUM_NF_READINGS       6
+#define ATH9K_NF_CAL_HIST_MAX 5
+
+struct ar5416IniArray {
+       u32 *ia_array;
+       u32 ia_rows;
+       u32 ia_columns;
+};
+
+#define INIT_INI_ARRAY(iniarray, array, rows, columns) do {    \
+               (iniarray)->ia_array = (u32 *)(array);          \
+               (iniarray)->ia_rows = (rows);                   \
+               (iniarray)->ia_columns = (columns);             \
+       } while (0)
+
+#define INI_RA(iniarray, row, column) \
+       (((iniarray)->ia_array)[(row) * ((iniarray)->ia_columns) + (column)])
+
+#define INIT_CAL(_perCal) do {                         \
+               (_perCal)->calState = CAL_WAITING;      \
+               (_perCal)->calNext = NULL;              \
+       } while (0)
+
+#define INSERT_CAL(_ahp, _perCal)                                      \
+       do {                                                            \
+               if ((_ahp)->cal_list_last == NULL) {                    \
+                       (_ahp)->cal_list =                              \
+                               (_ahp)->cal_list_last = (_perCal);      \
+                       ((_ahp)->cal_list_last)->calNext = (_perCal); \
+               } else {                                                \
+                       ((_ahp)->cal_list_last)->calNext = (_perCal); \
+                       (_ahp)->cal_list_last = (_perCal);              \
+                       (_perCal)->calNext = (_ahp)->cal_list;  \
+               }                                                       \
+       } while (0)
+
+enum ath9k_cal_state {
+       CAL_INACTIVE,
+       CAL_WAITING,
+       CAL_RUNNING,
+       CAL_DONE
+};
+
+#define MIN_CAL_SAMPLES     1
+#define MAX_CAL_SAMPLES    64
+#define INIT_LOG_COUNT      5
+#define PER_MIN_LOG_COUNT   2
+#define PER_MAX_LOG_COUNT  10
+
+struct ath9k_percal_data {
+       u32 calType;
+       u32 calNumSamples;
+       u32 calCountMax;
+       void (*calCollect) (struct ath_hw *);
+       void (*calPostProc) (struct ath_hw *, u8);
+};
+
+struct ath9k_cal_list {
+       const struct ath9k_percal_data *calData;
+       enum ath9k_cal_state calState;
+       struct ath9k_cal_list *calNext;
+};
+
+struct ath9k_nfcal_hist {
+       int16_t nfCalBuffer[ATH9K_NF_CAL_HIST_MAX];
+       u8 currIndex;
+       int16_t privNF;
+       u8 invalidNFcount;
+};
+
+#define MAX_PACAL_SKIPCOUNT 8
+struct ath9k_pacal_info{
+       int32_t prev_offset;    /* Previous value of PA offset value */
+       int8_t max_skipcount;   /* Max No. of times PACAL can be skipped */
+       int8_t skipcount;       /* No. of times the PACAL to be skipped */
+};
+
+int ath9k_hw_reset_calvalid(struct ath_hw *ah);
+void ath9k_hw_start_nfcal(struct ath_hw *ah, int update);
+void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan);
+int ath9k_hw_getnf(struct ath_hw *ah, struct ath9k_channel *chan);
+void ath9k_init_nfcal_hist_buffer(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 */
diff --git a/src/drivers/net/ath/ath9k/common.h b/src/drivers/net/ath/ath9k/common.h
new file mode 100644 (file)
index 0000000..009f803
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2009-2011 Atheros Communications Inc.
+ *
+ * Modified for iPXE by Scott K Logan <logans@cottsay.net> July 2011
+ * Original from Linux kernel 3.0.1
+ *
+ * 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 "../ath.h"
+
+#include "hw.h"
+#include "hw-ops.h"
+
+/* Common header for Atheros 802.11n base driver cores */
+
+#define WME_NUM_TID             16
+#define WME_BA_BMP_SIZE         64
+#define WME_MAX_BA              WME_BA_BMP_SIZE
+#define ATH_TID_MAX_BUFS        (2 * WME_MAX_BA)
+
+#define WME_AC_BE   2
+#define WME_NUM_AC  1
+
+#define ATH_RSSI_DUMMY_MARKER   0x127
+#define ATH_RSSI_LPF_LEN               10
+#define RSSI_LPF_THRESHOLD             -20
+#define ATH_RSSI_EP_MULTIPLIER     (1<<7)
+#define ATH_EP_MUL(x, mul)         ((x) * (mul))
+#define ATH_RSSI_IN(x)             (ATH_EP_MUL((x), ATH_RSSI_EP_MULTIPLIER))
+#define ATH_LPF_RSSI(x, y, len) \
+    ((x != ATH_RSSI_DUMMY_MARKER) ? (((x) * ((len) - 1) + (y)) / (len)) : (y))
+#define ATH_RSSI_LPF(x, y) do {                                        \
+    if ((y) >= RSSI_LPF_THRESHOLD)                                     \
+       x = ATH_LPF_RSSI((x), ATH_RSSI_IN((y)), ATH_RSSI_LPF_LEN);      \
+} while (0)
+#define ATH_EP_RND(x, mul)                                             \
+       ((((x)%(mul)) >= ((mul)/2)) ? ((x) + ((mul) - 1)) / (mul) : (x)/(mul))
+
+
+void ath9k_cmn_update_ichannel(struct ath9k_channel *ichan,
+                              struct net80211_channel *chan);
+struct ath9k_channel *ath9k_cmn_get_curchannel(struct net80211_device *dev,
+                                              struct ath_hw *ah);
+void ath9k_cmn_update_txpow(struct ath_hw *ah, u16 cur_txpow,
+                           u16 new_txpow, u16 *txpower);
diff --git a/src/drivers/net/ath/ath9k/eeprom.h b/src/drivers/net/ath/ath9k/eeprom.h
new file mode 100644 (file)
index 0000000..b451ebd
--- /dev/null
@@ -0,0 +1,714 @@
+/*
+ * Copyright (c) 2008-2011 Atheros Communications Inc.
+ *
+ * Modified for iPXE by Scott K Logan <logans@cottsay.net> July 2011
+ * Original from Linux kernel 3.0.1
+ *
+ * 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 EEPROM_H
+#define EEPROM_H
+
+#define AR_EEPROM_MODAL_SPURS   5
+
+#include "../ath.h"
+#include "ar9003_eeprom.h"
+
+#if __BYTE_ORDER == __BIG_ENDIAN
+#define AR5416_EEPROM_MAGIC 0x5aa5
+#else
+#define AR5416_EEPROM_MAGIC 0xa55a
+#endif
+
+#define CTRY_DEBUG   0x1ff
+#define        CTRY_DEFAULT 0
+
+#define AR_EEPROM_EEPCAP_COMPRESS_DIS   0x0001
+#define AR_EEPROM_EEPCAP_AES_DIS        0x0002
+#define AR_EEPROM_EEPCAP_FASTFRAME_DIS  0x0004
+#define AR_EEPROM_EEPCAP_BURST_DIS      0x0008
+#define AR_EEPROM_EEPCAP_MAXQCU         0x01F0
+#define AR_EEPROM_EEPCAP_MAXQCU_S       4
+#define AR_EEPROM_EEPCAP_HEAVY_CLIP_EN  0x0200
+#define AR_EEPROM_EEPCAP_KC_ENTRIES     0xF000
+#define AR_EEPROM_EEPCAP_KC_ENTRIES_S   12
+
+#define AR_EEPROM_EEREGCAP_EN_FCC_MIDBAND   0x0040
+#define AR_EEPROM_EEREGCAP_EN_KK_U1_EVEN    0x0080
+#define AR_EEPROM_EEREGCAP_EN_KK_U2         0x0100
+#define AR_EEPROM_EEREGCAP_EN_KK_MIDBAND    0x0200
+#define AR_EEPROM_EEREGCAP_EN_KK_U1_ODD     0x0400
+#define AR_EEPROM_EEREGCAP_EN_KK_NEW_11A    0x0800
+
+#define AR_EEPROM_EEREGCAP_EN_KK_U1_ODD_PRE4_0  0x4000
+#define AR_EEPROM_EEREGCAP_EN_KK_NEW_11A_PRE4_0 0x8000
+
+#define AR5416_EEPROM_MAGIC_OFFSET  0x0
+#define AR5416_EEPROM_S             2
+#define AR5416_EEPROM_OFFSET        0x2000
+#define AR5416_EEPROM_MAX           0xae0
+
+#define AR5416_EEPROM_START_ADDR \
+       (AR_SREV_9100(ah)) ? 0x1fff1000 : 0x503f1200
+
+#define SD_NO_CTL               0xE0
+#define NO_CTL                  0xff
+#define CTL_MODE_M              0xf
+#define CTL_11A                 0
+#define CTL_11B                 1
+#define CTL_11G                 2
+#define CTL_2GHT20              5
+#define CTL_5GHT20              6
+#define CTL_2GHT40              7
+#define CTL_5GHT40              8
+
+#define EXT_ADDITIVE (0x8000)
+#define CTL_11A_EXT (CTL_11A | EXT_ADDITIVE)
+#define CTL_11G_EXT (CTL_11G | EXT_ADDITIVE)
+#define CTL_11B_EXT (CTL_11B | EXT_ADDITIVE)
+
+#define SUB_NUM_CTL_MODES_AT_5G_40 2
+#define SUB_NUM_CTL_MODES_AT_2G_40 3
+
+#define INCREASE_MAXPOW_BY_TWO_CHAIN     6  /* 10*log10(2)*2 */
+#define INCREASE_MAXPOW_BY_THREE_CHAIN   10 /* 10*log10(3)*2 */
+
+/*
+ * For AR9285 and later chipsets, the following bits are not being programmed
+ * in EEPROM and so need to be enabled always.
+ *
+ * Bit 0: en_fcc_mid
+ * Bit 1: en_jap_mid
+ * Bit 2: en_fcc_dfs_ht40
+ * Bit 3: en_jap_ht40
+ * Bit 4: en_jap_dfs_ht40
+ */
+#define AR9285_RDEXT_DEFAULT    0x1F
+
+#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_VER_MASK (eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK)
+#define OLC_FOR_AR9280_20_LATER (AR_SREV_9280_20_OR_LATER(ah) && \
+                                ah->eep_ops->get_eeprom(ah, EEP_OL_PWRCTRL))
+#define OLC_FOR_AR9287_10_LATER (AR_SREV_9287_11_OR_LATER(ah) && \
+                                ah->eep_ops->get_eeprom(ah, EEP_OL_PWRCTRL))
+
+#define AR_EEPROM_RFSILENT_GPIO_SEL     0x001c
+#define AR_EEPROM_RFSILENT_GPIO_SEL_S   2
+#define AR_EEPROM_RFSILENT_POLARITY     0x0002
+#define AR_EEPROM_RFSILENT_POLARITY_S   1
+
+#define EEP_RFSILENT_ENABLED        0x0001
+#define EEP_RFSILENT_ENABLED_S      0
+#define EEP_RFSILENT_POLARITY       0x0002
+#define EEP_RFSILENT_POLARITY_S     1
+#define EEP_RFSILENT_GPIO_SEL       0x001c
+#define EEP_RFSILENT_GPIO_SEL_S     2
+
+#define AR5416_OPFLAGS_11A           0x01
+#define AR5416_OPFLAGS_11G           0x02
+#define AR5416_OPFLAGS_N_5G_HT40     0x04
+#define AR5416_OPFLAGS_N_2G_HT40     0x08
+#define AR5416_OPFLAGS_N_5G_HT20     0x10
+#define AR5416_OPFLAGS_N_2G_HT20     0x20
+
+#define AR5416_EEP_NO_BACK_VER       0x1
+#define AR5416_EEP_VER               0xE
+#define AR5416_EEP_VER_MINOR_MASK    0x0FFF
+#define AR5416_EEP_MINOR_VER_2       0x2
+#define AR5416_EEP_MINOR_VER_3       0x3
+#define AR5416_EEP_MINOR_VER_7       0x7
+#define AR5416_EEP_MINOR_VER_9       0x9
+#define AR5416_EEP_MINOR_VER_16      0x10
+#define AR5416_EEP_MINOR_VER_17      0x11
+#define AR5416_EEP_MINOR_VER_19      0x13
+#define AR5416_EEP_MINOR_VER_20      0x14
+#define AR5416_EEP_MINOR_VER_21      0x15
+#define AR5416_EEP_MINOR_VER_22      0x16
+
+#define AR5416_NUM_5G_CAL_PIERS         8
+#define AR5416_NUM_2G_CAL_PIERS         4
+#define AR5416_NUM_5G_20_TARGET_POWERS  8
+#define AR5416_NUM_5G_40_TARGET_POWERS  8
+#define AR5416_NUM_2G_CCK_TARGET_POWERS 3
+#define AR5416_NUM_2G_20_TARGET_POWERS  4
+#define AR5416_NUM_2G_40_TARGET_POWERS  4
+#define AR5416_NUM_CTLS                 24
+#define AR5416_NUM_BAND_EDGES           8
+#define AR5416_NUM_PD_GAINS             4
+#define AR5416_PD_GAINS_IN_MASK         4
+#define AR5416_PD_GAIN_ICEPTS           5
+#define AR5416_NUM_PDADC_VALUES         128
+#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 */
+#define AR5416_EEP_RXGAIN_23DB_BACKOFF     0
+#define AR5416_EEP_RXGAIN_13DB_BACKOFF     1
+#define AR5416_EEP_RXGAIN_ORIG             2
+
+/* Tx gain type values */
+#define AR5416_EEP_TXGAIN_ORIGINAL         0
+#define AR5416_EEP_TXGAIN_HIGH_POWER       1
+
+#define AR5416_EEP4K_START_LOC                64
+#define AR5416_EEP4K_NUM_2G_CAL_PIERS         3
+#define AR5416_EEP4K_NUM_2G_CCK_TARGET_POWERS 3
+#define AR5416_EEP4K_NUM_2G_20_TARGET_POWERS  3
+#define AR5416_EEP4K_NUM_2G_40_TARGET_POWERS  3
+#define AR5416_EEP4K_NUM_CTLS                 12
+#define AR5416_EEP4K_NUM_BAND_EDGES           4
+#define AR5416_EEP4K_NUM_PD_GAINS             2
+#define AR5416_EEP4K_MAX_CHAINS               1
+
+#define AR9280_TX_GAIN_TABLE_SIZE 22
+
+#define AR9287_EEP_VER               0xE
+#define AR9287_EEP_VER_MINOR_MASK    0xFFF
+#define AR9287_EEP_MINOR_VER_1       0x1
+#define AR9287_EEP_MINOR_VER_2       0x2
+#define AR9287_EEP_MINOR_VER_3       0x3
+#define AR9287_EEP_MINOR_VER         AR9287_EEP_MINOR_VER_3
+#define AR9287_EEP_MINOR_VER_b       AR9287_EEP_MINOR_VER
+#define AR9287_EEP_NO_BACK_VER       AR9287_EEP_MINOR_VER_1
+
+#define AR9287_EEP_START_LOC            128
+#define AR9287_HTC_EEP_START_LOC        256
+#define AR9287_NUM_2G_CAL_PIERS         3
+#define AR9287_NUM_2G_CCK_TARGET_POWERS 3
+#define AR9287_NUM_2G_20_TARGET_POWERS  3
+#define AR9287_NUM_2G_40_TARGET_POWERS  3
+#define AR9287_NUM_CTLS                12
+#define AR9287_NUM_BAND_EDGES          4
+#define AR9287_PD_GAIN_ICEPTS           1
+#define AR9287_EEPMISC_BIG_ENDIAN       0x01
+#define AR9287_EEPMISC_WOW              0x02
+#define AR9287_MAX_CHAINS               2
+#define AR9287_ANT_16S                  32
+
+#define AR9287_DATA_SZ                  32
+
+#define AR9287_PWR_TABLE_OFFSET_DB  -5
+
+#define AR9287_CHECKSUM_LOCATION (AR9287_EEP_START_LOC + 1)
+
+#define CTL_EDGE_TPOWER(_ctl) ((_ctl) & 0x3f)
+#define CTL_EDGE_FLAGS(_ctl) (((_ctl) >> 6) & 0x03)
+
+#define LNA_CTL_BUF_MODE       BIT(0)
+#define LNA_CTL_ISEL_LO                BIT(1)
+#define LNA_CTL_ISEL_HI                BIT(2)
+#define LNA_CTL_BUF_IN         BIT(3)
+#define LNA_CTL_FEM_BAND       BIT(4)
+#define LNA_CTL_LOCAL_BIAS     BIT(5)
+#define LNA_CTL_FORCE_XPA      BIT(6)
+#define LNA_CTL_USE_ANT1       BIT(7)
+
+enum eeprom_param {
+       EEP_NFTHRESH_5,
+       EEP_NFTHRESH_2,
+       EEP_MAC_MSW,
+       EEP_MAC_MID,
+       EEP_MAC_LSW,
+       EEP_REG_0,
+       EEP_REG_1,
+       EEP_OP_CAP,
+       EEP_OP_MODE,
+       EEP_RF_SILENT,
+       EEP_OB_5,
+       EEP_DB_5,
+       EEP_OB_2,
+       EEP_DB_2,
+       EEP_MINOR_REV,
+       EEP_TX_MASK,
+       EEP_RX_MASK,
+       EEP_FSTCLK_5G,
+       EEP_RXGAIN_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_DRIVE_STRENGTH,
+       EEP_INTERNAL_REGULATOR,
+       EEP_SWREG,
+       EEP_PAPRD,
+       EEP_MODAL_VER,
+       EEP_ANT_DIV_CTL1,
+       EEP_CHAIN_MASK_REDUCE
+};
+
+enum ar5416_rates {
+       rate6mb, rate9mb, rate12mb, rate18mb,
+       rate24mb, rate36mb, rate48mb, rate54mb,
+       rate1l, rate2l, rate2s, rate5_5l,
+       rate5_5s, rate11l, rate11s, rateXr,
+       rateHt20_0, rateHt20_1, rateHt20_2, rateHt20_3,
+       rateHt20_4, rateHt20_5, rateHt20_6, rateHt20_7,
+       rateHt40_0, rateHt40_1, rateHt40_2, rateHt40_3,
+       rateHt40_4, rateHt40_5, rateHt40_6, rateHt40_7,
+       rateDupCck, rateDupOfdm, rateExtCck, rateExtOfdm,
+       Ar5416RateSize
+};
+
+enum ath9k_hal_freq_band {
+       ATH9K_HAL_FREQ_BAND_5GHZ = 0,
+       ATH9K_HAL_FREQ_BAND_2GHZ = 1
+};
+
+struct base_eep_header {
+       u16 length;
+       u16 checksum;
+       u16 version;
+       u8 opCapFlags;
+       u8 eepMisc;
+       u16 regDmn[2];
+       u8 macAddr[6];
+       u8 rxMask;
+       u8 txMask;
+       u16 rfSilent;
+       u16 blueToothOptions;
+       u16 deviceCap;
+       u32 binBuildNumber;
+       u8 deviceType;
+       u8 pwdclkind;
+       u8 fastClk5g;
+       u8 divChain;
+       u8 rxGainType;
+       u8 dacHiPwrMode_5G;
+       u8 openLoopPwrCntl;
+       u8 dacLpMode;
+       u8 txGainType;
+       u8 rcChainMask;
+       u8 desiredScaleCCK;
+       u8 pwr_table_offset;
+       u8 frac_n_5g;
+       u8 futureBase_3[21];
+} __attribute__((packed));
+
+struct base_eep_header_4k {
+       u16 length;
+       u16 checksum;
+       u16 version;
+       u8 opCapFlags;
+       u8 eepMisc;
+       u16 regDmn[2];
+       u8 macAddr[6];
+       u8 rxMask;
+       u8 txMask;
+       u16 rfSilent;
+       u16 blueToothOptions;
+       u16 deviceCap;
+       u32 binBuildNumber;
+       u8 deviceType;
+       u8 txGainType;
+} __attribute__((packed));
+
+
+struct spur_chan {
+       u16 spurChan;
+       u8 spurRangeLow;
+       u8 spurRangeHigh;
+} __attribute__((packed));
+
+struct modal_eep_header {
+       u32 antCtrlChain[AR5416_MAX_CHAINS];
+       u32 antCtrlCommon;
+       u8 antennaGainCh[AR5416_MAX_CHAINS];
+       u8 switchSettling;
+       u8 txRxAttenCh[AR5416_MAX_CHAINS];
+       u8 rxTxMarginCh[AR5416_MAX_CHAINS];
+       u8 adcDesiredSize;
+       u8 pgaDesiredSize;
+       u8 xlnaGainCh[AR5416_MAX_CHAINS];
+       u8 txEndToXpaOff;
+       u8 txEndToRxOn;
+       u8 txFrameToXpaOn;
+       u8 thresh62;
+       u8 noiseFloorThreshCh[AR5416_MAX_CHAINS];
+       u8 xpdGain;
+       u8 xpd;
+       u8 iqCalICh[AR5416_MAX_CHAINS];
+       u8 iqCalQCh[AR5416_MAX_CHAINS];
+       u8 pdGainOverlap;
+       u8 ob;
+       u8 db;
+       u8 xpaBiasLvl;
+       u8 pwrDecreaseFor2Chain;
+       u8 pwrDecreaseFor3Chain;
+       u8 txFrameToDataStart;
+       u8 txFrameToPaOn;
+       u8 ht40PowerIncForPdadc;
+       u8 bswAtten[AR5416_MAX_CHAINS];
+       u8 bswMargin[AR5416_MAX_CHAINS];
+       u8 swSettleHt40;
+       u8 xatten2Db[AR5416_MAX_CHAINS];
+       u8 xatten2Margin[AR5416_MAX_CHAINS];
+       u8 ob_ch1;
+       u8 db_ch1;
+       u8 lna_ctl;
+       u8 miscBits;
+       u16 xpaBiasLvlFreq[3];
+       u8 futureModal[6];
+
+       struct spur_chan spurChans[AR_EEPROM_MODAL_SPURS];
+} __attribute__((packed));
+
+struct calDataPerFreqOpLoop {
+       u8 pwrPdg[2][5];
+       u8 vpdPdg[2][5];
+       u8 pcdac[2][5];
+       u8 empty[2][5];
+} __attribute__((packed));
+
+struct modal_eep_4k_header {
+       u32 antCtrlChain[AR5416_EEP4K_MAX_CHAINS];
+       u32 antCtrlCommon;
+       u8 antennaGainCh[AR5416_EEP4K_MAX_CHAINS];
+       u8 switchSettling;
+       u8 txRxAttenCh[AR5416_EEP4K_MAX_CHAINS];
+       u8 rxTxMarginCh[AR5416_EEP4K_MAX_CHAINS];
+       u8 adcDesiredSize;
+       u8 pgaDesiredSize;
+       u8 xlnaGainCh[AR5416_EEP4K_MAX_CHAINS];
+       u8 txEndToXpaOff;
+       u8 txEndToRxOn;
+       u8 txFrameToXpaOn;
+       u8 thresh62;
+       u8 noiseFloorThreshCh[AR5416_EEP4K_MAX_CHAINS];
+       u8 xpdGain;
+       u8 xpd;
+       u8 iqCalICh[AR5416_EEP4K_MAX_CHAINS];
+       u8 iqCalQCh[AR5416_EEP4K_MAX_CHAINS];
+       u8 pdGainOverlap;
+#ifdef __BIG_ENDIAN_BITFIELD
+       u8 ob_1:4, ob_0:4;
+       u8 db1_1:4, db1_0:4;
+#else
+       u8 ob_0:4, ob_1:4;
+       u8 db1_0:4, db1_1:4;
+#endif
+       u8 xpaBiasLvl;
+       u8 txFrameToDataStart;
+       u8 txFrameToPaOn;
+       u8 ht40PowerIncForPdadc;
+       u8 bswAtten[AR5416_EEP4K_MAX_CHAINS];
+       u8 bswMargin[AR5416_EEP4K_MAX_CHAINS];
+       u8 swSettleHt40;
+       u8 xatten2Db[AR5416_EEP4K_MAX_CHAINS];
+       u8 xatten2Margin[AR5416_EEP4K_MAX_CHAINS];
+#ifdef __BIG_ENDIAN_BITFIELD
+       u8 db2_1:4, db2_0:4;
+#else
+       u8 db2_0:4, db2_1:4;
+#endif
+       u8 version;
+#ifdef __BIG_ENDIAN_BITFIELD
+       u8 ob_3:4, ob_2:4;
+       u8 antdiv_ctl1:4, ob_4:4;
+       u8 db1_3:4, db1_2:4;
+       u8 antdiv_ctl2:4, db1_4:4;
+       u8 db2_2:4, db2_3:4;
+       u8 reserved:4, db2_4:4;
+#else
+       u8 ob_2:4, ob_3:4;
+       u8 ob_4:4, antdiv_ctl1:4;
+       u8 db1_2:4, db1_3:4;
+       u8 db1_4:4, antdiv_ctl2:4;
+       u8 db2_2:4, db2_3:4;
+       u8 db2_4:4, reserved:4;
+#endif
+       u8 tx_diversity;
+       u8 flc_pwr_thresh;
+       u8 bb_scale_smrt_antenna;
+#define EEP_4K_BB_DESIRED_SCALE_MASK   0x1f
+       u8 futureModal[1];
+       struct spur_chan spurChans[AR_EEPROM_MODAL_SPURS];
+} __attribute__((packed));
+
+struct base_eep_ar9287_header {
+       u16 length;
+       u16 checksum;
+       u16 version;
+       u8 opCapFlags;
+       u8 eepMisc;
+       u16 regDmn[2];
+       u8 macAddr[6];
+       u8 rxMask;
+       u8 txMask;
+       u16 rfSilent;
+       u16 blueToothOptions;
+       u16 deviceCap;
+       u32 binBuildNumber;
+       u8 deviceType;
+       u8 openLoopPwrCntl;
+       int8_t pwrTableOffset;
+       int8_t tempSensSlope;
+       int8_t tempSensSlopePalOn;
+       u8 futureBase[29];
+} __attribute__((packed));
+
+struct modal_eep_ar9287_header {
+       u32 antCtrlChain[AR9287_MAX_CHAINS];
+       u32 antCtrlCommon;
+       int8_t antennaGainCh[AR9287_MAX_CHAINS];
+       u8 switchSettling;
+       u8 txRxAttenCh[AR9287_MAX_CHAINS];
+       u8 rxTxMarginCh[AR9287_MAX_CHAINS];
+       int8_t adcDesiredSize;
+       u8 txEndToXpaOff;
+       u8 txEndToRxOn;
+       u8 txFrameToXpaOn;
+       u8 thresh62;
+       int8_t noiseFloorThreshCh[AR9287_MAX_CHAINS];
+       u8 xpdGain;
+       u8 xpd;
+       int8_t iqCalICh[AR9287_MAX_CHAINS];
+       int8_t iqCalQCh[AR9287_MAX_CHAINS];
+       u8 pdGainOverlap;
+       u8 xpaBiasLvl;
+       u8 txFrameToDataStart;
+       u8 txFrameToPaOn;
+       u8 ht40PowerIncForPdadc;
+       u8 bswAtten[AR9287_MAX_CHAINS];
+       u8 bswMargin[AR9287_MAX_CHAINS];
+       u8 swSettleHt40;
+       u8 version;
+       u8 db1;
+       u8 db2;
+       u8 ob_cck;
+       u8 ob_psk;
+       u8 ob_qam;
+       u8 ob_pal_off;
+       u8 futureModal[30];
+       struct spur_chan spurChans[AR_EEPROM_MODAL_SPURS];
+} __attribute__((packed));
+
+struct cal_data_per_freq {
+       u8 pwrPdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS];
+       u8 vpdPdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS];
+} __attribute__((packed));
+
+struct cal_data_per_freq_4k {
+       u8 pwrPdg[AR5416_EEP4K_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS];
+       u8 vpdPdg[AR5416_EEP4K_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS];
+} __attribute__((packed));
+
+struct cal_target_power_leg {
+       u8 bChannel;
+       u8 tPow2x[4];
+} __attribute__((packed));
+
+struct cal_target_power_ht {
+       u8 bChannel;
+       u8 tPow2x[8];
+} __attribute__((packed));
+
+struct cal_ctl_edges {
+       u8 bChannel;
+       u8 ctl;
+} __attribute__((packed));
+
+struct cal_data_op_loop_ar9287 {
+       u8 pwrPdg[2][5];
+       u8 vpdPdg[2][5];
+       u8 pcdac[2][5];
+       u8 empty[2][5];
+} __attribute__((packed));
+
+struct cal_data_per_freq_ar9287 {
+       u8 pwrPdg[AR5416_NUM_PD_GAINS][AR9287_PD_GAIN_ICEPTS];
+       u8 vpdPdg[AR5416_NUM_PD_GAINS][AR9287_PD_GAIN_ICEPTS];
+} __attribute__((packed));
+
+union cal_data_per_freq_ar9287_u {
+       struct cal_data_op_loop_ar9287 calDataOpen;
+       struct cal_data_per_freq_ar9287 calDataClose;
+} __attribute__((packed));
+
+struct cal_ctl_data_ar9287 {
+       struct cal_ctl_edges
+       ctlEdges[AR9287_MAX_CHAINS][AR9287_NUM_BAND_EDGES];
+} __attribute__((packed));
+
+struct cal_ctl_data {
+       struct cal_ctl_edges
+       ctlEdges[AR5416_MAX_CHAINS][AR5416_NUM_BAND_EDGES];
+} __attribute__((packed));
+
+struct cal_ctl_data_4k {
+       struct cal_ctl_edges
+       ctlEdges[AR5416_EEP4K_MAX_CHAINS][AR5416_EEP4K_NUM_BAND_EDGES];
+} __attribute__((packed));
+
+struct ar5416_eeprom_def {
+       struct base_eep_header baseEepHeader;
+       u8 custData[64];
+       struct modal_eep_header modalHeader[2];
+       u8 calFreqPier5G[AR5416_NUM_5G_CAL_PIERS];
+       u8 calFreqPier2G[AR5416_NUM_2G_CAL_PIERS];
+       struct cal_data_per_freq
+        calPierData5G[AR5416_MAX_CHAINS][AR5416_NUM_5G_CAL_PIERS];
+       struct cal_data_per_freq
+        calPierData2G[AR5416_MAX_CHAINS][AR5416_NUM_2G_CAL_PIERS];
+       struct cal_target_power_leg
+        calTargetPower5G[AR5416_NUM_5G_20_TARGET_POWERS];
+       struct cal_target_power_ht
+        calTargetPower5GHT20[AR5416_NUM_5G_20_TARGET_POWERS];
+       struct cal_target_power_ht
+        calTargetPower5GHT40[AR5416_NUM_5G_40_TARGET_POWERS];
+       struct cal_target_power_leg
+        calTargetPowerCck[AR5416_NUM_2G_CCK_TARGET_POWERS];
+       struct cal_target_power_leg
+        calTargetPower2G[AR5416_NUM_2G_20_TARGET_POWERS];
+       struct cal_target_power_ht
+        calTargetPower2GHT20[AR5416_NUM_2G_20_TARGET_POWERS];
+       struct cal_target_power_ht
+        calTargetPower2GHT40[AR5416_NUM_2G_40_TARGET_POWERS];
+       u8 ctlIndex[AR5416_NUM_CTLS];
+       struct cal_ctl_data ctlData[AR5416_NUM_CTLS];
+       u8 padding;
+} __attribute__((packed));
+
+struct ar5416_eeprom_4k {
+       struct base_eep_header_4k baseEepHeader;
+       u8 custData[20];
+       struct modal_eep_4k_header modalHeader;
+       u8 calFreqPier2G[AR5416_EEP4K_NUM_2G_CAL_PIERS];
+       struct cal_data_per_freq_4k
+       calPierData2G[AR5416_EEP4K_MAX_CHAINS][AR5416_EEP4K_NUM_2G_CAL_PIERS];
+       struct cal_target_power_leg
+       calTargetPowerCck[AR5416_EEP4K_NUM_2G_CCK_TARGET_POWERS];
+       struct cal_target_power_leg
+       calTargetPower2G[AR5416_EEP4K_NUM_2G_20_TARGET_POWERS];
+       struct cal_target_power_ht
+       calTargetPower2GHT20[AR5416_EEP4K_NUM_2G_20_TARGET_POWERS];
+       struct cal_target_power_ht
+       calTargetPower2GHT40[AR5416_EEP4K_NUM_2G_40_TARGET_POWERS];
+       u8 ctlIndex[AR5416_EEP4K_NUM_CTLS];
+       struct cal_ctl_data_4k ctlData[AR5416_EEP4K_NUM_CTLS];
+       u8 padding;
+} __attribute__((packed));
+
+struct ar9287_eeprom {
+       struct base_eep_ar9287_header baseEepHeader;
+       u8 custData[AR9287_DATA_SZ];
+       struct modal_eep_ar9287_header modalHeader;
+       u8 calFreqPier2G[AR9287_NUM_2G_CAL_PIERS];
+       union cal_data_per_freq_ar9287_u
+       calPierData2G[AR9287_MAX_CHAINS][AR9287_NUM_2G_CAL_PIERS];
+       struct cal_target_power_leg
+       calTargetPowerCck[AR9287_NUM_2G_CCK_TARGET_POWERS];
+       struct cal_target_power_leg
+       calTargetPower2G[AR9287_NUM_2G_20_TARGET_POWERS];
+       struct cal_target_power_ht
+       calTargetPower2GHT20[AR9287_NUM_2G_20_TARGET_POWERS];
+       struct cal_target_power_ht
+       calTargetPower2GHT40[AR9287_NUM_2G_40_TARGET_POWERS];
+       u8 ctlIndex[AR9287_NUM_CTLS];
+       struct cal_ctl_data_ar9287 ctlData[AR9287_NUM_CTLS];
+       u8 padding;
+} __attribute__((packed));
+
+enum reg_ext_bitmap {
+       REG_EXT_FCC_MIDBAND = 0,
+       REG_EXT_JAPAN_MIDBAND = 1,
+       REG_EXT_FCC_DFS_HT40 = 2,
+       REG_EXT_JAPAN_NONDFS_HT40 = 3,
+       REG_EXT_JAPAN_DFS_HT40 = 4
+};
+
+struct ath9k_country_entry {
+       u16 countryCode;
+       u16 regDmnEnum;
+       u16 regDmn5G;
+       u16 regDmn2G;
+       u8 isMultidomain;
+       u8 iso[3];
+};
+
+struct eeprom_ops {
+       int (*check_eeprom)(struct ath_hw *hw);
+       u32 (*get_eeprom)(struct ath_hw *hw, enum eeprom_param param);
+       int (*fill_eeprom)(struct ath_hw *hw);
+       int (*get_eeprom_ver)(struct ath_hw *hw);
+       int (*get_eeprom_rev)(struct ath_hw *hw);
+       void (*set_board_values)(struct ath_hw *hw, struct ath9k_channel *chan);
+       void (*set_addac)(struct ath_hw *hw, struct ath9k_channel *chan);
+       void (*set_txpower)(struct ath_hw *hw, struct ath9k_channel *chan,
+                          u16 cfgCtl, u8 twiceAntennaReduction,
+                          u8 twiceMaxRegulatoryPower, u8 powerLimit,
+                          int test);
+       u16 (*get_spur_channel)(struct ath_hw *ah, u16 i, int is2GHz);
+};
+
+void ath9k_hw_analog_shift_regwrite(struct ath_hw *ah, u32 reg, u32 val);
+void ath9k_hw_analog_shift_rmw(struct ath_hw *ah, u32 reg, u32 mask,
+                              u32 shift, u32 val);
+int16_t ath9k_hw_interpolate(u16 target, u16 srcLeft, u16 srcRight,
+                            int16_t targetLeft,
+                            int16_t targetRight);
+int ath9k_hw_get_lower_upper_index(u8 target, u8 *pList, u16 listSize,
+                                   u16 *indexL, u16 *indexR);
+int ath9k_hw_nvram_read(struct ath_common *common, u32 off, u16 *data);
+void ath9k_hw_usb_gen_fill_eeprom(struct ath_hw *ah, u16 *eep_data,
+                                 int eep_start_loc, int size);
+void ath9k_hw_fill_vpd_table(u8 pwrMin, u8 pwrMax, u8 *pPwrList,
+                            u8 *pVpdList, u16 numIntercepts,
+                            u8 *pRetVpdList);
+void ath9k_hw_get_legacy_target_powers(struct ath_hw *ah,
+                                      struct ath9k_channel *chan,
+                                      struct cal_target_power_leg *powInfo,
+                                      u16 numChannels,
+                                      struct cal_target_power_leg *pNewPower,
+                                      u16 numRates, int isExtTarget);
+void ath9k_hw_get_target_powers(struct ath_hw *ah,
+                               struct ath9k_channel *chan,
+                               struct cal_target_power_ht *powInfo,
+                               u16 numChannels,
+                               struct cal_target_power_ht *pNewPower,
+                               u16 numRates, int isHt40Target);
+u16 ath9k_hw_get_max_edge_power(u16 freq, struct cal_ctl_edges *pRdEdgesPower,
+                               int is2GHz, int num_band_edges);
+void ath9k_hw_update_regulatory_maxpower(struct ath_hw *ah);
+int ath9k_hw_eeprom_init(struct ath_hw *ah);
+
+void ath9k_hw_get_gain_boundaries_pdadcs(struct ath_hw *ah,
+                               struct ath9k_channel *chan,
+                               void *pRawDataSet,
+                               u8 *bChans, u16 availPiers,
+                               u16 tPdGainOverlap,
+                               u16 *pPdGainBoundaries, u8 *pPDADCValues,
+                               u16 numXpdGains);
+
+#define ar5416_get_ntxchains(_txchainmask)                     \
+       (((_txchainmask >> 2) & 1) +                            \
+        ((_txchainmask >> 1) & 1) + (_txchainmask & 1))
+
+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_ar9300_ops;
+
+#endif /* EEPROM_H */
diff --git a/src/drivers/net/ath/ath9k/hw-ops.h b/src/drivers/net/ath/ath9k/hw-ops.h
new file mode 100644 (file)
index 0000000..65cff3b
--- /dev/null
@@ -0,0 +1,268 @@
+/*
+ * Copyright (c) 2010-2011 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 int ath9k_hw_calibrate(struct ath_hw *ah,
+                                     struct ath9k_channel *chan,
+                                     u8 rxchainmask,
+                                     int longcal)
+{
+       return ath9k_hw_ops(ah)->calibrate(ah, chan, rxchainmask, longcal);
+}
+
+static inline int 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,
+                                 int is_firstseg, int is_lastseg,
+                                 const void *ds0, u32 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_set_clrdmask(struct ath_hw *ah, void *ds, int val)
+{
+       ath9k_hw_ops(ah)->set_clrdmask(ah, ds, val);
+}
+
+static inline void ath9k_hw_antdiv_comb_conf_get(struct ath_hw *ah,
+               struct ath_hw_antcomb_conf *antconf)
+{
+       ath9k_hw_ops(ah)->antdiv_comb_conf_get(ah, antconf);
+}
+
+static inline void ath9k_hw_antdiv_comb_conf_set(struct ath_hw *ah,
+               struct ath_hw_antcomb_conf *antconf)
+{
+       ath9k_hw_ops(ah)->antdiv_comb_conf_set(ah, antconf);
+}
+
+/* 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 int 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 1;
+
+       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 int 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_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, int value)
+{
+       return ath9k_hw_private_ops(ah)->set_diversity(ah, value);
+}
+
+static inline int 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 int 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);
+}
+
+#endif /* ATH9K_HW_OPS_H */
diff --git a/src/drivers/net/ath/ath9k/hw.h b/src/drivers/net/ath/ath9k/hw.h
new file mode 100644 (file)
index 0000000..c10df38
--- /dev/null
@@ -0,0 +1,995 @@
+/*
+ * Copyright (c) 2008-2011 Atheros Communications Inc.
+ *
+ * Modified for iPXE by Scott K Logan <logans@cottsay.net> July 2011
+ * Original from Linux kernel 3.0.1
+ *
+ * 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 HW_H
+#define HW_H
+
+#include <errno.h>
+
+#include "mac.h"
+#include "ani.h"
+#include "eeprom.h"
+#include "calib.h"
+#include "reg.h"
+#include "phy.h"
+
+#include "../regd.h"
+
+/* Keep all ath9k files under one errfile ID */
+#undef ERRFILE
+#define ERRFILE ERRFILE_ath9k
+
+#define ATHEROS_VENDOR_ID      0x168c
+
+#define AR5416_DEVID_PCI       0x0023
+#define AR5416_DEVID_PCIE      0x0024
+#define AR9160_DEVID_PCI       0x0027
+#define AR9280_DEVID_PCI       0x0029
+#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 AR9300_DEVID_AR9340    0x0031
+#define AR9300_DEVID_AR9485_PCIE 0x0032
+
+#define AR5416_AR9100_DEVID    0x000b
+
+#define        AR_SUBVENDOR_ID_NOG     0x0e11
+#define AR_SUBVENDOR_ID_NEW_A  0x7065
+#define AR5416_MAGIC           0x19641014
+
+#define AR9280_COEX2WIRE_SUBSYSID      0x309b
+#define AT9285_COEX3WIRE_SA_SUBSYSID   0x30aa
+#define AT9285_COEX3WIRE_DA_SUBSYSID   0x30ab
+
+#define AR9300_NUM_BT_WEIGHTS   4
+#define AR9300_NUM_WLAN_WEIGHTS 4
+
+#define ATH_AMPDU_LIMIT_MAX        (64 * 1024 - 1)
+
+#define        ATH_DEFAULT_NOISE_FLOOR -95
+
+#define ATH9K_RSSI_BAD                 -128
+
+#define ATH9K_NUM_CHANNELS     38
+
+/* Register read/write primitives */
+#define REG_WRITE(_ah, _reg, _val) \
+       (_ah)->reg_ops.write((_ah), (_val), (_reg))
+
+#define REG_READ(_ah, _reg) \
+       (_ah)->reg_ops.read((_ah), (_reg))
+
+#define REG_READ_MULTI(_ah, _addr, _val, _cnt)         \
+       (_ah)->reg_ops.multi_read((_ah), (_addr), (_val), (_cnt))
+
+#define REG_RMW(_ah, _reg, _set, _clr) \
+       (_ah)->reg_ops.rmw((_ah), (_reg), (_set), (_clr))
+
+#define ENABLE_REGWRITE_BUFFER(_ah)                                    \
+       do {                                                            \
+               if ((_ah)->reg_ops.enable_write_buffer) \
+                       (_ah)->reg_ops.enable_write_buffer((_ah)); \
+       } while (0)
+
+#define REGWRITE_BUFFER_FLUSH(_ah)                                     \
+       do {                                                            \
+               if ((_ah)->reg_ops.write_flush)         \
+                       (_ah)->reg_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_FIELD(_a, _r, _f, _v) \
+       REG_RMW(_a, _r, (((_v) << _f##_S) & _f), (_f))
+#define REG_READ_FIELD(_a, _r, _f) \
+       (((REG_READ(_a, _r) & _f) >> _f##_S))
+#define REG_SET_BIT(_a, _r, _f) \
+       REG_RMW(_a, _r, (_f), 0)
+#define REG_CLR_BIT(_a, _r, _f) \
+       REG_RMW(_a, _r, 0, (_f))
+
+#define DO_DELAY(x) do {                                       \
+               if (((++(x) % 64) == 0) &&                      \
+                   (ath9k_hw_common(ah)->bus_ops->ath_bus_type \
+                       != ATH_USB))                            \
+                       udelay(1);                              \
+       } while (0)
+
+#define REG_WRITE_ARRAY(iniarray, column, regWr) \
+       ath9k_hw_write_array(ah, iniarray, column, &(regWr))
+
+#define AR_GPIO_OUTPUT_MUX_AS_OUTPUT             0
+#define AR_GPIO_OUTPUT_MUX_AS_PCIE_ATTENTION_LED 1
+#define AR_GPIO_OUTPUT_MUX_AS_PCIE_POWER_LED     2
+#define AR_GPIO_OUTPUT_MUX_AS_TX_FRAME           3
+#define AR_GPIO_OUTPUT_MUX_AS_RX_CLEAR_EXTERNAL  4
+#define AR_GPIO_OUTPUT_MUX_AS_MAC_NETWORK_LED    5
+#define AR_GPIO_OUTPUT_MUX_AS_MAC_POWER_LED      6
+
+#define AR_GPIOD_MASK               0x00001FFF
+#define AR_GPIO_BIT(_gpio)          (1 << (_gpio))
+
+#define BASE_ACTIVATE_DELAY         100
+#define RTC_PLL_SETTLE_DELAY        (AR_SREV_9340(ah) ? 1000 : 100)
+#define COEF_SCALE_S                24
+#define HT40_CHANNEL_CENTER_SHIFT   10
+
+#define ATH9K_ANTENNA0_CHAINMASK    0x1
+#define ATH9K_ANTENNA1_CHAINMASK    0x2
+
+#define ATH9K_NUM_DMA_DEBUG_REGS    8
+#define ATH9K_NUM_QUEUES            10
+
+#define MAX_RATE_POWER              63
+#define AH_WAIT_TIMEOUT             100000 /* (us) */
+#define AH_TSF_WRITE_TIMEOUT        100    /* (us) */
+#define AH_TIME_QUANTUM             10
+#define AR_KEYTABLE_SIZE            128
+#define POWER_UP_TIME               10000
+#define SPUR_RSSI_THRESH            40
+
+#define CAB_TIMEOUT_VAL             10
+#define BEACON_TIMEOUT_VAL          10
+#define MIN_BEACON_TIMEOUT_VAL      1
+#define SLEEP_SLOP                  3
+
+#define INIT_CONFIG_STATUS          0x00000000
+#define INIT_RSSI_THR               0x00000700
+#define INIT_BCON_CNTRL_REG         0x00000000
+
+#define TU_TO_USEC(_tu)             ((_tu) << 10)
+
+#define ATH9K_HW_RX_HP_QDEPTH  16
+#define ATH9K_HW_RX_LP_QDEPTH  128
+
+#define PAPRD_GAIN_TABLE_ENTRIES    32
+#define PAPRD_TABLE_SZ              24
+
+enum ath_hw_txq_subtype {
+       ATH_TXQ_AC_BE = 0,
+};
+
+enum ath_ini_subsys {
+       ATH_INI_PRE = 0,
+       ATH_INI_CORE,
+       ATH_INI_POST,
+       ATH_INI_NUM_SPLIT,
+};
+
+enum ath9k_hw_caps {
+       ATH9K_HW_CAP_HT                         = BIT(0),
+       ATH9K_HW_CAP_RFSILENT                   = BIT(1),
+       ATH9K_HW_CAP_CST                        = BIT(2),
+       ATH9K_HW_CAP_AUTOSLEEP                  = BIT(4),
+       ATH9K_HW_CAP_4KB_SPLITTRANS             = BIT(5),
+       ATH9K_HW_CAP_EDMA                       = BIT(6),
+       ATH9K_HW_CAP_RAC_SUPPORTED              = BIT(7),
+       ATH9K_HW_CAP_LDPC                       = BIT(8),
+       ATH9K_HW_CAP_FASTCLOCK                  = BIT(9),
+       ATH9K_HW_CAP_SGI_20                     = BIT(10),
+       ATH9K_HW_CAP_PAPRD                      = BIT(11),
+       ATH9K_HW_CAP_ANT_DIV_COMB               = BIT(12),
+       ATH9K_HW_CAP_2GHZ                       = BIT(13),
+       ATH9K_HW_CAP_5GHZ                       = BIT(14),
+       ATH9K_HW_CAP_APM                        = BIT(15),
+};
+
+struct ath9k_hw_capabilities {
+       u32 hw_caps; /* ATH9K_HW_CAP_* from ath9k_hw_caps */
+       u16 rts_aggr_limit;
+       u8 tx_chainmask;
+       u8 rx_chainmask;
+       u8 max_txchains;
+       u8 max_rxchains;
+       u8 num_gpio_pins;
+       u8 rx_hp_qdepth;
+       u8 rx_lp_qdepth;
+       u8 rx_status_len;
+       u8 tx_desc_len;
+       u8 txs_len;
+       u16 pcie_lcr_offset;
+       int pcie_lcr_extsync_en;
+};
+
+struct ath9k_ops_config {
+       int dma_beacon_response_time;
+       int sw_beacon_response_time;
+       int additional_swba_backoff;
+       int ack_6mb;
+       u32 cwm_ignore_extcca;
+       u8 pcie_powersave_enable;
+       int pcieSerDesWrite;
+       u8 pcie_clock_req;
+       u32 pcie_waen;
+       u8 analog_shiftreg;
+       u8 paprd_disable;
+       u32 ofdm_trig_low;
+       u32 ofdm_trig_high;
+       u32 cck_trig_high;
+       u32 cck_trig_low;
+       u32 enable_ani;
+       int serialize_regmode;
+       int rx_intr_mitigation;
+       int tx_intr_mitigation;
+#define SPUR_DISABLE           0
+#define SPUR_ENABLE_IOCTL      1
+#define SPUR_ENABLE_EEPROM     2
+#define AR_SPUR_5413_1         1640
+#define AR_SPUR_5413_2         1200
+#define AR_NO_SPUR             0x8000
+#define AR_BASE_FREQ_2GHZ      2300
+#define AR_BASE_FREQ_5GHZ      4900
+#define AR_SPUR_FEEQ_BOUND_HT40 19
+#define AR_SPUR_FEEQ_BOUND_HT20 10
+       int spurmode;
+       u16 spurchans[AR_EEPROM_MODAL_SPURS][2];
+       u8 max_txtrig_level;
+       u16 ani_poll_interval; /* ANI poll interval in ms */
+};
+
+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,
+       ATH9K_INT_TX = 0x00000040,
+       ATH9K_INT_TXDESC = 0x00000080,
+       ATH9K_INT_TIM_TIMER = 0x00000100,
+       ATH9K_INT_BB_WATCHDOG = 0x00000400,
+       ATH9K_INT_TXURN = 0x00000800,
+       ATH9K_INT_MIB = 0x00001000,
+       ATH9K_INT_RXPHY = 0x00004000,
+       ATH9K_INT_RXKCM = 0x00008000,
+       ATH9K_INT_SWBA = 0x00010000,
+       ATH9K_INT_BMISS = 0x00040000,
+       ATH9K_INT_BNR = 0x00100000,
+       ATH9K_INT_TIM = 0x00200000,
+       ATH9K_INT_DTIM = 0x00400000,
+       ATH9K_INT_DTIMSYNC = 0x00800000,
+       ATH9K_INT_GPIO = 0x01000000,
+       ATH9K_INT_CABEND = 0x02000000,
+       ATH9K_INT_TSFOOR = 0x04000000,
+       ATH9K_INT_GENTIMER = 0x08000000,
+       ATH9K_INT_CST = 0x10000000,
+       ATH9K_INT_GTT = 0x20000000,
+       ATH9K_INT_FATAL = 0x40000000,
+       ATH9K_INT_GLOBAL = 0x80000000,
+       ATH9K_INT_BMISC = ATH9K_INT_TIM |
+               ATH9K_INT_DTIM |
+               ATH9K_INT_DTIMSYNC |
+               ATH9K_INT_TSFOOR |
+               ATH9K_INT_CABEND,
+       ATH9K_INT_COMMON = ATH9K_INT_RXNOFRM |
+               ATH9K_INT_RXDESC |
+               ATH9K_INT_RXEOL |
+               ATH9K_INT_RXORN |
+               ATH9K_INT_TXURN |
+               ATH9K_INT_TXDESC |
+               ATH9K_INT_MIB |
+               ATH9K_INT_RXPHY |
+               ATH9K_INT_RXKCM |
+               ATH9K_INT_SWBA |
+               ATH9K_INT_BMISS |
+               ATH9K_INT_GPIO,
+       ATH9K_INT_NOCARD = 0xffffffff
+};
+
+#define CHANNEL_CW_INT    0x00002
+#define CHANNEL_CCK       0x00020
+#define CHANNEL_OFDM      0x00040
+#define CHANNEL_2GHZ      0x00080
+#define CHANNEL_5GHZ      0x00100
+#define CHANNEL_PASSIVE   0x00200
+#define CHANNEL_DYN       0x00400
+#define CHANNEL_HALF      0x04000
+#define CHANNEL_QUARTER   0x08000
+#define CHANNEL_HT20      0x10000
+#define CHANNEL_HT40PLUS  0x20000
+#define CHANNEL_HT40MINUS 0x40000
+
+#define CHANNEL_A           (CHANNEL_5GHZ|CHANNEL_OFDM)
+#define CHANNEL_B           (CHANNEL_2GHZ|CHANNEL_CCK)
+#define CHANNEL_G           (CHANNEL_2GHZ|CHANNEL_OFDM)
+#define CHANNEL_G_HT20      (CHANNEL_2GHZ|CHANNEL_HT20)
+#define CHANNEL_A_HT20      (CHANNEL_5GHZ|CHANNEL_HT20)
+#define CHANNEL_G_HT40PLUS  (CHANNEL_2GHZ|CHANNEL_HT40PLUS)
+#define CHANNEL_G_HT40MINUS (CHANNEL_2GHZ|CHANNEL_HT40MINUS)
+#define CHANNEL_A_HT40PLUS  (CHANNEL_5GHZ|CHANNEL_HT40PLUS)
+#define CHANNEL_A_HT40MINUS (CHANNEL_5GHZ|CHANNEL_HT40MINUS)
+#define CHANNEL_ALL                            \
+       (CHANNEL_OFDM|                          \
+        CHANNEL_CCK|                           \
+        CHANNEL_2GHZ |                         \
+        CHANNEL_5GHZ |                         \
+        CHANNEL_HT20 |                         \
+        CHANNEL_HT40PLUS |                     \
+        CHANNEL_HT40MINUS)
+
+struct ath9k_hw_cal_data {
+       u16 channel;
+       u32 channelFlags;
+       int32_t CalValid;
+       int8_t iCoff;
+       int8_t qCoff;
+       int paprd_done;
+       int nfcal_pending;
+       int nfcal_interference;
+       u16 small_signal_gain[AR9300_MAX_CHAINS];
+       u32 pa_table[AR9300_MAX_CHAINS][PAPRD_TABLE_SZ];
+       struct ath9k_nfcal_hist nfCalHist[NUM_NF_READINGS];
+};
+
+struct ath9k_channel {
+       struct net80211_channel *chan;
+       struct ar5416AniState ani;
+       u16 channel;
+       u32 channelFlags;
+       u32 chanmode;
+       s16 noisefloor;
+};
+
+#define IS_CHAN_G(_c) ((((_c)->channelFlags & (CHANNEL_G)) == CHANNEL_G) || \
+       (((_c)->channelFlags & CHANNEL_G_HT20) == CHANNEL_G_HT20) || \
+       (((_c)->channelFlags & CHANNEL_G_HT40PLUS) == CHANNEL_G_HT40PLUS) || \
+       (((_c)->channelFlags & CHANNEL_G_HT40MINUS) == CHANNEL_G_HT40MINUS))
+#define IS_CHAN_OFDM(_c) (((_c)->channelFlags & CHANNEL_OFDM) != 0)
+#define IS_CHAN_5GHZ(_c) (((_c)->channelFlags & CHANNEL_5GHZ) != 0)
+#define IS_CHAN_2GHZ(_c) (((_c)->channelFlags & CHANNEL_2GHZ) != 0)
+#define IS_CHAN_HALF_RATE(_c) (((_c)->channelFlags & CHANNEL_HALF) != 0)
+#define IS_CHAN_QUARTER_RATE(_c) (((_c)->channelFlags & CHANNEL_QUARTER) != 0)
+#define IS_CHAN_A_FAST_CLOCK(_ah, _c)                  \
+       ((((_c)->channelFlags & CHANNEL_5GHZ) != 0) &&  \
+        ((_ah)->caps.hw_caps & ATH9K_HW_CAP_FASTCLOCK))
+
+/* These macros check chanmode and not channelFlags */
+#define IS_CHAN_B(_c) ((_c)->chanmode == CHANNEL_B)
+#define IS_CHAN_HT20(_c) (((_c)->chanmode == CHANNEL_A_HT20) ||        \
+                         ((_c)->chanmode == CHANNEL_G_HT20))
+#define IS_CHAN_HT40(_c) (((_c)->chanmode == CHANNEL_A_HT40PLUS) ||    \
+                         ((_c)->chanmode == CHANNEL_A_HT40MINUS) ||    \
+                         ((_c)->chanmode == CHANNEL_G_HT40PLUS) ||     \
+                         ((_c)->chanmode == CHANNEL_G_HT40MINUS))
+#define IS_CHAN_HT(_c) (IS_CHAN_HT20((_c)) || IS_CHAN_HT40((_c)))
+
+enum ath9k_power_mode {
+       ATH9K_PM_AWAKE = 0,
+       ATH9K_PM_FULL_SLEEP,
+       ATH9K_PM_NETWORK_SLEEP,
+       ATH9K_PM_UNDEFINED
+};
+
+enum ath9k_tp_scale {
+       ATH9K_TP_SCALE_MAX = 0,
+       ATH9K_TP_SCALE_50,
+       ATH9K_TP_SCALE_25,
+       ATH9K_TP_SCALE_12,
+       ATH9K_TP_SCALE_MIN
+};
+
+enum ser_reg_mode {
+       SER_REG_MODE_OFF = 0,
+       SER_REG_MODE_ON = 1,
+       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;
+       u32 bs_intval;
+#define ATH9K_BEACON_PERIOD       0x0000ffff
+#define ATH9K_TSFOOR_THRESHOLD    0x00004240 /* 16k us */
+       u32 bs_dtimperiod;
+       u16 bs_cfpperiod;
+       u16 bs_cfpmaxduration;
+       u32 bs_cfpnext;
+       u16 bs_timoffset;
+       u16 bs_bmissthreshold;
+       u32 bs_sleepduration;
+       u32 bs_tsfoor_threshold;
+};
+
+struct chan_centers {
+       u16 synth_center;
+       u16 ctl_center;
+       u16 ext_center;
+};
+
+enum {
+       ATH9K_RESET_POWER_ON,
+       ATH9K_RESET_WARM,
+       ATH9K_RESET_COLD,
+};
+
+struct ath9k_hw_version {
+       u32 magic;
+       u16 devid;
+       u16 subvendorid;
+       u32 macVersion;
+       u16 macRev;
+       u16 phyRev;
+       u16 analog5GhzRev;
+       u16 analog2GhzRev;
+       u16 subsysid;
+       enum ath_usb_dev usbdev;
+};
+
+/* Generic TSF timer definitions */
+
+#define ATH_MAX_GEN_TIMER      16
+
+#define AR_GENTMR_BIT(_index)  (1 << (_index))
+
+/*
+ * Using de Bruijin sequence to look up 1's index in a 32 bit number
+ * debruijn32 = 0000 0111 0111 1100 1011 0101 0011 0001
+ */
+#define debruijn32 0x077CB531U
+
+struct ath_gen_timer_configuration {
+       u32 next_addr;
+       u32 period_addr;
+       u32 mode_addr;
+       u32 mode_mask;
+};
+
+struct ath_gen_timer {
+       void (*trigger)(void *arg);
+       void (*overflow)(void *arg);
+       void *arg;
+       u8 index;
+};
+
+struct ath_gen_timer_table {
+       u32 gen_timer_index[32];
+       struct ath_gen_timer *timers[ATH_MAX_GEN_TIMER];
+       union {
+               unsigned long timer_bits;
+               u16 val;
+       } timer_mask;
+};
+
+struct ath_hw_antcomb_conf {
+       u8 main_lna_conf;
+       u8 alt_lna_conf;
+       u8 fast_div_bias;
+       u8 main_gaintb;
+       u8 alt_gaintb;
+       int lna1_lna2_delta;
+       u8 div_group;
+};
+
+/**
+ * struct ath_hw_radar_conf - radar detection initialization parameters
+ *
+ * @pulse_inband: threshold for checking the ratio of in-band power
+ *     to total power for short radar pulses (half dB steps)
+ * @pulse_inband_step: threshold for checking an in-band power to total
+ *     power ratio increase for short radar pulses (half dB steps)
+ * @pulse_height: threshold for detecting the beginning of a short
+ *     radar pulse (dB step)
+ * @pulse_rssi: threshold for detecting if a short radar pulse is
+ *     gone (dB step)
+ * @pulse_maxlen: maximum pulse length (0.8 us steps)
+ *
+ * @radar_rssi: RSSI threshold for starting long radar detection (dB steps)
+ * @radar_inband: threshold for checking the ratio of in-band power
+ *     to total power for long radar pulses (half dB steps)
+ * @fir_power: threshold for detecting the end of a long radar pulse (dB)
+ *
+ * @ext_channel: enable extension channel radar detection
+ */
+struct ath_hw_radar_conf {
+       unsigned int pulse_inband;
+       unsigned int pulse_inband_step;
+       unsigned int pulse_height;
+       unsigned int pulse_rssi;
+       unsigned int pulse_maxlen;
+
+       unsigned int radar_rssi;
+       unsigned int radar_inband;
+       int fir_power;
+
+       int ext_channel;
+};
+
+/**
+ * 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
+ *
+ * @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
+ *
+ * @ani_cache_ini_regs: cache the values for ANI from the initial
+ *     register settings through the register initialization.
+ */
+struct ath_hw_private_ops {
+       /* Calibration ops */
+       void (*init_cal_settings)(struct ath_hw *ah);
+       int (*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);
+       void (*setup_calibration)(struct ath_hw *ah,
+                                 struct ath9k_cal_list *currCal);
+
+       /* 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);
+       int (*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);
+       int (*rfbus_req)(struct ath_hw *ah);
+       void (*rfbus_done)(struct ath_hw *ah);
+       void (*restore_chainmask)(struct ath_hw *ah);
+       void (*set_diversity)(struct ath_hw *ah, int value);
+       u32 (*compute_pll_control)(struct ath_hw *ah,
+                                  struct ath9k_channel *chan);
+       int (*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 (*set_radar_params)(struct ath_hw *ah,
+                                struct ath_hw_radar_conf *conf);
+
+       /* ANI */
+       void (*ani_cache_ini_regs)(struct ath_hw *ah);
+};
+
+/**
+ * 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);
+       int (*calibrate)(struct ath_hw *ah,
+                         struct ath9k_channel *chan,
+                         u8 rxchainmask,
+                         int longcal);
+       int (*get_isr)(struct ath_hw *ah, enum ath9k_int *masked);
+       void (*fill_txdesc)(struct ath_hw *ah, void *ds, u32 seglen,
+                           int is_firstseg, int is_is_lastseg,
+                           const void *ds0, u32 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 (*set_clrdmask)(struct ath_hw *ah, void *ds, int val);
+       void (*antdiv_comb_conf_get)(struct ath_hw *ah,
+                       struct ath_hw_antcomb_conf *antconf);
+       void (*antdiv_comb_conf_set)(struct ath_hw *ah,
+                       struct ath_hw_antcomb_conf *antconf);
+
+};
+
+struct ath_nf_limits {
+       s16 max;
+       s16 min;
+       s16 nominal;
+};
+
+/* ah_flags */
+#define AH_USE_EEPROM   0x1
+#define AH_UNPLUGGED    0x2 /* The card has been physically removed. */
+
+struct ath_hw {
+       struct ath_ops reg_ops;
+
+       struct net80211_device *dev;
+       struct ath_common common;
+       struct ath9k_hw_version hw_version;
+       struct ath9k_ops_config config;
+       struct ath9k_hw_capabilities caps;
+       struct ath9k_channel channels[ATH9K_NUM_CHANNELS];
+       struct ath9k_channel *curchan;
+
+       union {
+               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;
+
+       int sw_mgmt_crypto;
+       int is_pciexpress;
+       int is_monitoring;
+       int need_an_top2_fixup;
+       u16 tx_trig_level;
+
+       u32 nf_regs[6];
+       struct ath_nf_limits nf_2g;
+       struct ath_nf_limits nf_5g;
+       u16 rfsilent;
+       u32 rfkill_gpio;
+       u32 rfkill_polarity;
+       u32 ah_flags;
+
+       int htc_reset_init;
+
+       enum ath9k_power_mode power_mode;
+
+       struct ath9k_hw_cal_data *caldata;
+       struct ath9k_pacal_info pacal_info;
+       struct ar5416Stats stats;
+       struct ath9k_tx_queue_info txq[ATH9K_NUM_TX_QUEUES];
+
+       int16_t curchan_rad_index;
+       int ah_ier;
+       enum ath9k_int imask;
+       u32 imrs2_reg;
+       u32 txok_interrupt_mask;
+       u32 txerr_interrupt_mask;
+       u32 txdesc_interrupt_mask;
+       u32 txeol_interrupt_mask;
+       u32 txurn_interrupt_mask;
+       int chip_fullsleep;
+       u32 atim_window;
+
+       /* Calibration */
+       u32 supp_cals;
+       struct ath9k_cal_list iq_caldata;
+       struct ath9k_cal_list adcgain_caldata;
+       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;
+#define totalPowerMeasI meas0.unsign
+#define totalPowerMeasQ meas1.unsign
+#define totalIqCorrMeas meas2.sign
+#define totalAdcIOddPhase  meas0.unsign
+#define totalAdcIEvenPhase meas1.unsign
+#define totalAdcQOddPhase  meas2.unsign
+#define totalAdcQEvenPhase meas3.unsign
+#define totalAdcDcOffsetIOddPhase  meas0.sign
+#define totalAdcDcOffsetIEvenPhase meas1.sign
+#define totalAdcDcOffsetQOddPhase  meas2.sign
+#define totalAdcDcOffsetQEvenPhase meas3.sign
+       union {
+               u32 unsign[AR5416_MAX_CHAINS];
+               int32_t sign[AR5416_MAX_CHAINS];
+       } meas0;
+       union {
+               u32 unsign[AR5416_MAX_CHAINS];
+               int32_t sign[AR5416_MAX_CHAINS];
+       } meas1;
+       union {
+               u32 unsign[AR5416_MAX_CHAINS];
+               int32_t sign[AR5416_MAX_CHAINS];
+       } meas2;
+       union {
+               u32 unsign[AR5416_MAX_CHAINS];
+               int32_t sign[AR5416_MAX_CHAINS];
+       } meas3;
+       u16 cal_samples;
+
+       u32 sta_id1_defaults;
+       u32 misc_mode;
+       enum {
+               AUTO_32KHZ,
+               USE_32KHZ,
+               DONT_USE_32KHZ,
+       } enable_32kHz_clock;
+
+       /* 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;
+       u32 *analogBank1Data;
+       u32 *analogBank2Data;
+       u32 *analogBank3Data;
+       u32 *analogBank6Data;
+       u32 *analogBank6TPCData;
+       u32 *analogBank7Data;
+       u32 *addac5416_21;
+       u32 *bank6Temp;
+
+       u8 txpower_limit;
+       int coverage_class;
+       u32 slottime;
+       u32 globaltxtimeout;
+
+       /* ANI */
+       u32 proc_phyerr;
+       u32 aniperiod;
+       int totalSizeDesired[5];
+       int coarse_high[5];
+       int coarse_low[5];
+       int firpwr[5];
+       enum ath9k_ani_cmd ani_function;
+
+       u32 intr_txqs;
+       u8 txchainmask;
+       u8 rxchainmask;
+
+       struct ath_hw_radar_conf radar_conf;
+
+       u32 originalGain[22];
+       int initPDADC;
+       int PDADCdelta;
+       int led_pin;
+       u32 gpio_mask;
+       u32 gpio_val;
+
+       struct ar5416IniArray iniModes;
+       struct ar5416IniArray iniCommon;
+       struct ar5416IniArray iniBank0;
+       struct ar5416IniArray iniBB_RfGain;
+       struct ar5416IniArray iniBank1;
+       struct ar5416IniArray iniBank2;
+       struct ar5416IniArray iniBank3;
+       struct ar5416IniArray iniBank6;
+       struct ar5416IniArray iniBank6TPC;
+       struct ar5416IniArray iniBank7;
+       struct ar5416IniArray iniAddac;
+       struct ar5416IniArray iniPcieSerdes;
+       struct ar5416IniArray iniPcieSerdesLowPower;
+       struct ar5416IniArray iniModesAdditional;
+       struct ar5416IniArray iniModesAdditional_40M;
+       struct ar5416IniArray iniModesRxGain;
+       struct ar5416IniArray iniModesTxGain;
+       struct ar5416IniArray iniModes_9271_1_0_only;
+       struct ar5416IniArray iniCckfirNormal;
+       struct ar5416IniArray iniCckfirJapan2484;
+       struct ar5416IniArray iniCommon_normal_cck_fir_coeff_9271;
+       struct ar5416IniArray iniCommon_japan_2484_cck_fir_coeff_9271;
+       struct ar5416IniArray iniModes_9271_ANI_reg;
+       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;
+
+       unsigned int paprd_target_power;
+       unsigned int paprd_training_power;
+       unsigned int paprd_ratemask;
+       unsigned int paprd_ratemask_ht40;
+       int paprd_table_write_done;
+       u32 paprd_gain_table_entries[PAPRD_GAIN_TABLE_ENTRIES];
+       u8 paprd_gain_table_index[PAPRD_GAIN_TABLE_ENTRIES];
+       /*
+        * Store the permanent value of Reg 0x4004in WARegVal
+        * so we dont have to R/M/W. We should not be reading
+        * this register when in sleep states.
+        */
+       u32 WARegVal;
+
+       /* Enterprise mode cap */
+       u32 ent_mode;
+
+       int is_clk_25mhz;
+};
+
+struct ath_bus_ops {
+       enum ath_bus_type ath_bus_type;
+       void (*read_cachesize)(struct ath_common *common, int *csz);
+       int (*eeprom_read)(struct ath_common *common, u32 off, u16 *data);
+       void (*bt_coex_prep)(struct ath_common *common);
+       void (*extn_synch_en)(struct ath_common *common);
+};
+
+static inline struct ath_common *ath9k_hw_common(struct ath_hw *ah)
+{
+       return &ah->common;
+}
+
+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;
+}
+
+static inline u8 get_streams(int mask)
+{
+       return !!(mask & BIT(0)) + !!(mask & BIT(1)) + !!(mask & BIT(2));
+}
+
+/* Initialization, Detach, Reset */
+const char *ath9k_hw_probe(u16 vendorid, u16 devid);
+void ath9k_hw_deinit(struct ath_hw *ah);
+int ath9k_hw_init(struct ath_hw *ah);
+int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
+                  struct ath9k_hw_cal_data *caldata, int bChannelChange);
+int ath9k_hw_fill_cap_info(struct ath_hw *ah);
+u32 ath9k_regd_get_ctl(struct ath_regulatory *reg, struct ath9k_channel *chan);
+
+/* GPIO / RFKILL / Antennae */
+void ath9k_hw_cfg_gpio_input(struct ath_hw *ah, u32 gpio);
+u32 ath9k_hw_gpio_get(struct ath_hw *ah, u32 gpio);
+void ath9k_hw_cfg_output(struct ath_hw *ah, u32 gpio,
+                        u32 ah_signal_type);
+void ath9k_hw_set_gpio(struct ath_hw *ah, u32 gpio, u32 val);
+u32 ath9k_hw_getdefantenna(struct ath_hw *ah);
+void ath9k_hw_setantenna(struct ath_hw *ah, u32 antenna);
+
+/* General Operation */
+int ath9k_hw_wait(struct ath_hw *ah, u32 reg, u32 mask, u32 val, u32 timeout);
+void ath9k_hw_write_array(struct ath_hw *ah, struct ar5416IniArray *array,
+                         int column, unsigned int *writecnt);
+u32 ath9k_hw_reverse_bits(u32 val, u32 n);
+u16 ath9k_hw_computetxtime(struct ath_hw *ah,
+                          u8 phy, int kbps,
+                          u32 frameLen, u16 rateix, int shortPreamble);
+void ath9k_hw_get_channel_centers(struct ath_hw *ah,
+                                 struct ath9k_channel *chan,
+                                 struct chan_centers *centers);
+u32 ath9k_hw_getrxfilter(struct ath_hw *ah);
+void ath9k_hw_setrxfilter(struct ath_hw *ah, u32 bits);
+int ath9k_hw_phy_disable(struct ath_hw *ah);
+int ath9k_hw_disable(struct ath_hw *ah);
+void ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit, int test);
+void ath9k_hw_setopmode(struct ath_hw *ah);
+void ath9k_hw_setmcastfilter(struct ath_hw *ah, u32 filter0, u32 filter1);
+void ath9k_hw_setbssidmask(struct ath_hw *ah);
+void ath9k_hw_write_associd(struct ath_hw *ah);
+void ath9k_hw_init_global_settings(struct ath_hw *ah);
+u32 ar9003_get_pll_sqsum_dvc(struct ath_hw *ah);
+void ath9k_hw_set11nmac2040(struct ath_hw *ah);
+int ath9k_hw_check_alive(struct ath_hw *ah);
+
+int ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode);
+
+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_update_async_fifo(struct ath_hw *ah);
+void ar9002_hw_enable_wep_aggregation(struct ath_hw *ah);
+
+/*
+ * Code specific to AR9003, we stuff these here to avoid callbacks
+ * for older families
+ */
+void ar9003_hw_disable_phy_restart(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);
+
+void ar9002_hw_load_ani_reg(struct ath_hw *ah, struct ath9k_channel *chan);
+/*
+ * ANI work can be shared between all families but a next
+ * generation implementation of ANI will be used only for AR9003 only
+ * for now as the other families still need to be tested with the same
+ * next generation ANI. Feel free to start testing it though for the
+ * older families (AR5008, AR9001, AR9002) by using modparam_force_new_ani.
+ */
+extern int modparam_force_new_ani;
+void ath9k_ani_reset(struct ath_hw *ah, int is_scanning);
+void ath9k_hw_proc_mib_event(struct ath_hw *ah);
+void ath9k_hw_ani_monitor(struct ath_hw *ah, struct ath9k_channel *chan);
+
+#define ATH_PCIE_CAP_LINK_CTRL 0x70
+#define ATH_PCIE_CAP_LINK_L0S  1
+#define ATH_PCIE_CAP_LINK_L1   2
+
+#define ATH9K_CLOCK_RATE_CCK           22
+#define ATH9K_CLOCK_RATE_5GHZ_OFDM     40
+#define ATH9K_CLOCK_RATE_2GHZ_OFDM     44
+#define ATH9K_CLOCK_FAST_RATE_5GHZ_OFDM 44
+
+#endif
diff --git a/src/drivers/net/ath/ath9k/mac.h b/src/drivers/net/ath/ath9k/mac.h
new file mode 100644 (file)
index 0000000..c11fe4a
--- /dev/null
@@ -0,0 +1,708 @@
+/*
+ * Copyright (c) 2008-2011 Atheros Communications Inc.
+ *
+ * Modified for iPXE by Scott K Logan <logans@cottsay.net> July 2011
+ * Original from Linux kernel 3.0.1
+ *
+ * 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 MAC_H
+#define MAC_H
+
+#include <unistd.h>
+
+#define RXSTATUS_RATE(ah, ads) (AR_SREV_5416_20_OR_LATER(ah) ?         \
+                               MS(ads->ds_rxstatus0, AR_RxRate) :      \
+                               (ads->ds_rxstatus3 >> 2) & 0xFF)
+
+#define set11nTries(_series, _index) \
+       (SM((_series)[_index].Tries, AR_XmitDataTries##_index))
+
+#define set11nRate(_series, _index) \
+       (SM((_series)[_index].Rate, AR_XmitRate##_index))
+
+#define set11nPktDurRTSCTS(_series, _index)                            \
+       (SM((_series)[_index].PktDuration, AR_PacketDur##_index) |      \
+        ((_series)[_index].RateFlags & ATH9K_RATESERIES_RTS_CTS   ?    \
+         AR_RTSCTSQual##_index : 0))
+
+#define set11nRateFlags(_series, _index)                               \
+       (((_series)[_index].RateFlags & ATH9K_RATESERIES_2040 ?         \
+         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
+#define CCK_PREAMBLE_BITS   144
+#define CCK_PLCP_BITS        48
+
+#define OFDM_SIFS_TIME        16
+#define OFDM_PREAMBLE_TIME    20
+#define OFDM_PLCP_BITS        22
+#define OFDM_SYMBOL_TIME      4
+
+#define OFDM_SIFS_TIME_HALF     32
+#define OFDM_PREAMBLE_TIME_HALF 40
+#define OFDM_PLCP_BITS_HALF     22
+#define OFDM_SYMBOL_TIME_HALF   8
+
+#define OFDM_SIFS_TIME_QUARTER      64
+#define OFDM_PREAMBLE_TIME_QUARTER  80
+#define OFDM_PLCP_BITS_QUARTER      22
+#define OFDM_SYMBOL_TIME_QUARTER    16
+
+#define INIT_AIFS       2
+#define INIT_CWMIN      15
+#define INIT_CWMIN_11B  31
+#define INIT_CWMAX      1023
+#define INIT_SH_RETRY   10
+#define INIT_LG_RETRY   10
+#define INIT_SSH_RETRY  32
+#define INIT_SLG_RETRY  32
+
+#define ATH9K_SLOT_TIME_6 6
+#define ATH9K_SLOT_TIME_9 9
+#define ATH9K_SLOT_TIME_20 20
+
+#define ATH9K_TXERR_XRETRY         0x01
+#define ATH9K_TXERR_FILT           0x02
+#define ATH9K_TXERR_FIFO           0x04
+#define ATH9K_TXERR_XTXOP          0x08
+#define ATH9K_TXERR_TIMER_EXPIRED  0x10
+#define ATH9K_TX_ACKED            0x20
+#define ATH9K_TXERR_MASK                                               \
+       (ATH9K_TXERR_XRETRY | ATH9K_TXERR_FILT | ATH9K_TXERR_FIFO |     \
+        ATH9K_TXERR_XTXOP | ATH9K_TXERR_TIMER_EXPIRED)
+
+#define ATH9K_TX_BA                0x01
+#define ATH9K_TX_PWRMGMT           0x02
+#define ATH9K_TX_DESC_CFG_ERR      0x04
+#define ATH9K_TX_DATA_UNDERRUN     0x08
+#define ATH9K_TX_DELIM_UNDERRUN    0x10
+#define ATH9K_TX_SW_FILTERED       0x80
+
+/* 64 bytes */
+#define MIN_TX_FIFO_THRESHOLD   0x1
+
+/*
+ * Single stream device AR9285 and AR9271 require 2 KB
+ * to work around a hardware issue, all other devices
+ * have can use the max 4 KB limit.
+ */
+#define MAX_TX_FIFO_THRESHOLD   ((4096 / 64) - 1)
+
+struct ath_tx_status {
+       u32 ts_tstamp;
+       u16 ts_seqnum;
+       u8 ts_status;
+       u8 ts_rateindex;
+       int8_t ts_rssi;
+       u8 ts_shortretry;
+       u8 ts_longretry;
+       u8 ts_virtcol;
+       u8 ts_flags;
+       int8_t ts_rssi_ctl0;
+       int8_t ts_rssi_ctl1;
+       int8_t ts_rssi_ctl2;
+       int8_t ts_rssi_ext0;
+       int8_t ts_rssi_ext1;
+       int8_t ts_rssi_ext2;
+       u8 qid;
+       u16 desc_id;
+       u8 tid;
+       u32 ba_low;
+       u32 ba_high;
+       u32 evm0;
+       u32 evm1;
+       u32 evm2;
+};
+
+struct ath_rx_status {
+       u32 rs_tstamp;
+       u16 rs_datalen;
+       u8 rs_status;
+       u8 rs_phyerr;
+       int8_t rs_rssi;
+       u8 rs_keyix;
+       u8 rs_rate;
+       u8 rs_antenna;
+       u8 rs_more;
+       int8_t rs_rssi_ctl0;
+       int8_t rs_rssi_ctl1;
+       int8_t rs_rssi_ctl2;
+       int8_t rs_rssi_ext0;
+       int8_t rs_rssi_ext1;
+       int8_t rs_rssi_ext2;
+       u8 rs_isaggr;
+       u8 rs_moreaggr;
+       u8 rs_num_delims;
+       u8 rs_flags;
+       u32 evm0;
+       u32 evm1;
+       u32 evm2;
+       u32 evm3;
+       u32 evm4;
+};
+
+struct ath_htc_rx_status {
+       uint64_t rs_tstamp;
+       uint16_t rs_datalen;
+       u8 rs_status;
+       u8 rs_phyerr;
+       int8_t rs_rssi;
+       int8_t rs_rssi_ctl0;
+       int8_t rs_rssi_ctl1;
+       int8_t rs_rssi_ctl2;
+       int8_t rs_rssi_ext0;
+       int8_t rs_rssi_ext1;
+       int8_t rs_rssi_ext2;
+       u8 rs_keyix;
+       u8 rs_rate;
+       u8 rs_antenna;
+       u8 rs_more;
+       u8 rs_isaggr;
+       u8 rs_moreaggr;
+       u8 rs_num_delims;
+       u8 rs_flags;
+       u8 rs_dummy;
+       uint32_t evm0;
+       uint32_t evm1;
+       uint32_t evm2;
+};
+
+#define ATH9K_RXERR_CRC           0x01
+#define ATH9K_RXERR_PHY           0x02
+#define ATH9K_RXERR_FIFO          0x04
+#define ATH9K_RXERR_DECRYPT       0x08
+#define ATH9K_RXERR_MIC           0x10
+
+#define ATH9K_RX_MORE             0x01
+#define ATH9K_RX_MORE_AGGR        0x02
+#define ATH9K_RX_GI               0x04
+#define ATH9K_RX_2040             0x08
+#define ATH9K_RX_DELIM_CRC_PRE    0x10
+#define ATH9K_RX_DELIM_CRC_POST   0x20
+#define ATH9K_RX_DECRYPT_BUSY     0x40
+
+#define ATH9K_RXKEYIX_INVALID  ((u8)-1)
+#define ATH9K_TXKEYIX_INVALID  ((u32)-1)
+
+enum ath9k_phyerr {
+       ATH9K_PHYERR_UNDERRUN             = 0,  /* Transmit underrun */
+       ATH9K_PHYERR_TIMING               = 1,  /* Timing error */
+       ATH9K_PHYERR_PARITY               = 2,  /* Illegal parity */
+       ATH9K_PHYERR_RATE                 = 3,  /* Illegal rate */
+       ATH9K_PHYERR_LENGTH               = 4,  /* Illegal length */
+       ATH9K_PHYERR_RADAR                = 5,  /* Radar detect */
+       ATH9K_PHYERR_SERVICE              = 6,  /* Illegal service */
+       ATH9K_PHYERR_TOR                  = 7,  /* Transmit override receive */
+
+       ATH9K_PHYERR_OFDM_TIMING          = 17,
+       ATH9K_PHYERR_OFDM_SIGNAL_PARITY   = 18,
+       ATH9K_PHYERR_OFDM_RATE_ILLEGAL    = 19,
+       ATH9K_PHYERR_OFDM_LENGTH_ILLEGAL  = 20,
+       ATH9K_PHYERR_OFDM_POWER_DROP      = 21,
+       ATH9K_PHYERR_OFDM_SERVICE         = 22,
+       ATH9K_PHYERR_OFDM_RESTART         = 23,
+       ATH9K_PHYERR_FALSE_RADAR_EXT      = 24,
+
+       ATH9K_PHYERR_CCK_TIMING           = 25,
+       ATH9K_PHYERR_CCK_HEADER_CRC       = 26,
+       ATH9K_PHYERR_CCK_RATE_ILLEGAL     = 27,
+       ATH9K_PHYERR_CCK_SERVICE          = 30,
+       ATH9K_PHYERR_CCK_RESTART          = 31,
+       ATH9K_PHYERR_CCK_LENGTH_ILLEGAL   = 32,
+       ATH9K_PHYERR_CCK_POWER_DROP       = 33,
+
+       ATH9K_PHYERR_HT_CRC_ERROR         = 34,
+       ATH9K_PHYERR_HT_LENGTH_ILLEGAL    = 35,
+       ATH9K_PHYERR_HT_RATE_ILLEGAL      = 36,
+
+       ATH9K_PHYERR_MAX                  = 37,
+};
+
+struct ath_desc {
+       u32 ds_link;
+       u32 ds_data;
+       u32 ds_ctl0;
+       u32 ds_ctl1;
+       u32 ds_hw[20];
+//     void *ds_vdata;
+} __attribute__((packed, aligned(4)));
+
+#define ATH9K_TXDESC_NOACK             0x0002
+#define ATH9K_TXDESC_RTSENA            0x0004
+#define ATH9K_TXDESC_CTSENA            0x0008
+/* ATH9K_TXDESC_INTREQ forces a tx interrupt to be generated for
+ * the descriptor its marked on.  We take a tx interrupt to reap
+ * descriptors when the h/w hits an EOL condition or
+ * when the descriptor is specifically marked to generate
+ * an interrupt with this flag. Descriptors should be
+ * marked periodically to insure timely replenishing of the
+ * supply needed for sending frames. Defering interrupts
+ * reduces system load and potentially allows more concurrent
+ * work to be done but if done to aggressively can cause
+ * senders to backup. When the hardware queue is left too
+ * large rate control information may also be too out of
+ * date. An Alternative for this is TX interrupt mitigation
+ * but this needs more testing. */
+#define ATH9K_TXDESC_INTREQ            0x0010
+#define ATH9K_TXDESC_VEOL              0x0020
+#define ATH9K_TXDESC_EXT_ONLY          0x0040
+#define ATH9K_TXDESC_EXT_AND_CTL       0x0080
+#define ATH9K_TXDESC_VMF               0x0100
+#define ATH9K_TXDESC_FRAG_IS_ON        0x0200
+#define ATH9K_TXDESC_LOWRXCHAIN                0x0400
+#define ATH9K_TXDESC_LDPC              0x00010000
+
+#define ATH9K_RXDESC_INTREQ            0x0020
+
+struct ar5416_desc {
+       u32 ds_link;
+       u32 ds_data;
+       u32 ds_ctl0;
+       u32 ds_ctl1;
+       union {
+               struct {
+                       u32 ctl2;
+                       u32 ctl3;
+                       u32 ctl4;
+                       u32 ctl5;
+                       u32 ctl6;
+                       u32 ctl7;
+                       u32 ctl8;
+                       u32 ctl9;
+                       u32 ctl10;
+                       u32 ctl11;
+                       u32 status0;
+                       u32 status1;
+                       u32 status2;
+                       u32 status3;
+                       u32 status4;
+                       u32 status5;
+                       u32 status6;
+                       u32 status7;
+                       u32 status8;
+                       u32 status9;
+               } tx;
+               struct {
+                       u32 status0;
+                       u32 status1;
+                       u32 status2;
+                       u32 status3;
+                       u32 status4;
+                       u32 status5;
+                       u32 status6;
+                       u32 status7;
+                       u32 status8;
+               } rx;
+       } u;
+} __attribute__((packed, aligned(4)));
+
+#define AR5416DESC(_ds)         ((struct ar5416_desc *)(_ds))
+#define AR5416DESC_CONST(_ds)   ((const struct ar5416_desc *)(_ds))
+
+#define ds_ctl2     u.tx.ctl2
+#define ds_ctl3     u.tx.ctl3
+#define ds_ctl4     u.tx.ctl4
+#define ds_ctl5     u.tx.ctl5
+#define ds_ctl6     u.tx.ctl6
+#define ds_ctl7     u.tx.ctl7
+#define ds_ctl8     u.tx.ctl8
+#define ds_ctl9     u.tx.ctl9
+#define ds_ctl10    u.tx.ctl10
+#define ds_ctl11    u.tx.ctl11
+
+#define ds_txstatus0    u.tx.status0
+#define ds_txstatus1    u.tx.status1
+#define ds_txstatus2    u.tx.status2
+#define ds_txstatus3    u.tx.status3
+#define ds_txstatus4    u.tx.status4
+#define ds_txstatus5    u.tx.status5
+#define ds_txstatus6    u.tx.status6
+#define ds_txstatus7    u.tx.status7
+#define ds_txstatus8    u.tx.status8
+#define ds_txstatus9    u.tx.status9
+
+#define ds_rxstatus0    u.rx.status0
+#define ds_rxstatus1    u.rx.status1
+#define ds_rxstatus2    u.rx.status2
+#define ds_rxstatus3    u.rx.status3
+#define ds_rxstatus4    u.rx.status4
+#define ds_rxstatus5    u.rx.status5
+#define ds_rxstatus6    u.rx.status6
+#define ds_rxstatus7    u.rx.status7
+#define ds_rxstatus8    u.rx.status8
+
+#define AR_FrameLen         0x00000fff
+#define AR_VirtMoreFrag     0x00001000
+#define AR_TxCtlRsvd00      0x0000e000
+#define AR_XmitPower        0x003f0000
+#define AR_XmitPower_S      16
+#define AR_RTSEnable        0x00400000
+#define AR_VEOL             0x00800000
+#define AR_ClrDestMask      0x01000000
+#define AR_TxCtlRsvd01      0x1e000000
+#define AR_TxIntrReq        0x20000000
+#define AR_DestIdxValid     0x40000000
+#define AR_CTSEnable        0x80000000
+
+#define AR_TxMore           0x00001000
+#define AR_DestIdx          0x000fe000
+#define AR_DestIdx_S        13
+#define AR_FrameType        0x00f00000
+#define AR_FrameType_S      20
+#define AR_NoAck            0x01000000
+#define AR_InsertTS         0x02000000
+#define AR_CorruptFCS       0x04000000
+#define AR_ExtOnly          0x08000000
+#define AR_ExtAndCtl        0x10000000
+#define AR_MoreAggr         0x20000000
+#define AR_IsAggr           0x40000000
+
+#define AR_BurstDur         0x00007fff
+#define AR_BurstDur_S       0
+#define AR_DurUpdateEna     0x00008000
+#define AR_XmitDataTries0   0x000f0000
+#define AR_XmitDataTries0_S 16
+#define AR_XmitDataTries1   0x00f00000
+#define AR_XmitDataTries1_S 20
+#define AR_XmitDataTries2   0x0f000000
+#define AR_XmitDataTries2_S 24
+#define AR_XmitDataTries3   0xf0000000
+#define AR_XmitDataTries3_S 28
+
+#define AR_XmitRate0        0x000000ff
+#define AR_XmitRate0_S      0
+#define AR_XmitRate1        0x0000ff00
+#define AR_XmitRate1_S      8
+#define AR_XmitRate2        0x00ff0000
+#define AR_XmitRate2_S      16
+#define AR_XmitRate3        0xff000000
+#define AR_XmitRate3_S      24
+
+#define AR_PacketDur0       0x00007fff
+#define AR_PacketDur0_S     0
+#define AR_RTSCTSQual0      0x00008000
+#define AR_PacketDur1       0x7fff0000
+#define AR_PacketDur1_S     16
+#define AR_RTSCTSQual1      0x80000000
+
+#define AR_PacketDur2       0x00007fff
+#define AR_PacketDur2_S     0
+#define AR_RTSCTSQual2      0x00008000
+#define AR_PacketDur3       0x7fff0000
+#define AR_PacketDur3_S     16
+#define AR_RTSCTSQual3      0x80000000
+
+#define AR_AggrLen          0x0000ffff
+#define AR_AggrLen_S        0
+#define AR_TxCtlRsvd60      0x00030000
+#define AR_PadDelim         0x03fc0000
+#define AR_PadDelim_S       18
+#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
+#define AR_ChainSel0        0x0000001c
+#define AR_ChainSel0_S      2
+#define AR_2040_1           0x00000020
+#define AR_GI1              0x00000040
+#define AR_ChainSel1        0x00000380
+#define AR_ChainSel1_S      7
+#define AR_2040_2           0x00000400
+#define AR_GI2              0x00000800
+#define AR_ChainSel2        0x00007000
+#define AR_ChainSel2_S      12
+#define AR_2040_3           0x00008000
+#define AR_GI3              0x00010000
+#define AR_ChainSel3        0x000e0000
+#define AR_ChainSel3_S      17
+#define AR_RTSCTSRate       0x0ff00000
+#define AR_RTSCTSRate_S     20
+#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
+#define AR_TxRSSIAnt01      0x0000ff00
+#define AR_TxRSSIAnt01_S    8
+#define AR_TxRSSIAnt02      0x00ff0000
+#define AR_TxRSSIAnt02_S    16
+#define AR_TxStatusRsvd00   0x3f000000
+#define AR_TxBaStatus       0x40000000
+#define AR_TxStatusRsvd01   0x80000000
+
+/*
+ * AR_FrmXmitOK - Frame transmission success flag. If set, the frame was
+ * transmitted successfully. If clear, no ACK or BA was received to indicate
+ * successful transmission when we were expecting an ACK or BA.
+ */
+#define AR_FrmXmitOK            0x00000001
+#define AR_ExcessiveRetries     0x00000002
+#define AR_FIFOUnderrun         0x00000004
+#define AR_Filtered             0x00000008
+#define AR_RTSFailCnt           0x000000f0
+#define AR_RTSFailCnt_S         4
+#define AR_DataFailCnt          0x00000f00
+#define AR_DataFailCnt_S        8
+#define AR_VirtRetryCnt         0x0000f000
+#define AR_VirtRetryCnt_S       12
+#define AR_TxDelimUnderrun      0x00010000
+#define AR_TxDataUnderrun       0x00020000
+#define AR_DescCfgErr           0x00040000
+#define AR_TxTimerExpired       0x00080000
+#define AR_TxStatusRsvd10       0xfff00000
+
+#define AR_SendTimestamp    ds_txstatus2
+#define AR_BaBitmapLow      ds_txstatus3
+#define AR_BaBitmapHigh     ds_txstatus4
+
+#define AR_TxRSSIAnt10      0x000000ff
+#define AR_TxRSSIAnt10_S    0
+#define AR_TxRSSIAnt11      0x0000ff00
+#define AR_TxRSSIAnt11_S    8
+#define AR_TxRSSIAnt12      0x00ff0000
+#define AR_TxRSSIAnt12_S    16
+#define AR_TxRSSICombined   0xff000000
+#define AR_TxRSSICombined_S 24
+
+#define AR_TxTid       0xf0000000
+#define AR_TxTid_S     28
+
+#define AR_TxEVM0           ds_txstatus5
+#define AR_TxEVM1           ds_txstatus6
+#define AR_TxEVM2           ds_txstatus7
+
+#define AR_TxDone           0x00000001
+#define AR_SeqNum           0x00001ffe
+#define AR_SeqNum_S         1
+#define AR_TxStatusRsvd80   0x0001e000
+#define AR_TxOpExceeded     0x00020000
+#define AR_TxStatusRsvd81   0x001c0000
+#define AR_FinalTxIdx       0x00600000
+#define AR_FinalTxIdx_S     21
+#define AR_TxStatusRsvd82   0x01800000
+#define AR_PowerMgmt        0x02000000
+#define AR_TxStatusRsvd83   0xfc000000
+
+#define AR_RxCTLRsvd00  0xffffffff
+
+#define AR_RxCtlRsvd00  0x00001000
+#define AR_RxIntrReq    0x00002000
+#define AR_RxCtlRsvd01  0xffffc000
+
+#define AR_RxRSSIAnt00      0x000000ff
+#define AR_RxRSSIAnt00_S    0
+#define AR_RxRSSIAnt01      0x0000ff00
+#define AR_RxRSSIAnt01_S    8
+#define AR_RxRSSIAnt02      0x00ff0000
+#define AR_RxRSSIAnt02_S    16
+#define AR_RxRate           0xff000000
+#define AR_RxRate_S         24
+#define AR_RxStatusRsvd00   0xff000000
+
+#define AR_DataLen          0x00000fff
+#define AR_RxMore           0x00001000
+#define AR_NumDelim         0x003fc000
+#define AR_NumDelim_S       14
+#define AR_RxStatusRsvd10   0xff800000
+
+#define AR_RcvTimestamp     ds_rxstatus2
+
+#define AR_GI               0x00000001
+#define AR_2040             0x00000002
+#define AR_Parallel40       0x00000004
+#define AR_Parallel40_S     2
+#define AR_RxStatusRsvd30   0x000000f8
+#define AR_RxAntenna       0xffffff00
+#define AR_RxAntenna_S     8
+
+#define AR_RxRSSIAnt10            0x000000ff
+#define AR_RxRSSIAnt10_S          0
+#define AR_RxRSSIAnt11            0x0000ff00
+#define AR_RxRSSIAnt11_S          8
+#define AR_RxRSSIAnt12            0x00ff0000
+#define AR_RxRSSIAnt12_S          16
+#define AR_RxRSSICombined         0xff000000
+#define AR_RxRSSICombined_S       24
+
+#define AR_RxEVM0           ds_rxstatus4
+#define AR_RxEVM1           ds_rxstatus5
+#define AR_RxEVM2           ds_rxstatus6
+
+#define AR_RxDone           0x00000001
+#define AR_RxFrameOK        0x00000002
+#define AR_CRCErr           0x00000004
+#define AR_DecryptCRCErr    0x00000008
+#define AR_PHYErr           0x00000010
+#define AR_MichaelErr       0x00000020
+#define AR_PreDelimCRCErr   0x00000040
+#define AR_RxStatusRsvd70   0x00000080
+#define AR_RxKeyIdxValid    0x00000100
+#define AR_KeyIdx           0x0000fe00
+#define AR_KeyIdx_S         9
+#define AR_PHYErrCode       0x0000ff00
+#define AR_PHYErrCode_S     8
+#define AR_RxMoreAggr       0x00010000
+#define AR_RxAggr           0x00020000
+#define AR_PostDelimCRCErr  0x00040000
+#define AR_RxStatusRsvd71   0x3ff80000
+#define AR_DecryptBusyErr   0x40000000
+#define AR_KeyMiss          0x80000000
+
+enum ath9k_tx_queue {
+       ATH9K_TX_QUEUE_INACTIVE = 0,
+       ATH9K_TX_QUEUE_DATA,
+};
+
+#define        ATH9K_NUM_TX_QUEUES 1
+
+/* Used as a queue subtype instead of a WMM AC */
+#define ATH9K_WME_UPSD 4
+
+enum ath9k_tx_queue_flags {
+       TXQ_FLAG_TXOKINT_ENABLE = 0x0001,
+       TXQ_FLAG_TXERRINT_ENABLE = 0x0001,
+       TXQ_FLAG_TXDESCINT_ENABLE = 0x0002,
+       TXQ_FLAG_TXEOLINT_ENABLE = 0x0004,
+       TXQ_FLAG_TXURNINT_ENABLE = 0x0008,
+       TXQ_FLAG_BACKOFF_DISABLE = 0x0010,
+       TXQ_FLAG_COMPRESSION_ENABLE = 0x0020,
+       TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE = 0x0040,
+       TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE = 0x0080,
+};
+
+#define ATH9K_TXQ_USEDEFAULT ((u32) -1)
+#define ATH9K_TXQ_USE_LOCKOUT_BKOFF_DIS 0x00000001
+
+#define ATH9K_DECOMP_MASK_SIZE     128
+#define ATH9K_READY_TIME_LO_BOUND  50
+#define ATH9K_READY_TIME_HI_BOUND  96
+
+enum ath9k_pkt_type {
+       ATH9K_PKT_TYPE_NORMAL = 0,
+       ATH9K_PKT_TYPE_ATIM,
+       ATH9K_PKT_TYPE_PSPOLL,
+       ATH9K_PKT_TYPE_BEACON,
+       ATH9K_PKT_TYPE_PROBE_RESP,
+       ATH9K_PKT_TYPE_CHIRP,
+       ATH9K_PKT_TYPE_GRP_POLL,
+};
+
+struct ath9k_tx_queue_info {
+       u32 tqi_ver;
+       enum ath9k_tx_queue tqi_type;
+       int tqi_subtype;
+       enum ath9k_tx_queue_flags tqi_qflags;
+       u32 tqi_priority;
+       u32 tqi_aifs;
+       u32 tqi_cwmin;
+       u32 tqi_cwmax;
+       u16 tqi_shretry;
+       u16 tqi_lgretry;
+       u32 tqi_cbrPeriod;
+       u32 tqi_cbrOverflowLimit;
+       u32 tqi_burstTime;
+       u32 tqi_readyTime;
+       u32 tqi_physCompBuf;
+       u32 tqi_intFlags;
+};
+
+enum ath9k_rx_filter {
+       ATH9K_RX_FILTER_UCAST = 0x00000001,
+       ATH9K_RX_FILTER_MCAST = 0x00000002,
+       ATH9K_RX_FILTER_BCAST = 0x00000004,
+       ATH9K_RX_FILTER_CONTROL = 0x00000008,
+       ATH9K_RX_FILTER_BEACON = 0x00000010,
+       ATH9K_RX_FILTER_PROM = 0x00000020,
+       ATH9K_RX_FILTER_PROBEREQ = 0x00000080,
+       ATH9K_RX_FILTER_PHYERR = 0x00000100,
+       ATH9K_RX_FILTER_MYBEACON = 0x00000200,
+       ATH9K_RX_FILTER_COMP_BAR = 0x00000400,
+       ATH9K_RX_FILTER_COMP_BA = 0x00000800,
+       ATH9K_RX_FILTER_UNCOMP_BA_BAR = 0x00001000,
+       ATH9K_RX_FILTER_PSPOLL = 0x00004000,
+       ATH9K_RX_FILTER_PHYRADAR = 0x00002000,
+       ATH9K_RX_FILTER_MCAST_BCAST_ALL = 0x00008000,
+};
+
+#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;
+       u32 Rate;
+       u32 PktDuration;
+       u32 ChSel;
+       u32 RateFlags;
+};
+
+enum ath9k_key_type {
+       ATH9K_KEY_TYPE_CLEAR,
+       ATH9K_KEY_TYPE_WEP,
+       ATH9K_KEY_TYPE_AES,
+       ATH9K_KEY_TYPE_TKIP,
+};
+
+struct ath_hw;
+struct ath9k_channel;
+enum ath9k_int;
+
+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);
+int ath9k_hw_updatetxtriglevel(struct ath_hw *ah, int bIncTrigLevel);
+int ath9k_hw_stop_dma_queue(struct ath_hw *ah, u32 q);
+void ath9k_hw_abort_tx_dma(struct ath_hw *ah);
+void ath9k_hw_gettxintrtxqs(struct ath_hw *ah, u32 *txqs);
+int ath9k_hw_set_txq_props(struct ath_hw *ah, int q,
+                           const struct ath9k_tx_queue_info *qinfo);
+int ath9k_hw_get_txq_props(struct ath_hw *ah, int q,
+                           struct ath9k_tx_queue_info *qinfo);
+int ath9k_hw_setuptxqueue(struct ath_hw *ah, enum ath9k_tx_queue type,
+                         const struct ath9k_tx_queue_info *qinfo);
+int ath9k_hw_releasetxqueue(struct ath_hw *ah, u32 q);
+int ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q);
+int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds,
+                       struct ath_rx_status *rs, u64 tsf);
+void ath9k_hw_setuprxdesc(struct ath_hw *ah, struct ath_desc *ds,
+                         u32 size, u32 flags);
+int ath9k_hw_setrxabort(struct ath_hw *ah, int set);
+void ath9k_hw_putrxbuf(struct ath_hw *ah, u32 rxdp);
+void ath9k_hw_startpcureceive(struct ath_hw *ah, int is_scanning);
+void ath9k_hw_abortpcurecv(struct ath_hw *ah);
+int ath9k_hw_stopdmarecv(struct ath_hw *ah, int *reset);
+
+/* Interrupt Handling */
+int ath9k_hw_intrpend(struct ath_hw *ah);
+void ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints);
+void ath9k_hw_enable_interrupts(struct ath_hw *ah);
+void ath9k_hw_disable_interrupts(struct ath_hw *ah);
+
+void ar9002_hw_attach_mac_ops(struct ath_hw *ah);
+
+#endif /* MAC_H */
diff --git a/src/drivers/net/ath/ath9k/phy.h b/src/drivers/net/ath/ath9k/phy.h
new file mode 100644 (file)
index 0000000..8b38030
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2008-2011 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 PHY_H
+#define PHY_H
+
+#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_TX_PWRCTRL_TX_GAIN_TAB_MAX   0x0007E000
+#define AR_PHY_TX_PWRCTRL_TX_GAIN_TAB_MAX_S 13
+#define AR_PHY_TX_GAIN_CLC       0x0000001E
+#define AR_PHY_TX_GAIN_CLC_S     1
+#define AR_PHY_TX_GAIN           0x0007F000
+#define AR_PHY_TX_GAIN_S         12
+
+#define AR_PHY_CLC_TBL1      0xa35c
+#define AR_PHY_CLC_I0        0x07ff0000
+#define AR_PHY_CLC_I0_S      16
+#define AR_PHY_CLC_Q0        0x0000ffd0
+#define AR_PHY_CLC_Q0_S      5
+
+#define ANTSWAP_AB 0x0001
+#define REDUCE_CHAIN_0 0x00000050
+#define REDUCE_CHAIN_1 0x00000051
+#define AR_PHY_CHIP_ID 0x9818
+
+#define        AR_PHY_TIMING11_SPUR_FREQ_SD            0x3FF00000
+#define        AR_PHY_TIMING11_SPUR_FREQ_SD_S          20
+
+#define AR_PHY_PLL_CONTROL 0x16180
+#define AR_PHY_PLL_MODE 0x16184
+
+#endif
diff --git a/src/drivers/net/ath/ath9k/reg.h b/src/drivers/net/ath/ath9k/reg.h
new file mode 100644 (file)
index 0000000..c18ee99
--- /dev/null
@@ -0,0 +1,1919 @@
+/*
+ * Copyright (c) 2008-2011 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 REG_H
+#define REG_H
+
+#include "../reg.h"
+
+#define AR_CR                0x0008
+#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_RXDP              0x000C
+
+#define AR_CFG               0x0014
+#define AR_CFG_SWTD          0x00000001
+#define AR_CFG_SWTB          0x00000002
+#define AR_CFG_SWRD          0x00000004
+#define AR_CFG_SWRB          0x00000008
+#define AR_CFG_SWRG          0x00000010
+#define AR_CFG_AP_ADHOC_INDICATION 0x00000020
+#define AR_CFG_PHOK          0x00000100
+#define AR_CFG_CLK_GATE_DIS  0x00000400
+#define AR_CFG_EEBS          0x00000200
+#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_IER               0x0024
+#define AR_IER_ENABLE        0x00000001
+#define AR_IER_DISABLE       0x00000000
+
+#define AR_TIMT              0x0028
+#define AR_TIMT_LAST         0x0000ffff
+#define AR_TIMT_LAST_S       0
+#define AR_TIMT_FIRST        0xffff0000
+#define AR_TIMT_FIRST_S      16
+
+#define AR_RIMT              0x002C
+#define AR_RIMT_LAST         0x0000ffff
+#define AR_RIMT_LAST_S       0
+#define AR_RIMT_FIRST        0xffff0000
+#define AR_RIMT_FIRST_S      16
+
+#define AR_DMASIZE_4B        0x00000000
+#define AR_DMASIZE_8B        0x00000001
+#define AR_DMASIZE_16B       0x00000002
+#define AR_DMASIZE_32B       0x00000003
+#define AR_DMASIZE_64B       0x00000004
+#define AR_DMASIZE_128B      0x00000005
+#define AR_DMASIZE_256B      0x00000006
+#define AR_DMASIZE_512B      0x00000007
+
+#define AR_TXCFG             0x0030
+#define AR_TXCFG_DMASZ_MASK  0x00000007
+#define AR_TXCFG_DMASZ_4B    0
+#define AR_TXCFG_DMASZ_8B    1
+#define AR_TXCFG_DMASZ_16B   2
+#define AR_TXCFG_DMASZ_32B   3
+#define AR_TXCFG_DMASZ_64B   4
+#define AR_TXCFG_DMASZ_128B  5
+#define AR_TXCFG_DMASZ_256B  6
+#define AR_TXCFG_DMASZ_512B  7
+#define AR_FTRIG             0x000003F0
+#define AR_FTRIG_S           4
+#define AR_FTRIG_IMMED       0x00000000
+#define AR_FTRIG_64B         0x00000010
+#define AR_FTRIG_128B        0x00000020
+#define AR_FTRIG_192B        0x00000030
+#define AR_FTRIG_256B        0x00000040
+#define AR_FTRIG_512B        0x00000080
+#define AR_TXCFG_ADHOC_BEACON_ATIM_TX_POLICY 0x00000800
+
+#define AR_RXCFG             0x0034
+#define AR_RXCFG_CHIRP       0x00000008
+#define AR_RXCFG_ZLFDMA      0x00000010
+#define AR_RXCFG_DMASZ_MASK  0x00000007
+#define AR_RXCFG_DMASZ_4B    0
+#define AR_RXCFG_DMASZ_8B    1
+#define AR_RXCFG_DMASZ_16B   2
+#define AR_RXCFG_DMASZ_32B   3
+#define AR_RXCFG_DMASZ_64B   4
+#define AR_RXCFG_DMASZ_128B  5
+#define AR_RXCFG_DMASZ_256B  6
+#define AR_RXCFG_DMASZ_512B  7
+
+#define AR_TOPS              0x0044
+#define AR_TOPS_MASK         0x0000FFFF
+
+#define AR_RXNPTO            0x0048
+#define AR_RXNPTO_MASK       0x000003FF
+
+#define AR_TXNPTO            0x004C
+#define AR_TXNPTO_MASK       0x000003FF
+#define AR_TXNPTO_QCU_MASK   0x000FFC00
+
+#define AR_RPGTO             0x0050
+#define AR_RPGTO_MASK        0x000003FF
+
+#define AR_RPCNT             0x0054
+#define AR_RPCNT_MASK        0x0000001F
+
+#define AR_MACMISC           0x0058
+#define AR_MACMISC_PCI_EXT_FORCE        0x00000010
+#define AR_MACMISC_DMA_OBS              0x000001E0
+#define AR_MACMISC_DMA_OBS_S            5
+#define AR_MACMISC_DMA_OBS_LINE_0       0
+#define AR_MACMISC_DMA_OBS_LINE_1       1
+#define AR_MACMISC_DMA_OBS_LINE_2       2
+#define AR_MACMISC_DMA_OBS_LINE_3       3
+#define AR_MACMISC_DMA_OBS_LINE_4       4
+#define AR_MACMISC_DMA_OBS_LINE_5       5
+#define AR_MACMISC_DMA_OBS_LINE_6       6
+#define AR_MACMISC_DMA_OBS_LINE_7       7
+#define AR_MACMISC_DMA_OBS_LINE_8       8
+#define AR_MACMISC_MISC_OBS             0x00000E00
+#define AR_MACMISC_MISC_OBS_S           9
+#define AR_MACMISC_MISC_OBS_BUS_LSB     0x00007000
+#define AR_MACMISC_MISC_OBS_BUS_LSB_S   12
+#define AR_MACMISC_MISC_OBS_BUS_MSB     0x00038000
+#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_GTXTO_TIMEOUT_LIMIT_S    16
+
+#define AR_GTTM     0x0068
+#define AR_GTTM_USEC          0x00000001
+#define AR_GTTM_IGNORE_IDLE   0x00000002
+#define AR_GTTM_RESET_IDLE    0x00000004
+#define AR_GTTM_CST_USEC      0x00000008
+
+#define AR_CST         0x006C
+#define AR_CST_TIMEOUT_COUNTER    0x0000FFFF
+#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_RXORN         0x00000020
+#define AR_ISR_TXOK          0x00000040
+#define AR_ISR_TXDESC        0x00000080
+#define AR_ISR_TXERR         0x00000100
+#define AR_ISR_TXNOPKT       0x00000200
+#define AR_ISR_TXEOL         0x00000400
+#define AR_ISR_TXURN         0x00000800
+#define AR_ISR_MIB           0x00001000
+#define AR_ISR_SWI           0x00002000
+#define AR_ISR_RXPHY         0x00004000
+#define AR_ISR_RXKCM         0x00008000
+#define AR_ISR_SWBA          0x00010000
+#define AR_ISR_BRSSI         0x00020000
+#define AR_ISR_BMISS         0x00040000
+#define AR_ISR_BNR           0x00100000
+#define AR_ISR_RXCHIRP       0x00200000
+#define AR_ISR_BCNMISC       0x00800000
+#define AR_ISR_TIM           0x00800000
+#define AR_ISR_QCBROVF       0x02000000
+#define AR_ISR_QCBRURN       0x04000000
+#define AR_ISR_QTRIG         0x08000000
+#define AR_ISR_GENTMR        0x10000000
+
+#define AR_ISR_TXMINTR       0x00080000
+#define AR_ISR_RXMINTR       0x01000000
+#define AR_ISR_TXINTM        0x40000000
+#define AR_ISR_RXINTM        0x80000000
+
+#define AR_ISR_S0               0x0084
+#define AR_ISR_S0_QCU_TXOK      0x000003FF
+#define AR_ISR_S0_QCU_TXOK_S    0
+#define AR_ISR_S0_QCU_TXDESC    0x03FF0000
+#define AR_ISR_S0_QCU_TXDESC_S  16
+
+#define AR_ISR_S1              0x0088
+#define AR_ISR_S1_QCU_TXERR    0x000003FF
+#define AR_ISR_S1_QCU_TXERR_S  0
+#define AR_ISR_S1_QCU_TXEOL    0x03FF0000
+#define AR_ISR_S1_QCU_TXEOL_S  16
+
+#define AR_ISR_S2              0x008c
+#define AR_ISR_S2_QCU_TXURN    0x000003FF
+#define AR_ISR_S2_BB_WATCHDOG  0x00010000
+#define AR_ISR_S2_CST          0x00400000
+#define AR_ISR_S2_GTT          0x00800000
+#define AR_ISR_S2_TIM          0x01000000
+#define AR_ISR_S2_CABEND       0x02000000
+#define AR_ISR_S2_DTIMSYNC     0x04000000
+#define AR_ISR_S2_BCNTO        0x08000000
+#define AR_ISR_S2_CABTO        0x10000000
+#define AR_ISR_S2_DTIM         0x20000000
+#define AR_ISR_S2_TSFOOR       0x40000000
+#define AR_ISR_S2_TBTT_TIME    0x80000000
+
+#define AR_ISR_S3             0x0090
+#define AR_ISR_S3_QCU_QCBROVF    0x000003FF
+#define AR_ISR_S3_QCU_QCBRURN    0x03FF0000
+
+#define AR_ISR_S4              0x0094
+#define AR_ISR_S4_QCU_QTRIG    0x000003FF
+#define AR_ISR_S4_RESV0        0xFFFFFC00
+
+#define AR_ISR_S5                   0x0098
+#define AR_ISR_S5_TIMER_TRIG        0x000000FF
+#define AR_ISR_S5_TIMER_THRESH      0x0007FE00
+#define AR_ISR_S5_TIM_TIMER         0x00000010
+#define AR_ISR_S5_DTIM_TIMER        0x00000020
+#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     0x0000FF80
+#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_IMR_S5_GENTIMER_TRIG     0x0000FF80
+#define AR_IMR_S5_GENTIMER_TRIG_S   0
+#define AR_IMR_S5_GENTIMER_THRESH   0xFF800000
+#define AR_IMR_S5_GENTIMER_THRESH_S 16
+
+#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_IMR_RXORN         0x00000020
+#define AR_IMR_TXOK          0x00000040
+#define AR_IMR_TXDESC        0x00000080
+#define AR_IMR_TXERR         0x00000100
+#define AR_IMR_TXNOPKT       0x00000200
+#define AR_IMR_TXEOL         0x00000400
+#define AR_IMR_TXURN         0x00000800
+#define AR_IMR_MIB           0x00001000
+#define AR_IMR_SWI           0x00002000
+#define AR_IMR_RXPHY         0x00004000
+#define AR_IMR_RXKCM         0x00008000
+#define AR_IMR_SWBA          0x00010000
+#define AR_IMR_BRSSI         0x00020000
+#define AR_IMR_BMISS         0x00040000
+#define AR_IMR_BNR           0x00100000
+#define AR_IMR_RXCHIRP       0x00200000
+#define AR_IMR_BCNMISC       0x00800000
+#define AR_IMR_TIM           0x00800000
+#define AR_IMR_QCBROVF       0x02000000
+#define AR_IMR_QCBRURN       0x04000000
+#define AR_IMR_QTRIG         0x08000000
+#define AR_IMR_GENTMR        0x10000000
+
+#define AR_IMR_TXMINTR       0x00080000
+#define AR_IMR_RXMINTR       0x01000000
+#define AR_IMR_TXINTM        0x40000000
+#define AR_IMR_RXINTM        0x80000000
+
+#define AR_IMR_S0               0x00a4
+#define AR_IMR_S0_QCU_TXOK      0x000003FF
+#define AR_IMR_S0_QCU_TXOK_S    0
+#define AR_IMR_S0_QCU_TXDESC    0x03FF0000
+#define AR_IMR_S0_QCU_TXDESC_S  16
+
+#define AR_IMR_S1              0x00a8
+#define AR_IMR_S1_QCU_TXERR    0x000003FF
+#define AR_IMR_S1_QCU_TXERR_S  0
+#define AR_IMR_S1_QCU_TXEOL    0x03FF0000
+#define AR_IMR_S1_QCU_TXEOL_S  16
+
+#define AR_IMR_S2              0x00ac
+#define AR_IMR_S2_QCU_TXURN    0x000003FF
+#define AR_IMR_S2_QCU_TXURN_S  0
+#define AR_IMR_S2_CST          0x00400000
+#define AR_IMR_S2_GTT          0x00800000
+#define AR_IMR_S2_TIM          0x01000000
+#define AR_IMR_S2_CABEND       0x02000000
+#define AR_IMR_S2_DTIMSYNC     0x04000000
+#define AR_IMR_S2_BCNTO        0x08000000
+#define AR_IMR_S2_CABTO        0x10000000
+#define AR_IMR_S2_DTIM         0x20000000
+#define AR_IMR_S2_TSFOOR       0x40000000
+
+#define AR_IMR_S3                0x00b0
+#define AR_IMR_S3_QCU_QCBROVF    0x000003FF
+#define AR_IMR_S3_QCU_QCBRURN    0x03FF0000
+#define AR_IMR_S3_QCU_QCBRURN_S  16
+
+#define AR_IMR_S4              0x00b4
+#define AR_IMR_S4_QCU_QTRIG    0x000003FF
+#define AR_IMR_S4_RESV0        0xFFFFFC00
+
+#define AR_IMR_S5              0x00b8
+#define AR_IMR_S5_TIMER_TRIG        0x000000FF
+#define AR_IMR_S5_TIMER_THRESH      0x0000FF00
+
+
+#define AR_ISR_RAC            0x00c0
+#define AR_ISR_S0_S           0x00c4
+#define AR_ISR_S0_QCU_TXOK      0x000003FF
+#define AR_ISR_S0_QCU_TXOK_S    0
+#define AR_ISR_S0_QCU_TXDESC    0x03FF0000
+#define AR_ISR_S0_QCU_TXDESC_S  16
+
+#define AR_ISR_S1_S           0x00c8
+#define AR_ISR_S1_QCU_TXERR    0x000003FF
+#define AR_ISR_S1_QCU_TXERR_S  0
+#define AR_ISR_S1_QCU_TXEOL    0x03FF0000
+#define AR_ISR_S1_QCU_TXEOL_S  16
+
+#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_DMADBG_3           0x00ec
+#define AR_DMADBG_4           0x00f0
+#define AR_DMADBG_5           0x00f4
+#define AR_DMADBG_6           0x00f8
+#define AR_DMADBG_7           0x00fc
+
+#define AR_NUM_QCU      10
+#define AR_QCU_0        0x0001
+#define AR_QCU_1        0x0002
+#define AR_QCU_2        0x0004
+#define AR_QCU_3        0x0008
+#define AR_QCU_4        0x0010
+#define AR_QCU_5        0x0020
+#define AR_QCU_6        0x0040
+#define AR_QCU_7        0x0080
+#define AR_QCU_8        0x0100
+#define AR_QCU_9        0x0200
+
+#define AR_Q0_TXDP           0x0800
+#define AR_Q1_TXDP           0x0804
+#define AR_Q2_TXDP           0x0808
+#define AR_Q3_TXDP           0x080c
+#define AR_Q4_TXDP           0x0810
+#define AR_Q5_TXDP           0x0814
+#define AR_Q6_TXDP           0x0818
+#define AR_Q7_TXDP           0x081c
+#define AR_Q8_TXDP           0x0820
+#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_TXD             0x0880
+#define AR_Q_TXD_M           0x000003FF
+
+#define AR_Q0_CBRCFG         0x08c0
+#define AR_Q1_CBRCFG         0x08c4
+#define AR_Q2_CBRCFG         0x08c8
+#define AR_Q3_CBRCFG         0x08cc
+#define AR_Q4_CBRCFG         0x08d0
+#define AR_Q5_CBRCFG         0x08d4
+#define AR_Q6_CBRCFG         0x08d8
+#define AR_Q7_CBRCFG         0x08dc
+#define AR_Q8_CBRCFG         0x08e0
+#define AR_Q9_CBRCFG         0x08e4
+#define AR_QCBRCFG(_i)      (AR_Q0_CBRCFG + ((_i)<<2))
+#define AR_Q_CBRCFG_INTERVAL     0x00FFFFFF
+#define AR_Q_CBRCFG_INTERVAL_S   0
+#define AR_Q_CBRCFG_OVF_THRESH   0xFF000000
+#define AR_Q_CBRCFG_OVF_THRESH_S 24
+
+#define AR_Q0_RDYTIMECFG         0x0900
+#define AR_Q1_RDYTIMECFG         0x0904
+#define AR_Q2_RDYTIMECFG         0x0908
+#define AR_Q3_RDYTIMECFG         0x090c
+#define AR_Q4_RDYTIMECFG         0x0910
+#define AR_Q5_RDYTIMECFG         0x0914
+#define AR_Q6_RDYTIMECFG         0x0918
+#define AR_Q7_RDYTIMECFG         0x091c
+#define AR_Q8_RDYTIMECFG         0x0920
+#define AR_Q9_RDYTIMECFG         0x0924
+#define AR_QRDYTIMECFG(_i)       (AR_Q0_RDYTIMECFG + ((_i)<<2))
+#define AR_Q_RDYTIMECFG_DURATION   0x00FFFFFF
+#define AR_Q_RDYTIMECFG_DURATION_S 0
+#define AR_Q_RDYTIMECFG_EN         0x01000000
+
+#define AR_Q_ONESHOTARM_SC       0x0940
+#define AR_Q_ONESHOTARM_SC_M     0x000003FF
+#define AR_Q_ONESHOTARM_SC_RESV0 0xFFFFFC00
+
+#define AR_Q_ONESHOTARM_CC       0x0980
+#define AR_Q_ONESHOTARM_CC_M     0x000003FF
+#define AR_Q_ONESHOTARM_CC_RESV0 0xFFFFFC00
+
+#define AR_Q0_MISC         0x09c0
+#define AR_Q1_MISC         0x09c4
+#define AR_Q2_MISC         0x09c8
+#define AR_Q3_MISC         0x09cc
+#define AR_Q4_MISC         0x09d0
+#define AR_Q5_MISC         0x09d4
+#define AR_Q6_MISC         0x09d8
+#define AR_Q7_MISC         0x09dc
+#define AR_Q8_MISC         0x09e0
+#define AR_Q9_MISC         0x09e4
+#define AR_QMISC(_i)       (AR_Q0_MISC + ((_i)<<2))
+#define AR_Q_MISC_FSP                     0x0000000F
+#define AR_Q_MISC_FSP_ASAP                0
+#define AR_Q_MISC_FSP_CBR                 1
+#define AR_Q_MISC_FSP_DBA_GATED           2
+#define AR_Q_MISC_FSP_TIM_GATED           3
+#define AR_Q_MISC_FSP_BEACON_SENT_GATED   4
+#define AR_Q_MISC_FSP_BEACON_RCVD_GATED   5
+#define AR_Q_MISC_ONE_SHOT_EN             0x00000010
+#define AR_Q_MISC_CBR_INCR_DIS1           0x00000020
+#define AR_Q_MISC_CBR_INCR_DIS0           0x00000040
+#define AR_Q_MISC_BEACON_USE              0x00000080
+#define AR_Q_MISC_CBR_EXP_CNTR_LIMIT_EN   0x00000100
+#define AR_Q_MISC_RDYTIME_EXP_POLICY      0x00000200
+#define AR_Q_MISC_RESET_CBR_EXP_CTR       0x00000400
+#define AR_Q_MISC_DCU_EARLY_TERM_REQ      0x00000800
+#define AR_Q_MISC_RESV0                   0xFFFFF000
+
+#define AR_Q0_STS         0x0a00
+#define AR_Q1_STS         0x0a04
+#define AR_Q2_STS         0x0a08
+#define AR_Q3_STS         0x0a0c
+#define AR_Q4_STS         0x0a10
+#define AR_Q5_STS         0x0a14
+#define AR_Q6_STS         0x0a18
+#define AR_Q7_STS         0x0a1c
+#define AR_Q8_STS         0x0a20
+#define AR_Q9_STS         0x0a24
+#define AR_QSTS(_i)       (AR_Q0_STS + ((_i)<<2))
+#define AR_Q_STS_PEND_FR_CNT          0x00000003
+#define AR_Q_STS_RESV0                0x000000FC
+#define AR_Q_STS_CBR_EXP_CNT          0x0000FF00
+#define AR_Q_STS_RESV1                0xFFFF0000
+
+#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_DCU_1        0x0002
+#define AR_DCU_2        0x0004
+#define AR_DCU_3        0x0008
+#define AR_DCU_4        0x0010
+#define AR_DCU_5        0x0020
+#define AR_DCU_6        0x0040
+#define AR_DCU_7        0x0080
+#define AR_DCU_8        0x0100
+#define AR_DCU_9        0x0200
+
+#define AR_D0_QCUMASK     0x1000
+#define AR_D1_QCUMASK     0x1004
+#define AR_D2_QCUMASK     0x1008
+#define AR_D3_QCUMASK     0x100c
+#define AR_D4_QCUMASK     0x1010
+#define AR_D5_QCUMASK     0x1014
+#define AR_D6_QCUMASK     0x1018
+#define AR_D7_QCUMASK     0x101c
+#define AR_D8_QCUMASK     0x1020
+#define AR_D9_QCUMASK     0x1024
+#define AR_DQCUMASK(_i)   (AR_D0_QCUMASK + ((_i)<<2))
+#define AR_D_QCUMASK         0x000003FF
+#define AR_D_QCUMASK_RESV0   0xFFFFFC00
+
+#define AR_D_TXBLK_CMD  0x1038
+#define AR_D_TXBLK_DATA(i) (AR_D_TXBLK_CMD+(i))
+
+#define AR_D0_LCL_IFS     0x1040
+#define AR_D1_LCL_IFS     0x1044
+#define AR_D2_LCL_IFS     0x1048
+#define AR_D3_LCL_IFS     0x104c
+#define AR_D4_LCL_IFS     0x1050
+#define AR_D5_LCL_IFS     0x1054
+#define AR_D6_LCL_IFS     0x1058
+#define AR_D7_LCL_IFS     0x105c
+#define AR_D8_LCL_IFS     0x1060
+#define AR_D9_LCL_IFS     0x1064
+#define AR_DLCL_IFS(_i)   (AR_D0_LCL_IFS + ((_i)<<2))
+#define AR_D_LCL_IFS_CWMIN       0x000003FF
+#define AR_D_LCL_IFS_CWMIN_S     0
+#define AR_D_LCL_IFS_CWMAX       0x000FFC00
+#define AR_D_LCL_IFS_CWMAX_S     10
+#define AR_D_LCL_IFS_AIFS        0x0FF00000
+#define AR_D_LCL_IFS_AIFS_S      20
+
+#define AR_D_LCL_IFS_RESV0    0xF0000000
+
+#define AR_D0_RETRY_LIMIT     0x1080
+#define AR_D1_RETRY_LIMIT     0x1084
+#define AR_D2_RETRY_LIMIT     0x1088
+#define AR_D3_RETRY_LIMIT     0x108c
+#define AR_D4_RETRY_LIMIT     0x1090
+#define AR_D5_RETRY_LIMIT     0x1094
+#define AR_D6_RETRY_LIMIT     0x1098
+#define AR_D7_RETRY_LIMIT     0x109c
+#define AR_D8_RETRY_LIMIT     0x10a0
+#define AR_D9_RETRY_LIMIT     0x10a4
+#define AR_DRETRY_LIMIT(_i)   (AR_D0_RETRY_LIMIT + ((_i)<<2))
+#define AR_D_RETRY_LIMIT_FR_SH       0x0000000F
+#define AR_D_RETRY_LIMIT_FR_SH_S     0
+#define AR_D_RETRY_LIMIT_STA_SH      0x00003F00
+#define AR_D_RETRY_LIMIT_STA_SH_S    8
+#define AR_D_RETRY_LIMIT_STA_LG      0x000FC000
+#define AR_D_RETRY_LIMIT_STA_LG_S    14
+#define AR_D_RETRY_LIMIT_RESV0       0xFFF00000
+
+#define AR_D0_CHNTIME     0x10c0
+#define AR_D1_CHNTIME     0x10c4
+#define AR_D2_CHNTIME     0x10c8
+#define AR_D3_CHNTIME     0x10cc
+#define AR_D4_CHNTIME     0x10d0
+#define AR_D5_CHNTIME     0x10d4
+#define AR_D6_CHNTIME     0x10d8
+#define AR_D7_CHNTIME     0x10dc
+#define AR_D8_CHNTIME     0x10e0
+#define AR_D9_CHNTIME     0x10e4
+#define AR_DCHNTIME(_i)   (AR_D0_CHNTIME + ((_i)<<2))
+#define AR_D_CHNTIME_DUR         0x000FFFFF
+#define AR_D_CHNTIME_DUR_S       0
+#define AR_D_CHNTIME_EN          0x00100000
+#define AR_D_CHNTIME_RESV0       0xFFE00000
+
+#define AR_D0_MISC        0x1100
+#define AR_D1_MISC        0x1104
+#define AR_D2_MISC        0x1108
+#define AR_D3_MISC        0x110c
+#define AR_D4_MISC        0x1110
+#define AR_D5_MISC        0x1114
+#define AR_D6_MISC        0x1118
+#define AR_D7_MISC        0x111c
+#define AR_D8_MISC        0x1120
+#define AR_D9_MISC        0x1124
+#define AR_DMISC(_i)      (AR_D0_MISC + ((_i)<<2))
+#define AR_D_MISC_BKOFF_THRESH        0x0000003F
+#define AR_D_MISC_RETRY_CNT_RESET_EN  0x00000040
+#define AR_D_MISC_CW_RESET_EN         0x00000080
+#define AR_D_MISC_FRAG_WAIT_EN        0x00000100
+#define AR_D_MISC_FRAG_BKOFF_EN       0x00000200
+#define AR_D_MISC_CW_BKOFF_EN         0x00001000
+#define AR_D_MISC_VIR_COL_HANDLING    0x0000C000
+#define AR_D_MISC_VIR_COL_HANDLING_S  14
+#define AR_D_MISC_VIR_COL_HANDLING_DEFAULT 0
+#define AR_D_MISC_VIR_COL_HANDLING_IGNORE  1
+#define AR_D_MISC_BEACON_USE          0x00010000
+#define AR_D_MISC_ARB_LOCKOUT_CNTRL   0x00060000
+#define AR_D_MISC_ARB_LOCKOUT_CNTRL_S 17
+#define AR_D_MISC_ARB_LOCKOUT_CNTRL_NONE     0
+#define AR_D_MISC_ARB_LOCKOUT_CNTRL_INTRA_FR 1
+#define AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL   2
+#define AR_D_MISC_ARB_LOCKOUT_IGNORE  0x00080000
+#define AR_D_MISC_SEQ_NUM_INCR_DIS    0x00100000
+#define AR_D_MISC_POST_FR_BKOFF_DIS   0x00200000
+#define AR_D_MISC_VIT_COL_CW_BKOFF_EN 0x00400000
+#define AR_D_MISC_BLOWN_IFS_RETRY_EN  0x00800000
+#define AR_D_MISC_RESV0               0xFF000000
+
+#define AR_D_SEQNUM      0x1140
+
+#define AR_D_GBL_IFS_SIFS         0x1030
+#define AR_D_GBL_IFS_SIFS_M       0x0000FFFF
+#define AR_D_GBL_IFS_SIFS_ASYNC_FIFO_DUR 0x000003AB
+#define AR_D_GBL_IFS_SIFS_RESV0   0xFFFFFFFF
+
+#define AR_D_TXBLK_BASE            0x1038
+#define AR_D_TXBLK_WRITE_BITMASK    0x0000FFFF
+#define AR_D_TXBLK_WRITE_BITMASK_S  0
+#define AR_D_TXBLK_WRITE_SLICE      0x000F0000
+#define AR_D_TXBLK_WRITE_SLICE_S    16
+#define AR_D_TXBLK_WRITE_DCU        0x00F00000
+#define AR_D_TXBLK_WRITE_DCU_S      20
+#define AR_D_TXBLK_WRITE_COMMAND    0x0F000000
+#define AR_D_TXBLK_WRITE_COMMAND_S      24
+
+#define AR_D_GBL_IFS_SLOT         0x1070
+#define AR_D_GBL_IFS_SLOT_M       0x0000FFFF
+#define AR_D_GBL_IFS_SLOT_RESV0   0xFFFF0000
+#define AR_D_GBL_IFS_SLOT_ASYNC_FIFO_DUR   0x00000420
+
+#define AR_D_GBL_IFS_EIFS         0x10b0
+#define AR_D_GBL_IFS_EIFS_M       0x0000FFFF
+#define AR_D_GBL_IFS_EIFS_RESV0   0xFFFF0000
+#define AR_D_GBL_IFS_EIFS_ASYNC_FIFO_DUR   0x0000A5EB
+
+#define AR_D_GBL_IFS_MISC        0x10f0
+#define AR_D_GBL_IFS_MISC_LFSR_SLICE_SEL        0x00000007
+#define AR_D_GBL_IFS_MISC_TURBO_MODE            0x00000008
+#define AR_D_GBL_IFS_MISC_USEC_DURATION         0x000FFC00
+#define AR_D_GBL_IFS_MISC_DCU_ARBITER_DLY       0x00300000
+#define AR_D_GBL_IFS_MISC_RANDOM_LFSR_SLICE_DIS 0x01000000
+#define AR_D_GBL_IFS_MISC_SLOT_XMIT_WIND_LEN    0x06000000
+#define AR_D_GBL_IFS_MISC_FORCE_XMIT_SLOT_BOUND 0x08000000
+#define AR_D_GBL_IFS_MISC_IGNORE_BACKOFF        0x10000000
+
+#define AR_D_FPCTL                  0x1230
+#define AR_D_FPCTL_DCU              0x0000000F
+#define AR_D_FPCTL_DCU_S            0
+#define AR_D_FPCTL_PREFETCH_EN      0x00000010
+#define AR_D_FPCTL_BURST_PREFETCH   0x00007FE0
+#define AR_D_FPCTL_BURST_PREFETCH_S 5
+
+#define AR_D_TXPSE                 0x1270
+#define AR_D_TXPSE_CTRL            0x000003FF
+#define AR_D_TXPSE_RESV0           0x0000FC00
+#define AR_D_TXPSE_STATUS          0x00010000
+#define AR_D_TXPSE_RESV1           0xFFFE0000
+
+#define AR_D_TXSLOTMASK            0x12f0
+#define AR_D_TXSLOTMASK_NUM        0x0000000F
+
+#define AR_CFG_LED                     0x1f04
+#define AR_CFG_SCLK_RATE_IND           0x00000003
+#define AR_CFG_SCLK_RATE_IND_S         0
+#define AR_CFG_SCLK_32MHZ              0x00000000
+#define AR_CFG_SCLK_4MHZ               0x00000001
+#define AR_CFG_SCLK_1MHZ               0x00000002
+#define AR_CFG_SCLK_32KHZ              0x00000003
+#define AR_CFG_LED_BLINK_SLOW          0x00000008
+#define AR_CFG_LED_BLINK_THRESH_SEL    0x00000070
+#define AR_CFG_LED_MODE_SEL            0x00000380
+#define AR_CFG_LED_MODE_SEL_S          7
+#define AR_CFG_LED_POWER               0x00000280
+#define AR_CFG_LED_POWER_S             7
+#define AR_CFG_LED_NETWORK             0x00000300
+#define AR_CFG_LED_NETWORK_S           7
+#define AR_CFG_LED_MODE_PROP           0x0
+#define AR_CFG_LED_MODE_RPROP          0x1
+#define AR_CFG_LED_MODE_SPLIT          0x2
+#define AR_CFG_LED_MODE_RAND           0x3
+#define AR_CFG_LED_MODE_POWER_OFF      0x4
+#define AR_CFG_LED_MODE_POWER_ON       0x5
+#define AR_CFG_LED_MODE_NETWORK_OFF    0x4
+#define AR_CFG_LED_MODE_NETWORK_ON     0x6
+#define AR_CFG_LED_ASSOC_CTL           0x00000c00
+#define AR_CFG_LED_ASSOC_CTL_S         10
+#define AR_CFG_LED_ASSOC_NONE          0x0
+#define AR_CFG_LED_ASSOC_ACTIVE        0x1
+#define AR_CFG_LED_ASSOC_PENDING       0x2
+
+#define AR_CFG_LED_BLINK_SLOW          0x00000008
+#define AR_CFG_LED_BLINK_SLOW_S        3
+
+#define AR_CFG_LED_BLINK_THRESH_SEL    0x00000070
+#define AR_CFG_LED_BLINK_THRESH_SEL_S  4
+
+#define AR_MAC_SLEEP                0x1f00
+#define AR_MAC_SLEEP_MAC_AWAKE      0x00000000
+#define AR_MAC_SLEEP_MAC_ASLEEP     0x00000001
+
+#define AR_RC                0x4000
+#define AR_RC_AHB            0x00000001
+#define AR_RC_APB            0x00000002
+#define AR_RC_HOSTIF         0x00000100
+
+#define AR_WA                  (AR_SREV_9340(ah) ? 0x40c4 : 0x4004)
+#define AR_WA_BIT6                     (1 << 6)
+#define AR_WA_BIT7                     (1 << 7)
+#define AR_WA_BIT23                    (1 << 23)
+#define AR_WA_D3_L1_DISABLE            (1 << 14)
+#define AR_WA_D3_TO_L1_DISABLE_REAL     (1 << 16)
+#define AR_WA_ASPM_TIMER_BASED_DISABLE  (1 << 17)
+#define AR_WA_RESET_EN                  (1 << 18) /* Sw Control to enable PCI-Reset to POR (bit 15) */
+#define AR_WA_ANALOG_SHIFT              (1 << 20)
+#define AR_WA_POR_SHORT                 (1 << 21) /* PCI-E Phy reset control */
+#define AR_WA_BIT22                    (1 << 22)
+#define AR9285_WA_DEFAULT              0x004a050b
+#define AR9280_WA_DEFAULT              0x0040073b
+#define AR_WA_DEFAULT                  0x0000073f
+
+
+#define AR_PM_STATE                 0x4008
+#define AR_PM_STATE_PME_D3COLD_VAUX 0x00100000
+
+#define AR_HOST_TIMEOUT             (AR_SREV_9340(ah) ? 0x4008 : 0x4018)
+#define AR_HOST_TIMEOUT_APB_CNTR    0x0000FFFF
+#define AR_HOST_TIMEOUT_APB_CNTR_S  0
+#define AR_HOST_TIMEOUT_LCL_CNTR    0xFFFF0000
+#define AR_HOST_TIMEOUT_LCL_CNTR_S  16
+
+#define AR_EEPROM                0x401c
+#define AR_EEPROM_ABSENT         0x00000100
+#define AR_EEPROM_CORRUPT        0x00000200
+#define AR_EEPROM_PROT_MASK      0x03FFFC00
+#define AR_EEPROM_PROT_MASK_S    10
+
+#define EEPROM_PROTECT_RP_0_31        0x0001
+#define EEPROM_PROTECT_WP_0_31        0x0002
+#define EEPROM_PROTECT_RP_32_63       0x0004
+#define EEPROM_PROTECT_WP_32_63       0x0008
+#define EEPROM_PROTECT_RP_64_127      0x0010
+#define EEPROM_PROTECT_WP_64_127      0x0020
+#define EEPROM_PROTECT_RP_128_191     0x0040
+#define EEPROM_PROTECT_WP_128_191     0x0080
+#define EEPROM_PROTECT_RP_192_255     0x0100
+#define EEPROM_PROTECT_WP_192_255     0x0200
+#define EEPROM_PROTECT_RP_256_511     0x0400
+#define EEPROM_PROTECT_WP_256_511     0x0800
+#define EEPROM_PROTECT_RP_512_1023    0x1000
+#define EEPROM_PROTECT_WP_512_1023    0x2000
+#define EEPROM_PROTECT_RP_1024_2047   0x4000
+#define EEPROM_PROTECT_WP_1024_2047   0x8000
+
+#define AR_SREV \
+       ((AR_SREV_9100(ah)) ? 0x0600 : (AR_SREV_9340(ah) \
+                                       ? 0x400c : 0x4020))
+
+#define AR_SREV_ID \
+       ((AR_SREV_9100(ah)) ? 0x00000FFF : 0x000000FF)
+#define AR_SREV_VERSION                       0x000000F0
+#define AR_SREV_VERSION_S                     4
+#define AR_SREV_REVISION                      0x00000007
+
+#define AR_SREV_ID2                           0xFFFFFFFF
+#define AR_SREV_VERSION2                     0xFFFC0000
+#define AR_SREV_VERSION2_S                    18
+#define AR_SREV_TYPE2                        0x0003F000
+#define AR_SREV_TYPE2_S                       12
+#define AR_SREV_TYPE2_CHAIN                  0x00001000
+#define AR_SREV_TYPE2_HOST_MODE                      0x00002000
+#define AR_SREV_REVISION2                    0x00000F00
+#define AR_SREV_REVISION2_S                  8
+
+#define AR_SREV_VERSION_5416_PCI       0xD
+#define AR_SREV_VERSION_5416_PCIE      0xC
+#define AR_SREV_REVISION_5416_10       0
+#define AR_SREV_REVISION_5416_20       1
+#define AR_SREV_REVISION_5416_22       2
+#define AR_SREV_VERSION_9100           0x14
+#define AR_SREV_VERSION_9160           0x40
+#define AR_SREV_REVISION_9160_10       0
+#define AR_SREV_REVISION_9160_11       1
+#define AR_SREV_VERSION_9280           0x80
+#define AR_SREV_REVISION_9280_10       0
+#define AR_SREV_REVISION_9280_20       1
+#define AR_SREV_REVISION_9280_21       2
+#define AR_SREV_VERSION_9285           0xC0
+#define AR_SREV_REVISION_9285_10       0
+#define AR_SREV_REVISION_9285_11       1
+#define AR_SREV_REVISION_9285_12       2
+#define AR_SREV_VERSION_9287           0x180
+#define AR_SREV_REVISION_9287_10       0
+#define AR_SREV_REVISION_9287_11       1
+#define AR_SREV_REVISION_9287_12       2
+#define AR_SREV_REVISION_9287_13       3
+#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_VERSION_9485           0x240
+#define AR_SREV_REVISION_9485_10       0
+#define AR_SREV_REVISION_9485_11        1
+#define AR_SREV_VERSION_9340           0x300
+
+#define AR_SREV_5416(_ah) \
+       (((_ah)->hw_version.macVersion == AR_SREV_VERSION_5416_PCI) || \
+        ((_ah)->hw_version.macVersion == AR_SREV_VERSION_5416_PCIE))
+#define AR_SREV_5416_20_OR_LATER(_ah) \
+       (((AR_SREV_5416(_ah)) && \
+        ((_ah)->hw_version.macRev >= AR_SREV_REVISION_5416_20)) || \
+        ((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9100))
+#define AR_SREV_5416_22_OR_LATER(_ah) \
+       (((AR_SREV_5416(_ah)) && \
+        ((_ah)->hw_version.macRev >= AR_SREV_REVISION_5416_22)) || \
+        ((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9100))
+
+#define AR_SREV_9100(ah) \
+       ((ah->hw_version.macVersion) == AR_SREV_VERSION_9100)
+#define AR_SREV_9100_OR_LATER(_ah) \
+       (((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9100))
+
+#define AR_SREV_9160(_ah) \
+       (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9160))
+#define AR_SREV_9160_10_OR_LATER(_ah) \
+       (((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9160))
+#define AR_SREV_9160_11(_ah) \
+       (AR_SREV_9160(_ah) && \
+        ((_ah)->hw_version.macRev == AR_SREV_REVISION_9160_11))
+#define AR_SREV_9280(_ah) \
+       (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9280))
+#define AR_SREV_9280_20_OR_LATER(_ah) \
+       (((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9280))
+#define AR_SREV_9280_20(_ah) \
+       (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9280))
+
+#define AR_SREV_9285(_ah) \
+       (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9285))
+#define AR_SREV_9285_12_OR_LATER(_ah) \
+       (((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9285))
+
+#define AR_SREV_9287(_ah) \
+       (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9287))
+#define AR_SREV_9287_11_OR_LATER(_ah) \
+       (((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9287))
+#define AR_SREV_9287_11(_ah) \
+       (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9287) && \
+        ((_ah)->hw_version.macRev == AR_SREV_REVISION_9287_11))
+#define AR_SREV_9287_12(_ah) \
+       (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9287) && \
+        ((_ah)->hw_version.macRev == AR_SREV_REVISION_9287_12))
+#define AR_SREV_9287_12_OR_LATER(_ah) \
+       (((_ah)->hw_version.macVersion > AR_SREV_VERSION_9287) || \
+        (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9287) && \
+         ((_ah)->hw_version.macRev >= AR_SREV_REVISION_9287_12)))
+#define AR_SREV_9287_13_OR_LATER(_ah) \
+       (((_ah)->hw_version.macVersion > AR_SREV_VERSION_9287) || \
+        (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9287) && \
+         ((_ah)->hw_version.macRev >= AR_SREV_REVISION_9287_13)))
+
+#define AR_SREV_9271(_ah) \
+    (((_ah))->hw_version.macVersion == AR_SREV_VERSION_9271)
+#define AR_SREV_9271_10(_ah) \
+    (AR_SREV_9271(_ah) && \
+     ((_ah)->hw_version.macRev == AR_SREV_REVISION_9271_10))
+#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_OR_LATER(_ah) \
+       ((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9300)
+
+#define AR_SREV_9485(_ah) \
+       (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9485))
+#define AR_SREV_9485_10(_ah) \
+       (AR_SREV_9485(_ah) && \
+        ((_ah)->hw_version.macRev == AR_SREV_REVISION_9485_10))
+#define AR_SREV_9485_11(_ah) \
+       (AR_SREV_9485(_ah) && \
+        ((_ah)->hw_version.macRev == AR_SREV_REVISION_9485_11))
+#define AR_SREV_9485_OR_LATER(_ah) \
+       (((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9485))
+
+#define AR_SREV_9340(_ah) \
+       (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9340))
+
+#define AR_SREV_9285E_20(_ah) \
+    (AR_SREV_9285_12_OR_LATER(_ah) && \
+     ((REG_READ(_ah, AR_AN_SYNTH9) & 0x7) == 0x1))
+
+enum ath_usb_dev {
+       AR9280_USB = 1, /* AR7010 + AR9280, UB94 */
+       AR9287_USB = 2, /* AR7010 + AR9287, UB95 */
+       STORAGE_DEVICE = 3,
+};
+
+#define AR_DEVID_7010(_ah) \
+       (((_ah)->hw_version.usbdev == AR9280_USB) || \
+        ((_ah)->hw_version.usbdev == AR9287_USB))
+
+#define AR_RADIO_SREV_MAJOR                   0xf0
+#define AR_RAD5133_SREV_MAJOR                 0xc0
+#define AR_RAD2133_SREV_MAJOR                 0xd0
+#define AR_RAD5122_SREV_MAJOR                 0xe0
+#define AR_RAD2122_SREV_MAJOR                 0xf0
+
+#define AR_AHB_MODE                           0x4024
+#define AR_AHB_EXACT_WR_EN                    0x00000000
+#define AR_AHB_BUF_WR_EN                      0x00000001
+#define AR_AHB_EXACT_RD_EN                    0x00000000
+#define AR_AHB_CACHELINE_RD_EN                0x00000002
+#define AR_AHB_PREFETCH_RD_EN                 0x00000004
+#define AR_AHB_PAGE_SIZE_1K                   0x00000000
+#define AR_AHB_PAGE_SIZE_2K                   0x00000008
+#define AR_AHB_PAGE_SIZE_4K                   0x00000010
+#define AR_AHB_CUSTOM_BURST_EN                0x000000C0
+#define AR_AHB_CUSTOM_BURST_EN_S              6
+#define AR_AHB_CUSTOM_BURST_ASYNC_FIFO_VAL    3
+
+#define AR_INTR_RTC_IRQ                       0x00000001
+#define AR_INTR_MAC_IRQ                       0x00000002
+#define AR_INTR_EEP_PROT_ACCESS               0x00000004
+#define AR_INTR_MAC_AWAKE                     0x00020000
+#define AR_INTR_MAC_ASLEEP                    0x00040000
+#define AR_INTR_SPURIOUS                      0xFFFFFFFF
+
+
+#define AR_INTR_SYNC_CAUSE                    (AR_SREV_9340(ah) ? 0x4010 : 0x4028)
+#define AR_INTR_SYNC_CAUSE_CLR                (AR_SREV_9340(ah) ? 0x4010 : 0x4028)
+
+
+#define AR_INTR_SYNC_ENABLE                   (AR_SREV_9340(ah) ? 0x4014 : 0x402c)
+#define AR_INTR_SYNC_ENABLE_GPIO              0xFFFC0000
+#define AR_INTR_SYNC_ENABLE_GPIO_S            18
+
+enum {
+       AR_INTR_SYNC_RTC_IRQ = 0x00000001,
+       AR_INTR_SYNC_MAC_IRQ = 0x00000002,
+       AR_INTR_SYNC_EEPROM_ILLEGAL_ACCESS = 0x00000004,
+       AR_INTR_SYNC_APB_TIMEOUT = 0x00000008,
+       AR_INTR_SYNC_PCI_MODE_CONFLICT = 0x00000010,
+       AR_INTR_SYNC_HOST1_FATAL = 0x00000020,
+       AR_INTR_SYNC_HOST1_PERR = 0x00000040,
+       AR_INTR_SYNC_TRCV_FIFO_PERR = 0x00000080,
+       AR_INTR_SYNC_RADM_CPL_EP = 0x00000100,
+       AR_INTR_SYNC_RADM_CPL_DLLP_ABORT = 0x00000200,
+       AR_INTR_SYNC_RADM_CPL_TLP_ABORT = 0x00000400,
+       AR_INTR_SYNC_RADM_CPL_ECRC_ERR = 0x00000800,
+       AR_INTR_SYNC_RADM_CPL_TIMEOUT = 0x00001000,
+       AR_INTR_SYNC_LOCAL_TIMEOUT = 0x00002000,
+       AR_INTR_SYNC_PM_ACCESS = 0x00004000,
+       AR_INTR_SYNC_MAC_AWAKE = 0x00008000,
+       AR_INTR_SYNC_MAC_ASLEEP = 0x00010000,
+       AR_INTR_SYNC_MAC_SLEEP_ACCESS = 0x00020000,
+       AR_INTR_SYNC_ALL = 0x0003FFFF,
+
+
+       AR_INTR_SYNC_DEFAULT = (AR_INTR_SYNC_HOST1_FATAL |
+                               AR_INTR_SYNC_HOST1_PERR |
+                               AR_INTR_SYNC_RADM_CPL_EP |
+                               AR_INTR_SYNC_RADM_CPL_DLLP_ABORT |
+                               AR_INTR_SYNC_RADM_CPL_TLP_ABORT |
+                               AR_INTR_SYNC_RADM_CPL_ECRC_ERR |
+                               AR_INTR_SYNC_RADM_CPL_TIMEOUT |
+                               AR_INTR_SYNC_LOCAL_TIMEOUT |
+                               AR_INTR_SYNC_MAC_SLEEP_ACCESS),
+
+       AR_INTR_SYNC_SPURIOUS = 0xFFFFFFFF,
+
+};
+
+#define AR_INTR_ASYNC_MASK                       (AR_SREV_9340(ah) ? 0x4018 : 0x4030)
+#define AR_INTR_ASYNC_MASK_GPIO                  0xFFFC0000
+#define AR_INTR_ASYNC_MASK_GPIO_S                18
+
+#define AR_INTR_SYNC_MASK                        (AR_SREV_9340(ah) ? 0x401c : 0x4034)
+#define AR_INTR_SYNC_MASK_GPIO                   0xFFFC0000
+#define AR_INTR_SYNC_MASK_GPIO_S                 18
+
+#define AR_INTR_ASYNC_CAUSE_CLR                  (AR_SREV_9340(ah) ? 0x4020 : 0x4038)
+#define AR_INTR_ASYNC_CAUSE                      (AR_SREV_9340(ah) ? 0x4020 : 0x4038)
+
+#define AR_INTR_ASYNC_ENABLE                     (AR_SREV_9340(ah) ? 0x4024 : 0x403c)
+#define AR_INTR_ASYNC_ENABLE_GPIO                0xFFFC0000
+#define AR_INTR_ASYNC_ENABLE_GPIO_S              18
+
+#define AR_PCIE_SERDES                           0x4040
+#define AR_PCIE_SERDES2                          0x4044
+#define AR_PCIE_PM_CTRL                          (AR_SREV_9340(ah) ? 0x4004 : 0x4014)
+#define AR_PCIE_PM_CTRL_ENA                      0x00080000
+
+#define AR_NUM_GPIO                              14
+#define AR928X_NUM_GPIO                          10
+#define AR9285_NUM_GPIO                          12
+#define AR9287_NUM_GPIO                          11
+#define AR9271_NUM_GPIO                          16
+#define AR9300_NUM_GPIO                          17
+#define AR7010_NUM_GPIO                          16
+
+#define AR_GPIO_IN_OUT                           (AR_SREV_9340(ah) ? 0x4028 : 0x4048)
+#define AR_GPIO_IN_VAL                           0x0FFFC000
+#define AR_GPIO_IN_VAL_S                         14
+#define AR928X_GPIO_IN_VAL                       0x000FFC00
+#define AR928X_GPIO_IN_VAL_S                     10
+#define AR9285_GPIO_IN_VAL                       0x00FFF000
+#define AR9285_GPIO_IN_VAL_S                     12
+#define AR9287_GPIO_IN_VAL                       0x003FF800
+#define AR9287_GPIO_IN_VAL_S                     11
+#define AR9271_GPIO_IN_VAL                       0xFFFF0000
+#define AR9271_GPIO_IN_VAL_S                     16
+#define AR7010_GPIO_IN_VAL                       0x0000FFFF
+#define AR7010_GPIO_IN_VAL_S                     0
+
+#define AR_GPIO_IN                              (AR_SREV_9340(ah) ? 0x402c : 0x404c)
+#define AR9300_GPIO_IN_VAL                       0x0001FFFF
+#define AR9300_GPIO_IN_VAL_S                     0
+
+#define AR_GPIO_OE_OUT                           (AR_SREV_9340(ah) ? 0x4030 : \
+                                                 (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 AR7010_GPIO_OE                           0x52000
+#define AR7010_GPIO_OE_MASK                      0x1
+#define AR7010_GPIO_OE_AS_OUTPUT                 0x0
+#define AR7010_GPIO_OE_AS_INPUT                  0x1
+#define AR7010_GPIO_IN                           0x52004
+#define AR7010_GPIO_OUT                          0x52008
+#define AR7010_GPIO_SET                          0x5200C
+#define AR7010_GPIO_CLEAR                        0x52010
+#define AR7010_GPIO_INT                          0x52014
+#define AR7010_GPIO_INT_TYPE                     0x52018
+#define AR7010_GPIO_INT_POLARITY                 0x5201C
+#define AR7010_GPIO_PENDING                      0x52020
+#define AR7010_GPIO_INT_MASK                     0x52024
+#define AR7010_GPIO_FUNCTION                     0x52028
+
+#define AR_GPIO_INTR_POL                         (AR_SREV_9340(ah) ? 0x4038 : \
+                                                 (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                     (AR_SREV_9340(ah) ? 0x403c : \
+                                                 (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
+#define AR_GPIO_INPUT_EN_VAL_BT_FREQUENCY_S      3
+#define AR_GPIO_INPUT_EN_VAL_BT_ACTIVE_DEF       0x00000010
+#define AR_GPIO_INPUT_EN_VAL_BT_ACTIVE_S         4
+#define AR_GPIO_INPUT_EN_VAL_RFSILENT_DEF        0x00000080
+#define AR_GPIO_INPUT_EN_VAL_RFSILENT_DEF_S      7
+#define AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_BB      0x00000400
+#define AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_BB_S    10
+#define AR_GPIO_INPUT_EN_VAL_BT_ACTIVE_BB        0x00001000
+#define AR_GPIO_INPUT_EN_VAL_BT_ACTIVE_BB_S      12
+#define AR_GPIO_INPUT_EN_VAL_RFSILENT_BB         0x00008000
+#define AR_GPIO_INPUT_EN_VAL_RFSILENT_BB_S       15
+#define AR_GPIO_RTC_RESET_OVERRIDE_ENABLE        0x00010000
+#define AR_GPIO_JTAG_DISABLE                     0x00020000
+
+#define AR_GPIO_INPUT_MUX1                       (AR_SREV_9340(ah) ? 0x4040 : \
+                                                 (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                       (AR_SREV_9340(ah) ? 0x4044 : \
+                                                 (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
+#define AR_GPIO_INPUT_MUX2_RFSILENT_S            4
+#define AR_GPIO_INPUT_MUX2_RTC_RESET             0x00000f00
+#define AR_GPIO_INPUT_MUX2_RTC_RESET_S           8
+
+#define AR_GPIO_OUTPUT_MUX1                      (AR_SREV_9340(ah) ? 0x4048 : \
+                                                 (AR_SREV_9300_20_OR_LATER(ah) ? 0x4068 : 0x4060))
+#define AR_GPIO_OUTPUT_MUX2                      (AR_SREV_9340(ah) ? 0x404c : \
+                                                 (AR_SREV_9300_20_OR_LATER(ah) ? 0x406c : 0x4064))
+#define AR_GPIO_OUTPUT_MUX3                      (AR_SREV_9340(ah) ? 0x4050 : \
+                                                 (AR_SREV_9300_20_OR_LATER(ah) ? 0x4070 : 0x4068))
+
+#define AR_INPUT_STATE                           (AR_SREV_9340(ah) ? 0x4054 : \
+                                                 (AR_SREV_9300_20_OR_LATER(ah) ? 0x4074 : 0x406c))
+
+#define AR_EEPROM_STATUS_DATA                    (AR_SREV_9340(ah) ? 0x40c8 : \
+                                                 (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
+#define AR_EEPROM_STATUS_DATA_BUSY_ACCESS        0x00020000
+#define AR_EEPROM_STATUS_DATA_PROT_ACCESS        0x00040000
+#define AR_EEPROM_STATUS_DATA_ABSENT_ACCESS      0x00080000
+
+#define AR_OBS                  (AR_SREV_9340(ah) ? 0x405c : \
+                                (AR_SREV_9300_20_OR_LATER(ah) ? 0x4088 : 0x4080))
+
+#define AR_GPIO_PDPU                             (AR_SREV_9300_20_OR_LATER(ah) ? 0x4090 : 0x4088)
+
+#define AR_PCIE_MSI                             (AR_SREV_9340(ah) ? 0x40d8 : \
+                                                (AR_SREV_9300_20_OR_LATER(ah) ? 0x40a4 : 0x4094))
+#define AR_PCIE_MSI_ENABLE                       0x00000001
+
+#define AR_INTR_PRIO_SYNC_ENABLE  (AR_SREV_9340(ah) ? 0x4088 : 0x40c4)
+#define AR_INTR_PRIO_ASYNC_MASK   (AR_SREV_9340(ah) ? 0x408c : 0x40c8)
+#define AR_INTR_PRIO_SYNC_MASK    (AR_SREV_9340(ah) ? 0x4090 : 0x40cc)
+#define AR_INTR_PRIO_ASYNC_ENABLE (AR_SREV_9340(ah) ? 0x4094 : 0x40d4)
+#define AR_ENT_OTP               0x40d8
+#define AR_ENT_OTP_CHAIN2_DISABLE               0x00020000
+#define AR_ENT_OTP_MPSD                0x00800000
+
+#define AR_CH0_BB_DPLL1                 0x16180
+#define AR_CH0_BB_DPLL1_REFDIV  0xF8000000
+#define AR_CH0_BB_DPLL1_REFDIV_S 27
+#define AR_CH0_BB_DPLL1_NINI    0x07FC0000
+#define AR_CH0_BB_DPLL1_NINI_S  18
+#define AR_CH0_BB_DPLL1_NFRAC   0x0003FFFF
+#define AR_CH0_BB_DPLL1_NFRAC_S         0
+
+#define AR_CH0_BB_DPLL2                     0x16184
+#define AR_CH0_BB_DPLL2_LOCAL_PLL       0x40000000
+#define AR_CH0_BB_DPLL2_LOCAL_PLL_S     30
+#define AR_CH0_DPLL2_KI              0x3C000000
+#define AR_CH0_DPLL2_KI_S            26
+#define AR_CH0_DPLL2_KD              0x03F80000
+#define AR_CH0_DPLL2_KD_S            19
+#define AR_CH0_BB_DPLL2_EN_NEGTRIG   0x00040000
+#define AR_CH0_BB_DPLL2_EN_NEGTRIG_S 18
+#define AR_CH0_BB_DPLL2_PLL_PWD             0x00010000
+#define AR_CH0_BB_DPLL2_PLL_PWD_S    16
+#define AR_CH0_BB_DPLL2_OUTDIV      0x0000E000
+#define AR_CH0_BB_DPLL2_OUTDIV_S     13
+
+#define AR_CH0_BB_DPLL3          0x16188
+#define AR_CH0_BB_DPLL3_PHASE_SHIFT    0x3F800000
+#define AR_CH0_BB_DPLL3_PHASE_SHIFT_S  23
+
+#define AR_CH0_DDR_DPLL2         0x16244
+#define AR_CH0_DDR_DPLL3         0x16248
+#define AR_CH0_DPLL3_PHASE_SHIFT     0x3F800000
+#define AR_CH0_DPLL3_PHASE_SHIFT_S   23
+#define AR_PHY_CCA_NOM_VAL_2GHZ      -118
+
+#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
+#define AR_RTC_9160_PLL_REFDIV  0x00003C00
+#define AR_RTC_9160_PLL_REFDIV_S 10
+#define AR_RTC_9160_PLL_CLKSEL 0x0000C000
+#define AR_RTC_9160_PLL_CLKSEL_S 14
+
+#define AR_RTC_BASE             0x00020000
+#define AR_RTC_RC \
+       ((AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x0000) : 0x7000)
+#define AR_RTC_RC_M            0x00000003
+#define AR_RTC_RC_MAC_WARM      0x00000001
+#define AR_RTC_RC_MAC_COLD      0x00000002
+#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)
+
+#define AR_RTC_PLL_CONTROL2    0x703c
+
+#define AR_RTC_PLL_DIV          0x0000001f
+#define AR_RTC_PLL_DIV_S        0
+#define AR_RTC_PLL_DIV2         0x00000020
+#define AR_RTC_PLL_REFDIV_5     0x000000c0
+#define AR_RTC_PLL_CLKSEL       0x00000300
+#define AR_RTC_PLL_CLKSEL_S     8
+#define AR_RTC_PLL_BYPASS      0x00010000
+
+#define PLL3 0x16188
+#define PLL3_DO_MEAS_MASK 0x40000000
+#define PLL4 0x1618c
+#define PLL4_MEAS_DONE    0x8
+#define SQSUM_DVC_MASK 0x007ffff8
+
+#define AR_RTC_RESET \
+       ((AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x0040) : 0x7040)
+#define AR_RTC_RESET_EN                (0x00000001)
+
+#define AR_RTC_STATUS \
+       ((AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x0044) : 0x7044)
+
+#define AR_RTC_STATUS_M \
+       ((AR_SREV_9100(ah)) ? 0x0000003f : 0x0000000f)
+
+#define AR_RTC_PM_STATUS_M      0x0000000f
+
+#define AR_RTC_STATUS_SHUTDOWN  0x00000001
+#define AR_RTC_STATUS_ON        0x00000002
+#define AR_RTC_STATUS_SLEEP     0x00000004
+#define AR_RTC_STATUS_WAKEUP    0x00000008
+
+#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)
+#define AR_RTC_FORCE_WAKE_EN        0x00000001
+#define AR_RTC_FORCE_WAKE_ON_INT    0x00000002
+
+
+#define AR_RTC_INTR_CAUSE \
+       ((AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x0050) : 0x7050)
+
+#define AR_RTC_INTR_ENABLE \
+       ((AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x0054) : 0x7054)
+
+#define AR_RTC_INTR_MASK \
+       ((AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x0058) : 0x7058)
+
+/* RTC_DERIVED_* - only for AR9100 */
+
+#define AR_RTC_DERIVED_CLK \
+       (AR_SREV_9100(ah) ? (AR_RTC_BASE + 0x0038) : 0x7038)
+#define AR_RTC_DERIVED_CLK_PERIOD    0x0000fffe
+#define AR_RTC_DERIVED_CLK_PERIOD_S  1
+
+#define        AR_SEQ_MASK     0x8060
+
+#define AR_AN_RF2G1_CH0         0x7810
+#define AR_AN_RF2G1_CH0_OB      0x03800000
+#define AR_AN_RF2G1_CH0_OB_S    23
+#define AR_AN_RF2G1_CH0_DB      0x1C000000
+#define AR_AN_RF2G1_CH0_DB_S    26
+
+#define AR_AN_RF5G1_CH0         0x7818
+#define AR_AN_RF5G1_CH0_OB5     0x00070000
+#define AR_AN_RF5G1_CH0_OB5_S   16
+#define AR_AN_RF5G1_CH0_DB5     0x00380000
+#define AR_AN_RF5G1_CH0_DB5_S   19
+
+#define AR_AN_RF2G1_CH1         0x7834
+#define AR_AN_RF2G1_CH1_OB      0x03800000
+#define AR_AN_RF2G1_CH1_OB_S    23
+#define AR_AN_RF2G1_CH1_DB      0x1C000000
+#define AR_AN_RF2G1_CH1_DB_S    26
+
+#define AR_AN_RF5G1_CH1         0x783C
+#define AR_AN_RF5G1_CH1_OB5     0x00070000
+#define AR_AN_RF5G1_CH1_OB5_S   16
+#define AR_AN_RF5G1_CH1_DB5     0x00380000
+#define AR_AN_RF5G1_CH1_DB5_S   19
+
+#define AR_AN_TOP1                  0x7890
+#define AR_AN_TOP1_DACIPMODE       0x00040000
+#define AR_AN_TOP1_DACIPMODE_S     18
+
+#define AR_AN_TOP2                  0x7894
+#define AR_AN_TOP2_XPABIAS_LVL      0xC0000000
+#define AR_AN_TOP2_XPABIAS_LVL_S    30
+#define AR_AN_TOP2_LOCALBIAS        0x00200000
+#define AR_AN_TOP2_LOCALBIAS_S      21
+#define AR_AN_TOP2_PWDCLKIND        0x00400000
+#define AR_AN_TOP2_PWDCLKIND_S      22
+
+#define AR_AN_SYNTH9            0x7868
+#define AR_AN_SYNTH9_REFDIVA    0xf8000000
+#define AR_AN_SYNTH9_REFDIVA_S  27
+
+#define AR9285_AN_RF2G1              0x7820
+#define AR9285_AN_RF2G1_ENPACAL      0x00000800
+#define AR9285_AN_RF2G1_ENPACAL_S    11
+#define AR9285_AN_RF2G1_PDPADRV1     0x02000000
+#define AR9285_AN_RF2G1_PDPADRV1_S   25
+#define AR9285_AN_RF2G1_PDPADRV2     0x01000000
+#define AR9285_AN_RF2G1_PDPADRV2_S   24
+#define AR9285_AN_RF2G1_PDPAOUT      0x00800000
+#define AR9285_AN_RF2G1_PDPAOUT_S    23
+
+
+#define AR9285_AN_RF2G2              0x7824
+#define AR9285_AN_RF2G2_OFFCAL       0x00001000
+#define AR9285_AN_RF2G2_OFFCAL_S     12
+
+#define AR9285_AN_RF2G3             0x7828
+#define AR9285_AN_RF2G3_PDVCCOMP    0x02000000
+#define AR9285_AN_RF2G3_PDVCCOMP_S  25
+#define AR9285_AN_RF2G3_OB_0    0x00E00000
+#define AR9285_AN_RF2G3_OB_0_S    21
+#define AR9285_AN_RF2G3_OB_1    0x001C0000
+#define AR9285_AN_RF2G3_OB_1_S    18
+#define AR9285_AN_RF2G3_OB_2    0x00038000
+#define AR9285_AN_RF2G3_OB_2_S    15
+#define AR9285_AN_RF2G3_OB_3    0x00007000
+#define AR9285_AN_RF2G3_OB_3_S    12
+#define AR9285_AN_RF2G3_OB_4    0x00000E00
+#define AR9285_AN_RF2G3_OB_4_S    9
+
+#define AR9285_AN_RF2G3_DB1_0    0x000001C0
+#define AR9285_AN_RF2G3_DB1_0_S    6
+#define AR9285_AN_RF2G3_DB1_1    0x00000038
+#define AR9285_AN_RF2G3_DB1_1_S    3
+#define AR9285_AN_RF2G3_DB1_2    0x00000007
+#define AR9285_AN_RF2G3_DB1_2_S    0
+#define AR9285_AN_RF2G4         0x782C
+#define AR9285_AN_RF2G4_DB1_3    0xE0000000
+#define AR9285_AN_RF2G4_DB1_3_S    29
+#define AR9285_AN_RF2G4_DB1_4    0x1C000000
+#define AR9285_AN_RF2G4_DB1_4_S    26
+
+#define AR9285_AN_RF2G4_DB2_0    0x03800000
+#define AR9285_AN_RF2G4_DB2_0_S    23
+#define AR9285_AN_RF2G4_DB2_1    0x00700000
+#define AR9285_AN_RF2G4_DB2_1_S    20
+#define AR9285_AN_RF2G4_DB2_2    0x000E0000
+#define AR9285_AN_RF2G4_DB2_2_S    17
+#define AR9285_AN_RF2G4_DB2_3    0x0001C000
+#define AR9285_AN_RF2G4_DB2_3_S    14
+#define AR9285_AN_RF2G4_DB2_4    0x00003800
+#define AR9285_AN_RF2G4_DB2_4_S    11
+
+#define AR9285_RF2G5                   0x7830
+#define AR9285_RF2G5_IC50TX            0xfffff8ff
+#define AR9285_RF2G5_IC50TX_SET                0x00000400
+#define AR9285_RF2G5_IC50TX_XE_SET     0x00000500
+#define AR9285_RF2G5_IC50TX_CLEAR      0x00000700
+#define AR9285_RF2G5_IC50TX_CLEAR_S    8
+
+/* AR9271 : 0x7828, 0x782c different setting from AR9285 */
+#define AR9271_AN_RF2G3_OB_cck         0x001C0000
+#define AR9271_AN_RF2G3_OB_cck_S       18
+#define AR9271_AN_RF2G3_OB_psk         0x00038000
+#define AR9271_AN_RF2G3_OB_psk_S       15
+#define AR9271_AN_RF2G3_OB_qam         0x00007000
+#define AR9271_AN_RF2G3_OB_qam_S       12
+
+#define AR9271_AN_RF2G3_DB_1           0x00E00000
+#define AR9271_AN_RF2G3_DB_1_S         21
+
+#define AR9271_AN_RF2G3_CCOMP          0xFFF
+#define AR9271_AN_RF2G3_CCOMP_S                0
+
+#define AR9271_AN_RF2G4_DB_2           0xE0000000
+#define AR9271_AN_RF2G4_DB_2_S         29
+
+#define AR9285_AN_RF2G6                 0x7834
+#define AR9285_AN_RF2G6_CCOMP           0x00007800
+#define AR9285_AN_RF2G6_CCOMP_S         11
+#define AR9285_AN_RF2G6_OFFS            0x03f00000
+#define AR9285_AN_RF2G6_OFFS_S          20
+
+#define AR9271_AN_RF2G6_OFFS            0x07f00000
+#define AR9271_AN_RF2G6_OFFS_S            20
+
+#define AR9285_AN_RF2G7                 0x7838
+#define AR9285_AN_RF2G7_PWDDB           0x00000002
+#define AR9285_AN_RF2G7_PWDDB_S         1
+#define AR9285_AN_RF2G7_PADRVGN2TAB0    0xE0000000
+#define AR9285_AN_RF2G7_PADRVGN2TAB0_S  29
+
+#define AR9285_AN_RF2G8                  0x783C
+#define AR9285_AN_RF2G8_PADRVGN2TAB0     0x0001C000
+#define AR9285_AN_RF2G8_PADRVGN2TAB0_S   14
+
+
+#define AR9285_AN_RF2G9          0x7840
+#define AR9285_AN_RXTXBB1              0x7854
+#define AR9285_AN_RXTXBB1_PDRXTXBB1    0x00000020
+#define AR9285_AN_RXTXBB1_PDRXTXBB1_S  5
+#define AR9285_AN_RXTXBB1_PDV2I        0x00000080
+#define AR9285_AN_RXTXBB1_PDV2I_S      7
+#define AR9285_AN_RXTXBB1_PDDACIF      0x00000100
+#define AR9285_AN_RXTXBB1_PDDACIF_S    8
+#define AR9285_AN_RXTXBB1_SPARE9       0x00000001
+#define AR9285_AN_RXTXBB1_SPARE9_S     0
+
+#define AR9285_AN_TOP2           0x7868
+
+#define AR9285_AN_TOP3                  0x786c
+#define AR9285_AN_TOP3_XPABIAS_LVL      0x0000000C
+#define AR9285_AN_TOP3_XPABIAS_LVL_S    2
+#define AR9285_AN_TOP3_PWDDAC           0x00800000
+#define AR9285_AN_TOP3_PWDDAC_S    23
+
+#define AR9285_AN_TOP4           0x7870
+#define AR9285_AN_TOP4_DEFAULT   0x10142c00
+
+#define AR9287_AN_RF2G3_CH0             0x7808
+#define AR9287_AN_RF2G3_CH1             0x785c
+#define AR9287_AN_RF2G3_DB1             0xE0000000
+#define AR9287_AN_RF2G3_DB1_S           29
+#define AR9287_AN_RF2G3_DB2             0x1C000000
+#define AR9287_AN_RF2G3_DB2_S           26
+#define AR9287_AN_RF2G3_OB_CCK          0x03800000
+#define AR9287_AN_RF2G3_OB_CCK_S        23
+#define AR9287_AN_RF2G3_OB_PSK          0x00700000
+#define AR9287_AN_RF2G3_OB_PSK_S        20
+#define AR9287_AN_RF2G3_OB_QAM          0x000E0000
+#define AR9287_AN_RF2G3_OB_QAM_S        17
+#define AR9287_AN_RF2G3_OB_PAL_OFF      0x0001C000
+#define AR9287_AN_RF2G3_OB_PAL_OFF_S    14
+
+#define AR9287_AN_TXPC0                 0x7898
+#define AR9287_AN_TXPC0_TXPCMODE        0x0000C000
+#define AR9287_AN_TXPC0_TXPCMODE_S      14
+#define AR9287_AN_TXPC0_TXPCMODE_NORMAL    0
+#define AR9287_AN_TXPC0_TXPCMODE_TEST      1
+#define AR9287_AN_TXPC0_TXPCMODE_TEMPSENSE 2
+#define AR9287_AN_TXPC0_TXPCMODE_ATBTEST   3
+
+#define AR9287_AN_TOP2                  0x78b4
+#define AR9287_AN_TOP2_XPABIAS_LVL      0xC0000000
+#define AR9287_AN_TOP2_XPABIAS_LVL_S    30
+
+/* AR9271 specific stuff */
+#define AR9271_RESET_POWER_DOWN_CONTROL                0x50044
+#define AR9271_RADIO_RF_RST                    0x20
+#define AR9271_GATE_MAC_CTL                    0x4000
+
+#define AR_STA_ID0                 0x8000
+#define AR_STA_ID1                 0x8004
+#define AR_STA_ID1_SADH_MASK       0x0000FFFF
+#define AR_STA_ID1_STA_AP          0x00010000
+#define AR_STA_ID1_ADHOC           0x00020000
+#define AR_STA_ID1_PWR_SAV         0x00040000
+#define AR_STA_ID1_KSRCHDIS        0x00080000
+#define AR_STA_ID1_PCF             0x00100000
+#define AR_STA_ID1_USE_DEFANT      0x00200000
+#define AR_STA_ID1_DEFANT_UPDATE   0x00400000
+#define AR_STA_ID1_AR9100_BA_FIX   0x00400000
+#define AR_STA_ID1_RTS_USE_DEF     0x00800000
+#define AR_STA_ID1_ACKCTS_6MB      0x01000000
+#define AR_STA_ID1_BASE_RATE_11B   0x02000000
+#define AR_STA_ID1_SECTOR_SELF_GEN 0x04000000
+#define AR_STA_ID1_CRPT_MIC_ENABLE 0x08000000
+#define AR_STA_ID1_KSRCH_MODE      0x10000000
+#define AR_STA_ID1_PRESERVE_SEQNUM 0x20000000
+#define AR_STA_ID1_CBCIV_ENDIAN    0x40000000
+#define AR_STA_ID1_MCAST_KSRCH     0x80000000
+
+#define AR_BSS_ID0          0x8008
+#define AR_BSS_ID1          0x800C
+#define AR_BSS_ID1_U16       0x0000FFFF
+#define AR_BSS_ID1_AID       0x07FF0000
+#define AR_BSS_ID1_AID_S     16
+
+#define AR_BCN_RSSI_AVE      0x8010
+#define AR_BCN_RSSI_AVE_MASK 0x00000FFF
+
+#define AR_TIME_OUT         0x8014
+#define AR_TIME_OUT_ACK      0x00003FFF
+#define AR_TIME_OUT_ACK_S    0
+#define AR_TIME_OUT_CTS      0x3FFF0000
+#define AR_TIME_OUT_CTS_S    16
+#define AR_TIME_OUT_ACK_CTS_ASYNC_FIFO_DUR    0x16001D56
+
+#define AR_RSSI_THR          0x8018
+#define AR_RSSI_THR_MASK     0x000000FF
+#define AR_RSSI_THR_BM_THR   0x0000FF00
+#define AR_RSSI_THR_BM_THR_S 8
+#define AR_RSSI_BCN_WEIGHT   0x1F000000
+#define AR_RSSI_BCN_WEIGHT_S 24
+#define AR_RSSI_BCN_RSSI_RST 0x20000000
+
+#define AR_USEC              0x801c
+#define AR_USEC_USEC         0x0000007F
+#define AR_USEC_TX_LAT       0x007FC000
+#define AR_USEC_TX_LAT_S     14
+#define AR_USEC_RX_LAT       0x1F800000
+#define AR_USEC_RX_LAT_S     23
+#define AR_USEC_ASYNC_FIFO_DUR    0x12e00074
+
+#define AR_RESET_TSF        0x8020
+#define AR_RESET_TSF_ONCE   0x01000000
+
+#define AR_MAX_CFP_DUR      0x8038
+#define AR_CFP_VAL          0x0000FFFF
+
+#define AR_RX_FILTER        0x803C
+
+#define AR_MCAST_FIL0       0x8040
+#define AR_MCAST_FIL1       0x8044
+
+/*
+ * AR_DIAG_SW - Register which can be used for diagnostics and testing purposes.
+ *
+ * The force RX abort (AR_DIAG_RX_ABORT, bit 25) can be used in conjunction with
+ * RX block (AR_DIAG_RX_DIS, bit 5) to help fast channel change to shut down
+ * receive. The force RX abort bit will kill any frame which is currently being
+ * transferred between the MAC and baseband. The RX block bit (AR_DIAG_RX_DIS)
+ * will prevent any new frames from getting started.
+ */
+#define AR_DIAG_SW                  0x8048
+#define AR_DIAG_CACHE_ACK           0x00000001
+#define AR_DIAG_ACK_DIS             0x00000002
+#define AR_DIAG_CTS_DIS             0x00000004
+#define AR_DIAG_ENCRYPT_DIS         0x00000008
+#define AR_DIAG_DECRYPT_DIS         0x00000010
+#define AR_DIAG_RX_DIS              0x00000020 /* RX block */
+#define AR_DIAG_LOOP_BACK           0x00000040
+#define AR_DIAG_CORR_FCS            0x00000080
+#define AR_DIAG_CHAN_INFO           0x00000100
+#define AR_DIAG_SCRAM_SEED          0x0001FE00
+#define AR_DIAG_SCRAM_SEED_S        8
+#define AR_DIAG_FRAME_NV0           0x00020000
+#define AR_DIAG_OBS_PT_SEL1         0x000C0000
+#define AR_DIAG_OBS_PT_SEL1_S       18
+#define AR_DIAG_FORCE_RX_CLEAR      0x00100000 /* force rx_clear high */
+#define AR_DIAG_IGNORE_VIRT_CS      0x00200000
+#define AR_DIAG_FORCE_CH_IDLE_HIGH  0x00400000
+#define AR_DIAG_EIFS_CTRL_ENA       0x00800000
+#define AR_DIAG_DUAL_CHAIN_INFO     0x01000000
+#define AR_DIAG_RX_ABORT            0x02000000 /* Force RX abort */
+#define AR_DIAG_SATURATE_CYCLE_CNT  0x04000000
+#define AR_DIAG_OBS_PT_SEL2         0x08000000
+#define AR_DIAG_RX_CLEAR_CTL_LOW    0x10000000
+#define AR_DIAG_RX_CLEAR_EXT_LOW    0x20000000
+
+#define AR_TSF_L32          0x804c
+#define AR_TSF_U32          0x8050
+
+#define AR_TST_ADDAC        0x8054
+#define AR_DEF_ANTENNA      0x8058
+
+#define AR_AES_MUTE_MASK0       0x805c
+#define AR_AES_MUTE_MASK0_FC    0x0000FFFF
+#define AR_AES_MUTE_MASK0_QOS   0xFFFF0000
+#define AR_AES_MUTE_MASK0_QOS_S 16
+
+#define AR_AES_MUTE_MASK1       0x8060
+#define AR_AES_MUTE_MASK1_SEQ   0x0000FFFF
+#define AR_AES_MUTE_MASK1_FC_MGMT 0xFFFF0000
+#define AR_AES_MUTE_MASK1_FC_MGMT_S 16
+
+#define AR_GATED_CLKS       0x8064
+#define AR_GATED_CLKS_TX    0x00000002
+#define AR_GATED_CLKS_RX    0x00000004
+#define AR_GATED_CLKS_REG   0x00000008
+
+#define AR_OBS_BUS_CTRL     0x8068
+#define AR_OBS_BUS_SEL_1    0x00040000
+#define AR_OBS_BUS_SEL_2    0x00080000
+#define AR_OBS_BUS_SEL_3    0x000C0000
+#define AR_OBS_BUS_SEL_4    0x08040000
+#define AR_OBS_BUS_SEL_5    0x08080000
+
+#define AR_OBS_BUS_1               0x806c
+#define AR_OBS_BUS_1_PCU           0x00000001
+#define AR_OBS_BUS_1_RX_END        0x00000002
+#define AR_OBS_BUS_1_RX_WEP        0x00000004
+#define AR_OBS_BUS_1_RX_BEACON     0x00000008
+#define AR_OBS_BUS_1_RX_FILTER     0x00000010
+#define AR_OBS_BUS_1_TX_HCF        0x00000020
+#define AR_OBS_BUS_1_QUIET_TIME    0x00000040
+#define AR_OBS_BUS_1_CHAN_IDLE     0x00000080
+#define AR_OBS_BUS_1_TX_HOLD       0x00000100
+#define AR_OBS_BUS_1_TX_FRAME      0x00000200
+#define AR_OBS_BUS_1_RX_FRAME      0x00000400
+#define AR_OBS_BUS_1_RX_CLEAR      0x00000800
+#define AR_OBS_BUS_1_WEP_STATE     0x0003F000
+#define AR_OBS_BUS_1_WEP_STATE_S   12
+#define AR_OBS_BUS_1_RX_STATE      0x01F00000
+#define AR_OBS_BUS_1_RX_STATE_S    20
+#define AR_OBS_BUS_1_TX_STATE      0x7E000000
+#define AR_OBS_BUS_1_TX_STATE_S    25
+
+#define AR_LAST_TSTP        0x8080
+#define AR_NAV              0x8084
+#define AR_RTS_OK           0x8088
+#define AR_RTS_FAIL         0x808c
+#define AR_ACK_FAIL         0x8090
+#define AR_FCS_FAIL         0x8094
+#define AR_BEACON_CNT       0x8098
+
+#define AR_SLEEP1               0x80d4
+#define AR_SLEEP1_ASSUME_DTIM   0x00080000
+#define AR_SLEEP1_CAB_TIMEOUT   0xFFE00000
+#define AR_SLEEP1_CAB_TIMEOUT_S 21
+
+#define AR_SLEEP2                   0x80d8
+#define AR_SLEEP2_BEACON_TIMEOUT    0xFFE00000
+#define AR_SLEEP2_BEACON_TIMEOUT_S  21
+
+#define AR_TPC                 0x80e8
+#define AR_TPC_ACK             0x0000003f
+#define AR_TPC_ACK_S           0x00
+#define AR_TPC_CTS             0x00003f00
+#define AR_TPC_CTS_S           0x08
+#define AR_TPC_CHIRP           0x003f0000
+#define AR_TPC_CHIRP_S         0x16
+
+#define AR_QUIET1          0x80fc
+#define AR_QUIET1_NEXT_QUIET_S         0
+#define AR_QUIET1_NEXT_QUIET_M         0x0000ffff
+#define AR_QUIET1_QUIET_ENABLE         0x00010000
+#define AR_QUIET1_QUIET_ACK_CTS_ENABLE 0x00020000
+#define AR_QUIET1_QUIET_ACK_CTS_ENABLE_S 17
+#define AR_QUIET2          0x8100
+#define AR_QUIET2_QUIET_PERIOD_S       0
+#define AR_QUIET2_QUIET_PERIOD_M       0x0000ffff
+#define AR_QUIET2_QUIET_DUR_S     16
+#define AR_QUIET2_QUIET_DUR       0xffff0000
+
+#define AR_TSF_PARM        0x8104
+#define AR_TSF_INCREMENT_M     0x000000ff
+#define AR_TSF_INCREMENT_S     0x00
+
+#define AR_QOS_NO_ACK              0x8108
+#define AR_QOS_NO_ACK_TWO_BIT      0x0000000f
+#define AR_QOS_NO_ACK_TWO_BIT_S    0
+#define AR_QOS_NO_ACK_BIT_OFF      0x00000070
+#define AR_QOS_NO_ACK_BIT_OFF_S    4
+#define AR_QOS_NO_ACK_BYTE_OFF     0x00000180
+#define AR_QOS_NO_ACK_BYTE_OFF_S   7
+
+#define AR_PHY_ERR         0x810c
+
+#define AR_PHY_ERR_DCHIRP      0x00000008
+#define AR_PHY_ERR_RADAR       0x00000020
+#define AR_PHY_ERR_OFDM_TIMING 0x00020000
+#define AR_PHY_ERR_CCK_TIMING  0x02000000
+
+#define AR_RXFIFO_CFG          0x8114
+
+
+#define AR_MIC_QOS_CONTROL 0x8118
+#define AR_MIC_QOS_SELECT  0x811c
+
+#define AR_PCU_MISC                0x8120
+#define AR_PCU_FORCE_BSSID_MATCH   0x00000001
+#define AR_PCU_MIC_NEW_LOC_ENA     0x00000004
+#define AR_PCU_TX_ADD_TSF          0x00000008
+#define AR_PCU_CCK_SIFS_MODE       0x00000010
+#define AR_PCU_RX_ANT_UPDT         0x00000800
+#define AR_PCU_TXOP_TBTT_LIMIT_ENA 0x00001000
+#define AR_PCU_MISS_BCN_IN_SLEEP   0x00004000
+#define AR_PCU_BUG_12306_FIX_ENA   0x00020000
+#define AR_PCU_FORCE_QUIET_COLL    0x00040000
+#define AR_PCU_TBTT_PROTECT        0x00200000
+#define AR_PCU_CLEAR_VMF           0x01000000
+#define AR_PCU_CLEAR_BA_VALID      0x04000000
+#define AR_PCU_ALWAYS_PERFORM_KEYSEARCH 0x10000000
+
+#define AR_PCU_BT_ANT_PREVENT_RX   0x00100000
+#define AR_PCU_BT_ANT_PREVENT_RX_S 20
+
+#define AR_FILT_OFDM           0x8124
+#define AR_FILT_OFDM_COUNT     0x00FFFFFF
+
+#define AR_FILT_CCK            0x8128
+#define AR_FILT_CCK_COUNT      0x00FFFFFF
+
+#define AR_PHY_ERR_1           0x812c
+#define AR_PHY_ERR_1_COUNT     0x00FFFFFF
+#define AR_PHY_ERR_MASK_1      0x8130
+
+#define AR_PHY_ERR_2           0x8134
+#define AR_PHY_ERR_2_COUNT     0x00FFFFFF
+#define AR_PHY_ERR_MASK_2      0x8138
+
+#define AR_PHY_COUNTMAX        (3 << 22)
+#define AR_MIBCNT_INTRMASK     (3 << 22)
+
+#define AR_TSFOOR_THRESHOLD       0x813c
+#define AR_TSFOOR_THRESHOLD_VAL   0x0000FFFF
+
+#define AR_PHY_ERR_EIFS_MASK   0x8144
+
+#define AR_PHY_ERR_3           0x8168
+#define AR_PHY_ERR_3_COUNT     0x00FFFFFF
+#define AR_PHY_ERR_MASK_3      0x816c
+
+#define AR_BT_COEX_MODE            0x8170
+#define AR_BT_TIME_EXTEND          0x000000ff
+#define AR_BT_TIME_EXTEND_S        0
+#define AR_BT_TXSTATE_EXTEND       0x00000100
+#define AR_BT_TXSTATE_EXTEND_S     8
+#define AR_BT_TX_FRAME_EXTEND      0x00000200
+#define AR_BT_TX_FRAME_EXTEND_S    9
+#define AR_BT_MODE                 0x00000c00
+#define AR_BT_MODE_S               10
+#define AR_BT_QUIET                0x00001000
+#define AR_BT_QUIET_S              12
+#define AR_BT_QCU_THRESH           0x0001e000
+#define AR_BT_QCU_THRESH_S         13
+#define AR_BT_RX_CLEAR_POLARITY    0x00020000
+#define AR_BT_RX_CLEAR_POLARITY_S  17
+#define AR_BT_PRIORITY_TIME        0x00fc0000
+#define AR_BT_PRIORITY_TIME_S      18
+#define AR_BT_FIRST_SLOT_TIME      0xff000000
+#define AR_BT_FIRST_SLOT_TIME_S    24
+
+#define AR_BT_COEX_WEIGHT          0x8174
+#define AR_BT_COEX_WGHT                   0xff55
+#define AR_STOMP_ALL_WLAN_WGHT    0xfcfc
+#define AR_STOMP_LOW_WLAN_WGHT    0xa8a8
+#define AR_STOMP_NONE_WLAN_WGHT           0x0000
+#define AR_BTCOEX_BT_WGHT          0x0000ffff
+#define AR_BTCOEX_BT_WGHT_S        0
+#define AR_BTCOEX_WL_WGHT          0xffff0000
+#define AR_BTCOEX_WL_WGHT_S        16
+
+#define AR_BT_COEX_WL_WEIGHTS0     0x8174
+#define AR_BT_COEX_WL_WEIGHTS1     0x81c4
+
+#define AR_BT_COEX_BT_WEIGHTS0     0x83ac
+#define AR_BT_COEX_BT_WEIGHTS1     0x83b0
+#define AR_BT_COEX_BT_WEIGHTS2     0x83b4
+#define AR_BT_COEX_BT_WEIGHTS3     0x83b8
+
+#define AR9300_BT_WGHT                     0xcccc4444
+#define AR9300_STOMP_ALL_WLAN_WGHT0        0xfffffff0
+#define AR9300_STOMP_ALL_WLAN_WGHT1        0xfffffff0
+#define AR9300_STOMP_LOW_WLAN_WGHT0        0x88888880
+#define AR9300_STOMP_LOW_WLAN_WGHT1        0x88888880
+#define AR9300_STOMP_NONE_WLAN_WGHT0       0x00000000
+#define AR9300_STOMP_NONE_WLAN_WGHT1       0x00000000
+
+#define AR_BT_COEX_MODE2           0x817c
+#define AR_BT_BCN_MISS_THRESH      0x000000ff
+#define AR_BT_BCN_MISS_THRESH_S    0
+#define AR_BT_BCN_MISS_CNT         0x0000ff00
+#define AR_BT_BCN_MISS_CNT_S       8
+#define AR_BT_HOLD_RX_CLEAR        0x00010000
+#define AR_BT_HOLD_RX_CLEAR_S      16
+#define AR_BT_DISABLE_BT_ANT       0x00100000
+#define AR_BT_DISABLE_BT_ANT_S     20
+
+#define AR_TXSIFS              0x81d0
+#define AR_TXSIFS_TIME         0x000000FF
+#define AR_TXSIFS_TX_LATENCY   0x00000F00
+#define AR_TXSIFS_TX_LATENCY_S 8
+#define AR_TXSIFS_ACK_SHIFT    0x00007000
+#define AR_TXSIFS_ACK_SHIFT_S  12
+
+#define AR_TXOP_X          0x81ec
+#define AR_TXOP_X_VAL      0x000000FF
+
+
+#define AR_TXOP_0_3    0x81f0
+#define AR_TXOP_4_7    0x81f4
+#define AR_TXOP_8_11   0x81f8
+#define AR_TXOP_12_15  0x81fc
+
+#define AR_NEXT_NDP2_TIMER                  0x8180
+#define AR_FIRST_NDP_TIMER                  7
+#define AR_NDP2_PERIOD                      0x81a0
+#define AR_NDP2_TIMER_MODE                  0x81c0
+
+#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
+#define AR_DBA_TIMER_EN                     0x00000002
+#define AR_SWBA_TIMER_EN                    0x00000004
+#define AR_HCF_TIMER_EN                     0x00000008
+#define AR_TIM_TIMER_EN                     0x00000010
+#define AR_DTIM_TIMER_EN                    0x00000020
+#define AR_QUIET_TIMER_EN                   0x00000040
+#define AR_NDP_TIMER_EN                     0x00000080
+#define AR_TIMER_OVERFLOW_INDEX             0x00000700
+#define AR_TIMER_OVERFLOW_INDEX_S           8
+#define AR_TIMER_THRESH                     0xFFFFF000
+#define AR_TIMER_THRESH_S                   12
+
+#define AR_SLP32_MODE                  0x8244
+#define AR_SLP32_HALF_CLK_LATENCY      0x000FFFFF
+#define AR_SLP32_ENA                   0x00100000
+#define AR_SLP32_TSF_WRITE_STATUS      0x00200000
+
+#define AR_SLP32_WAKE              0x8248
+#define AR_SLP32_WAKE_XTL_TIME     0x0000FFFF
+
+#define AR_SLP32_INC               0x824c
+#define AR_SLP32_TST_INC           0x000FFFFF
+
+#define AR_SLP_CNT         0x8250
+#define AR_SLP_CYCLE_CNT   0x8254
+
+#define AR_SLP_MIB_CTRL    0x8258
+#define AR_SLP_MIB_CLEAR   0x00000001
+#define AR_SLP_MIB_PENDING 0x00000002
+
+#define AR_MAC_PCU_LOGIC_ANALYZER               0x8264
+#define AR_MAC_PCU_LOGIC_ANALYZER_DISBUG20768   0x20000000
+
+
+#define AR_2040_MODE                0x8318
+#define AR_2040_JOINED_RX_CLEAR 0x00000001
+
+
+#define AR_EXTRCCNT         0x8328
+
+#define AR_SELFGEN_MASK         0x832c
+
+#define AR_PCU_TXBUF_CTRL               0x8340
+#define AR_PCU_TXBUF_CTRL_SIZE_MASK     0x7FF
+#define AR_PCU_TXBUF_CTRL_USABLE_SIZE   0x700
+#define AR_9285_PCU_TXBUF_CTRL_USABLE_SIZE   0x380
+
+#define AR_PCU_MISC_MODE2               0x8344
+#define AR_PCU_MISC_MODE2_MGMT_CRYPTO_ENABLE           0x00000002
+#define AR_PCU_MISC_MODE2_NO_CRYPTO_FOR_NON_DATA_PKT   0x00000004
+
+#define AR_PCU_MISC_MODE2_RESERVED                     0x00000038
+#define AR_PCU_MISC_MODE2_ADHOC_MCAST_KEYID_ENABLE     0x00000040
+#define AR_PCU_MISC_MODE2_CFP_IGNORE                   0x00000080
+#define AR_PCU_MISC_MODE2_MGMT_QOS                     0x0000FF00
+#define AR_PCU_MISC_MODE2_MGMT_QOS_S                   8
+#define AR_PCU_MISC_MODE2_ENABLE_LOAD_NAV_BEACON_DURATION 0x00010000
+#define AR_PCU_MISC_MODE2_ENABLE_AGGWEP                0x00020000
+#define AR_PCU_MISC_MODE2_HWWAR1                       0x00100000
+#define AR_PCU_MISC_MODE2_HWWAR2                       0x02000000
+#define AR_PCU_MISC_MODE2_RESERVED2                    0xFFFE0000
+
+#define AR_MAC_PCU_ASYNC_FIFO_REG3                     0x8358
+#define AR_MAC_PCU_ASYNC_FIFO_REG3_DATAPATH_SEL        0x00000400
+#define AR_MAC_PCU_ASYNC_FIFO_REG3_SOFT_RESET          0x80000000
+
+
+#define AR_AES_MUTE_MASK0       0x805c
+#define AR_AES_MUTE_MASK0_FC    0x0000FFFF
+#define AR_AES_MUTE_MASK0_QOS   0xFFFF0000
+#define AR_AES_MUTE_MASK0_QOS_S 16
+
+#define AR_AES_MUTE_MASK1              0x8060
+#define AR_AES_MUTE_MASK1_SEQ          0x0000FFFF
+#define AR_AES_MUTE_MASK1_SEQ_S        0
+#define AR_AES_MUTE_MASK1_FC_MGMT      0xFFFF0000
+#define AR_AES_MUTE_MASK1_FC_MGMT_S    16
+
+#define AR_RATE_DURATION_0      0x8700
+#define AR_RATE_DURATION_31     0x87CC
+#define AR_RATE_DURATION_32     0x8780
+#define AR_RATE_DURATION(_n)    (AR_RATE_DURATION_0 + ((_n)<<2))
+
+
+#define AR_KEYTABLE_0           0x8800
+#define AR_KEYTABLE(_n)         (AR_KEYTABLE_0 + ((_n)*32))
+#define AR_KEY_CACHE_SIZE       128
+#define AR_RSVD_KEYTABLE_ENTRIES 4
+#define AR_KEY_TYPE             0x00000007
+#define AR_KEYTABLE_TYPE_40     0x00000000
+#define AR_KEYTABLE_TYPE_104    0x00000001
+#define AR_KEYTABLE_TYPE_128    0x00000003
+#define AR_KEYTABLE_TYPE_TKIP   0x00000004
+#define AR_KEYTABLE_TYPE_AES    0x00000005
+#define AR_KEYTABLE_TYPE_CCM    0x00000006
+#define AR_KEYTABLE_TYPE_CLR    0x00000007
+#define AR_KEYTABLE_ANT         0x00000008
+#define AR_KEYTABLE_VALID       0x00008000
+#define AR_KEYTABLE_KEY0(_n)    (AR_KEYTABLE(_n) + 0)
+#define AR_KEYTABLE_KEY1(_n)    (AR_KEYTABLE(_n) + 4)
+#define AR_KEYTABLE_KEY2(_n)    (AR_KEYTABLE(_n) + 8)
+#define AR_KEYTABLE_KEY3(_n)    (AR_KEYTABLE(_n) + 12)
+#define AR_KEYTABLE_KEY4(_n)    (AR_KEYTABLE(_n) + 16)
+#define AR_KEYTABLE_TYPE(_n)    (AR_KEYTABLE(_n) + 20)
+#define AR_KEYTABLE_MAC0(_n)    (AR_KEYTABLE(_n) + 24)
+#define AR_KEYTABLE_MAC1(_n)    (AR_KEYTABLE(_n) + 28)
+
+#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
diff --git a/src/drivers/net/ath/ath_hw.c b/src/drivers/net/ath/ath_hw.c
new file mode 100644 (file)
index 0000000..8e31288
--- /dev/null
@@ -0,0 +1,183 @@
+/*
+ * Copyright (c) 2009 Atheros Communications Inc.
+ *
+ * Modified for iPXE by Scott K Logan <logans@cottsay.net> July 2011
+ * Original from Linux kernel 3.0.1
+ *
+ * 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 <ipxe/io.h>
+
+#include "ath.h"
+#include "reg.h"
+
+#define REG_READ       (common->ops->read)
+#define REG_WRITE      (common->ops->write)
+
+/**
+ * ath_hw_set_bssid_mask - filter out bssids we listen
+ *
+ * @common: the ath_common struct for the device.
+ *
+ * BSSID masking is a method used by AR5212 and newer hardware to inform PCU
+ * which bits of the interface's MAC address should be looked at when trying
+ * to decide which packets to ACK. In station mode and AP mode with a single
+ * BSS every bit matters since we lock to only one BSS. In AP mode with
+ * multiple BSSes (virtual interfaces) not every bit matters because hw must
+ * accept frames for all BSSes and so we tweak some bits of our mac address
+ * in order to have multiple BSSes.
+ *
+ * NOTE: This is a simple filter and does *not* filter out all
+ * relevant frames. Some frames that are not for us might get ACKed from us
+ * by PCU because they just match the mask.
+ *
+ * When handling multiple BSSes you can get the BSSID mask by computing the
+ * set of  ~ ( MAC XOR BSSID ) for all bssids we handle.
+ *
+ * When you do this you are essentially computing the common bits of all your
+ * BSSes. Later it is assumed the hardware will "and" (&) the BSSID mask with
+ * the MAC address to obtain the relevant bits and compare the result with
+ * (frame's BSSID & mask) to see if they match.
+ *
+ * Simple example: on your card you have have two BSSes you have created with
+ * BSSID-01 and BSSID-02. Lets assume BSSID-01 will not use the MAC address.
+ * There is another BSSID-03 but you are not part of it. For simplicity's sake,
+ * assuming only 4 bits for a mac address and for BSSIDs you can then have:
+ *
+ *                  \
+ * MAC:        0001 |
+ * BSSID-01:   0100 | --> Belongs to us
+ * BSSID-02:   1001 |
+ *                  /
+ * -------------------
+ * BSSID-03:   0110  | --> External
+ * -------------------
+ *
+ * Our bssid_mask would then be:
+ *
+ *             On loop iteration for BSSID-01:
+ *             ~(0001 ^ 0100)  -> ~(0101)
+ *                             ->   1010
+ *             bssid_mask      =    1010
+ *
+ *             On loop iteration for BSSID-02:
+ *             bssid_mask &= ~(0001   ^   1001)
+ *             bssid_mask =   (1010)  & ~(0001 ^ 1001)
+ *             bssid_mask =   (1010)  & ~(1000)
+ *             bssid_mask =   (1010)  &  (0111)
+ *             bssid_mask =   0010
+ *
+ * A bssid_mask of 0010 means "only pay attention to the second least
+ * significant bit". This is because its the only bit common
+ * amongst the MAC and all BSSIDs we support. To findout what the real
+ * common bit is we can simply "&" the bssid_mask now with any BSSID we have
+ * or our MAC address (we assume the hardware uses the MAC address).
+ *
+ * Now, suppose there's an incoming frame for BSSID-03:
+ *
+ * IFRAME-01:  0110
+ *
+ * An easy eye-inspeciton of this already should tell you that this frame
+ * will not pass our check. This is because the bssid_mask tells the
+ * hardware to only look at the second least significant bit and the
+ * common bit amongst the MAC and BSSIDs is 0, this frame has the 2nd LSB
+ * as 1, which does not match 0.
+ *
+ * So with IFRAME-01 we *assume* the hardware will do:
+ *
+ *     allow = (IFRAME-01 & bssid_mask) == (bssid_mask & MAC) ? 1 : 0;
+ *  --> allow = (0110 & 0010) == (0010 & 0001) ? 1 : 0;
+ *  --> allow = (0010) == 0000 ? 1 : 0;
+ *  --> allow = 0
+ *
+ *  Lets now test a frame that should work:
+ *
+ * IFRAME-02:  0001 (we should allow)
+ *
+ *     allow = (IFRAME-02 & bssid_mask) == (bssid_mask & MAC) ? 1 : 0;
+ *  --> allow = (0001 & 0010) ==  (0010 & 0001) ? 1 :0;
+ *  --> allow = (0000) == (0000)
+ *  --> allow = 1
+ *
+ * Other examples:
+ *
+ * IFRAME-03:  0100 --> allowed
+ * IFRAME-04:  1001 --> allowed
+ * IFRAME-05:  1101 --> allowed but its not for us!!!
+ *
+ */
+void ath_hw_setbssidmask(struct ath_common *common)
+{
+       void *ah = common->ah;
+
+       REG_WRITE(ah, get_unaligned_le32(common->bssidmask), AR_BSSMSKL);
+       REG_WRITE(ah, get_unaligned_le16(common->bssidmask + 4), AR_BSSMSKU);
+}
+
+
+/**
+ * ath_hw_cycle_counters_update - common function to update cycle counters
+ *
+ * @common: the ath_common struct for the device.
+ *
+ * This function is used to update all cycle counters in one place.
+ * It has to be called while holding common->cc_lock!
+ */
+void ath_hw_cycle_counters_update(struct ath_common *common)
+{
+       u32 cycles, busy, rx, tx;
+       void *ah = common->ah;
+
+       /* freeze */
+       REG_WRITE(ah, AR_MIBC_FMC, AR_MIBC);
+
+       /* read */
+       cycles = REG_READ(ah, AR_CCCNT);
+       busy = REG_READ(ah, AR_RCCNT);
+       rx = REG_READ(ah, AR_RFCNT);
+       tx = REG_READ(ah, AR_TFCNT);
+
+       /* clear */
+       REG_WRITE(ah, 0, AR_CCCNT);
+       REG_WRITE(ah, 0, AR_RFCNT);
+       REG_WRITE(ah, 0, AR_RCCNT);
+       REG_WRITE(ah, 0, AR_TFCNT);
+
+       /* unfreeze */
+       REG_WRITE(ah, 0, AR_MIBC);
+
+       /* update all cycle counters here */
+       common->cc_ani.cycles += cycles;
+       common->cc_ani.rx_busy += busy;
+       common->cc_ani.rx_frame += rx;
+       common->cc_ani.tx_frame += tx;
+
+       common->cc_survey.cycles += cycles;
+       common->cc_survey.rx_busy += busy;
+       common->cc_survey.rx_frame += rx;
+       common->cc_survey.tx_frame += tx;
+}
+
+int32_t ath_hw_get_listen_time(struct ath_common *common)
+{
+       struct ath_cycle_counters *cc = &common->cc_ani;
+       int32_t listen_time;
+
+       listen_time = (cc->cycles - cc->rx_frame - cc->tx_frame) /
+                     (common->clockrate * 1000);
+
+       memset(cc, 0, sizeof(*cc));
+
+       return listen_time;
+}
diff --git a/src/drivers/net/ath/ath_key.c b/src/drivers/net/ath/ath_key.c
new file mode 100644 (file)
index 0000000..d269a45
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2009 Atheros Communications Inc.
+ * Copyright (c) 2010 Bruno Randolf <br1@einfach.org>
+ *
+ * Modified for iPXE by Scott K Logan <logans@cottsay.net> July 2011
+ * Original from Linux kernel 3.0.1
+ *
+ * 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 "ath.h"
+#include "reg.h"
+
+#define REG_READ                       (common->ops->read)
+#define REG_WRITE(_ah, _reg, _val)     (common->ops->write)(_ah, _val, _reg)
+#define ENABLE_REGWRITE_BUFFER(_ah)                    \
+       if (common->ops->enable_write_buffer)           \
+               common->ops->enable_write_buffer((_ah));
+
+#define REGWRITE_BUFFER_FLUSH(_ah)                     \
+       if (common->ops->write_flush)                   \
+               common->ops->write_flush((_ah));
+
+
+#define IEEE80211_WEP_NKID      4       /* number of key ids */
+
+/************************/
+/* Key Cache Management */
+/************************/
+
+int ath_hw_keyreset(struct ath_common *common, u16 entry)
+{
+       u32 keyType;
+       void *ah = common->ah;
+
+       if (entry >= common->keymax) {
+               DBG("ath: keycache entry %d out of range\n", entry);
+               return 0;
+       }
+
+       keyType = REG_READ(ah, AR_KEYTABLE_TYPE(entry));
+
+       ENABLE_REGWRITE_BUFFER(ah);
+
+       REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), 0);
+       REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), 0);
+       REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), 0);
+       REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), 0);
+       REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), 0);
+       REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), AR_KEYTABLE_TYPE_CLR);
+       REG_WRITE(ah, AR_KEYTABLE_MAC0(entry), 0);
+       REG_WRITE(ah, AR_KEYTABLE_MAC1(entry), 0);
+
+       if (keyType == AR_KEYTABLE_TYPE_TKIP) {
+               u16 micentry = entry + 64;
+
+               REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), 0);
+               REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), 0);
+               REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), 0);
+               REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), 0);
+               if (common->crypt_caps & ATH_CRYPT_CAP_MIC_COMBINED) {
+                       REG_WRITE(ah, AR_KEYTABLE_KEY4(micentry), 0);
+                       REG_WRITE(ah, AR_KEYTABLE_TYPE(micentry),
+                                 AR_KEYTABLE_TYPE_CLR);
+               }
+
+       }
+
+       REGWRITE_BUFFER_FLUSH(ah);
+
+       return 1;
+}
diff --git a/src/drivers/net/ath/ath_main.c b/src/drivers/net/ath/ath_main.c
new file mode 100644 (file)
index 0000000..85d159a
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2009 Atheros Communications Inc.
+ *
+ * Modified for iPXE by Scott K Logan <logans@cottsay.net> July 2011
+ * Original from Linux kernel 3.0.1
+ *
+ * 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 <ipxe/io.h>
+
+#include "ath.h"
+
+struct io_buffer *ath_rxbuf_alloc(struct ath_common *common,
+                               u32 len,
+                               u32 *iob_addr)
+{
+       struct io_buffer *iob;
+       u32 off;
+
+       /*
+        * Cache-line-align.  This is important (for the
+        * 5210 at least) as not doing so causes bogus data
+        * in rx'd frames.
+        */
+
+       /* Note: the kernel can allocate a value greater than
+        * what we ask it to give us. We really only need 4 KB as that
+        * is this hardware supports and in fact we need at least 3849
+        * as that is the MAX AMSDU size this hardware supports.
+        * Unfortunately this means we may get 8 KB here from the
+        * kernel... and that is actually what is observed on some
+        * systems :( */
+       iob = alloc_iob(len + common->cachelsz - 1);
+       if (iob != NULL) {
+               *iob_addr = virt_to_bus(iob->data);
+               off = ((unsigned long) iob->data) % common->cachelsz;
+               if (off != 0)
+               {
+                       iob_reserve(iob, common->cachelsz - off);
+                       *iob_addr += common->cachelsz - off;
+               }
+       } else {
+               DBG("ath: iobuffer alloc of size %d failed\n", len);
+               return NULL;
+       }
+
+       return iob;
+}
diff --git a/src/drivers/net/ath/ath_regd.c b/src/drivers/net/ath/ath_regd.c
new file mode 100644 (file)
index 0000000..190b1f9
--- /dev/null
@@ -0,0 +1,602 @@
+/*
+ * Copyright (c) 2008-2009 Atheros Communications Inc.
+ *
+ * Modified for iPXE by Scott K Logan <logans@cottsay.net> July 2011
+ * Original from Linux kernel 3.0.1
+ *
+ * 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 "regd.h"
+#include "regd_common.h"
+
+/*
+ * This is a set of common rules used by our world regulatory domains.
+ * We have 12 world regulatory domains. To save space we consolidate
+ * the regulatory domains in 5 structures by frequency and change
+ * the flags on our reg_notifier() on a case by case basis.
+ */
+
+/* Only these channels all allow active scan on all world regulatory domains */
+#define ATH9K_2GHZ_CH01_11     REG_RULE(2412-10, 2462+10, 40, 0, 20, 0)
+
+/* We enable active scan on these a case by case basis by regulatory domain */
+#define ATH9K_2GHZ_CH12_13     REG_RULE(2467-10, 2472+10, 40, 0, 20,\
+                                       NL80211_RRF_PASSIVE_SCAN)
+#define ATH9K_2GHZ_CH14                REG_RULE(2484-10, 2484+10, 40, 0, 20,\
+                               NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_OFDM)
+
+/* We allow IBSS on these on a case by case basis by regulatory domain */
+#define ATH9K_5GHZ_5150_5350   REG_RULE(5150-10, 5350+10, 40, 0, 30,\
+                               NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS)
+#define ATH9K_5GHZ_5470_5850   REG_RULE(5470-10, 5850+10, 40, 0, 30,\
+                               NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS)
+#define ATH9K_5GHZ_5725_5850   REG_RULE(5725-10, 5850+10, 40, 0, 30,\
+                               NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS)
+
+#define ATH9K_2GHZ_ALL         ATH9K_2GHZ_CH01_11, \
+                               ATH9K_2GHZ_CH12_13, \
+                               ATH9K_2GHZ_CH14
+
+#define ATH9K_5GHZ_ALL         ATH9K_5GHZ_5150_5350, \
+                               ATH9K_5GHZ_5470_5850
+
+/* This one skips what we call "mid band" */
+#define ATH9K_5GHZ_NO_MIDBAND  ATH9K_5GHZ_5150_5350, \
+                               ATH9K_5GHZ_5725_5850
+
+///* Can be used for:
+// * 0x60, 0x61, 0x62 */
+//static const struct ieee80211_regdomain ath_world_regdom_60_61_62 = {
+//     .n_reg_rules = 5,
+//     .alpha2 =  "99",
+//     .reg_rules = {
+//             ATH9K_2GHZ_ALL,
+//             ATH9K_5GHZ_ALL,
+//     }
+//};
+//
+///* Can be used by 0x63 and 0x65 */
+//static const struct ieee80211_regdomain ath_world_regdom_63_65 = {
+//     .n_reg_rules = 4,
+//     .alpha2 =  "99",
+//     .reg_rules = {
+//             ATH9K_2GHZ_CH01_11,
+//             ATH9K_2GHZ_CH12_13,
+//             ATH9K_5GHZ_NO_MIDBAND,
+//     }
+//};
+//
+///* Can be used by 0x64 only */
+//static const struct ieee80211_regdomain ath_world_regdom_64 = {
+//     .n_reg_rules = 3,
+//     .alpha2 =  "99",
+//     .reg_rules = {
+//             ATH9K_2GHZ_CH01_11,
+//             ATH9K_5GHZ_NO_MIDBAND,
+//     }
+//};
+//
+///* Can be used by 0x66 and 0x69 */
+//static const struct ieee80211_regdomain ath_world_regdom_66_69 = {
+//     .n_reg_rules = 3,
+//     .alpha2 =  "99",
+//     .reg_rules = {
+//             ATH9K_2GHZ_CH01_11,
+//             ATH9K_5GHZ_ALL,
+//     }
+//};
+//
+///* Can be used by 0x67, 0x68, 0x6A and 0x6C */
+//static const struct ieee80211_regdomain ath_world_regdom_67_68_6A_6C = {
+//     .n_reg_rules = 4,
+//     .alpha2 =  "99",
+//     .reg_rules = {
+//             ATH9K_2GHZ_CH01_11,
+//             ATH9K_2GHZ_CH12_13,
+//             ATH9K_5GHZ_ALL,
+//     }
+//};
+//
+//static inline int is_wwr_sku(u16 regd)
+//{
+//     return ((regd & COUNTRY_ERD_FLAG) != COUNTRY_ERD_FLAG) &&
+//             (((regd & WORLD_SKU_MASK) == WORLD_SKU_PREFIX) ||
+//             (regd == WORLD));
+//}
+//
+//static u16 ath_regd_get_eepromRD(struct ath_regulatory *reg)
+//{
+//     return reg->current_rd & ~WORLDWIDE_ROAMING_FLAG;
+//}
+//
+//int ath_is_world_regd(struct ath_regulatory *reg)
+//{
+//     return is_wwr_sku(ath_regd_get_eepromRD(reg));
+//}
+//
+//static const struct ieee80211_regdomain *ath_default_world_regdomain(void)
+//{
+//     /* this is the most restrictive */
+//     return &ath_world_regdom_64;
+//}
+//
+//static const struct
+//ieee80211_regdomain *ath_world_regdomain(struct ath_regulatory *reg)
+//{
+//     switch (reg->regpair->regDmnEnum) {
+//     case 0x60:
+//     case 0x61:
+//     case 0x62:
+//             return &ath_world_regdom_60_61_62;
+//     case 0x63:
+//     case 0x65:
+//             return &ath_world_regdom_63_65;
+//     case 0x64:
+//             return &ath_world_regdom_64;
+//     case 0x66:
+//     case 0x69:
+//             return &ath_world_regdom_66_69;
+//     case 0x67:
+//     case 0x68:
+//     case 0x6A:
+//     case 0x6C:
+//             return &ath_world_regdom_67_68_6A_6C;
+//     default:
+//             WARN_ON(1);
+//             return ath_default_world_regdomain();
+//     }
+//}
+//
+//int ath_is_49ghz_allowed(u16 regdomain)
+//{
+//     /* possibly more */
+//     return regdomain == MKK9_MKKC;
+//}
+//
+///* Frequency is one where radar detection is required */
+//static int ath_is_radar_freq(u16 center_freq)
+//{
+//     return (center_freq >= 5260 && center_freq <= 5700);
+//}
+//
+///*
+// * N.B: These exception rules do not apply radar freqs.
+// *
+// * - We enable adhoc (or beaconing) if allowed by 11d
+// * - We enable active scan if the channel is allowed by 11d
+// * - If no country IE has been processed and a we determine we have
+// *   received a beacon on a channel we can enable active scan and
+// *   adhoc (or beaconing).
+// */
+//static void
+//ath_reg_apply_beaconing_flags(struct wiphy *wiphy,
+//                           enum nl80211_reg_initiator initiator)
+//{
+//     int band;
+//     struct ieee80211_supported_band *sband;
+//     const struct ieee80211_reg_rule *reg_rule;
+//     struct net80211_channel *ch;
+//     unsigned int i;
+//     u32 bandwidth = 0;
+//     int r;
+//
+//     for (band = 0; band < NET80211_NR_BANDS; band++) {
+//
+//             if (!wiphy->bands[band])
+//                     continue;
+//
+//             sband = wiphy->bands[band];
+//
+//             for (i = 0; i < sband->n_channels; i++) {
+//
+//                     ch = &sband->channels[i];
+//
+//                     if (ath_is_radar_freq(ch->center_freq) ||
+//                         (ch->flags & IEEE80211_CHAN_RADAR))
+//                             continue;
+//
+//                     if (initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE) {
+//                             r = freq_reg_info(wiphy,
+//                                               ch->center_freq,
+//                                               bandwidth,
+//                                               &reg_rule);
+//                             if (r)
+//                                     continue;
+//                             /*
+//                              * If 11d had a rule for this channel ensure
+//                              * we enable adhoc/beaconing if it allows us to
+//                              * use it. Note that we would have disabled it
+//                              * by applying our static world regdomain by
+//                              * default during init, prior to calling our
+//                              * regulatory_hint().
+//                              */
+//                             if (!(reg_rule->flags &
+//                                 NL80211_RRF_NO_IBSS))
+//                                     ch->flags &=
+//                                       ~IEEE80211_CHAN_NO_IBSS;
+//                             if (!(reg_rule->flags &
+//                                 NL80211_RRF_PASSIVE_SCAN))
+//                                     ch->flags &=
+//                                       ~IEEE80211_CHAN_PASSIVE_SCAN;
+//                     } else {
+//                             if (ch->beacon_found)
+//                                     ch->flags &= ~(IEEE80211_CHAN_NO_IBSS |
+//                                       IEEE80211_CHAN_PASSIVE_SCAN);
+//                     }
+//             }
+//     }
+//
+//}
+//
+///* Allows active scan scan on Ch 12 and 13 */
+//static void
+//ath_reg_apply_active_scan_flags(struct wiphy *wiphy,
+//                             enum nl80211_reg_initiator initiator)
+//{
+//     struct ieee80211_supported_band *sband;
+//     struct net80211_channel *ch;
+//     const struct ieee80211_reg_rule *reg_rule;
+//     u32 bandwidth = 0;
+//     int r;
+//
+//     sband = wiphy->bands[NET80211_BAND_2GHZ];
+//
+//     /*
+//      * If no country IE has been received always enable active scan
+//      * on these channels. This is only done for specific regulatory SKUs
+//      */
+//     if (initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE) {
+//             ch = &sband->channels[11]; /* CH 12 */
+//             if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
+//                     ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
+//             ch = &sband->channels[12]; /* CH 13 */
+//             if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
+//                     ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
+//             return;
+//     }
+//
+//     /*
+//      * If a country IE has been received check its rule for this
+//      * channel first before enabling active scan. The passive scan
+//      * would have been enforced by the initial processing of our
+//      * custom regulatory domain.
+//      */
+//
+//     ch = &sband->channels[11]; /* CH 12 */
+//     r = freq_reg_info(wiphy, ch->center_freq, bandwidth, &reg_rule);
+//     if (!r) {
+//             if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN))
+//                     if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
+//                             ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
+//     }
+//
+//     ch = &sband->channels[12]; /* CH 13 */
+//     r = freq_reg_info(wiphy, ch->center_freq, bandwidth, &reg_rule);
+//     if (!r) {
+//             if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN))
+//                     if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
+//                             ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
+//     }
+//}
+//
+///* Always apply Radar/DFS rules on freq range 5260 MHz - 5700 MHz */
+//static void ath_reg_apply_radar_flags(struct wiphy *wiphy)
+//{
+//     struct ieee80211_supported_band *sband;
+//     struct net80211_channel *ch;
+//     unsigned int i;
+//
+//     if (!wiphy->bands[NET80211_BAND_5GHZ])
+//             return;
+//
+//     sband = wiphy->bands[NET80211_BAND_5GHZ];
+//
+//     for (i = 0; i < sband->n_channels; i++) {
+//             ch = &sband->channels[i];
+//             if (!ath_is_radar_freq(ch->center_freq))
+//                     continue;
+//             /* We always enable radar detection/DFS on this
+//              * frequency range. Additionally we also apply on
+//              * this frequency range:
+//              * - If STA mode does not yet have DFS supports disable
+//              *   active scanning
+//              * - If adhoc mode does not support DFS yet then
+//              *   disable adhoc in the frequency.
+//              * - If AP mode does not yet support radar detection/DFS
+//              *   do not allow AP mode
+//              */
+//             if (!(ch->flags & IEEE80211_CHAN_DISABLED))
+//                     ch->flags |= IEEE80211_CHAN_RADAR |
+//                                  IEEE80211_CHAN_NO_IBSS |
+//                                  IEEE80211_CHAN_PASSIVE_SCAN;
+//     }
+//}
+//
+//static void ath_reg_apply_world_flags(struct wiphy *wiphy,
+//                                   enum nl80211_reg_initiator initiator,
+//                                   struct ath_regulatory *reg)
+//{
+//     switch (reg->regpair->regDmnEnum) {
+//     case 0x60:
+//     case 0x63:
+//     case 0x66:
+//     case 0x67:
+//     case 0x6C:
+//             ath_reg_apply_beaconing_flags(wiphy, initiator);
+//             break;
+//     case 0x68:
+//             ath_reg_apply_beaconing_flags(wiphy, initiator);
+//             ath_reg_apply_active_scan_flags(wiphy, initiator);
+//             break;
+//     }
+//}
+//
+//int ath_reg_notifier_apply(struct wiphy *wiphy,
+//                        struct regulatory_request *request,
+//                        struct ath_regulatory *reg)
+//{
+//     /* We always apply this */
+//     ath_reg_apply_radar_flags(wiphy);
+//
+//     /*
+//      * This would happen when we have sent a custom regulatory request
+//      * a world regulatory domain and the scheduler hasn't yet processed
+//      * any pending requests in the queue.
+//      */
+//     if (!request)
+//             return 0;
+//
+//     switch (request->initiator) {
+//     case NL80211_REGDOM_SET_BY_DRIVER:
+//     case NL80211_REGDOM_SET_BY_CORE:
+//     case NL80211_REGDOM_SET_BY_USER:
+//             break;
+//     case NL80211_REGDOM_SET_BY_COUNTRY_IE:
+//             if (ath_is_world_regd(reg))
+//                     ath_reg_apply_world_flags(wiphy, request->initiator,
+//                                               reg);
+//             break;
+//     }
+//
+//     return 0;
+//}
+//
+//static int ath_regd_is_eeprom_valid(struct ath_regulatory *reg)
+//{
+//     u16 rd = ath_regd_get_eepromRD(reg);
+//     int i;
+//
+//     if (rd & COUNTRY_ERD_FLAG) {
+//             /* EEPROM value is a country code */
+//             u16 cc = rd & ~COUNTRY_ERD_FLAG;
+//             DBG2(
+//                    "ath: EEPROM indicates we should expect "
+//                     "a country code\n");
+//             for (i = 0; i < ARRAY_SIZE(allCountries); i++)
+//                     if (allCountries[i].countryCode == cc)
+//                             return 1;
+//     } else {
+//             /* EEPROM value is a regpair value */
+//             if (rd != CTRY_DEFAULT)
+//                     DBG2("ath: EEPROM indicates we "
+//                            "should expect a direct regpair map\n");
+//             for (i = 0; i < ARRAY_SIZE(regDomainPairs); i++)
+//                     if (regDomainPairs[i].regDmnEnum == rd)
+//                             return 1;
+//     }
+//     DBG(
+//              "ath: invalid regulatory domain/country code 0x%x\n", rd);
+//     return 0;
+//}
+//
+///* EEPROM country code to regpair mapping */
+//static struct country_code_to_enum_rd*
+//ath_regd_find_country(u16 countryCode)
+//{
+//     int i;
+//
+//     for (i = 0; i < ARRAY_SIZE(allCountries); i++) {
+//             if (allCountries[i].countryCode == countryCode)
+//                     return &allCountries[i];
+//     }
+//     return NULL;
+//}
+//
+///* EEPROM rd code to regpair mapping */
+//static struct country_code_to_enum_rd*
+//ath_regd_find_country_by_rd(int regdmn)
+//{
+//     int i;
+//
+//     for (i = 0; i < ARRAY_SIZE(allCountries); i++) {
+//             if (allCountries[i].regDmnEnum == regdmn)
+//                     return &allCountries[i];
+//     }
+//     return NULL;
+//}
+//
+///* Returns the map of the EEPROM set RD to a country code */
+//static u16 ath_regd_get_default_country(u16 rd)
+//{
+//     if (rd & COUNTRY_ERD_FLAG) {
+//             struct country_code_to_enum_rd *country = NULL;
+//             u16 cc = rd & ~COUNTRY_ERD_FLAG;
+//
+//             country = ath_regd_find_country(cc);
+//             if (country != NULL)
+//                     return cc;
+//     }
+//
+//     return CTRY_DEFAULT;
+//}
+//
+//static struct reg_dmn_pair_mapping*
+//ath_get_regpair(int regdmn)
+//{
+//     int i;
+//
+//     if (regdmn == NO_ENUMRD)
+//             return NULL;
+//     for (i = 0; i < ARRAY_SIZE(regDomainPairs); i++) {
+//             if (regDomainPairs[i].regDmnEnum == regdmn)
+//                     return &regDomainPairs[i];
+//     }
+//     return NULL;
+//}
+//
+//static int
+//ath_regd_init_wiphy(struct ath_regulatory *reg,
+//                 struct wiphy *wiphy,
+//                 int (*reg_notifier)(struct wiphy *wiphy,
+//                                     struct regulatory_request *request))
+//{
+//     const struct ieee80211_regdomain *regd;
+//
+//     wiphy->reg_notifier = reg_notifier;
+//     wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
+//
+//     if (ath_is_world_regd(reg)) {
+//             /*
+//              * Anything applied here (prior to wiphy registration) gets
+//              * saved on the wiphy orig_* parameters
+//              */
+//             regd = ath_world_regdomain(reg);
+//             wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY;
+//     } else {
+//             /*
+//              * This gets applied in the case of the absence of CRDA,
+//              * it's our own custom world regulatory domain, similar to
+//              * cfg80211's but we enable passive scanning.
+//              */
+//             regd = ath_default_world_regdomain();
+//     }
+//     wiphy_apply_custom_regulatory(wiphy, regd);
+//     ath_reg_apply_radar_flags(wiphy);
+//     ath_reg_apply_world_flags(wiphy, NL80211_REGDOM_SET_BY_DRIVER, reg);
+//     return 0;
+//}
+//
+///*
+// * Some users have reported their EEPROM programmed with
+// * 0x8000 set, this is not a supported regulatory domain
+// * but since we have more than one user with it we need
+// * a solution for them. We default to 0x64, which is the
+// * default Atheros world regulatory domain.
+// */
+//static void ath_regd_sanitize(struct ath_regulatory *reg)
+//{
+//     if (reg->current_rd != COUNTRY_ERD_FLAG)
+//             return;
+//     DBG2("ath: EEPROM regdomain sanitized\n");
+//     reg->current_rd = 0x64;
+//}
+//
+//int
+//ath_regd_init(struct ath_regulatory *reg,
+//           struct wiphy *wiphy,
+//           int (*reg_notifier)(struct wiphy *wiphy,
+//                               struct regulatory_request *request))
+//{
+//     struct country_code_to_enum_rd *country = NULL;
+//     u16 regdmn;
+//
+//     if (!reg)
+//             return -EINVAL;
+//
+//     ath_regd_sanitize(reg);
+//
+//     DBG2("ath: EEPROM regdomain: 0x%0x\n", reg->current_rd);
+//
+//     if (!ath_regd_is_eeprom_valid(reg)) {
+//             DBG("ath: Invalid EEPROM contents\n");
+//             return -EINVAL;
+//     }
+//
+//     regdmn = ath_regd_get_eepromRD(reg);
+//     reg->country_code = ath_regd_get_default_country(regdmn);
+//
+//     if (reg->country_code == CTRY_DEFAULT &&
+//         regdmn == CTRY_DEFAULT) {
+//             DBG2("ath: EEPROM indicates default "
+//                    "country code should be used\n");
+//             reg->country_code = CTRY_UNITED_STATES;
+//     }
+//
+//     if (reg->country_code == CTRY_DEFAULT) {
+//             country = NULL;
+//     } else {
+//             DBG2("ath: doing EEPROM country->regdmn "
+//                    "map search\n");
+//             country = ath_regd_find_country(reg->country_code);
+//             if (country == NULL) {
+//                     DBG(
+//                             "ath: no valid country maps found for "
+//                             "country code: 0x%0x\n",
+//                             reg->country_code);
+//                     return -EINVAL;
+//             } else {
+//                     regdmn = country->regDmnEnum;
+//                     DBG2("ath: country maps to "
+//                            "regdmn code: 0x%0x\n",
+//                            regdmn);
+//             }
+//     }
+//
+//     reg->regpair = ath_get_regpair(regdmn);
+//
+//     if (!reg->regpair) {
+//             DBG("ath: "
+//                     "No regulatory domain pair found, cannot continue\n");
+//             return -EINVAL;
+//     }
+//
+//     if (!country)
+//             country = ath_regd_find_country_by_rd(regdmn);
+//
+//     if (country) {
+//             reg->alpha2[0] = country->isoName[0];
+//             reg->alpha2[1] = country->isoName[1];
+//     } else {
+//             reg->alpha2[0] = '0';
+//             reg->alpha2[1] = '0';
+//     }
+//
+//     DBG2("ath: Country alpha2 being used: %c%c\n",
+//             reg->alpha2[0], reg->alpha2[1]);
+//     DBG2("ath: Regpair used: 0x%0x\n",
+//             reg->regpair->regDmnEnum);
+//
+//     ath_regd_init_wiphy(reg, wiphy, reg_notifier);
+//     return 0;
+//}
+
+u32 ath_regd_get_band_ctl(struct ath_regulatory *reg,
+                         int band)
+{
+       /* TODO Cottsay: reg */
+//     if (!reg->regpair ||
+//         (reg->country_code == CTRY_DEFAULT &&
+//          is_wwr_sku(ath_regd_get_eepromRD(reg)))) {
+//             return SD_NO_CTL;
+//     }
+
+       switch (band) {
+       case NET80211_BAND_2GHZ:
+               return reg->regpair->reg_2ghz_ctl;
+       case NET80211_BAND_5GHZ:
+               return reg->regpair->reg_5ghz_ctl;
+       default:
+               return NO_CTL;
+       }
+}
diff --git a/src/drivers/net/ath/reg.h b/src/drivers/net/ath/reg.h
new file mode 100644 (file)
index 0000000..484a8f1
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2008-2009 Atheros Communications Inc.
+ *
+ * Modified for iPXE by Scott K Logan <logans@cottsay.net> July 2011
+ * Original from Linux kernel 3.0.1
+ *
+ * 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 ATH_REGISTERS_H
+#define ATH_REGISTERS_H
+
+#define AR_MIBC                        0x0040
+#define AR_MIBC_COW            0x00000001
+#define AR_MIBC_FMC            0x00000002
+#define AR_MIBC_CMC            0x00000004
+#define AR_MIBC_MCS            0x00000008
+
+/*
+ * BSSID mask registers. See ath_hw_set_bssid_mask()
+ * for detailed documentation about these registers.
+ */
+#define AR_BSSMSKL             0x80e0
+#define AR_BSSMSKU             0x80e4
+
+#define AR_TFCNT               0x80ec
+#define AR_RFCNT               0x80f0
+#define AR_RCCNT               0x80f4
+#define AR_CCCNT               0x80f8
+
+#define AR_KEYTABLE_0           0x8800
+#define AR_KEYTABLE(_n)         (AR_KEYTABLE_0 + ((_n)*32))
+#define AR_KEY_CACHE_SIZE       128
+#define AR_RSVD_KEYTABLE_ENTRIES 4
+#define AR_KEY_TYPE             0x00000007
+#define AR_KEYTABLE_TYPE_40     0x00000000
+#define AR_KEYTABLE_TYPE_104    0x00000001
+#define AR_KEYTABLE_TYPE_128    0x00000003
+#define AR_KEYTABLE_TYPE_TKIP   0x00000004
+#define AR_KEYTABLE_TYPE_AES    0x00000005
+#define AR_KEYTABLE_TYPE_CCM    0x00000006
+#define AR_KEYTABLE_TYPE_CLR    0x00000007
+#define AR_KEYTABLE_ANT         0x00000008
+#define AR_KEYTABLE_VALID       0x00008000
+#define AR_KEYTABLE_KEY0(_n)    (AR_KEYTABLE(_n) + 0)
+#define AR_KEYTABLE_KEY1(_n)    (AR_KEYTABLE(_n) + 4)
+#define AR_KEYTABLE_KEY2(_n)    (AR_KEYTABLE(_n) + 8)
+#define AR_KEYTABLE_KEY3(_n)    (AR_KEYTABLE(_n) + 12)
+#define AR_KEYTABLE_KEY4(_n)    (AR_KEYTABLE(_n) + 16)
+#define AR_KEYTABLE_TYPE(_n)    (AR_KEYTABLE(_n) + 20)
+#define AR_KEYTABLE_MAC0(_n)    (AR_KEYTABLE(_n) + 24)
+#define AR_KEYTABLE_MAC1(_n)    (AR_KEYTABLE(_n) + 28)
+
+#endif /* ATH_REGISTERS_H */
diff --git a/src/drivers/net/ath/regd.h b/src/drivers/net/ath/regd.h
new file mode 100644 (file)
index 0000000..6954c5f
--- /dev/null
@@ -0,0 +1,263 @@
+/*
+ * Copyright (c) 2008-2009 Atheros Communications Inc.
+ *
+ * Modified for iPXE by Scott K Logan <logans@cottsay.net> July 2011
+ * Original from Linux kernel 3.0.1
+ *
+ * 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 REGD_H
+#define REGD_H
+
+#include "ath.h"
+
+enum ctl_group {
+       CTL_FCC = 0x10,
+       CTL_MKK = 0x40,
+       CTL_ETSI = 0x30,
+};
+
+#define NO_CTL 0xff
+#define SD_NO_CTL               0xE0
+#define NO_CTL                  0xff
+#define CTL_11A                 0
+#define CTL_11B                 1
+#define CTL_11G                 2
+#define CTL_2GHT20              5
+#define CTL_5GHT20              6
+#define CTL_2GHT40              7
+#define CTL_5GHT40              8
+
+#define CTRY_DEBUG 0x1ff
+#define CTRY_DEFAULT 0
+
+#define COUNTRY_ERD_FLAG        0x8000
+#define WORLDWIDE_ROAMING_FLAG  0x4000
+
+#define MULTI_DOMAIN_MASK 0xFF00
+
+#define WORLD_SKU_MASK          0x00F0
+#define WORLD_SKU_PREFIX        0x0060
+
+#define CHANNEL_HALF_BW         10
+#define CHANNEL_QUARTER_BW      5
+
+struct country_code_to_enum_rd {
+       u16 countryCode;
+       u16 regDmnEnum;
+       const char *isoName;
+};
+
+enum CountryCode {
+       CTRY_ALBANIA = 8,
+       CTRY_ALGERIA = 12,
+       CTRY_ARGENTINA = 32,
+       CTRY_ARMENIA = 51,
+       CTRY_ARUBA = 533,
+       CTRY_AUSTRALIA = 36,
+       CTRY_AUSTRIA = 40,
+       CTRY_AZERBAIJAN = 31,
+       CTRY_BAHRAIN = 48,
+       CTRY_BANGLADESH = 50,
+       CTRY_BARBADOS = 52,
+       CTRY_BELARUS = 112,
+       CTRY_BELGIUM = 56,
+       CTRY_BELIZE = 84,
+       CTRY_BOLIVIA = 68,
+       CTRY_BOSNIA_HERZ = 70,
+       CTRY_BRAZIL = 76,
+       CTRY_BRUNEI_DARUSSALAM = 96,
+       CTRY_BULGARIA = 100,
+       CTRY_CAMBODIA = 116,
+       CTRY_CANADA = 124,
+       CTRY_CHILE = 152,
+       CTRY_CHINA = 156,
+       CTRY_COLOMBIA = 170,
+       CTRY_COSTA_RICA = 188,
+       CTRY_CROATIA = 191,
+       CTRY_CYPRUS = 196,
+       CTRY_CZECH = 203,
+       CTRY_DENMARK = 208,
+       CTRY_DOMINICAN_REPUBLIC = 214,
+       CTRY_ECUADOR = 218,
+       CTRY_EGYPT = 818,
+       CTRY_EL_SALVADOR = 222,
+       CTRY_ESTONIA = 233,
+       CTRY_FAEROE_ISLANDS = 234,
+       CTRY_FINLAND = 246,
+       CTRY_FRANCE = 250,
+       CTRY_GEORGIA = 268,
+       CTRY_GERMANY = 276,
+       CTRY_GREECE = 300,
+       CTRY_GREENLAND = 304,
+       CTRY_GRENEDA = 308,
+       CTRY_GUAM = 316,
+       CTRY_GUATEMALA = 320,
+       CTRY_HAITI = 332,
+       CTRY_HONDURAS = 340,
+       CTRY_HONG_KONG = 344,
+       CTRY_HUNGARY = 348,
+       CTRY_ICELAND = 352,
+       CTRY_INDIA = 356,
+       CTRY_INDONESIA = 360,
+       CTRY_IRAN = 364,
+       CTRY_IRAQ = 368,
+       CTRY_IRELAND = 372,
+       CTRY_ISRAEL = 376,
+       CTRY_ITALY = 380,
+       CTRY_JAMAICA = 388,
+       CTRY_JAPAN = 392,
+       CTRY_JORDAN = 400,
+       CTRY_KAZAKHSTAN = 398,
+       CTRY_KENYA = 404,
+       CTRY_KOREA_NORTH = 408,
+       CTRY_KOREA_ROC = 410,
+       CTRY_KOREA_ROC2 = 411,
+       CTRY_KOREA_ROC3 = 412,
+       CTRY_KUWAIT = 414,
+       CTRY_LATVIA = 428,
+       CTRY_LEBANON = 422,
+       CTRY_LIBYA = 434,
+       CTRY_LIECHTENSTEIN = 438,
+       CTRY_LITHUANIA = 440,
+       CTRY_LUXEMBOURG = 442,
+       CTRY_MACAU = 446,
+       CTRY_MACEDONIA = 807,
+       CTRY_MALAYSIA = 458,
+       CTRY_MALTA = 470,
+       CTRY_MEXICO = 484,
+       CTRY_MONACO = 492,
+       CTRY_MOROCCO = 504,
+       CTRY_NEPAL = 524,
+       CTRY_NETHERLANDS = 528,
+       CTRY_NETHERLANDS_ANTILLES = 530,
+       CTRY_NEW_ZEALAND = 554,
+       CTRY_NICARAGUA = 558,
+       CTRY_NORWAY = 578,
+       CTRY_OMAN = 512,
+       CTRY_PAKISTAN = 586,
+       CTRY_PANAMA = 591,
+       CTRY_PAPUA_NEW_GUINEA = 598,
+       CTRY_PARAGUAY = 600,
+       CTRY_PERU = 604,
+       CTRY_PHILIPPINES = 608,
+       CTRY_POLAND = 616,
+       CTRY_PORTUGAL = 620,
+       CTRY_PUERTO_RICO = 630,
+       CTRY_QATAR = 634,
+       CTRY_ROMANIA = 642,
+       CTRY_RUSSIA = 643,
+       CTRY_SAUDI_ARABIA = 682,
+       CTRY_SERBIA_MONTENEGRO = 891,
+       CTRY_SINGAPORE = 702,
+       CTRY_SLOVAKIA = 703,
+       CTRY_SLOVENIA = 705,
+       CTRY_SOUTH_AFRICA = 710,
+       CTRY_SPAIN = 724,
+       CTRY_SRI_LANKA = 144,
+       CTRY_SWEDEN = 752,
+       CTRY_SWITZERLAND = 756,
+       CTRY_SYRIA = 760,
+       CTRY_TAIWAN = 158,
+       CTRY_THAILAND = 764,
+       CTRY_TRINIDAD_Y_TOBAGO = 780,
+       CTRY_TUNISIA = 788,
+       CTRY_TURKEY = 792,
+       CTRY_UAE = 784,
+       CTRY_UKRAINE = 804,
+       CTRY_UNITED_KINGDOM = 826,
+       CTRY_UNITED_STATES = 840,
+       CTRY_UNITED_STATES_FCC49 = 842,
+       CTRY_URUGUAY = 858,
+       CTRY_UZBEKISTAN = 860,
+       CTRY_VENEZUELA = 862,
+       CTRY_VIET_NAM = 704,
+       CTRY_YEMEN = 887,
+       CTRY_ZIMBABWE = 716,
+       CTRY_JAPAN1 = 393,
+       CTRY_JAPAN2 = 394,
+       CTRY_JAPAN3 = 395,
+       CTRY_JAPAN4 = 396,
+       CTRY_JAPAN5 = 397,
+       CTRY_JAPAN6 = 4006,
+       CTRY_JAPAN7 = 4007,
+       CTRY_JAPAN8 = 4008,
+       CTRY_JAPAN9 = 4009,
+       CTRY_JAPAN10 = 4010,
+       CTRY_JAPAN11 = 4011,
+       CTRY_JAPAN12 = 4012,
+       CTRY_JAPAN13 = 4013,
+       CTRY_JAPAN14 = 4014,
+       CTRY_JAPAN15 = 4015,
+       CTRY_JAPAN16 = 4016,
+       CTRY_JAPAN17 = 4017,
+       CTRY_JAPAN18 = 4018,
+       CTRY_JAPAN19 = 4019,
+       CTRY_JAPAN20 = 4020,
+       CTRY_JAPAN21 = 4021,
+       CTRY_JAPAN22 = 4022,
+       CTRY_JAPAN23 = 4023,
+       CTRY_JAPAN24 = 4024,
+       CTRY_JAPAN25 = 4025,
+       CTRY_JAPAN26 = 4026,
+       CTRY_JAPAN27 = 4027,
+       CTRY_JAPAN28 = 4028,
+       CTRY_JAPAN29 = 4029,
+       CTRY_JAPAN30 = 4030,
+       CTRY_JAPAN31 = 4031,
+       CTRY_JAPAN32 = 4032,
+       CTRY_JAPAN33 = 4033,
+       CTRY_JAPAN34 = 4034,
+       CTRY_JAPAN35 = 4035,
+       CTRY_JAPAN36 = 4036,
+       CTRY_JAPAN37 = 4037,
+       CTRY_JAPAN38 = 4038,
+       CTRY_JAPAN39 = 4039,
+       CTRY_JAPAN40 = 4040,
+       CTRY_JAPAN41 = 4041,
+       CTRY_JAPAN42 = 4042,
+       CTRY_JAPAN43 = 4043,
+       CTRY_JAPAN44 = 4044,
+       CTRY_JAPAN45 = 4045,
+       CTRY_JAPAN46 = 4046,
+       CTRY_JAPAN47 = 4047,
+       CTRY_JAPAN48 = 4048,
+       CTRY_JAPAN49 = 4049,
+       CTRY_JAPAN50 = 4050,
+       CTRY_JAPAN51 = 4051,
+       CTRY_JAPAN52 = 4052,
+       CTRY_JAPAN53 = 4053,
+       CTRY_JAPAN54 = 4054,
+       CTRY_JAPAN55 = 4055,
+       CTRY_JAPAN56 = 4056,
+       CTRY_JAPAN57 = 4057,
+       CTRY_JAPAN58 = 4058,
+       CTRY_JAPAN59 = 4059,
+       CTRY_AUSTRALIA2 = 5000,
+       CTRY_CANADA2 = 5001,
+       CTRY_BELGIUM2 = 5002
+};
+
+int ath_is_world_regd(struct ath_regulatory *reg);
+int ath_is_49ghz_allowed(u16 redomain);
+//int ath_regd_init(struct ath_regulatory *reg, struct wiphy *wiphy,
+//               int (*reg_notifier)(struct wiphy *wiphy,
+//               struct regulatory_request *request));
+u32 ath_regd_get_band_ctl(struct ath_regulatory *reg,
+                         int band);
+//int ath_reg_notifier_apply(struct wiphy *wiphy,
+//                        struct regulatory_request *request,
+//                        struct ath_regulatory *reg);
+
+#endif
diff --git a/src/drivers/net/ath/regd_common.h b/src/drivers/net/ath/regd_common.h
new file mode 100644 (file)
index 0000000..ee1ac3f
--- /dev/null
@@ -0,0 +1,481 @@
+/*
+ * Copyright (c) 2008-2009 Atheros Communications Inc.
+ *
+ * Modified for iPXE by Scott K Logan <logans@cottsay.net> July 2011
+ * Original from Linux kernel 3.0.1
+ *
+ * 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 REGD_COMMON_H
+#define REGD_COMMON_H
+
+enum EnumRd {
+       NO_ENUMRD = 0x00,
+       NULL1_WORLD = 0x03,
+       NULL1_ETSIB = 0x07,
+       NULL1_ETSIC = 0x08,
+       FCC1_FCCA = 0x10,
+       FCC1_WORLD = 0x11,
+       FCC4_FCCA = 0x12,
+       FCC5_FCCA = 0x13,
+       FCC6_FCCA = 0x14,
+
+       FCC2_FCCA = 0x20,
+       FCC2_WORLD = 0x21,
+       FCC2_ETSIC = 0x22,
+       FCC6_WORLD = 0x23,
+       FRANCE_RES = 0x31,
+       FCC3_FCCA = 0x3A,
+       FCC3_WORLD = 0x3B,
+
+       ETSI1_WORLD = 0x37,
+       ETSI3_ETSIA = 0x32,
+       ETSI2_WORLD = 0x35,
+       ETSI3_WORLD = 0x36,
+       ETSI4_WORLD = 0x30,
+       ETSI4_ETSIC = 0x38,
+       ETSI5_WORLD = 0x39,
+       ETSI6_WORLD = 0x34,
+       ETSI_RESERVED = 0x33,
+
+       MKK1_MKKA = 0x40,
+       MKK1_MKKB = 0x41,
+       APL4_WORLD = 0x42,
+       MKK2_MKKA = 0x43,
+       APL_RESERVED = 0x44,
+       APL2_WORLD = 0x45,
+       APL2_APLC = 0x46,
+       APL3_WORLD = 0x47,
+       MKK1_FCCA = 0x48,
+       APL2_APLD = 0x49,
+       MKK1_MKKA1 = 0x4A,
+       MKK1_MKKA2 = 0x4B,
+       MKK1_MKKC = 0x4C,
+
+       APL3_FCCA = 0x50,
+       APL1_WORLD = 0x52,
+       APL1_FCCA = 0x53,
+       APL1_APLA = 0x54,
+       APL1_ETSIC = 0x55,
+       APL2_ETSIC = 0x56,
+       APL5_WORLD = 0x58,
+       APL6_WORLD = 0x5B,
+       APL7_FCCA = 0x5C,
+       APL8_WORLD = 0x5D,
+       APL9_WORLD = 0x5E,
+
+       WOR0_WORLD = 0x60,
+       WOR1_WORLD = 0x61,
+       WOR2_WORLD = 0x62,
+       WOR3_WORLD = 0x63,
+       WOR4_WORLD = 0x64,
+       WOR5_ETSIC = 0x65,
+
+       WOR01_WORLD = 0x66,
+       WOR02_WORLD = 0x67,
+       EU1_WORLD = 0x68,
+
+       WOR9_WORLD = 0x69,
+       WORA_WORLD = 0x6A,
+       WORB_WORLD = 0x6B,
+       WORC_WORLD = 0x6C,
+
+       MKK3_MKKB = 0x80,
+       MKK3_MKKA2 = 0x81,
+       MKK3_MKKC = 0x82,
+
+       MKK4_MKKB = 0x83,
+       MKK4_MKKA2 = 0x84,
+       MKK4_MKKC = 0x85,
+
+       MKK5_MKKB = 0x86,
+       MKK5_MKKA2 = 0x87,
+       MKK5_MKKC = 0x88,
+
+       MKK6_MKKB = 0x89,
+       MKK6_MKKA2 = 0x8A,
+       MKK6_MKKC = 0x8B,
+
+       MKK7_MKKB = 0x8C,
+       MKK7_MKKA2 = 0x8D,
+       MKK7_MKKC = 0x8E,
+
+       MKK8_MKKB = 0x8F,
+       MKK8_MKKA2 = 0x90,
+       MKK8_MKKC = 0x91,
+
+       MKK14_MKKA1 = 0x92,
+       MKK15_MKKA1 = 0x93,
+
+       MKK10_FCCA = 0xD0,
+       MKK10_MKKA1 = 0xD1,
+       MKK10_MKKC = 0xD2,
+       MKK10_MKKA2 = 0xD3,
+
+       MKK11_MKKA = 0xD4,
+       MKK11_FCCA = 0xD5,
+       MKK11_MKKA1 = 0xD6,
+       MKK11_MKKC = 0xD7,
+       MKK11_MKKA2 = 0xD8,
+
+       MKK12_MKKA = 0xD9,
+       MKK12_FCCA = 0xDA,
+       MKK12_MKKA1 = 0xDB,
+       MKK12_MKKC = 0xDC,
+       MKK12_MKKA2 = 0xDD,
+
+       MKK13_MKKB = 0xDE,
+
+       MKK3_MKKA = 0xF0,
+       MKK3_MKKA1 = 0xF1,
+       MKK3_FCCA = 0xF2,
+       MKK4_MKKA = 0xF3,
+       MKK4_MKKA1 = 0xF4,
+       MKK4_FCCA = 0xF5,
+       MKK9_MKKA = 0xF6,
+       MKK10_MKKA = 0xF7,
+       MKK6_MKKA1 = 0xF8,
+       MKK6_FCCA = 0xF9,
+       MKK7_MKKA1 = 0xFA,
+       MKK7_FCCA = 0xFB,
+       MKK9_FCCA = 0xFC,
+       MKK9_MKKA1 = 0xFD,
+       MKK9_MKKC = 0xFE,
+       MKK9_MKKA2 = 0xFF,
+
+       WORLD = 0x0199,
+       DEBUG_REG_DMN = 0x01ff,
+};
+
+///* Regpair to CTL band mapping */
+//static struct reg_dmn_pair_mapping regDomainPairs[] = {
+//     /* regpair, 5 GHz CTL, 2 GHz CTL */
+//     {NO_ENUMRD, DEBUG_REG_DMN, DEBUG_REG_DMN},
+//     {NULL1_WORLD, NO_CTL, CTL_ETSI},
+//     {NULL1_ETSIB, NO_CTL, CTL_ETSI},
+//     {NULL1_ETSIC, NO_CTL, CTL_ETSI},
+//
+//     {FCC2_FCCA, CTL_FCC, CTL_FCC},
+//     {FCC2_WORLD, CTL_FCC, CTL_ETSI},
+//     {FCC2_ETSIC, CTL_FCC, CTL_ETSI},
+//     {FCC3_FCCA, CTL_FCC, CTL_FCC},
+//     {FCC3_WORLD, CTL_FCC, CTL_ETSI},
+//     {FCC4_FCCA, CTL_FCC, CTL_FCC},
+//     {FCC5_FCCA, CTL_FCC, CTL_FCC},
+//     {FCC6_FCCA, CTL_FCC, CTL_FCC},
+//     {FCC6_WORLD, CTL_FCC, CTL_ETSI},
+//
+//     {ETSI1_WORLD, CTL_ETSI, CTL_ETSI},
+//     {ETSI2_WORLD, CTL_ETSI, CTL_ETSI},
+//     {ETSI3_WORLD, CTL_ETSI, CTL_ETSI},
+//     {ETSI4_WORLD, CTL_ETSI, CTL_ETSI},
+//     {ETSI5_WORLD, CTL_ETSI, CTL_ETSI},
+//     {ETSI6_WORLD, CTL_ETSI, CTL_ETSI},
+//
+//     /* XXX: For ETSI3_ETSIA, Was NO_CTL meant for the 2 GHz band ? */
+//     {ETSI3_ETSIA, CTL_ETSI, CTL_ETSI},
+//     {FRANCE_RES, CTL_ETSI, CTL_ETSI},
+//
+//     {FCC1_WORLD, CTL_FCC, CTL_ETSI},
+//     {FCC1_FCCA, CTL_FCC, CTL_FCC},
+//     {APL1_WORLD, CTL_FCC, CTL_ETSI},
+//     {APL2_WORLD, CTL_FCC, CTL_ETSI},
+//     {APL3_WORLD, CTL_FCC, CTL_ETSI},
+//     {APL4_WORLD, CTL_FCC, CTL_ETSI},
+//     {APL5_WORLD, CTL_FCC, CTL_ETSI},
+//     {APL6_WORLD, CTL_ETSI, CTL_ETSI},
+//     {APL8_WORLD, CTL_ETSI, CTL_ETSI},
+//     {APL9_WORLD, CTL_ETSI, CTL_ETSI},
+//
+//     {APL3_FCCA, CTL_FCC, CTL_FCC},
+//     {APL7_FCCA, CTL_FCC, CTL_FCC},
+//     {APL1_ETSIC, CTL_FCC, CTL_ETSI},
+//     {APL2_ETSIC, CTL_FCC, CTL_ETSI},
+//     {APL2_APLD, CTL_FCC, NO_CTL},
+//
+//     {MKK1_MKKA, CTL_MKK, CTL_MKK},
+//     {MKK1_MKKB, CTL_MKK, CTL_MKK},
+//     {MKK1_FCCA, CTL_MKK, CTL_FCC},
+//     {MKK1_MKKA1, CTL_MKK, CTL_MKK},
+//     {MKK1_MKKA2, CTL_MKK, CTL_MKK},
+//     {MKK1_MKKC, CTL_MKK, CTL_MKK},
+//
+//     {MKK2_MKKA, CTL_MKK, CTL_MKK},
+//     {MKK3_MKKA, CTL_MKK, CTL_MKK},
+//     {MKK3_MKKB, CTL_MKK, CTL_MKK},
+//     {MKK3_MKKA1, CTL_MKK, CTL_MKK},
+//     {MKK3_MKKA2, CTL_MKK, CTL_MKK},
+//     {MKK3_MKKC, CTL_MKK, CTL_MKK},
+//     {MKK3_FCCA, CTL_MKK, CTL_FCC},
+//
+//     {MKK4_MKKA, CTL_MKK, CTL_MKK},
+//     {MKK4_MKKB, CTL_MKK, CTL_MKK},
+//     {MKK4_MKKA1, CTL_MKK, CTL_MKK},
+//     {MKK4_MKKA2, CTL_MKK, CTL_MKK},
+//     {MKK4_MKKC, CTL_MKK, CTL_MKK},
+//     {MKK4_FCCA, CTL_MKK, CTL_FCC},
+//
+//     {MKK5_MKKB, CTL_MKK, CTL_MKK},
+//     {MKK5_MKKA2, CTL_MKK, CTL_MKK},
+//     {MKK5_MKKC, CTL_MKK, CTL_MKK},
+//
+//     {MKK6_MKKB, CTL_MKK, CTL_MKK},
+//     {MKK6_MKKA1, CTL_MKK, CTL_MKK},
+//     {MKK6_MKKA2, CTL_MKK, CTL_MKK},
+//     {MKK6_MKKC, CTL_MKK, CTL_MKK},
+//     {MKK6_FCCA, CTL_MKK, CTL_FCC},
+//
+//     {MKK7_MKKB, CTL_MKK, CTL_MKK},
+//     {MKK7_MKKA1, CTL_MKK, CTL_MKK},
+//     {MKK7_MKKA2, CTL_MKK, CTL_MKK},
+//     {MKK7_MKKC, CTL_MKK, CTL_MKK},
+//     {MKK7_FCCA, CTL_MKK, CTL_FCC},
+//
+//     {MKK8_MKKB, CTL_MKK, CTL_MKK},
+//     {MKK8_MKKA2, CTL_MKK, CTL_MKK},
+//     {MKK8_MKKC, CTL_MKK, CTL_MKK},
+//
+//     {MKK9_MKKA, CTL_MKK, CTL_MKK},
+//     {MKK9_FCCA, CTL_MKK, CTL_FCC},
+//     {MKK9_MKKA1, CTL_MKK, CTL_MKK},
+//     {MKK9_MKKA2, CTL_MKK, CTL_MKK},
+//     {MKK9_MKKC, CTL_MKK, CTL_MKK},
+//
+//     {MKK10_MKKA, CTL_MKK, CTL_MKK},
+//     {MKK10_FCCA, CTL_MKK, CTL_FCC},
+//     {MKK10_MKKA1, CTL_MKK, CTL_MKK},
+//     {MKK10_MKKA2, CTL_MKK, CTL_MKK},
+//     {MKK10_MKKC, CTL_MKK, CTL_MKK},
+//
+//     {MKK11_MKKA, CTL_MKK, CTL_MKK},
+//     {MKK11_FCCA, CTL_MKK, CTL_FCC},
+//     {MKK11_MKKA1, CTL_MKK, CTL_MKK},
+//     {MKK11_MKKA2, CTL_MKK, CTL_MKK},
+//     {MKK11_MKKC, CTL_MKK, CTL_MKK},
+//
+//     {MKK12_MKKA, CTL_MKK, CTL_MKK},
+//     {MKK12_FCCA, CTL_MKK, CTL_FCC},
+//     {MKK12_MKKA1, CTL_MKK, CTL_MKK},
+//     {MKK12_MKKA2, CTL_MKK, CTL_MKK},
+//     {MKK12_MKKC, CTL_MKK, CTL_MKK},
+//
+//     {MKK13_MKKB, CTL_MKK, CTL_MKK},
+//     {MKK14_MKKA1, CTL_MKK, CTL_MKK},
+//     {MKK15_MKKA1, CTL_MKK, CTL_MKK},
+//
+//     {WOR0_WORLD, NO_CTL, NO_CTL},
+//     {WOR1_WORLD, NO_CTL, NO_CTL},
+//     {WOR2_WORLD, NO_CTL, NO_CTL},
+//     {WOR3_WORLD, NO_CTL, NO_CTL},
+//     {WOR4_WORLD, NO_CTL, NO_CTL},
+//     {WOR5_ETSIC, NO_CTL, NO_CTL},
+//     {WOR01_WORLD, NO_CTL, NO_CTL},
+//     {WOR02_WORLD, NO_CTL, NO_CTL},
+//     {EU1_WORLD, NO_CTL, NO_CTL},
+//     {WOR9_WORLD, NO_CTL, NO_CTL},
+//     {WORA_WORLD, NO_CTL, NO_CTL},
+//     {WORB_WORLD, NO_CTL, NO_CTL},
+//     {WORC_WORLD, NO_CTL, NO_CTL},
+//};
+//
+//static struct country_code_to_enum_rd allCountries[] = {
+//     {CTRY_DEBUG, NO_ENUMRD, "DB"},
+//     {CTRY_DEFAULT, FCC1_FCCA, "CO"},
+//     {CTRY_ALBANIA, NULL1_WORLD, "AL"},
+//     {CTRY_ALGERIA, NULL1_WORLD, "DZ"},
+//     {CTRY_ARGENTINA, FCC3_WORLD, "AR"},
+//     {CTRY_ARMENIA, ETSI4_WORLD, "AM"},
+//     {CTRY_ARUBA, ETSI1_WORLD, "AW"},
+//     {CTRY_AUSTRALIA, FCC2_WORLD, "AU"},
+//     {CTRY_AUSTRALIA2, FCC6_WORLD, "AU"},
+//     {CTRY_AUSTRIA, ETSI1_WORLD, "AT"},
+//     {CTRY_AZERBAIJAN, ETSI4_WORLD, "AZ"},
+//     {CTRY_BAHRAIN, APL6_WORLD, "BH"},
+//     {CTRY_BANGLADESH, NULL1_WORLD, "BD"},
+//     {CTRY_BARBADOS, FCC2_WORLD, "BB"},
+//     {CTRY_BELARUS, ETSI1_WORLD, "BY"},
+//     {CTRY_BELGIUM, ETSI1_WORLD, "BE"},
+//     {CTRY_BELGIUM2, ETSI4_WORLD, "BL"},
+//     {CTRY_BELIZE, APL1_ETSIC, "BZ"},
+//     {CTRY_BOLIVIA, APL1_ETSIC, "BO"},
+//     {CTRY_BOSNIA_HERZ, ETSI1_WORLD, "BA"},
+//     {CTRY_BRAZIL, FCC3_WORLD, "BR"},
+//     {CTRY_BRUNEI_DARUSSALAM, APL1_WORLD, "BN"},
+//     {CTRY_BULGARIA, ETSI6_WORLD, "BG"},
+//     {CTRY_CAMBODIA, ETSI1_WORLD, "KH"},
+//     {CTRY_CANADA, FCC3_FCCA, "CA"},
+//     {CTRY_CANADA2, FCC6_FCCA, "CA"},
+//     {CTRY_CHILE, APL6_WORLD, "CL"},
+//     {CTRY_CHINA, APL1_WORLD, "CN"},
+//     {CTRY_COLOMBIA, FCC1_FCCA, "CO"},
+//     {CTRY_COSTA_RICA, FCC1_WORLD, "CR"},
+//     {CTRY_CROATIA, ETSI1_WORLD, "HR"},
+//     {CTRY_CYPRUS, ETSI1_WORLD, "CY"},
+//     {CTRY_CZECH, ETSI3_WORLD, "CZ"},
+//     {CTRY_DENMARK, ETSI1_WORLD, "DK"},
+//     {CTRY_DOMINICAN_REPUBLIC, FCC1_FCCA, "DO"},
+//     {CTRY_ECUADOR, FCC1_WORLD, "EC"},
+//     {CTRY_EGYPT, ETSI3_WORLD, "EG"},
+//     {CTRY_EL_SALVADOR, FCC1_WORLD, "SV"},
+//     {CTRY_ESTONIA, ETSI1_WORLD, "EE"},
+//     {CTRY_FINLAND, ETSI1_WORLD, "FI"},
+//     {CTRY_FRANCE, ETSI1_WORLD, "FR"},
+//     {CTRY_GEORGIA, ETSI4_WORLD, "GE"},
+//     {CTRY_GERMANY, ETSI1_WORLD, "DE"},
+//     {CTRY_GREECE, ETSI1_WORLD, "GR"},
+//     {CTRY_GREENLAND, ETSI1_WORLD, "GL"},
+//     {CTRY_GRENEDA, FCC3_FCCA, "GD"},
+//     {CTRY_GUAM, FCC1_FCCA, "GU"},
+//     {CTRY_GUATEMALA, FCC1_FCCA, "GT"},
+//     {CTRY_HAITI, ETSI1_WORLD, "HT"},
+//     {CTRY_HONDURAS, NULL1_WORLD, "HN"},
+//     {CTRY_HONG_KONG, FCC3_WORLD, "HK"},
+//     {CTRY_HUNGARY, ETSI1_WORLD, "HU"},
+//     {CTRY_ICELAND, ETSI1_WORLD, "IS"},
+//     {CTRY_INDIA, APL6_WORLD, "IN"},
+//     {CTRY_INDONESIA, NULL1_WORLD, "ID"},
+//     {CTRY_IRAN, APL1_WORLD, "IR"},
+//     {CTRY_IRELAND, ETSI1_WORLD, "IE"},
+//     {CTRY_ISRAEL, NULL1_WORLD, "IL"},
+//     {CTRY_ITALY, ETSI1_WORLD, "IT"},
+//     {CTRY_JAMAICA, FCC3_WORLD, "JM"},
+//
+//     {CTRY_JAPAN, MKK1_MKKA, "JP"},
+//     {CTRY_JAPAN1, MKK1_MKKB, "JP"},
+//     {CTRY_JAPAN2, MKK1_FCCA, "JP"},
+//     {CTRY_JAPAN3, MKK2_MKKA, "JP"},
+//     {CTRY_JAPAN4, MKK1_MKKA1, "JP"},
+//     {CTRY_JAPAN5, MKK1_MKKA2, "JP"},
+//     {CTRY_JAPAN6, MKK1_MKKC, "JP"},
+//     {CTRY_JAPAN7, MKK3_MKKB, "JP"},
+//     {CTRY_JAPAN8, MKK3_MKKA2, "JP"},
+//     {CTRY_JAPAN9, MKK3_MKKC, "JP"},
+//     {CTRY_JAPAN10, MKK4_MKKB, "JP"},
+//     {CTRY_JAPAN11, MKK4_MKKA2, "JP"},
+//     {CTRY_JAPAN12, MKK4_MKKC, "JP"},
+//     {CTRY_JAPAN13, MKK5_MKKB, "JP"},
+//     {CTRY_JAPAN14, MKK5_MKKA2, "JP"},
+//     {CTRY_JAPAN15, MKK5_MKKC, "JP"},
+//     {CTRY_JAPAN16, MKK6_MKKB, "JP"},
+//     {CTRY_JAPAN17, MKK6_MKKA2, "JP"},
+//     {CTRY_JAPAN18, MKK6_MKKC, "JP"},
+//     {CTRY_JAPAN19, MKK7_MKKB, "JP"},
+//     {CTRY_JAPAN20, MKK7_MKKA2, "JP"},
+//     {CTRY_JAPAN21, MKK7_MKKC, "JP"},
+//     {CTRY_JAPAN22, MKK8_MKKB, "JP"},
+//     {CTRY_JAPAN23, MKK8_MKKA2, "JP"},
+//     {CTRY_JAPAN24, MKK8_MKKC, "JP"},
+//     {CTRY_JAPAN25, MKK3_MKKA, "JP"},
+//     {CTRY_JAPAN26, MKK3_MKKA1, "JP"},
+//     {CTRY_JAPAN27, MKK3_FCCA, "JP"},
+//     {CTRY_JAPAN28, MKK4_MKKA1, "JP"},
+//     {CTRY_JAPAN29, MKK4_FCCA, "JP"},
+//     {CTRY_JAPAN30, MKK6_MKKA1, "JP"},
+//     {CTRY_JAPAN31, MKK6_FCCA, "JP"},
+//     {CTRY_JAPAN32, MKK7_MKKA1, "JP"},
+//     {CTRY_JAPAN33, MKK7_FCCA, "JP"},
+//     {CTRY_JAPAN34, MKK9_MKKA, "JP"},
+//     {CTRY_JAPAN35, MKK10_MKKA, "JP"},
+//     {CTRY_JAPAN36, MKK4_MKKA, "JP"},
+//     {CTRY_JAPAN37, MKK9_FCCA, "JP"},
+//     {CTRY_JAPAN38, MKK9_MKKA1, "JP"},
+//     {CTRY_JAPAN39, MKK9_MKKC, "JP"},
+//     {CTRY_JAPAN40, MKK9_MKKA2, "JP"},
+//     {CTRY_JAPAN41, MKK10_FCCA, "JP"},
+//     {CTRY_JAPAN42, MKK10_MKKA1, "JP"},
+//     {CTRY_JAPAN43, MKK10_MKKC, "JP"},
+//     {CTRY_JAPAN44, MKK10_MKKA2, "JP"},
+//     {CTRY_JAPAN45, MKK11_MKKA, "JP"},
+//     {CTRY_JAPAN46, MKK11_FCCA, "JP"},
+//     {CTRY_JAPAN47, MKK11_MKKA1, "JP"},
+//     {CTRY_JAPAN48, MKK11_MKKC, "JP"},
+//     {CTRY_JAPAN49, MKK11_MKKA2, "JP"},
+//     {CTRY_JAPAN50, MKK12_MKKA, "JP"},
+//     {CTRY_JAPAN51, MKK12_FCCA, "JP"},
+//     {CTRY_JAPAN52, MKK12_MKKA1, "JP"},
+//     {CTRY_JAPAN53, MKK12_MKKC, "JP"},
+//     {CTRY_JAPAN54, MKK12_MKKA2, "JP"},
+//     {CTRY_JAPAN57, MKK13_MKKB, "JP"},
+//     {CTRY_JAPAN58, MKK14_MKKA1, "JP"},
+//     {CTRY_JAPAN59, MKK15_MKKA1, "JP"},
+//
+//     {CTRY_JORDAN, ETSI2_WORLD, "JO"},
+//     {CTRY_KAZAKHSTAN, NULL1_WORLD, "KZ"},
+//     {CTRY_KOREA_NORTH, APL9_WORLD, "KP"},
+//     {CTRY_KOREA_ROC, APL9_WORLD, "KR"},
+//     {CTRY_KOREA_ROC2, APL2_WORLD, "K2"},
+//     {CTRY_KOREA_ROC3, APL9_WORLD, "K3"},
+//     {CTRY_KUWAIT, ETSI3_WORLD, "KW"},
+//     {CTRY_LATVIA, ETSI1_WORLD, "LV"},
+//     {CTRY_LEBANON, NULL1_WORLD, "LB"},
+//     {CTRY_LIECHTENSTEIN, ETSI1_WORLD, "LI"},
+//     {CTRY_LITHUANIA, ETSI1_WORLD, "LT"},
+//     {CTRY_LUXEMBOURG, ETSI1_WORLD, "LU"},
+//     {CTRY_MACAU, FCC2_WORLD, "MO"},
+//     {CTRY_MACEDONIA, NULL1_WORLD, "MK"},
+//     {CTRY_MALAYSIA, APL8_WORLD, "MY"},
+//     {CTRY_MALTA, ETSI1_WORLD, "MT"},
+//     {CTRY_MEXICO, FCC1_FCCA, "MX"},
+//     {CTRY_MONACO, ETSI4_WORLD, "MC"},
+//     {CTRY_MOROCCO, APL4_WORLD, "MA"},
+//     {CTRY_NEPAL, APL1_WORLD, "NP"},
+//     {CTRY_NETHERLANDS, ETSI1_WORLD, "NL"},
+//     {CTRY_NETHERLANDS_ANTILLES, ETSI1_WORLD, "AN"},
+//     {CTRY_NEW_ZEALAND, FCC2_ETSIC, "NZ"},
+//     {CTRY_NORWAY, ETSI1_WORLD, "NO"},
+//     {CTRY_OMAN, FCC3_WORLD, "OM"},
+//     {CTRY_PAKISTAN, NULL1_WORLD, "PK"},
+//     {CTRY_PANAMA, FCC1_FCCA, "PA"},
+//     {CTRY_PAPUA_NEW_GUINEA, FCC1_WORLD, "PG"},
+//     {CTRY_PERU, APL1_WORLD, "PE"},
+//     {CTRY_PHILIPPINES, APL1_WORLD, "PH"},
+//     {CTRY_POLAND, ETSI1_WORLD, "PL"},
+//     {CTRY_PORTUGAL, ETSI1_WORLD, "PT"},
+//     {CTRY_PUERTO_RICO, FCC1_FCCA, "PR"},
+//     {CTRY_QATAR, APL1_WORLD, "QA"},
+//     {CTRY_ROMANIA, NULL1_WORLD, "RO"},
+//     {CTRY_RUSSIA, NULL1_WORLD, "RU"},
+//     {CTRY_SAUDI_ARABIA, NULL1_WORLD, "SA"},
+//     {CTRY_SERBIA_MONTENEGRO, ETSI1_WORLD, "CS"},
+//     {CTRY_SINGAPORE, APL6_WORLD, "SG"},
+//     {CTRY_SLOVAKIA, ETSI1_WORLD, "SK"},
+//     {CTRY_SLOVENIA, ETSI1_WORLD, "SI"},
+//     {CTRY_SOUTH_AFRICA, FCC3_WORLD, "ZA"},
+//     {CTRY_SPAIN, ETSI1_WORLD, "ES"},
+//     {CTRY_SRI_LANKA, FCC3_WORLD, "LK"},
+//     {CTRY_SWEDEN, ETSI1_WORLD, "SE"},
+//     {CTRY_SWITZERLAND, ETSI1_WORLD, "CH"},
+//     {CTRY_SYRIA, NULL1_WORLD, "SY"},
+//     {CTRY_TAIWAN, APL3_FCCA, "TW"},
+//     {CTRY_THAILAND, FCC3_WORLD, "TH"},
+//     {CTRY_TRINIDAD_Y_TOBAGO, FCC3_WORLD, "TT"},
+//     {CTRY_TUNISIA, ETSI3_WORLD, "TN"},
+//     {CTRY_TURKEY, ETSI3_WORLD, "TR"},
+//     {CTRY_UKRAINE, NULL1_WORLD, "UA"},
+//     {CTRY_UAE, NULL1_WORLD, "AE"},
+//     {CTRY_UNITED_KINGDOM, ETSI1_WORLD, "GB"},
+//     {CTRY_UNITED_STATES, FCC3_FCCA, "US"},
+//     /* This "PS" is for US public safety actually... to support this we
+//      * would need to assign new special alpha2 to CRDA db as with the world
+//      * regdomain and use another alpha2 */
+//     {CTRY_UNITED_STATES_FCC49, FCC4_FCCA, "PS"},
+//     {CTRY_URUGUAY, FCC3_WORLD, "UY"},
+//     {CTRY_UZBEKISTAN, FCC3_FCCA, "UZ"},
+//     {CTRY_VENEZUELA, APL2_ETSIC, "VE"},
+//     {CTRY_VIET_NAM, NULL1_WORLD, "VN"},
+//     {CTRY_YEMEN, NULL1_WORLD, "YE"},
+//     {CTRY_ZIMBABWE, NULL1_WORLD, "ZW"},
+//};
+
+#endif
index 3073383baa22326003e7065f8bc0582714a74a08..414d7f17ec4cbd6c92ab8e1ab777807981e81e0e 100644 (file)
@@ -137,6 +137,8 @@ FILE_LICENCE ( GPL2_OR_LATER );
 #define ERRFILE_virtio_net          ( ERRFILE_DRIVER | 0x005c0000 )
 #define ERRFILE_tap                 ( ERRFILE_DRIVER | 0x005d0000 )
 #define ERRFILE_igbvf_main          ( ERRFILE_DRIVER | 0x005e0000 )
+#define ERRFILE_ath9k               ( ERRFILE_DRIVER | 0x005f0000 )
+#define ERRFILE_ath                 ( ERRFILE_DRIVER | 0x00600000 )
 
 #define ERRFILE_scsi                ( ERRFILE_DRIVER | 0x00700000 )
 #define ERRFILE_arbel               ( ERRFILE_DRIVER | 0x00710000 )
index 3c30f06c405f70b35fda9b99941677949cd45af1..771872c82fb9b64c2dbfebdadcf824f7230d4346 100644 (file)
@@ -272,7 +272,7 @@ enum net80211_crypto_alg {
 #define NET80211_MAX_RATES     16
 
 /** The maximum number of channels we allow to be configured simultaneously */
-#define NET80211_MAX_CHANNELS  32
+#define NET80211_MAX_CHANNELS  40
 
 /** Seconds we'll wait to get all fragments of a packet */
 #define NET80211_FRAG_TIMEOUT  2