linux-wireless.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3 00/97] ath9k: add AR9003 support
@ 2010-04-15 21:38 Luis R. Rodriguez
  2010-04-15 21:38 ` [PATCH v3 01/97] ath9k_hw: start building an abstraction layer for hardware routines Luis R. Rodriguez
                   ` (96 more replies)
  0 siblings, 97 replies; 103+ messages in thread
From: Luis R. Rodriguez @ 2010-04-15 21:38 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Luis R. Rodriguez

This series adds AR9003 support to ath9k, this 3rd series one final
bug Felix found on the the AR_BufLen abstraction on the patch titled
"ath9k_hw: Fill descriptor abstrations for AR9003". Its now fixed
and don't have any other pending issues. Since the patches depend
on some other ones we have no option but to resubmit.

The all-in-one git am'able patch can be found here:

http://bombadil.infradead.org/~mcgrof/patches/ath9k/2010/all-04-15-v1.patch
sha1sum: cf0a362c75acd475de5e33e3400545e3d8f74e63

Felix Fietkau (14):
  ath9k_hw: add silicon revision macros for AR9300
  ath9k_hw: add a macro for abstracting generic timer access
  ath9k_hw: fix a missing hex prefix for a register mask
  ath9k_hw: add simple register abstraction for some AR9300 registers
  ath9k_hw: add support for GPIO differences on AR9003
  ath9k_hw: Add AR9003 PHY register definitions
  ath9k_hw: Set the channel on AR9003
  ath9k_hw: Implement PLL control on AR9003
  ath9k_hw: Implement spur mitigation on AR9003
  ath9k_hw: Split off ANI control to the PHY ops
  ath9k: Add Rx EDMA support
  ath9k_hw: Split out the function for reading the noise floor
  ath9k_hw: move AR9280 PCI EEPROM fix to eeprom_def.c
  ath9k_hw: Update ath9k_hw_set_dma for AR9300

Luis R. Rodriguez (52):
  ath9k_hw: start building an abstraction layer for hardware routines
  ath9k_hw: AR9003 does not have AR_RC_AHB skip its setting
  ath9k_hw: remove wrapper ath9k_hw_write_regs()
  ath9k_hw: Move some RF ops to the private callbacks
  ath9k_hw: skip PLL initialization on AR9003 on Power-On-Reset
  ath9k_hw: add some comments for ath9k_set_power_network_sleep()
  ath9k_hw: add a private callback for PLL control computation
  ath9k_hw: Add AR9003 PHY support
  ath9k_hw: move init config and default after chip is up
  ath9k_hw: add the AR9003 ar9003_hw_macversion_supported()
  ath9k_hw: disable ANI for AR9003
  ath9k: disable the MIB interrupt if ANI is disabled
  ath9k_hw: add common channel select helpers for ar900[23]
  ath9k_hw: split initvals.h by hardware family
  ath9k_hw: add initvals for the AR9003 hardware family
  ath9k_hw: add helpers for processing the AR9003 INI
  ath9k_hw: add all the AR9003 PHY callbacks
  ath9k_hw: add a helper for Power Amplifier calibration for AR9002
  ath9k_hw: add a helper for the OLC tem compensation for AR9002
  ath9k_hw: rename PA calib for AR9287
  ath9k_hw: shift code for AR9280 OLC temp comp
  ath9k_hw: move the AR9280 OLC temp comp to its own helper
  ath9k_hw: simplify OLC temp compensation for AR9002
  ath9k_hw: rename the PA calib routines to match their families
  ath9k_hw: rename getNoiseFloorThresh() to ath9k_hw_loadnf()
  ath9k_hw: move the cal AR9100 calibration settings
  ath9k_hw: split calib code by hardware families
  ath9k_hw: add the AR9003 ar9003_hw_init_cal callback
  ath9k_hw: add the config_pci_powersave AR9003 callback
  ath9k_hw: split the generic hardware code by hardware family
  ath9k_hw: move the cck channel 14 INI to the AR9002 hw code
  ath9k_hw: move TX/RX gain INI stuff to its own hardware family code
  ath9k_hw: abstract the AR_PHY_AGC_CONTROL register access
  ath9k_hw: abstract loading noisefloor
  ath9k_hw: fill in the callbacks for calibration for AR9003
  ath9k_hw: complete AR9003 calibration
  ath9k_hw: rename eep_AR9287_ops to eep_ar9287_ops
  ath9k_hw: restore mac address reading logic
  ath9k_hw: add OFDM spur mitigation for AR9003
  ath9k_hw: move the RF claim stuff to AR9002 hardware family
  ath9k_hw: add the AR9300 SREV hw name print
  ath9k_hw: add TX/RX gain register initialization for AR9003
  ath9k_hw: skip asynch fifo enablement to AR9003
  ath9k_hw: skip WEP aggregation enable code for AR9003
  ath9k_hw: move AR9002 mac ops to its own file
  ath9k: add RXLP and RXHP to debugfs counters
  ath9k_hw: enable CRC check of descriptors for AR9003
  ath9k_hw: set cwmin and cwmax to 0 for for AR9003 upon txq reset
  mac80211: add LDPC control flag
  ath9k_hw: add LDPC support for AR9003
  ath9k: add LDPC support
  ath9k_hw: add the PCI ID for the first AR9300 device

Senthil Balasubramanian (5):
  ath9k_hw: Add the PCI IDs for AR9300 and fill up the pci_id_tables
  ath9k_hw: update the chip tests for AR9003
  ath9k_hw: prevent reset control register zeroing on AR9003 reset
  ath9k_hw: the eep_map is used only for AR9280 PCI card ini fixup
  ath9k_hw: Implement AR9003 eeprom callbacks

Vasanthakumar Thiagarajan (26):
  ath9k_hw: Add hw cap flag for EDMA for the AR9003 family
  ath9k_hw: Fill few hw cap for edma
  ath9k_hw: Add abstraction for rx enable
  ath9k_hw: Fill rx_enable() for the AR9003 hardware family
  ath9k_hw: Add few routines for rx edma support
  ath9k_hw: Define tx control struct for AR9003
  ath9k_hw: Move code which populates ds_data to ath9k_hw
  ath9k_hw: Add abstraction to set/get link pointer
  ath9k: Use abstraction to get link pointer
  ath9k: Use memcpy in ath_clone_txbuf()
  ath9k: Remove ATH9K_TX_SW_ABORTED and introduce a bool for this
    purpose
  ath9k: Make bf_desc of ath_buf opaque
  ath9k_hw: Abstract the routine which returns interrupt status
  ath9k_hw: Initialize interrupt mask for AR9003
  ath9k_hw: Fill get_isr() for AR9003
  ath9k_hw: Configure Tx interrupt mitigation timer
  ath9k: Load SW filtered NF values and start NF cal during full reset
    for AR9003
  ath9k_hw: Define abstraction for tx desc access
  ath9k_hw: Add function to configure tx status ring buffer
  ath9k_hw: Fill descriptor abstrations for AR9003
  ath9k: Setup appropriate tx desc for regular dma and edma
  ath9k: Initialize and configure tx status for EDMA
  ath9k_hw: Compute pointer checksum over the link descriptor
  ath9k: Add Tx EDMA support
  ath9k: Enable TXOK and TXERR interrupts for TX EDMA
  ath9k_hw: Abort rx if hw is not coming out of full sleep in reset

 drivers/net/wireless/ath/ath9k/Makefile            |   16 +-
 drivers/net/wireless/ath/ath9k/ani.c               |  185 +--
 drivers/net/wireless/ath/ath9k/ar5008_initvals.h   |  742 ++++++++
 drivers/net/wireless/ath/ath9k/ar5008_phy.c        | 1347 +++++++++++++
 drivers/net/wireless/ath/ath9k/ar9001_initvals.h   | 1254 +++++++++++++
 drivers/net/wireless/ath/ath9k/ar9002_calib.c      |  995 ++++++++++
 drivers/net/wireless/ath/ath9k/ar9002_hw.c         |  588 ++++++
 .../ath/ath9k/{initvals.h => ar9002_initvals.h}    | 1984 +-------------------
 drivers/net/wireless/ath/ath9k/ar9002_mac.c        |  480 +++++
 drivers/net/wireless/ath/ath9k/ar9002_phy.c        |  534 ++++++
 drivers/net/wireless/ath/ath9k/ar9002_phy.h        |  572 ++++++
 drivers/net/wireless/ath/ath9k/ar9003_calib.c      |  802 ++++++++
 drivers/net/wireless/ath/ath9k/ar9003_eeprom.c     | 1856 ++++++++++++++++++
 drivers/net/wireless/ath/ath9k/ar9003_eeprom.h     |  323 ++++
 drivers/net/wireless/ath/ath9k/ar9003_hw.c         |  205 ++
 drivers/net/wireless/ath/ath9k/ar9003_initvals.h   | 1793 ++++++++++++++++++
 drivers/net/wireless/ath/ath9k/ar9003_mac.c        |  611 ++++++
 drivers/net/wireless/ath/ath9k/ar9003_mac.h        |  120 ++
 drivers/net/wireless/ath/ath9k/ar9003_phy.c        | 1142 +++++++++++
 drivers/net/wireless/ath/ath9k/ar9003_phy.h        |  847 +++++++++
 drivers/net/wireless/ath/ath9k/ath9k.h             |   24 +-
 drivers/net/wireless/ath/ath9k/beacon.c            |    5 +-
 drivers/net/wireless/ath/ath9k/calib.c             | 1089 +-----------
 drivers/net/wireless/ath/ath9k/calib.h             |   19 +-
 drivers/net/wireless/ath/ath9k/common.h            |    4 +-
 drivers/net/wireless/ath/ath9k/debug.c             |   22 +-
 drivers/net/wireless/ath/ath9k/debug.h             |    4 +
 drivers/net/wireless/ath/ath9k/eeprom.c            |    9 +-
 drivers/net/wireless/ath/ath9k/eeprom.h            |   22 +-
 drivers/net/wireless/ath/ath9k/eeprom_4k.c         |    7 +-
 drivers/net/wireless/ath/ath9k/eeprom_9287.c       |    9 +-
 drivers/net/wireless/ath/ath9k/eeprom_def.c        |   13 +-
 drivers/net/wireless/ath/ath9k/hw-ops.h            |  280 +++
 drivers/net/wireless/ath/ath9k/hw.c                | 1647 +++--------------
 drivers/net/wireless/ath/ath9k/hw.h                |  234 +++-
 drivers/net/wireless/ath/ath9k/init.c              |   38 +-
 drivers/net/wireless/ath/ath9k/mac.c               |  463 ++---
 drivers/net/wireless/ath/ath9k/mac.h               |   49 +-
 drivers/net/wireless/ath/ath9k/main.c              |   51 +-
 drivers/net/wireless/ath/ath9k/pci.c               |    1 +
 drivers/net/wireless/ath/ath9k/phy.c               |  978 ----------
 drivers/net/wireless/ath/ath9k/phy.h               |  584 +------
 drivers/net/wireless/ath/ath9k/rc.c                |    9 +
 drivers/net/wireless/ath/ath9k/recv.c              |  518 ++++--
 drivers/net/wireless/ath/ath9k/reg.h               |  167 ++-
 drivers/net/wireless/ath/ath9k/xmit.c              |  365 +++-
 include/net/mac80211.h                             |    2 +
 47 files changed, 16166 insertions(+), 6843 deletions(-)
 create mode 100644 drivers/net/wireless/ath/ath9k/ar5008_initvals.h
 create mode 100644 drivers/net/wireless/ath/ath9k/ar5008_phy.c
 create mode 100644 drivers/net/wireless/ath/ath9k/ar9001_initvals.h
 create mode 100644 drivers/net/wireless/ath/ath9k/ar9002_calib.c
 create mode 100644 drivers/net/wireless/ath/ath9k/ar9002_hw.c
 rename drivers/net/wireless/ath/ath9k/{initvals.h => ar9002_initvals.h} (79%)
 create mode 100644 drivers/net/wireless/ath/ath9k/ar9002_mac.c
 create mode 100644 drivers/net/wireless/ath/ath9k/ar9002_phy.c
 create mode 100644 drivers/net/wireless/ath/ath9k/ar9002_phy.h
 create mode 100644 drivers/net/wireless/ath/ath9k/ar9003_calib.c
 create mode 100644 drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
 create mode 100644 drivers/net/wireless/ath/ath9k/ar9003_eeprom.h
 create mode 100644 drivers/net/wireless/ath/ath9k/ar9003_hw.c
 create mode 100644 drivers/net/wireless/ath/ath9k/ar9003_initvals.h
 create mode 100644 drivers/net/wireless/ath/ath9k/ar9003_mac.c
 create mode 100644 drivers/net/wireless/ath/ath9k/ar9003_mac.h
 create mode 100644 drivers/net/wireless/ath/ath9k/ar9003_phy.c
 create mode 100644 drivers/net/wireless/ath/ath9k/ar9003_phy.h
 create mode 100644 drivers/net/wireless/ath/ath9k/hw-ops.h
 delete mode 100644 drivers/net/wireless/ath/ath9k/phy.c


^ permalink raw reply	[flat|nested] 103+ messages in thread

* [PATCH v3 01/97] ath9k_hw: start building an abstraction layer for hardware routines
  2010-04-15 21:38 [PATCH v3 00/97] ath9k: add AR9003 support Luis R. Rodriguez
@ 2010-04-15 21:38 ` Luis R. Rodriguez
  2010-04-15 21:38 ` [PATCH v3 02/97] ath9k_hw: add silicon revision macros for AR9300 Luis R. Rodriguez
                   ` (95 subsequent siblings)
  96 siblings, 0 replies; 103+ messages in thread
From: Luis R. Rodriguez @ 2010-04-15 21:38 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Luis R. Rodriguez

ath9k supports the AR5008, AR9001 and AR9002 family of Atheros
chipsets, all 802.11n. The new breed of 802.11n chips, the
AR9003 family will be supported as well soon. To help with its
support we're going to add a few callbacks for hardware routines
which differ considerably instead of adding branch checks for
the revision at runtime.

Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/common.h |    1 +
 drivers/net/wireless/ath/ath9k/hw-ops.h |   31 ++++++++
 drivers/net/wireless/ath/ath9k/hw.c     |  125 +++++++++++++++++++++---------
 drivers/net/wireless/ath/ath9k/hw.h     |   47 +++++++++++-
 drivers/net/wireless/ath/ath9k/init.c   |    7 +-
 5 files changed, 166 insertions(+), 45 deletions(-)
 create mode 100644 drivers/net/wireless/ath/ath9k/hw-ops.h

diff --git a/drivers/net/wireless/ath/ath9k/common.h b/drivers/net/wireless/ath/ath9k/common.h
index 72a835d..1a87283 100644
--- a/drivers/net/wireless/ath/ath9k/common.h
+++ b/drivers/net/wireless/ath/ath9k/common.h
@@ -20,6 +20,7 @@
 #include "../debug.h"
 
 #include "hw.h"
+#include "hw-ops.h"
 
 /* Common header for Atheros 802.11n base driver cores */
 
diff --git a/drivers/net/wireless/ath/ath9k/hw-ops.h b/drivers/net/wireless/ath/ath9k/hw-ops.h
new file mode 100644
index 0000000..ee33146
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/hw-ops.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2010 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef ATH9K_HW_OPS_H
+#define ATH9K_HW_OPS_H
+
+#include "hw.h"
+
+/* Hardware core and driver accessible callbacks */
+
+static inline void ath9k_hw_configpcipowersave(struct ath_hw *ah,
+					       int restore,
+					       int power_off)
+{
+	ath9k_hw_ops(ah)->config_pci_powersave(ah, restore, power_off);
+}
+
+#endif /* ATH9K_HW_OPS_H */
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index af730c7..97c9711 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -19,6 +19,7 @@
 #include <asm/unaligned.h>
 
 #include "hw.h"
+#include "hw-ops.h"
 #include "rc.h"
 #include "initvals.h"
 
@@ -26,6 +27,8 @@
 #define ATH9K_CLOCK_RATE_5GHZ_OFDM	40
 #define ATH9K_CLOCK_RATE_2GHZ_OFDM	44
 
+static void ar9002_hw_attach_ops(struct ath_hw *ah);
+
 static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type);
 static void ath9k_hw_set_regs(struct ath_hw *ah, struct ath9k_channel *chan);
 
@@ -46,6 +49,25 @@ static void __exit ath9k_exit(void)
 }
 module_exit(ath9k_exit);
 
+/* Private hardware callbacks */
+
+static void ath9k_hw_init_cal_settings(struct ath_hw *ah)
+{
+	ath9k_hw_private_ops(ah)->init_cal_settings(ah);
+}
+
+static void ath9k_hw_init_mode_regs(struct ath_hw *ah)
+{
+	ath9k_hw_private_ops(ah)->init_mode_regs(ah);
+}
+
+static bool ath9k_hw_macversion_supported(struct ath_hw *ah)
+{
+	struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
+
+	return priv_ops->macversion_supported(ah->hw_version.macVersion);
+}
+
 /********************/
 /* Helper Functions */
 /********************/
@@ -369,7 +391,6 @@ static void ath9k_hw_init_config(struct ath_hw *ah)
 	if (num_possible_cpus() > 1)
 		ah->config.serialize_regmode = SER_REG_MODE_AUTO;
 }
-EXPORT_SYMBOL(ath9k_hw_init);
 
 static void ath9k_hw_init_defaults(struct ath_hw *ah)
 {
@@ -533,27 +554,7 @@ static int ath9k_hw_post_init(struct ath_hw *ah)
 	return 0;
 }
 
-static bool ath9k_hw_devid_supported(u16 devid)
-{
-	switch (devid) {
-	case AR5416_DEVID_PCI:
-	case AR5416_DEVID_PCIE:
-	case AR5416_AR9100_DEVID:
-	case AR9160_DEVID_PCI:
-	case AR9280_DEVID_PCI:
-	case AR9280_DEVID_PCIE:
-	case AR9285_DEVID_PCIE:
-	case AR5416_DEVID_AR9287_PCI:
-	case AR5416_DEVID_AR9287_PCIE:
-	case AR2427_DEVID_PCIE:
-		return true;
-	default:
-		break;
-	}
-	return false;
-}
-
-static bool ath9k_hw_macversion_supported(u32 macversion)
+static bool ar9002_hw_macversion_supported(u32 macversion)
 {
 	switch (macversion) {
 	case AR_SREV_VERSION_5416_PCI:
@@ -571,7 +572,7 @@ static bool ath9k_hw_macversion_supported(u32 macversion)
 	return false;
 }
 
-static void ath9k_hw_init_cal_settings(struct ath_hw *ah)
+static void ar9002_hw_init_cal_settings(struct ath_hw *ah)
 {
 	if (AR_SREV_9160_10_OR_LATER(ah)) {
 		if (AR_SREV_9280_10_OR_LATER(ah)) {
@@ -595,7 +596,7 @@ static void ath9k_hw_init_cal_settings(struct ath_hw *ah)
 	}
 }
 
-static void ath9k_hw_init_mode_regs(struct ath_hw *ah)
+static void ar9002_hw_init_mode_regs(struct ath_hw *ah)
 {
 	if (AR_SREV_9271(ah)) {
 		INIT_INI_ARRAY(&ah->iniModes, ar9271Modes_9271,
@@ -855,20 +856,12 @@ static void ath9k_hw_init_eeprom_fix(struct ath_hw *ah)
 			  "needs fixup for AR_AN_TOP2 register\n");
 }
 
-int ath9k_hw_init(struct ath_hw *ah)
+/* Called for all hardware families */
+static int __ath9k_hw_init(struct ath_hw *ah)
 {
 	struct ath_common *common = ath9k_hw_common(ah);
 	int r = 0;
 
-	if (common->bus_ops->ath_bus_type != ATH_USB) {
-		if (!ath9k_hw_devid_supported(ah->hw_version.devid)) {
-			ath_print(common, ATH_DBG_FATAL,
-				  "Unsupported device ID: 0x%0x\n",
-				  ah->hw_version.devid);
-			return -EOPNOTSUPP;
-		}
-	}
-
 	ath9k_hw_init_defaults(ah);
 	ath9k_hw_init_config(ah);
 
@@ -878,6 +871,8 @@ int ath9k_hw_init(struct ath_hw *ah)
 		return -EIO;
 	}
 
+	ar9002_hw_attach_ops(ah);
+
 	if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) {
 		ath_print(common, ATH_DBG_FATAL, "Couldn't wakeup chip\n");
 		return -EIO;
@@ -902,7 +897,7 @@ int ath9k_hw_init(struct ath_hw *ah)
 	else
 		ah->config.max_txtrig_level = MAX_TX_FIFO_THRESHOLD;
 
-	if (!ath9k_hw_macversion_supported(ah->hw_version.macVersion)) {
+	if (!ath9k_hw_macversion_supported(ah)) {
 		ath_print(common, ATH_DBG_FATAL,
 			  "Mac Chip Rev 0x%02x.%x is not supported by "
 			  "this driver\n", ah->hw_version.macVersion,
@@ -919,6 +914,7 @@ int ath9k_hw_init(struct ath_hw *ah)
 	if (AR_SREV_9271(ah))
 		ah->is_pciexpress = false;
 
+	/* XXX: move this to its own hw op */
 	ah->hw_version.phyRev = REG_READ(ah, AR_PHY_CHIP_ID);
 
 	ath9k_hw_init_cal_settings(ah);
@@ -980,6 +976,45 @@ int ath9k_hw_init(struct ath_hw *ah)
 	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 AR5416_DEVID_AR9287_PCI:
+	case AR5416_DEVID_AR9287_PCIE:
+	case AR2427_DEVID_PCIE:
+		break;
+	default:
+		if (common->bus_ops->ath_bus_type == ATH_USB)
+			break;
+		ath_print(common, ATH_DBG_FATAL,
+			  "Hardware device ID 0x%04x not supported\n",
+			  ah->hw_version.devid);
+		return -EOPNOTSUPP;
+	}
+
+	ret = __ath9k_hw_init(ah);
+	if (ret) {
+		ath_print(common, ATH_DBG_FATAL,
+			  "Unable to initialize hardware; "
+			  "initialization status: %d\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(ath9k_hw_init);
+
 static void ath9k_hw_init_bb(struct ath_hw *ah,
 			     struct ath9k_channel *chan)
 {
@@ -2501,7 +2536,9 @@ EXPORT_SYMBOL(ath9k_hw_setpower);
  * Programming the SerDes must go through the same 288 bit serial shift
  * register as the other analog registers.  Hence the 9 writes.
  */
-void ath9k_hw_configpcipowersave(struct ath_hw *ah, int restore, int power_off)
+static void ar9002_hw_configpcipowersave(struct ath_hw *ah,
+					 int restore,
+					 int power_off)
 {
 	u8 i;
 	u32 val;
@@ -2519,7 +2556,7 @@ void ath9k_hw_configpcipowersave(struct ath_hw *ah, int restore, int power_off)
 			/*
 			 * AR9280 2.0 or later chips use SerDes values from the
 			 * initvals.h initialized depending on chipset during
-			 * ath9k_hw_init()
+			 * __ath9k_hw_init()
 			 */
 			for (i = 0; i < ah->iniPcieSerdes.ia_rows; i++) {
 				REG_WRITE(ah, INI_RA(&ah->iniPcieSerdes, i, 0),
@@ -2623,7 +2660,6 @@ void ath9k_hw_configpcipowersave(struct ath_hw *ah, int restore, int power_off)
 		}
 	}
 }
-EXPORT_SYMBOL(ath9k_hw_configpcipowersave);
 
 /**********************/
 /* Interrupt Handling */
@@ -3918,3 +3954,16 @@ void ath9k_hw_name(struct ath_hw *ah, char *hw_name, size_t len)
 	hw_name[used] = '\0';
 }
 EXPORT_SYMBOL(ath9k_hw_name);
+
+/* Sets up the AR5008/AR9001/AR9002 hardware familiy callbacks */
+static 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_cal_settings = ar9002_hw_init_cal_settings;
+	priv_ops->init_mode_regs = ar9002_hw_init_mode_regs;
+	priv_ops->macversion_supported = ar9002_hw_macversion_supported;
+
+	ops->config_pci_powersave = ar9002_hw_configpcipowersave;
+}
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index f4821cf..dfe8502 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -440,6 +440,36 @@ struct ath_gen_timer_table {
 	} timer_mask;
 };
 
+/**
+ * struct ath_hw_private_ops - callbacks used internally by hardware code
+ *
+ * This structure contains private callbacks designed to only be used internally
+ * by the hardware core.
+ *
+ * @init_cal_settings: Initializes calibration settings
+ * @init_mode_regs: Initializes mode registers
+ * @macversion_supported: If this specific mac revision is supported
+ */
+struct ath_hw_private_ops {
+	void (*init_cal_settings)(struct ath_hw *ah);
+	void (*init_mode_regs)(struct ath_hw *ah);
+	bool (*macversion_supported)(u32 macversion);
+};
+
+/**
+ * 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:
+ */
+struct ath_hw_ops {
+	void (*config_pci_powersave)(struct ath_hw *ah,
+				     int restore,
+				     int power_off);
+};
+
 struct ath_hw {
 	struct ieee80211_hw *hw;
 	struct ath_common common;
@@ -540,6 +570,11 @@ struct ath_hw {
 	void (*ath9k_hw_spur_mitigate_freq)(struct ath_hw *ah,
 					    struct ath9k_channel *chan);
 
+	/* Private to hardware code */
+	struct ath_hw_private_ops private_ops;
+	/* Accessed by the lower level driver */
+	struct ath_hw_ops ops;
+
 	/* Used to program the radio on non single-chip devices */
 	u32 *analogBank0Data;
 	u32 *analogBank1Data;
@@ -619,6 +654,16 @@ static inline struct ath_regulatory *ath9k_hw_regulatory(struct ath_hw *ah)
 	return &(ath9k_hw_common(ah)->regulatory);
 }
 
+static inline struct ath_hw_private_ops *ath9k_hw_private_ops(struct ath_hw *ah)
+{
+	return &ah->private_ops;
+}
+
+static inline struct ath_hw_ops *ath9k_hw_ops(struct ath_hw *ah)
+{
+	return &ah->ops;
+}
+
 /* Initialization, Detach, Reset */
 const char *ath9k_hw_probe(u16 vendorid, u16 devid);
 void ath9k_hw_deinit(struct ath_hw *ah);
@@ -681,8 +726,6 @@ void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah,
 
 bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode);
 
-void ath9k_hw_configpcipowersave(struct ath_hw *ah, int restore, int power_off);
-
 /* Interrupt Handling */
 bool ath9k_hw_intrpend(struct ath_hw *ah);
 bool ath9k_hw_getisr(struct ath_hw *ah, enum ath9k_int *masked);
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index b78308c..d769759 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -568,13 +568,10 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid,
 	ath_read_cachesize(common, &csz);
 	common->cachelsz = csz << 2; /* convert to bytes */
 
+	/* Initializes the hardware for all supported chipsets */
 	ret = ath9k_hw_init(ah);
-	if (ret) {
-		ath_print(common, ATH_DBG_FATAL,
-			  "Unable to initialize hardware; "
-			  "initialization status: %d\n", ret);
+	if (ret)
 		goto err_hw;
-	}
 
 	ret = ath9k_init_debug(ah);
 	if (ret) {
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 103+ messages in thread

* [PATCH v3 02/97] ath9k_hw: add silicon revision macros for AR9300
  2010-04-15 21:38 [PATCH v3 00/97] ath9k: add AR9003 support Luis R. Rodriguez
  2010-04-15 21:38 ` [PATCH v3 01/97] ath9k_hw: start building an abstraction layer for hardware routines Luis R. Rodriguez
@ 2010-04-15 21:38 ` Luis R. Rodriguez
  2010-04-15 21:38 ` [PATCH v3 03/97] ath9k_hw: add a macro for abstracting generic timer access Luis R. Rodriguez
                   ` (94 subsequent siblings)
  96 siblings, 0 replies; 103+ messages in thread
From: Luis R. Rodriguez @ 2010-04-15 21:38 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Felix Fietkau

From: Felix Fietkau <nbd@openwrt.org>

AR9300 will be the first device supported of the AR9003
family. AR9300 1.0 hardware exists but it is not going to
be sold anywhere so we completely skip its support.

Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
 drivers/net/wireless/ath/ath9k/reg.h |   11 +++++++++++
 1 files changed, 11 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h
index 7e36ad7..5ab6d6e 100644
--- a/drivers/net/wireless/ath/ath9k/reg.h
+++ b/drivers/net/wireless/ath/ath9k/reg.h
@@ -759,6 +759,8 @@
 #define AR_SREV_VERSION_9271			0x140
 #define AR_SREV_REVISION_9271_10		0
 #define AR_SREV_REVISION_9271_11		1
+#define AR_SREV_VERSION_9300                  0x1c0
+#define AR_SREV_REVISION_9300_20              2 /* 2.0 and 2.1 */
 
 #define AR_SREV_5416(_ah) \
 	(((_ah)->hw_version.macVersion == AR_SREV_VERSION_5416_PCI) || \
@@ -844,6 +846,15 @@
 #define AR_SREV_9271_11(_ah) \
     (AR_SREV_9271(_ah) && \
      ((_ah)->hw_version.macRev == AR_SREV_REVISION_9271_11))
+#define AR_SREV_9300(_ah) \
+	(((_ah)->hw_version.macVersion == AR_SREV_VERSION_9300))
+#define AR_SREV_9300_20(_ah) \
+	(((_ah)->hw_version.macVersion == AR_SREV_VERSION_9300) && \
+	 ((_ah)->hw_version.macRev == AR_SREV_REVISION_9300_20))
+#define AR_SREV_9300_20_OR_LATER(_ah) \
+	(((_ah)->hw_version.macVersion > AR_SREV_VERSION_9300) || \
+	 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9300) && \
+	  ((_ah)->hw_version.macRev >= AR_SREV_REVISION_9300_20)))
 
 #define AR_SREV_9285E_20(_ah) \
     (AR_SREV_9285_12_OR_LATER(_ah) && \
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 103+ messages in thread

* [PATCH v3 03/97] ath9k_hw: add a macro for abstracting generic timer access
  2010-04-15 21:38 [PATCH v3 00/97] ath9k: add AR9003 support Luis R. Rodriguez
  2010-04-15 21:38 ` [PATCH v3 01/97] ath9k_hw: start building an abstraction layer for hardware routines Luis R. Rodriguez
  2010-04-15 21:38 ` [PATCH v3 02/97] ath9k_hw: add silicon revision macros for AR9300 Luis R. Rodriguez
@ 2010-04-15 21:38 ` Luis R. Rodriguez
  2010-04-15 21:38 ` [PATCH v3 04/97] ath9k_hw: fix a missing hex prefix for a register mask Luis R. Rodriguez
                   ` (93 subsequent siblings)
  96 siblings, 0 replies; 103+ messages in thread
From: Luis R. Rodriguez @ 2010-04-15 21:38 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Felix Fietkau

From: Felix Fietkau <nbd@openwrt.org>

Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
 drivers/net/wireless/ath/ath9k/reg.h |   38 +++++++++++++++++----------------
 1 files changed, 20 insertions(+), 18 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h
index 5ab6d6e..68d55a2 100644
--- a/drivers/net/wireless/ath/ath9k/reg.h
+++ b/drivers/net/wireless/ath/ath9k/reg.h
@@ -1610,24 +1610,26 @@ enum {
 #define AR_FIRST_NDP_TIMER                  7
 #define AR_NDP2_PERIOD                      0x81a0
 #define AR_NDP2_TIMER_MODE                  0x81c0
-#define AR_NEXT_TBTT_TIMER                  0x8200
-#define AR_NEXT_DMA_BEACON_ALERT            0x8204
-#define AR_NEXT_SWBA                        0x8208
-#define AR_NEXT_CFP                         0x8208
-#define AR_NEXT_HCF                         0x820C
-#define AR_NEXT_TIM                         0x8210
-#define AR_NEXT_DTIM                        0x8214
-#define AR_NEXT_QUIET_TIMER                 0x8218
-#define AR_NEXT_NDP_TIMER                   0x821C
-
-#define AR_BEACON_PERIOD                    0x8220
-#define AR_DMA_BEACON_PERIOD                0x8224
-#define AR_SWBA_PERIOD                      0x8228
-#define AR_HCF_PERIOD                       0x822C
-#define AR_TIM_PERIOD                       0x8230
-#define AR_DTIM_PERIOD                      0x8234
-#define AR_QUIET_PERIOD                     0x8238
-#define AR_NDP_PERIOD                       0x823C
+
+#define AR_GEN_TIMERS(_i)                   (0x8200 + ((_i) << 2))
+#define AR_NEXT_TBTT_TIMER                  AR_GEN_TIMERS(0)
+#define AR_NEXT_DMA_BEACON_ALERT            AR_GEN_TIMERS(1)
+#define AR_NEXT_SWBA                        AR_GEN_TIMERS(2)
+#define AR_NEXT_CFP                         AR_GEN_TIMERS(2)
+#define AR_NEXT_HCF                         AR_GEN_TIMERS(3)
+#define AR_NEXT_TIM                         AR_GEN_TIMERS(4)
+#define AR_NEXT_DTIM                        AR_GEN_TIMERS(5)
+#define AR_NEXT_QUIET_TIMER                 AR_GEN_TIMERS(6)
+#define AR_NEXT_NDP_TIMER                   AR_GEN_TIMERS(7)
+
+#define AR_BEACON_PERIOD                    AR_GEN_TIMERS(8)
+#define AR_DMA_BEACON_PERIOD                AR_GEN_TIMERS(9)
+#define AR_SWBA_PERIOD                      AR_GEN_TIMERS(10)
+#define AR_HCF_PERIOD                       AR_GEN_TIMERS(11)
+#define AR_TIM_PERIOD                       AR_GEN_TIMERS(12)
+#define AR_DTIM_PERIOD                      AR_GEN_TIMERS(13)
+#define AR_QUIET_PERIOD                     AR_GEN_TIMERS(14)
+#define AR_NDP_PERIOD                       AR_GEN_TIMERS(15)
 
 #define AR_TIMER_MODE                       0x8240
 #define AR_TBTT_TIMER_EN                    0x00000001
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 103+ messages in thread

* [PATCH v3 04/97] ath9k_hw: fix a missing hex prefix for a register mask
  2010-04-15 21:38 [PATCH v3 00/97] ath9k: add AR9003 support Luis R. Rodriguez
                   ` (2 preceding siblings ...)
  2010-04-15 21:38 ` [PATCH v3 03/97] ath9k_hw: add a macro for abstracting generic timer access Luis R. Rodriguez
@ 2010-04-15 21:38 ` Luis R. Rodriguez
  2010-04-15 21:38 ` [PATCH v3 05/97] ath9k_hw: add simple register abstraction for some AR9300 registers Luis R. Rodriguez
                   ` (92 subsequent siblings)
  96 siblings, 0 replies; 103+ messages in thread
From: Luis R. Rodriguez @ 2010-04-15 21:38 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Felix Fietkau

From: Felix Fietkau <nbd@openwrt.org>

This is not a stable code fix as this register is not used anywhere.

Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
 drivers/net/wireless/ath/ath9k/reg.h |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h
index 68d55a2..c1e58da 100644
--- a/drivers/net/wireless/ath/ath9k/reg.h
+++ b/drivers/net/wireless/ath/ath9k/reg.h
@@ -1544,7 +1544,7 @@ enum {
 #define AR_TSFOOR_THRESHOLD       0x813c
 #define AR_TSFOOR_THRESHOLD_VAL   0x0000FFFF
 
-#define AR_PHY_ERR_EIFS_MASK   8144
+#define AR_PHY_ERR_EIFS_MASK   0x8144
 
 #define AR_PHY_ERR_3           0x8168
 #define AR_PHY_ERR_3_COUNT     0x00FFFFFF
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 103+ messages in thread

* [PATCH v3 05/97] ath9k_hw: add simple register abstraction for some AR9300 registers
  2010-04-15 21:38 [PATCH v3 00/97] ath9k: add AR9003 support Luis R. Rodriguez
                   ` (3 preceding siblings ...)
  2010-04-15 21:38 ` [PATCH v3 04/97] ath9k_hw: fix a missing hex prefix for a register mask Luis R. Rodriguez
@ 2010-04-15 21:38 ` Luis R. Rodriguez
  2010-04-15 21:38 ` [PATCH v3 06/97] ath9k_hw: add support for GPIO differences on AR9003 Luis R. Rodriguez
                   ` (91 subsequent siblings)
  96 siblings, 0 replies; 103+ messages in thread
From: Luis R. Rodriguez @ 2010-04-15 21:38 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Felix Fietkau

From: Felix Fietkau <nbd@openwrt.org>

Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
 drivers/net/wireless/ath/ath9k/reg.h |   42 +++++++++++++++++-----------------
 1 files changed, 21 insertions(+), 21 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h
index c1e58da..d56b4ea 100644
--- a/drivers/net/wireless/ath/ath9k/reg.h
+++ b/drivers/net/wireless/ath/ath9k/reg.h
@@ -20,7 +20,7 @@
 #include "../reg.h"
 
 #define AR_CR                0x0008
-#define AR_CR_RXE            0x00000004
+#define AR_CR_RXE            (AR_SREV_9300_20_OR_LATER(ah) ? 0x0000000c : 0x00000004)
 #define AR_CR_RXD            0x00000020
 #define AR_CR_SWI            0x00000040
 
@@ -232,7 +232,6 @@
 #define AR_ISR_S5_TIMER_THRESH      0x0007FE00
 #define AR_ISR_S5_TIM_TIMER         0x00000010
 #define AR_ISR_S5_DTIM_TIMER        0x00000020
-#define AR_ISR_S5_S                 0x00d8
 #define AR_IMR_S5                   0x00b8
 #define AR_IMR_S5_TIM_TIMER         0x00000010
 #define AR_IMR_S5_DTIM_TIMER        0x00000020
@@ -240,7 +239,6 @@
 #define AR_ISR_S5_GENTIMER_TRIG_S   0
 #define AR_ISR_S5_GENTIMER_THRESH   0xFF800000
 #define AR_ISR_S5_GENTIMER_THRESH_S 16
-#define AR_ISR_S5_S                 0x00d8
 #define AR_IMR_S5_GENTIMER_TRIG     0x0000FF80
 #define AR_IMR_S5_GENTIMER_TRIG_S   0
 #define AR_IMR_S5_GENTIMER_THRESH   0xFF800000
@@ -332,10 +330,10 @@
 #define AR_ISR_S1_QCU_TXEOL    0x03FF0000
 #define AR_ISR_S1_QCU_TXEOL_S  16
 
-#define AR_ISR_S2_S           0x00cc
-#define AR_ISR_S3_S           0x00d0
-#define AR_ISR_S4_S           0x00d4
-#define AR_ISR_S5_S           0x00d8
+#define AR_ISR_S2_S           (AR_SREV_9300_20_OR_LATER(ah) ? 0x00d0 : 0x00cc)
+#define AR_ISR_S3_S           (AR_SREV_9300_20_OR_LATER(ah) ? 0x00d4 : 0x00d0)
+#define AR_ISR_S4_S           (AR_SREV_9300_20_OR_LATER(ah) ? 0x00d8 : 0x00d4)
+#define AR_ISR_S5_S           (AR_SREV_9300_20_OR_LATER(ah) ? 0x00dc : 0x00d8)
 #define AR_DMADBG_0           0x00e0
 #define AR_DMADBG_1           0x00e4
 #define AR_DMADBG_2           0x00e8
@@ -968,19 +966,21 @@ enum {
 #define AR9287_GPIO_IN_VAL_S                     11
 #define AR9271_GPIO_IN_VAL                       0xFFFF0000
 #define AR9271_GPIO_IN_VAL_S                     16
+#define AR9300_GPIO_IN_VAL                       0x0001FFFF
+#define AR9300_GPIO_IN_VAL_S                     0
 
-#define AR_GPIO_OE_OUT                           0x404c
+#define AR_GPIO_OE_OUT                           (AR_SREV_9300_20_OR_LATER(ah) ? 0x4050 : 0x404c)
 #define AR_GPIO_OE_OUT_DRV                       0x3
 #define AR_GPIO_OE_OUT_DRV_NO                    0x0
 #define AR_GPIO_OE_OUT_DRV_LOW                   0x1
 #define AR_GPIO_OE_OUT_DRV_HI                    0x2
 #define AR_GPIO_OE_OUT_DRV_ALL                   0x3
 
-#define AR_GPIO_INTR_POL                         0x4050
-#define AR_GPIO_INTR_POL_VAL                     0x00001FFF
+#define AR_GPIO_INTR_POL                         (AR_SREV_9300_20_OR_LATER(ah) ? 0x4058 : 0x4050)
+#define AR_GPIO_INTR_POL_VAL                     0x0001FFFF
 #define AR_GPIO_INTR_POL_VAL_S                   0
 
-#define AR_GPIO_INPUT_EN_VAL                     0x4054
+#define AR_GPIO_INPUT_EN_VAL                     (AR_SREV_9300_20_OR_LATER(ah) ? 0x405c : 0x4054)
 #define AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_DEF     0x00000004
 #define AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_S       2
 #define AR_GPIO_INPUT_EN_VAL_BT_FREQUENCY_DEF    0x00000008
@@ -998,13 +998,13 @@ enum {
 #define AR_GPIO_RTC_RESET_OVERRIDE_ENABLE        0x00010000
 #define AR_GPIO_JTAG_DISABLE                     0x00020000
 
-#define AR_GPIO_INPUT_MUX1                       0x4058
+#define AR_GPIO_INPUT_MUX1                       (AR_SREV_9300_20_OR_LATER(ah) ? 0x4060 : 0x4058)
 #define AR_GPIO_INPUT_MUX1_BT_ACTIVE             0x000f0000
 #define AR_GPIO_INPUT_MUX1_BT_ACTIVE_S           16
 #define AR_GPIO_INPUT_MUX1_BT_PRIORITY           0x00000f00
 #define AR_GPIO_INPUT_MUX1_BT_PRIORITY_S         8
 
-#define AR_GPIO_INPUT_MUX2                       0x405c
+#define AR_GPIO_INPUT_MUX2                       (AR_SREV_9300_20_OR_LATER(ah) ? 0x4064 : 0x405c)
 #define AR_GPIO_INPUT_MUX2_CLK25                 0x0000000f
 #define AR_GPIO_INPUT_MUX2_CLK25_S               0
 #define AR_GPIO_INPUT_MUX2_RFSILENT              0x000000f0
@@ -1012,13 +1012,13 @@ enum {
 #define AR_GPIO_INPUT_MUX2_RTC_RESET             0x00000f00
 #define AR_GPIO_INPUT_MUX2_RTC_RESET_S           8
 
-#define AR_GPIO_OUTPUT_MUX1                      0x4060
-#define AR_GPIO_OUTPUT_MUX2                      0x4064
-#define AR_GPIO_OUTPUT_MUX3                      0x4068
+#define AR_GPIO_OUTPUT_MUX1                      (AR_SREV_9300_20_OR_LATER(ah) ? 0x4068 : 0x4060)
+#define AR_GPIO_OUTPUT_MUX2                      (AR_SREV_9300_20_OR_LATER(ah) ? 0x406c : 0x4064)
+#define AR_GPIO_OUTPUT_MUX3                      (AR_SREV_9300_20_OR_LATER(ah) ? 0x4070 : 0x4068)
 
-#define AR_INPUT_STATE                           0x406c
+#define AR_INPUT_STATE                           (AR_SREV_9300_20_OR_LATER(ah) ? 0x4074 : 0x406c)
 
-#define AR_EEPROM_STATUS_DATA                    0x407c
+#define AR_EEPROM_STATUS_DATA                    (AR_SREV_9300_20_OR_LATER(ah) ? 0x4084 : 0x407c)
 #define AR_EEPROM_STATUS_DATA_VAL                0x0000ffff
 #define AR_EEPROM_STATUS_DATA_VAL_S              0
 #define AR_EEPROM_STATUS_DATA_BUSY               0x00010000
@@ -1026,11 +1026,11 @@ enum {
 #define AR_EEPROM_STATUS_DATA_PROT_ACCESS        0x00040000
 #define AR_EEPROM_STATUS_DATA_ABSENT_ACCESS      0x00080000
 
-#define AR_OBS                  0x4080
+#define AR_OBS                  (AR_SREV_9300_20_OR_LATER(ah) ? 0x4088 : 0x4080)
 
-#define AR_GPIO_PDPU                             0x4088
+#define AR_GPIO_PDPU                             (AR_SREV_9300_20_OR_LATER(ah) ? 0x4090 : 0x4088)
 
-#define AR_PCIE_MSI                              0x4094
+#define AR_PCIE_MSI                              (AR_SREV_9300_20_OR_LATER(ah) ? 0x40a4 : 0x4094)
 #define AR_PCIE_MSI_ENABLE                       0x00000001
 
 
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 103+ messages in thread

* [PATCH v3 06/97] ath9k_hw: add support for GPIO differences on AR9003
  2010-04-15 21:38 [PATCH v3 00/97] ath9k: add AR9003 support Luis R. Rodriguez
                   ` (4 preceding siblings ...)
  2010-04-15 21:38 ` [PATCH v3 05/97] ath9k_hw: add simple register abstraction for some AR9300 registers Luis R. Rodriguez
@ 2010-04-15 21:38 ` Luis R. Rodriguez
  2010-04-15 21:38 ` [PATCH v3 07/97] ath9k_hw: AR9003 does not have AR_RC_AHB skip its setting Luis R. Rodriguez
                   ` (90 subsequent siblings)
  96 siblings, 0 replies; 103+ messages in thread
From: Luis R. Rodriguez @ 2010-04-15 21:38 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Felix Fietkau

From: Felix Fietkau <nbd@openwrt.org>

Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
 drivers/net/wireless/ath/ath9k/hw.c  |    4 +++-
 drivers/net/wireless/ath/ath9k/reg.h |    1 +
 2 files changed, 4 insertions(+), 1 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 97c9711..d924cbc 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -3441,7 +3441,9 @@ u32 ath9k_hw_gpio_get(struct ath_hw *ah, u32 gpio)
 	if (gpio >= ah->caps.num_gpio_pins)
 		return 0xffffffff;
 
-	if (AR_SREV_9271(ah))
+	if (AR_SREV_9300_20_OR_LATER(ah))
+		return MS_REG_READ(AR9300, gpio) != 0;
+	else if (AR_SREV_9271(ah))
 		return MS_REG_READ(AR9271, gpio) != 0;
 	else if (AR_SREV_9287_10_OR_LATER(ah))
 		return MS_REG_READ(AR9287, gpio) != 0;
diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h
index d56b4ea..d524891 100644
--- a/drivers/net/wireless/ath/ath9k/reg.h
+++ b/drivers/net/wireless/ath/ath9k/reg.h
@@ -954,6 +954,7 @@ enum {
 #define AR9285_NUM_GPIO                          12
 #define AR9287_NUM_GPIO                          11
 #define AR9271_NUM_GPIO                          16
+#define AR9300_NUM_GPIO                          17
 
 #define AR_GPIO_IN_OUT                           0x4048
 #define AR_GPIO_IN_VAL                           0x0FFFC000
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 103+ messages in thread

* [PATCH v3 07/97] ath9k_hw: AR9003 does not have AR_RC_AHB skip its setting
  2010-04-15 21:38 [PATCH v3 00/97] ath9k: add AR9003 support Luis R. Rodriguez
                   ` (5 preceding siblings ...)
  2010-04-15 21:38 ` [PATCH v3 06/97] ath9k_hw: add support for GPIO differences on AR9003 Luis R. Rodriguez
@ 2010-04-15 21:38 ` Luis R. Rodriguez
  2010-04-15 21:38 ` [PATCH v3 08/97] ath9k_hw: remove wrapper ath9k_hw_write_regs() Luis R. Rodriguez
                   ` (89 subsequent siblings)
  96 siblings, 0 replies; 103+ messages in thread
From: Luis R. Rodriguez @ 2010-04-15 21:38 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Luis R. Rodriguez, Felix Fietkau

AR9003 does not have a reset control for AHB.

Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
 drivers/net/wireless/ath/ath9k/hw.c |   24 +++++++++++++++++++-----
 1 files changed, 19 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index d924cbc..0e85a24 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -1698,11 +1698,16 @@ static bool ath9k_hw_set_reset(struct ath_hw *ah, int type)
 		if (tmpReg &
 		    (AR_INTR_SYNC_LOCAL_TIMEOUT |
 		     AR_INTR_SYNC_RADM_CPL_TIMEOUT)) {
+			u32 val;
 			REG_WRITE(ah, AR_INTR_SYNC_ENABLE, 0);
-			REG_WRITE(ah, AR_RC, AR_RC_AHB | AR_RC_HOSTIF);
-		} else {
+
+			val = AR_RC_HOSTIF;
+			if (!AR_SREV_9300_20_OR_LATER(ah))
+				val |= AR_RC_AHB;
+			REG_WRITE(ah, AR_RC, val);
+
+		} else if (!AR_SREV_9300_20_OR_LATER(ah))
 			REG_WRITE(ah, AR_RC, AR_RC_AHB);
-		}
 
 		rst_flags = AR_RTC_RC_MAC_WARM;
 		if (type == ATH9K_RESET_COLD)
@@ -1733,7 +1738,7 @@ static bool ath9k_hw_set_reset_power_on(struct ath_hw *ah)
 	REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN |
 		  AR_RTC_FORCE_WAKE_ON_INT);
 
-	if (!AR_SREV_9100(ah))
+	if (!AR_SREV_9100(ah) && !AR_SREV_9300_20_OR_LATER(ah))
 		REG_WRITE(ah, AR_RC, AR_RC_AHB);
 
 	REG_WRITE(ah, AR_RTC_RESET, 0);
@@ -2414,15 +2419,24 @@ EXPORT_SYMBOL(ath9k_hw_keyisvalid);
 /* Power Management (Chipset) */
 /******************************/
 
+/*
+ * Notify Power Mgt is disabled in self-generated frames.
+ * If requested, force chip to sleep.
+ */
 static void ath9k_set_power_sleep(struct ath_hw *ah, int setChip)
 {
 	REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV);
 	if (setChip) {
+		/*
+		 * Clear the RTC force wake bit to allow the
+		 * mac to go to sleep.
+		 */
 		REG_CLR_BIT(ah, AR_RTC_FORCE_WAKE,
 			    AR_RTC_FORCE_WAKE_EN);
-		if (!AR_SREV_9100(ah))
+		if (!AR_SREV_9100(ah) && !AR_SREV_9300_20_OR_LATER(ah))
 			REG_WRITE(ah, AR_RC, AR_RC_AHB | AR_RC_HOSTIF);
 
+		/* Shutdown chip. Active low */
 		if (!AR_SREV_5416(ah) && !AR_SREV_9271(ah))
 			REG_CLR_BIT(ah, (AR_RTC_RESET),
 				    AR_RTC_RESET_EN);
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 103+ messages in thread

* [PATCH v3 08/97] ath9k_hw: remove wrapper ath9k_hw_write_regs()
  2010-04-15 21:38 [PATCH v3 00/97] ath9k: add AR9003 support Luis R. Rodriguez
                   ` (6 preceding siblings ...)
  2010-04-15 21:38 ` [PATCH v3 07/97] ath9k_hw: AR9003 does not have AR_RC_AHB skip its setting Luis R. Rodriguez
@ 2010-04-15 21:38 ` Luis R. Rodriguez
  2010-04-15 21:38 ` [PATCH v3 09/97] ath9k_hw: Move some RF ops to the private callbacks Luis R. Rodriguez
                   ` (88 subsequent siblings)
  96 siblings, 0 replies; 103+ messages in thread
From: Luis R. Rodriguez @ 2010-04-15 21:38 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Luis R. Rodriguez

This is used only once by ath9k_hw_process_ini() to
write an array of phy registers through REG_WRITE_ARRAY(),
but we already call REG_WRITE_ARRAY() multiple times
on the same caller so just remove this pointless wrapper.
We'll eventually just move the ath9k_hw_process_ini()
caller as an callback to abstract away between different
hardware families.

Although this change is subtle I should note that this
does change the delay pattern on writing the next series
of registers. REG_WRITE_ARRAY() uses a counter for each
register write and does a udelay(1) every 64 writes. By
removing this call it means that the counter is processed
for all the iniBB_RfGain registers and is incremented
on ath9k_hw_process_ini(), before this the after the call
ath9k_hw_write_regs() was made the register counter was
kept at the same index number prior to the call.

Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/hw.c  |    2 +-
 drivers/net/wireless/ath/ath9k/phy.c |   15 ---------------
 drivers/net/wireless/ath/ath9k/phy.h |    3 ---
 3 files changed, 1 insertions(+), 19 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 0e85a24..f81e273 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -1484,7 +1484,7 @@ static int ath9k_hw_process_ini(struct ath_hw *ah,
 					modesIndex, regWrites);
 	}
 
-	ath9k_hw_write_regs(ah, freqIndex, regWrites);
+	REG_WRITE_ARRAY(&ah->iniBB_RfGain, freqIndex, regWrites);
 
 	if (AR_SREV_9280_20(ah) && IS_CHAN_A_5MHZ_SPACED(chan)) {
 		REG_WRITE_ARRAY(&ah->iniModesAdditional, modesIndex,
diff --git a/drivers/net/wireless/ath/ath9k/phy.c b/drivers/net/wireless/ath/ath9k/phy.c
index 2547b3c..c45f5b8 100644
--- a/drivers/net/wireless/ath/ath9k/phy.c
+++ b/drivers/net/wireless/ath/ath9k/phy.c
@@ -44,21 +44,6 @@
 #include "hw.h"
 
 /**
- * ath9k_hw_write_regs - ??
- *
- * @ah: atheros hardware structure
- * @freqIndex:
- * @regWrites:
- *
- * Used for both the chipsets with an external AR2133/AR5133 radios and
- * single-chip devices.
- */
-void ath9k_hw_write_regs(struct ath_hw *ah, u32 freqIndex, int regWrites)
-{
-	REG_WRITE_ARRAY(&ah->iniBB_RfGain, freqIndex, regWrites);
-}
-
-/**
  * ath9k_hw_ar9280_set_channel - set channel on single-chip device
  * @ah: atheros hardware structure
  * @chan:
diff --git a/drivers/net/wireless/ath/ath9k/phy.h b/drivers/net/wireless/ath/ath9k/phy.h
index 0132e4c..4b6e494 100644
--- a/drivers/net/wireless/ath/ath9k/phy.h
+++ b/drivers/net/wireless/ath/ath9k/phy.h
@@ -17,9 +17,6 @@
 #ifndef PHY_H
 #define PHY_H
 
-/* Common between single chip and non single-chip solutions */
-void ath9k_hw_write_regs(struct ath_hw *ah, u32 freqIndex, int regWrites);
-
 /* Single chip radio settings */
 int ath9k_hw_ar9280_set_channel(struct ath_hw *ah, struct ath9k_channel *chan);
 void ath9k_hw_9280_spur_mitigate(struct ath_hw *ah, struct ath9k_channel *chan);
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 103+ messages in thread

* [PATCH v3 09/97] ath9k_hw: Move some RF ops to the private callbacks
  2010-04-15 21:38 [PATCH v3 00/97] ath9k: add AR9003 support Luis R. Rodriguez
                   ` (7 preceding siblings ...)
  2010-04-15 21:38 ` [PATCH v3 08/97] ath9k_hw: remove wrapper ath9k_hw_write_regs() Luis R. Rodriguez
@ 2010-04-15 21:38 ` Luis R. Rodriguez
  2010-04-16 19:43   ` John W. Linville
  2010-04-15 21:38 ` [PATCH v3 10/97] ath9k_hw: skip PLL initialization on AR9003 on Power-On-Reset Luis R. Rodriguez
                   ` (87 subsequent siblings)
  96 siblings, 1 reply; 103+ messages in thread
From: Luis R. Rodriguez @ 2010-04-15 21:38 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Luis R. Rodriguez, Felix Fietkau

The PHY split is easier done in a few steps. First move
the RF ops to the private ops and rename them accordingly.
We split PHY stuff up first for the AR5008 and AR9002
families. There are some callbacks that AR9002 share
with the AR5008 familiy so we set those first, if AR9002
has some different callbacks it will override them upon
hardware init.

Signed-off-by: Felix Fietkau <nbd@openwrt.org>
Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/Makefile            |    3 +-
 drivers/net/wireless/ath/ath9k/ani.c               |    1 +
 .../net/wireless/ath/ath9k/{phy.c => ar5008_phy.c} |  884 ++++++++++----------
 drivers/net/wireless/ath/ath9k/ar9002_phy.c        |  450 ++++++++++
 drivers/net/wireless/ath/ath9k/ar9002_phy.h        |  581 +++++++++++++
 drivers/net/wireless/ath/ath9k/calib.c             |    1 +
 drivers/net/wireless/ath/ath9k/eeprom_4k.c         |    1 +
 drivers/net/wireless/ath/ath9k/eeprom_9287.c       |    1 +
 drivers/net/wireless/ath/ath9k/eeprom_def.c        |    1 +
 drivers/net/wireless/ath/ath9k/hw-ops.h            |  113 +++
 drivers/net/wireless/ath/ath9k/hw.c                |  467 +----------
 drivers/net/wireless/ath/ath9k/hw.h                |   46 +-
 drivers/net/wireless/ath/ath9k/init.c              |    2 +-
 drivers/net/wireless/ath/ath9k/phy.h               |  576 +-------------
 14 files changed, 1673 insertions(+), 1454 deletions(-)
 rename drivers/net/wireless/ath/ath9k/{phy.c => ar5008_phy.c} (54%)
 create mode 100644 drivers/net/wireless/ath/ath9k/ar9002_phy.c
 create mode 100644 drivers/net/wireless/ath/ath9k/ar9002_phy.h

diff --git a/drivers/net/wireless/ath/ath9k/Makefile b/drivers/net/wireless/ath/ath9k/Makefile
index 97133be..db63ba2 100644
--- a/drivers/net/wireless/ath/ath9k/Makefile
+++ b/drivers/net/wireless/ath/ath9k/Makefile
@@ -14,13 +14,14 @@ ath9k-$(CONFIG_ATH9K_DEBUGFS) += debug.o
 obj-$(CONFIG_ATH9K) += ath9k.o
 
 ath9k_hw-y:=	hw.o \
+		ar9002_phy.o \
+		ar5008_phy.o \
 		eeprom.o \
 		eeprom_def.o \
 		eeprom_4k.o \
 		eeprom_9287.o \
 		calib.o \
 		ani.o \
-		phy.o \
 		btcoex.o \
 		mac.o \
 
diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c
index 2a0cd64..031802c 100644
--- a/drivers/net/wireless/ath/ath9k/ani.c
+++ b/drivers/net/wireless/ath/ath9k/ani.c
@@ -15,6 +15,7 @@
  */
 
 #include "hw.h"
+#include "ar9002_phy.h"
 
 static int ath9k_hw_get_ani_channel_idx(struct ath_hw *ah,
 					struct ath9k_channel *chan)
diff --git a/drivers/net/wireless/ath/ath9k/phy.c b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
similarity index 54%
rename from drivers/net/wireless/ath/ath9k/phy.c
rename to drivers/net/wireless/ath/ath9k/ar5008_phy.c
index c45f5b8..982b0d3 100644
--- a/drivers/net/wireless/ath/ath9k/phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008-2009 Atheros Communications Inc.
+ * Copyright (c) 2008-2010 Atheros Communications Inc.
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -14,410 +14,15 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-/**
- * DOC: Programming Atheros 802.11n analog front end radios
- *
- * AR5416 MAC based PCI devices and AR518 MAC based PCI-Express
- * devices have either an external AR2133 analog front end radio for single
- * band 2.4 GHz communication or an AR5133 analog front end radio for dual
- * band 2.4 GHz / 5 GHz communication.
- *
- * All devices after the AR5416 and AR5418 family starting with the AR9280
- * have their analog front radios, MAC/BB and host PCIe/USB interface embedded
- * into a single-chip and require less programming.
- *
- * The following single-chips exist with a respective embedded radio:
- *
- * AR9280 - 11n dual-band 2x2 MIMO for PCIe
- * AR9281 - 11n single-band 1x2 MIMO for PCIe
- * AR9285 - 11n single-band 1x1 for PCIe
- * AR9287 - 11n single-band 2x2 MIMO for PCIe
- *
- * AR9220 - 11n dual-band 2x2 MIMO for PCI
- * AR9223 - 11n single-band 2x2 MIMO for PCI
- *
- * AR9287 - 11n single-band 1x1 MIMO for USB
- */
-
-#include <linux/slab.h>
-
 #include "hw.h"
-
-/**
- * ath9k_hw_ar9280_set_channel - set channel on single-chip device
- * @ah: atheros hardware structure
- * @chan:
- *
- * This is the function to change channel on single-chip devices, that is
- * all devices after ar9280.
- *
- * This function takes the channel value in MHz and sets
- * hardware channel value. Assumes writes have been enabled to analog bus.
- *
- * Actual Expression,
- *
- * For 2GHz channel,
- * Channel Frequency = (3/4) * freq_ref * (chansel[8:0] + chanfrac[16:0]/2^17)
- * (freq_ref = 40MHz)
- *
- * For 5GHz channel,
- * Channel Frequency = (3/2) * freq_ref * (chansel[8:0] + chanfrac[16:0]/2^10)
- * (freq_ref = 40MHz/(24>>amodeRefSel))
- */
-int ath9k_hw_ar9280_set_channel(struct ath_hw *ah, struct ath9k_channel *chan)
-{
-	u16 bMode, fracMode, aModeRefSel = 0;
-	u32 freq, ndiv, channelSel = 0, channelFrac = 0, reg32 = 0;
-	struct chan_centers centers;
-	u32 refDivA = 24;
-
-	ath9k_hw_get_channel_centers(ah, chan, &centers);
-	freq = centers.synth_center;
-
-	reg32 = REG_READ(ah, AR_PHY_SYNTH_CONTROL);
-	reg32 &= 0xc0000000;
-
-	if (freq < 4800) { /* 2 GHz, fractional mode */
-		u32 txctl;
-		int regWrites = 0;
-
-		bMode = 1;
-		fracMode = 1;
-		aModeRefSel = 0;
-		channelSel = (freq * 0x10000) / 15;
-
-		if (AR_SREV_9287_11_OR_LATER(ah)) {
-			if (freq == 2484) {
-				/* Enable channel spreading for channel 14 */
-				REG_WRITE_ARRAY(&ah->iniCckfirJapan2484,
-						1, regWrites);
-			} else {
-				REG_WRITE_ARRAY(&ah->iniCckfirNormal,
-						1, regWrites);
-			}
-		} else {
-			txctl = REG_READ(ah, AR_PHY_CCK_TX_CTRL);
-			if (freq == 2484) {
-				/* Enable channel spreading for channel 14 */
-				REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
-					  txctl | AR_PHY_CCK_TX_CTRL_JAPAN);
-			} else {
-				REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
-					  txctl &~ AR_PHY_CCK_TX_CTRL_JAPAN);
-			}
-		}
-	} else {
-		bMode = 0;
-		fracMode = 0;
-
-		switch(ah->eep_ops->get_eeprom(ah, EEP_FRAC_N_5G)) {
-		case 0:
-			if ((freq % 20) == 0) {
-				aModeRefSel = 3;
-			} else if ((freq % 10) == 0) {
-				aModeRefSel = 2;
-			}
-			if (aModeRefSel)
-				break;
-		case 1:
-		default:
-			aModeRefSel = 0;
-			/*
-			 * Enable 2G (fractional) mode for channels
-			 * which are 5MHz spaced.
-			 */
-			fracMode = 1;
-			refDivA = 1;
-			channelSel = (freq * 0x8000) / 15;
-
-			/* RefDivA setting */
-			REG_RMW_FIELD(ah, AR_AN_SYNTH9,
-				      AR_AN_SYNTH9_REFDIVA, refDivA);
-
-		}
-
-		if (!fracMode) {
-			ndiv = (freq * (refDivA >> aModeRefSel)) / 60;
-			channelSel = ndiv & 0x1ff;
-			channelFrac = (ndiv & 0xfffffe00) * 2;
-			channelSel = (channelSel << 17) | channelFrac;
-		}
-	}
-
-	reg32 = reg32 |
-	    (bMode << 29) |
-	    (fracMode << 28) | (aModeRefSel << 26) | (channelSel);
-
-	REG_WRITE(ah, AR_PHY_SYNTH_CONTROL, reg32);
-
-	ah->curchan = chan;
-	ah->curchan_rad_index = -1;
-
-	return 0;
-}
-
-/**
- * ath9k_hw_9280_spur_mitigate - convert baseband spur frequency
- * @ah: atheros hardware structure
- * @chan:
- *
- * For single-chip solutions. Converts to baseband spur frequency given the
- * input channel frequency and compute register settings below.
- */
-void ath9k_hw_9280_spur_mitigate(struct ath_hw *ah, struct ath9k_channel *chan)
-{
-	int bb_spur = AR_NO_SPUR;
-	int freq;
-	int bin, cur_bin;
-	int bb_spur_off, spur_subchannel_sd;
-	int spur_freq_sd;
-	int spur_delta_phase;
-	int denominator;
-	int upper, lower, cur_vit_mask;
-	int tmp, newVal;
-	int i;
-	int pilot_mask_reg[4] = { AR_PHY_TIMING7, AR_PHY_TIMING8,
-			  AR_PHY_PILOT_MASK_01_30, AR_PHY_PILOT_MASK_31_60
-	};
-	int chan_mask_reg[4] = { AR_PHY_TIMING9, AR_PHY_TIMING10,
-			 AR_PHY_CHANNEL_MASK_01_30, AR_PHY_CHANNEL_MASK_31_60
-	};
-	int inc[4] = { 0, 100, 0, 0 };
-	struct chan_centers centers;
-
-	int8_t mask_m[123];
-	int8_t mask_p[123];
-	int8_t mask_amt;
-	int tmp_mask;
-	int cur_bb_spur;
-	bool is2GHz = IS_CHAN_2GHZ(chan);
-
-	memset(&mask_m, 0, sizeof(int8_t) * 123);
-	memset(&mask_p, 0, sizeof(int8_t) * 123);
-
-	ath9k_hw_get_channel_centers(ah, chan, &centers);
-	freq = centers.synth_center;
-
-	ah->config.spurmode = SPUR_ENABLE_EEPROM;
-	for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
-		cur_bb_spur = ah->eep_ops->get_spur_channel(ah, i, is2GHz);
-
-		if (is2GHz)
-			cur_bb_spur = (cur_bb_spur / 10) + AR_BASE_FREQ_2GHZ;
-		else
-			cur_bb_spur = (cur_bb_spur / 10) + AR_BASE_FREQ_5GHZ;
-
-		if (AR_NO_SPUR == cur_bb_spur)
-			break;
-		cur_bb_spur = cur_bb_spur - freq;
-
-		if (IS_CHAN_HT40(chan)) {
-			if ((cur_bb_spur > -AR_SPUR_FEEQ_BOUND_HT40) &&
-			    (cur_bb_spur < AR_SPUR_FEEQ_BOUND_HT40)) {
-				bb_spur = cur_bb_spur;
-				break;
-			}
-		} else if ((cur_bb_spur > -AR_SPUR_FEEQ_BOUND_HT20) &&
-			   (cur_bb_spur < AR_SPUR_FEEQ_BOUND_HT20)) {
-			bb_spur = cur_bb_spur;
-			break;
-		}
-	}
-
-	if (AR_NO_SPUR == bb_spur) {
-		REG_CLR_BIT(ah, AR_PHY_FORCE_CLKEN_CCK,
-			    AR_PHY_FORCE_CLKEN_CCK_MRC_MUX);
-		return;
-	} else {
-		REG_CLR_BIT(ah, AR_PHY_FORCE_CLKEN_CCK,
-			    AR_PHY_FORCE_CLKEN_CCK_MRC_MUX);
-	}
-
-	bin = bb_spur * 320;
-
-	tmp = REG_READ(ah, AR_PHY_TIMING_CTRL4(0));
-
-	newVal = tmp | (AR_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI |
-			AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER |
-			AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK |
-			AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK);
-	REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0), newVal);
-
-	newVal = (AR_PHY_SPUR_REG_MASK_RATE_CNTL |
-		  AR_PHY_SPUR_REG_ENABLE_MASK_PPM |
-		  AR_PHY_SPUR_REG_MASK_RATE_SELECT |
-		  AR_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI |
-		  SM(SPUR_RSSI_THRESH, AR_PHY_SPUR_REG_SPUR_RSSI_THRESH));
-	REG_WRITE(ah, AR_PHY_SPUR_REG, newVal);
-
-	if (IS_CHAN_HT40(chan)) {
-		if (bb_spur < 0) {
-			spur_subchannel_sd = 1;
-			bb_spur_off = bb_spur + 10;
-		} else {
-			spur_subchannel_sd = 0;
-			bb_spur_off = bb_spur - 10;
-		}
-	} else {
-		spur_subchannel_sd = 0;
-		bb_spur_off = bb_spur;
-	}
-
-	if (IS_CHAN_HT40(chan))
-		spur_delta_phase =
-			((bb_spur * 262144) /
-			 10) & AR_PHY_TIMING11_SPUR_DELTA_PHASE;
-	else
-		spur_delta_phase =
-			((bb_spur * 524288) /
-			 10) & AR_PHY_TIMING11_SPUR_DELTA_PHASE;
-
-	denominator = IS_CHAN_2GHZ(chan) ? 44 : 40;
-	spur_freq_sd = ((bb_spur_off * 2048) / denominator) & 0x3ff;
-
-	newVal = (AR_PHY_TIMING11_USE_SPUR_IN_AGC |
-		  SM(spur_freq_sd, AR_PHY_TIMING11_SPUR_FREQ_SD) |
-		  SM(spur_delta_phase, AR_PHY_TIMING11_SPUR_DELTA_PHASE));
-	REG_WRITE(ah, AR_PHY_TIMING11, newVal);
-
-	newVal = spur_subchannel_sd << AR_PHY_SFCORR_SPUR_SUBCHNL_SD_S;
-	REG_WRITE(ah, AR_PHY_SFCORR_EXT, newVal);
-
-	cur_bin = -6000;
-	upper = bin + 100;
-	lower = bin - 100;
-
-	for (i = 0; i < 4; i++) {
-		int pilot_mask = 0;
-		int chan_mask = 0;
-		int bp = 0;
-		for (bp = 0; bp < 30; bp++) {
-			if ((cur_bin > lower) && (cur_bin < upper)) {
-				pilot_mask = pilot_mask | 0x1 << bp;
-				chan_mask = chan_mask | 0x1 << bp;
-			}
-			cur_bin += 100;
-		}
-		cur_bin += inc[i];
-		REG_WRITE(ah, pilot_mask_reg[i], pilot_mask);
-		REG_WRITE(ah, chan_mask_reg[i], chan_mask);
-	}
-
-	cur_vit_mask = 6100;
-	upper = bin + 120;
-	lower = bin - 120;
-
-	for (i = 0; i < 123; i++) {
-		if ((cur_vit_mask > lower) && (cur_vit_mask < upper)) {
-
-			/* workaround for gcc bug #37014 */
-			volatile int tmp_v = abs(cur_vit_mask - bin);
-
-			if (tmp_v < 75)
-				mask_amt = 1;
-			else
-				mask_amt = 0;
-			if (cur_vit_mask < 0)
-				mask_m[abs(cur_vit_mask / 100)] = mask_amt;
-			else
-				mask_p[cur_vit_mask / 100] = mask_amt;
-		}
-		cur_vit_mask -= 100;
-	}
-
-	tmp_mask = (mask_m[46] << 30) | (mask_m[47] << 28)
-		| (mask_m[48] << 26) | (mask_m[49] << 24)
-		| (mask_m[50] << 22) | (mask_m[51] << 20)
-		| (mask_m[52] << 18) | (mask_m[53] << 16)
-		| (mask_m[54] << 14) | (mask_m[55] << 12)
-		| (mask_m[56] << 10) | (mask_m[57] << 8)
-		| (mask_m[58] << 6) | (mask_m[59] << 4)
-		| (mask_m[60] << 2) | (mask_m[61] << 0);
-	REG_WRITE(ah, AR_PHY_BIN_MASK_1, tmp_mask);
-	REG_WRITE(ah, AR_PHY_VIT_MASK2_M_46_61, tmp_mask);
-
-	tmp_mask = (mask_m[31] << 28)
-		| (mask_m[32] << 26) | (mask_m[33] << 24)
-		| (mask_m[34] << 22) | (mask_m[35] << 20)
-		| (mask_m[36] << 18) | (mask_m[37] << 16)
-		| (mask_m[48] << 14) | (mask_m[39] << 12)
-		| (mask_m[40] << 10) | (mask_m[41] << 8)
-		| (mask_m[42] << 6) | (mask_m[43] << 4)
-		| (mask_m[44] << 2) | (mask_m[45] << 0);
-	REG_WRITE(ah, AR_PHY_BIN_MASK_2, tmp_mask);
-	REG_WRITE(ah, AR_PHY_MASK2_M_31_45, tmp_mask);
-
-	tmp_mask = (mask_m[16] << 30) | (mask_m[16] << 28)
-		| (mask_m[18] << 26) | (mask_m[18] << 24)
-		| (mask_m[20] << 22) | (mask_m[20] << 20)
-		| (mask_m[22] << 18) | (mask_m[22] << 16)
-		| (mask_m[24] << 14) | (mask_m[24] << 12)
-		| (mask_m[25] << 10) | (mask_m[26] << 8)
-		| (mask_m[27] << 6) | (mask_m[28] << 4)
-		| (mask_m[29] << 2) | (mask_m[30] << 0);
-	REG_WRITE(ah, AR_PHY_BIN_MASK_3, tmp_mask);
-	REG_WRITE(ah, AR_PHY_MASK2_M_16_30, tmp_mask);
-
-	tmp_mask = (mask_m[0] << 30) | (mask_m[1] << 28)
-		| (mask_m[2] << 26) | (mask_m[3] << 24)
-		| (mask_m[4] << 22) | (mask_m[5] << 20)
-		| (mask_m[6] << 18) | (mask_m[7] << 16)
-		| (mask_m[8] << 14) | (mask_m[9] << 12)
-		| (mask_m[10] << 10) | (mask_m[11] << 8)
-		| (mask_m[12] << 6) | (mask_m[13] << 4)
-		| (mask_m[14] << 2) | (mask_m[15] << 0);
-	REG_WRITE(ah, AR_PHY_MASK_CTL, tmp_mask);
-	REG_WRITE(ah, AR_PHY_MASK2_M_00_15, tmp_mask);
-
-	tmp_mask = (mask_p[15] << 28)
-		| (mask_p[14] << 26) | (mask_p[13] << 24)
-		| (mask_p[12] << 22) | (mask_p[11] << 20)
-		| (mask_p[10] << 18) | (mask_p[9] << 16)
-		| (mask_p[8] << 14) | (mask_p[7] << 12)
-		| (mask_p[6] << 10) | (mask_p[5] << 8)
-		| (mask_p[4] << 6) | (mask_p[3] << 4)
-		| (mask_p[2] << 2) | (mask_p[1] << 0);
-	REG_WRITE(ah, AR_PHY_BIN_MASK2_1, tmp_mask);
-	REG_WRITE(ah, AR_PHY_MASK2_P_15_01, tmp_mask);
-
-	tmp_mask = (mask_p[30] << 28)
-		| (mask_p[29] << 26) | (mask_p[28] << 24)
-		| (mask_p[27] << 22) | (mask_p[26] << 20)
-		| (mask_p[25] << 18) | (mask_p[24] << 16)
-		| (mask_p[23] << 14) | (mask_p[22] << 12)
-		| (mask_p[21] << 10) | (mask_p[20] << 8)
-		| (mask_p[19] << 6) | (mask_p[18] << 4)
-		| (mask_p[17] << 2) | (mask_p[16] << 0);
-	REG_WRITE(ah, AR_PHY_BIN_MASK2_2, tmp_mask);
-	REG_WRITE(ah, AR_PHY_MASK2_P_30_16, tmp_mask);
-
-	tmp_mask = (mask_p[45] << 28)
-		| (mask_p[44] << 26) | (mask_p[43] << 24)
-		| (mask_p[42] << 22) | (mask_p[41] << 20)
-		| (mask_p[40] << 18) | (mask_p[39] << 16)
-		| (mask_p[38] << 14) | (mask_p[37] << 12)
-		| (mask_p[36] << 10) | (mask_p[35] << 8)
-		| (mask_p[34] << 6) | (mask_p[33] << 4)
-		| (mask_p[32] << 2) | (mask_p[31] << 0);
-	REG_WRITE(ah, AR_PHY_BIN_MASK2_3, tmp_mask);
-	REG_WRITE(ah, AR_PHY_MASK2_P_45_31, tmp_mask);
-
-	tmp_mask = (mask_p[61] << 30) | (mask_p[60] << 28)
-		| (mask_p[59] << 26) | (mask_p[58] << 24)
-		| (mask_p[57] << 22) | (mask_p[56] << 20)
-		| (mask_p[55] << 18) | (mask_p[54] << 16)
-		| (mask_p[53] << 14) | (mask_p[52] << 12)
-		| (mask_p[51] << 10) | (mask_p[50] << 8)
-		| (mask_p[49] << 6) | (mask_p[48] << 4)
-		| (mask_p[47] << 2) | (mask_p[46] << 0);
-	REG_WRITE(ah, AR_PHY_BIN_MASK2_4, tmp_mask);
-	REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask);
-}
+#include "hw-ops.h"
+#include "../regd.h"
+#include "ar9002_phy.h"
 
 /* All code below is for non single-chip solutions */
 
 /**
- * ath9k_phy_modify_rx_buffer() - perform analog swizzling of parameters
+ * ar5008_hw_phy_modify_rx_buffer() - perform analog swizzling of parameters
  * @rfbuf:
  * @reg32:
  * @numBits:
@@ -427,9 +32,9 @@ void ath9k_hw_9280_spur_mitigate(struct ath_hw *ah, struct ath9k_channel *chan)
  * Performs analog "swizzling" of parameters into their location.
  * Used on external AR2133/AR5133 radios.
  */
-static void ath9k_phy_modify_rx_buffer(u32 *rfBuf, u32 reg32,
-				       u32 numBits, u32 firstBit,
-				       u32 column)
+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;
@@ -480,16 +85,15 @@ static void ath9k_phy_modify_rx_buffer(u32 *rfBuf, u32 reg32,
  *  2nd Mod:
  *    Less than 2412 uses value of 0, 2412 and above uses value of 2
  */
-static void ath9k_hw_force_bias(struct ath_hw *ah, u16 synth_freq)
+static void ar5008_hw_force_bias(struct ath_hw *ah, u16 synth_freq)
 {
 	struct ath_common *common = ath9k_hw_common(ah);
 	u32 tmp_reg;
 	int reg_writes = 0;
 	u32 new_bias = 0;
 
-	if (!AR_SREV_5416(ah) || synth_freq >= 3000) {
+	if (!AR_SREV_5416(ah) || synth_freq >= 3000)
 		return;
-	}
 
 	BUG_ON(AR_SREV_9280_10_OR_LATER(ah));
 
@@ -508,14 +112,14 @@ static void ath9k_hw_force_bias(struct ath_hw *ah, u16 synth_freq)
 		  new_bias, synth_freq);
 
 	/* swizzle rf_pwd_icsyndiv */
-	ath9k_phy_modify_rx_buffer(ah->analogBank6Data, tmp_reg, 3, 181, 3);
+	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);
 }
 
 /**
- * ath9k_hw_set_channel - tune to a channel on the external AR2133/AR5133 radios
+ * ar5008_hw_set_channel - tune to a channel on the external AR2133/AR5133 radios
  * @ah: atheros hardware stucture
  * @chan:
  *
@@ -523,7 +127,7 @@ static void ath9k_hw_force_bias(struct ath_hw *ah, u16 synth_freq)
  * the channel value. Assumes writes enabled to analog bus and bank6 register
  * cache in ah->analogBank6Data.
  */
-int ath9k_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan)
+static int ar5008_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan)
 {
 	struct ath_common *common = ath9k_hw_common(ah);
 	u32 channelSel = 0;
@@ -584,7 +188,7 @@ int ath9k_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan)
 		return -EINVAL;
 	}
 
-	ath9k_hw_force_bias(ah, freq);
+	ar5008_hw_force_bias(ah, freq);
 
 	reg32 =
 	    (channelSel << 8) | (aModeRefSel << 2) | (bModeSynth << 1) |
@@ -599,14 +203,15 @@ int ath9k_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan)
 }
 
 /**
- * ath9k_hw_spur_mitigate - convert baseband spur frequency for external radios
+ * 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.
  */
-void ath9k_hw_spur_mitigate(struct ath_hw *ah, struct ath9k_channel *chan)
+static void ar5008_hw_spur_mitigate(struct ath_hw *ah,
+				    struct ath9k_channel *chan)
 {
 	int bb_spur = AR_NO_SPUR;
 	int bin, cur_bin;
@@ -808,12 +413,12 @@ void ath9k_hw_spur_mitigate(struct ath_hw *ah, struct ath9k_channel *chan)
 }
 
 /**
- * ath9k_hw_rf_alloc_ext_banks - allocates banks for external radio programming
+ * 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.
  */
-int ath9k_hw_rf_alloc_ext_banks(struct ath_hw *ah)
+static int ar5008_hw_rf_alloc_ext_banks(struct ath_hw *ah)
 {
 #define ATH_ALLOC_BANK(bank, size) do { \
 		bank = kzalloc((sizeof(u32) * size), GFP_KERNEL); \
@@ -845,12 +450,11 @@ int ath9k_hw_rf_alloc_ext_banks(struct ath_hw *ah)
 
 
 /**
- * ath9k_hw_rf_free_ext_banks - Free memory for analog bank scratch buffers
+ * ar5008_hw_rf_free_ext_banks - Free memory for analog bank scratch buffers
  * @ah: atheros hardware struture
  * For the external AR2133/AR5133 radios banks.
  */
-void
-ath9k_hw_rf_free_ext_banks(struct ath_hw *ah)
+static void ar5008_hw_rf_free_ext_banks(struct ath_hw *ah)
 {
 #define ATH_FREE_BANK(bank) do { \
 		kfree(bank); \
@@ -873,7 +477,7 @@ ath9k_hw_rf_free_ext_banks(struct ath_hw *ah)
 }
 
 /* *
- * ath9k_hw_set_rf_regs - programs rf registers based on EEPROM
+ * ar5008_hw_set_rf_regs - programs rf registers based on EEPROM
  * @ah: atheros hardware structure
  * @chan:
  * @modesIndex:
@@ -884,8 +488,9 @@ ath9k_hw_rf_free_ext_banks(struct ath_hw *ah)
  * all rf registers. This routine requires access to the analog
  * rf device. This is not required for single-chip devices.
  */
-bool ath9k_hw_set_rf_regs(struct ath_hw *ah, struct ath9k_channel *chan,
-			  u16 modesIndex)
+static bool ar5008_hw_set_rf_regs(struct ath_hw *ah,
+				  struct ath9k_channel *chan,
+				  u16 modesIndex)
 {
 	u32 eepMinorRev;
 	u32 ob5GHz = 0, db5GHz = 0;
@@ -928,17 +533,17 @@ bool ath9k_hw_set_rf_regs(struct ath_hw *ah, struct ath9k_channel *chan,
 		if (IS_CHAN_2GHZ(chan)) {
 			ob2GHz = ah->eep_ops->get_eeprom(ah, EEP_OB_2);
 			db2GHz = ah->eep_ops->get_eeprom(ah, EEP_DB_2);
-			ath9k_phy_modify_rx_buffer(ah->analogBank6Data,
-						   ob2GHz, 3, 197, 0);
-			ath9k_phy_modify_rx_buffer(ah->analogBank6Data,
-						   db2GHz, 3, 194, 0);
+			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);
-			ath9k_phy_modify_rx_buffer(ah->analogBank6Data,
-						   ob5GHz, 3, 203, 0);
-			ath9k_phy_modify_rx_buffer(ah->analogBank6Data,
-						   db5GHz, 3, 200, 0);
+			ar5008_hw_phy_modify_rx_buffer(ah->analogBank6Data,
+						       ob5GHz, 3, 203, 0);
+			ar5008_hw_phy_modify_rx_buffer(ah->analogBank6Data,
+						       db5GHz, 3, 200, 0);
 		}
 	}
 
@@ -961,3 +566,426 @@ bool ath9k_hw_set_rf_regs(struct ath_hw *ah, struct ath9k_channel *chan,
 
 	return true;
 }
+
+static void ar5008_hw_init_bb(struct ath_hw *ah,
+			      struct ath9k_channel *chan)
+{
+	u32 synthDelay;
+
+	synthDelay = REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY;
+	if (IS_CHAN_B(chan))
+		synthDelay = (4 * synthDelay) / 22;
+	else
+		synthDelay /= 10;
+
+	REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
+
+	udelay(synthDelay + BASE_ACTIVATE_DELAY);
+}
+
+static void ar5008_hw_init_chain_masks(struct ath_hw *ah)
+{
+	int rx_chainmask, tx_chainmask;
+
+	rx_chainmask = ah->rxchainmask;
+	tx_chainmask = ah->txchainmask;
+
+	switch (rx_chainmask) {
+	case 0x5:
+		REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP,
+			    AR_PHY_SWAP_ALT_CHAIN);
+	case 0x3:
+		if (ah->hw_version.macVersion == AR_SREV_REVISION_5416_10) {
+			REG_WRITE(ah, AR_PHY_RX_CHAINMASK, 0x7);
+			REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, 0x7);
+			break;
+		}
+	case 0x1:
+	case 0x2:
+	case 0x7:
+		REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx_chainmask);
+		REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx_chainmask);
+		break;
+	default:
+		break;
+	}
+
+	REG_WRITE(ah, AR_SELFGEN_MASK, tx_chainmask);
+	if (tx_chainmask == 0x5) {
+		REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP,
+			    AR_PHY_SWAP_ALT_CHAIN);
+	}
+	if (AR_SREV_9100(ah))
+		REG_WRITE(ah, AR_PHY_ANALOG_SWAP,
+			  REG_READ(ah, AR_PHY_ANALOG_SWAP) | 0x00000001);
+}
+
+static void ar5008_hw_override_ini(struct ath_hw *ah,
+				   struct ath9k_channel *chan)
+{
+	u32 val;
+
+	/*
+	 * Set the RX_ABORT and RX_DIS and clear if off only after
+	 * RXE is set for MAC. This prevents frames with corrupted
+	 * descriptor status.
+	 */
+	REG_SET_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
+
+	if (AR_SREV_9280_10_OR_LATER(ah)) {
+		val = REG_READ(ah, AR_PCU_MISC_MODE2);
+
+		if (!AR_SREV_9271(ah))
+			val &= ~AR_PCU_MISC_MODE2_HWWAR1;
+
+		if (AR_SREV_9287_10_OR_LATER(ah))
+			val = val & (~AR_PCU_MISC_MODE2_HWWAR2);
+
+		REG_WRITE(ah, AR_PCU_MISC_MODE2, val);
+	}
+
+	if (!AR_SREV_5416_20_OR_LATER(ah) ||
+	    AR_SREV_9280_10_OR_LATER(ah))
+		return;
+	/*
+	 * Disable BB clock gating
+	 * Necessary to avoid issues on AR5416 2.0
+	 */
+	REG_WRITE(ah, 0x9800 + (651 << 2), 0x11);
+
+	/*
+	 * Disable RIFS search on some chips to avoid baseband
+	 * hang issues.
+	 */
+	if (AR_SREV_9100(ah) || AR_SREV_9160(ah)) {
+		val = REG_READ(ah, AR_PHY_HEAVY_CLIP_FACTOR_RIFS);
+		val &= ~AR_PHY_RIFS_INIT_DELAY;
+		REG_WRITE(ah, AR_PHY_HEAVY_CLIP_FACTOR_RIFS, val);
+	}
+}
+
+static void ar5008_hw_set_channel_regs(struct ath_hw *ah,
+				       struct ath9k_channel *chan)
+{
+	u32 phymode;
+	u32 enableDacFifo = 0;
+
+	if (AR_SREV_9285_10_OR_LATER(ah))
+		enableDacFifo = (REG_READ(ah, AR_PHY_TURBO) &
+					 AR_PHY_FC_ENABLE_DAC_FIFO);
+
+	phymode = AR_PHY_FC_HT_EN | AR_PHY_FC_SHORT_GI_40
+		| AR_PHY_FC_SINGLE_HT_LTF1 | AR_PHY_FC_WALSH | enableDacFifo;
+
+	if (IS_CHAN_HT40(chan)) {
+		phymode |= AR_PHY_FC_DYN2040_EN;
+
+		if ((chan->chanmode == CHANNEL_A_HT40PLUS) ||
+		    (chan->chanmode == CHANNEL_G_HT40PLUS))
+			phymode |= AR_PHY_FC_DYN2040_PRI_CH;
+
+	}
+	REG_WRITE(ah, AR_PHY_TURBO, phymode);
+
+	ath9k_hw_set11nmac2040(ah);
+
+	REG_WRITE(ah, AR_GTXTO, 25 << AR_GTXTO_TIMEOUT_LIMIT_S);
+	REG_WRITE(ah, AR_CST, 0xF << AR_CST_TIMEOUT_LIMIT_S);
+}
+
+
+static int ar5008_hw_process_ini(struct ath_hw *ah,
+				 struct ath9k_channel *chan)
+{
+	struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
+	int i, regWrites = 0;
+	struct ieee80211_channel *channel = chan->chan;
+	u32 modesIndex, freqIndex;
+
+	switch (chan->chanmode) {
+	case CHANNEL_A:
+	case CHANNEL_A_HT20:
+		modesIndex = 1;
+		freqIndex = 1;
+		break;
+	case CHANNEL_A_HT40PLUS:
+	case CHANNEL_A_HT40MINUS:
+		modesIndex = 2;
+		freqIndex = 1;
+		break;
+	case CHANNEL_G:
+	case CHANNEL_G_HT20:
+	case CHANNEL_B:
+		modesIndex = 4;
+		freqIndex = 2;
+		break;
+	case CHANNEL_G_HT40PLUS:
+	case CHANNEL_G_HT40MINUS:
+		modesIndex = 3;
+		freqIndex = 2;
+		break;
+
+	default:
+		return -EINVAL;
+	}
+
+	if (AR_SREV_9287_12_OR_LATER(ah)) {
+		/* Enable ASYNC FIFO */
+		REG_SET_BIT(ah, AR_MAC_PCU_ASYNC_FIFO_REG3,
+				AR_MAC_PCU_ASYNC_FIFO_REG3_DATAPATH_SEL);
+		REG_SET_BIT(ah, AR_PHY_MODE, AR_PHY_MODE_ASYNCFIFO);
+		REG_CLR_BIT(ah, AR_MAC_PCU_ASYNC_FIFO_REG3,
+				AR_MAC_PCU_ASYNC_FIFO_REG3_SOFT_RESET);
+		REG_SET_BIT(ah, AR_MAC_PCU_ASYNC_FIFO_REG3,
+				AR_MAC_PCU_ASYNC_FIFO_REG3_SOFT_RESET);
+	}
+
+	/*
+	 * Set correct baseband to analog shift setting to
+	 * access analog chips.
+	 */
+	REG_WRITE(ah, AR_PHY(0), 0x00000007);
+
+	/* Write ADDAC shifts */
+	REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_EXTERNAL_RADIO);
+	ah->eep_ops->set_addac(ah, chan);
+
+	if (AR_SREV_5416_22_OR_LATER(ah)) {
+		REG_WRITE_ARRAY(&ah->iniAddac, 1, regWrites);
+	} else {
+		struct ar5416IniArray temp;
+		u32 addacSize =
+			sizeof(u32) * ah->iniAddac.ia_rows *
+			ah->iniAddac.ia_columns;
+
+		/* For AR5416 2.0/2.1 */
+		memcpy(ah->addac5416_21,
+		       ah->iniAddac.ia_array, addacSize);
+
+		/* override CLKDRV value at [row, column] = [31, 1] */
+		(ah->addac5416_21)[31 * ah->iniAddac.ia_columns + 1] = 0;
+
+		temp.ia_array = ah->addac5416_21;
+		temp.ia_columns = ah->iniAddac.ia_columns;
+		temp.ia_rows = ah->iniAddac.ia_rows;
+		REG_WRITE_ARRAY(&temp, 1, regWrites);
+	}
+
+	REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_INTERNAL_ADDAC);
+
+	for (i = 0; i < ah->iniModes.ia_rows; i++) {
+		u32 reg = INI_RA(&ah->iniModes, i, 0);
+		u32 val = INI_RA(&ah->iniModes, i, modesIndex);
+
+		if (reg == AR_AN_TOP2 && ah->need_an_top2_fixup)
+			val &= ~AR_AN_TOP2_PWDCLKIND;
+
+		REG_WRITE(ah, reg, val);
+
+		if (reg >= 0x7800 && reg < 0x78a0
+		    && ah->config.analog_shiftreg) {
+			udelay(100);
+		}
+
+		DO_DELAY(regWrites);
+	}
+
+	if (AR_SREV_9280(ah) || AR_SREV_9287_10_OR_LATER(ah))
+		REG_WRITE_ARRAY(&ah->iniModesRxGain, modesIndex, regWrites);
+
+	if (AR_SREV_9280(ah) || AR_SREV_9285_12_OR_LATER(ah) ||
+	    AR_SREV_9287_10_OR_LATER(ah))
+		REG_WRITE_ARRAY(&ah->iniModesTxGain, modesIndex, regWrites);
+
+	if (AR_SREV_9271_10(ah))
+		REG_WRITE_ARRAY(&ah->iniModes_9271_1_0_only,
+				modesIndex, regWrites);
+
+	/* Write common array parameters */
+	for (i = 0; i < ah->iniCommon.ia_rows; i++) {
+		u32 reg = INI_RA(&ah->iniCommon, i, 0);
+		u32 val = INI_RA(&ah->iniCommon, i, 1);
+
+		REG_WRITE(ah, reg, val);
+
+		if (reg >= 0x7800 && reg < 0x78a0
+		    && ah->config.analog_shiftreg) {
+			udelay(100);
+		}
+
+		DO_DELAY(regWrites);
+	}
+
+	if (AR_SREV_9271(ah)) {
+		if (ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE) == 1)
+			REG_WRITE_ARRAY(&ah->iniModes_high_power_tx_gain_9271,
+					modesIndex, regWrites);
+		else
+			REG_WRITE_ARRAY(&ah->iniModes_normal_power_tx_gain_9271,
+					modesIndex, regWrites);
+	}
+
+	REG_WRITE_ARRAY(&ah->iniBB_RfGain, freqIndex, regWrites);
+
+	if (AR_SREV_9280_20(ah) && IS_CHAN_A_5MHZ_SPACED(chan)) {
+		REG_WRITE_ARRAY(&ah->iniModesAdditional, modesIndex,
+				regWrites);
+	}
+
+	ar5008_hw_override_ini(ah, chan);
+	ar5008_hw_set_channel_regs(ah, chan);
+	ar5008_hw_init_chain_masks(ah);
+	ath9k_olc_init(ah);
+
+	/* Set TX power */
+	ah->eep_ops->set_txpower(ah, chan,
+				 ath9k_regd_get_ctl(regulatory, chan),
+				 channel->max_antenna_gain * 2,
+				 channel->max_power * 2,
+				 min((u32) MAX_RATE_POWER,
+				 (u32) regulatory->power_limit));
+
+	/* Write analog registers */
+	if (!ath9k_hw_set_rf_regs(ah, chan, freqIndex)) {
+		ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL,
+			  "ar5416SetRfRegs failed\n");
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static void ar5008_hw_set_rfmode(struct ath_hw *ah, struct ath9k_channel *chan)
+{
+	u32 rfMode = 0;
+
+	if (chan == NULL)
+		return;
+
+	rfMode |= (IS_CHAN_B(chan) || IS_CHAN_G(chan))
+		? AR_PHY_MODE_DYNAMIC : AR_PHY_MODE_OFDM;
+
+	if (!AR_SREV_9280_10_OR_LATER(ah))
+		rfMode |= (IS_CHAN_5GHZ(chan)) ?
+			AR_PHY_MODE_RF5GHZ : AR_PHY_MODE_RF2GHZ;
+
+	if ((AR_SREV_9280_20(ah) || AR_SREV_9300_20_OR_LATER(ah))
+	    && IS_CHAN_A_5MHZ_SPACED(chan))
+		rfMode |= (AR_PHY_MODE_DYNAMIC | AR_PHY_MODE_DYN_CCK_DISABLE);
+
+	REG_WRITE(ah, AR_PHY_MODE, rfMode);
+}
+
+static void ar5008_hw_mark_phy_inactive(struct ath_hw *ah)
+{
+	REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS);
+}
+
+static void ar5008_hw_set_delta_slope(struct ath_hw *ah,
+				      struct ath9k_channel *chan)
+{
+	u32 coef_scaled, ds_coef_exp, ds_coef_man;
+	u32 clockMhzScaled = 0x64000000;
+	struct chan_centers centers;
+
+	if (IS_CHAN_HALF_RATE(chan))
+		clockMhzScaled = clockMhzScaled >> 1;
+	else if (IS_CHAN_QUARTER_RATE(chan))
+		clockMhzScaled = clockMhzScaled >> 2;
+
+	ath9k_hw_get_channel_centers(ah, chan, &centers);
+	coef_scaled = clockMhzScaled / centers.synth_center;
+
+	ath9k_hw_get_delta_slope_vals(ah, coef_scaled, &ds_coef_man,
+				      &ds_coef_exp);
+
+	REG_RMW_FIELD(ah, AR_PHY_TIMING3,
+		      AR_PHY_TIMING3_DSC_MAN, ds_coef_man);
+	REG_RMW_FIELD(ah, AR_PHY_TIMING3,
+		      AR_PHY_TIMING3_DSC_EXP, ds_coef_exp);
+
+	coef_scaled = (9 * coef_scaled) / 10;
+
+	ath9k_hw_get_delta_slope_vals(ah, coef_scaled, &ds_coef_man,
+				      &ds_coef_exp);
+
+	REG_RMW_FIELD(ah, AR_PHY_HALFGI,
+		      AR_PHY_HALFGI_DSC_MAN, ds_coef_man);
+	REG_RMW_FIELD(ah, AR_PHY_HALFGI,
+		      AR_PHY_HALFGI_DSC_EXP, ds_coef_exp);
+}
+
+static bool ar5008_hw_rfbus_req(struct ath_hw *ah)
+{
+	REG_WRITE(ah, AR_PHY_RFBUS_REQ, AR_PHY_RFBUS_REQ_EN);
+	return ath9k_hw_wait(ah, AR_PHY_RFBUS_GRANT, AR_PHY_RFBUS_GRANT_EN,
+			   AR_PHY_RFBUS_GRANT_EN, AH_WAIT_TIMEOUT);
+}
+
+static void ar5008_hw_rfbus_done(struct ath_hw *ah)
+{
+	u32 synthDelay = REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY;
+	if (IS_CHAN_B(ah->curchan))
+		synthDelay = (4 * synthDelay) / 22;
+	else
+		synthDelay /= 10;
+
+	udelay(synthDelay + BASE_ACTIVATE_DELAY);
+
+	REG_WRITE(ah, AR_PHY_RFBUS_REQ, 0);
+}
+
+static void ar5008_hw_enable_rfkill(struct ath_hw *ah)
+{
+	REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL,
+		    AR_GPIO_INPUT_EN_VAL_RFSILENT_BB);
+
+	REG_CLR_BIT(ah, AR_GPIO_INPUT_MUX2,
+		    AR_GPIO_INPUT_MUX2_RFSILENT);
+
+	ath9k_hw_cfg_gpio_input(ah, ah->rfkill_gpio);
+	REG_SET_BIT(ah, AR_PHY_TEST, RFSILENT_BB);
+}
+
+static void ar5008_restore_chainmask(struct ath_hw *ah)
+{
+	int rx_chainmask = ah->rxchainmask;
+
+	if ((rx_chainmask == 0x5) || (rx_chainmask == 0x3)) {
+		REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx_chainmask);
+		REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx_chainmask);
+	}
+}
+
+static void ar5008_set_diversity(struct ath_hw *ah, bool value)
+{
+	u32 v = REG_READ(ah, AR_PHY_CCK_DETECT);
+	if (value)
+		v |= AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV;
+	else
+		v &= ~AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV;
+	REG_WRITE(ah, AR_PHY_CCK_DETECT, v);
+}
+
+void ar5008_hw_attach_phy_ops(struct ath_hw *ah)
+{
+	struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
+
+	priv_ops->rf_set_freq = ar5008_hw_set_channel;
+	priv_ops->spur_mitigate_freq = ar5008_hw_spur_mitigate;
+
+	priv_ops->rf_alloc_ext_banks = ar5008_hw_rf_alloc_ext_banks;
+	priv_ops->rf_free_ext_banks = ar5008_hw_rf_free_ext_banks;
+	priv_ops->set_rf_regs = ar5008_hw_set_rf_regs;
+	priv_ops->set_channel_regs = ar5008_hw_set_channel_regs;
+	priv_ops->init_bb = ar5008_hw_init_bb;
+	priv_ops->process_ini = ar5008_hw_process_ini;
+	priv_ops->set_rfmode = ar5008_hw_set_rfmode;
+	priv_ops->mark_phy_inactive = ar5008_hw_mark_phy_inactive;
+	priv_ops->set_delta_slope = ar5008_hw_set_delta_slope;
+	priv_ops->rfbus_req = ar5008_hw_rfbus_req;
+	priv_ops->rfbus_done = ar5008_hw_rfbus_done;
+	priv_ops->enable_rfkill = ar5008_hw_enable_rfkill;
+	priv_ops->restore_chainmask = ar5008_restore_chainmask;
+	priv_ops->set_diversity = ar5008_set_diversity;
+}
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_phy.c b/drivers/net/wireless/ath/ath9k/ar9002_phy.c
new file mode 100644
index 0000000..29b50ca
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/ar9002_phy.c
@@ -0,0 +1,450 @@
+/*
+ * Copyright (c) 2008-2010 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/**
+ * DOC: Programming Atheros 802.11n analog front end radios
+ *
+ * AR5416 MAC based PCI devices and AR518 MAC based PCI-Express
+ * devices have either an external AR2133 analog front end radio for single
+ * band 2.4 GHz communication or an AR5133 analog front end radio for dual
+ * band 2.4 GHz / 5 GHz communication.
+ *
+ * All devices after the AR5416 and AR5418 family starting with the AR9280
+ * have their analog front radios, MAC/BB and host PCIe/USB interface embedded
+ * into a single-chip and require less programming.
+ *
+ * The following single-chips exist with a respective embedded radio:
+ *
+ * AR9280 - 11n dual-band 2x2 MIMO for PCIe
+ * AR9281 - 11n single-band 1x2 MIMO for PCIe
+ * AR9285 - 11n single-band 1x1 for PCIe
+ * AR9287 - 11n single-band 2x2 MIMO for PCIe
+ *
+ * AR9220 - 11n dual-band 2x2 MIMO for PCI
+ * AR9223 - 11n single-band 2x2 MIMO for PCI
+ *
+ * AR9287 - 11n single-band 1x1 MIMO for USB
+ */
+
+#include "hw.h"
+#include "ar9002_phy.h"
+
+/**
+ * ar9002_hw_set_channel - set channel on single-chip device
+ * @ah: atheros hardware structure
+ * @chan:
+ *
+ * This is the function to change channel on single-chip devices, that is
+ * all devices after ar9280.
+ *
+ * This function takes the channel value in MHz and sets
+ * hardware channel value. Assumes writes have been enabled to analog bus.
+ *
+ * Actual Expression,
+ *
+ * For 2GHz channel,
+ * Channel Frequency = (3/4) * freq_ref * (chansel[8:0] + chanfrac[16:0]/2^17)
+ * (freq_ref = 40MHz)
+ *
+ * For 5GHz channel,
+ * Channel Frequency = (3/2) * freq_ref * (chansel[8:0] + chanfrac[16:0]/2^10)
+ * (freq_ref = 40MHz/(24>>amodeRefSel))
+ */
+static int ar9002_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan)
+{
+	u16 bMode, fracMode, aModeRefSel = 0;
+	u32 freq, ndiv, channelSel = 0, channelFrac = 0, reg32 = 0;
+	struct chan_centers centers;
+	u32 refDivA = 24;
+
+	ath9k_hw_get_channel_centers(ah, chan, &centers);
+	freq = centers.synth_center;
+
+	reg32 = REG_READ(ah, AR_PHY_SYNTH_CONTROL);
+	reg32 &= 0xc0000000;
+
+	if (freq < 4800) { /* 2 GHz, fractional mode */
+		u32 txctl;
+		int regWrites = 0;
+
+		bMode = 1;
+		fracMode = 1;
+		aModeRefSel = 0;
+		channelSel = (freq * 0x10000) / 15;
+
+		if (AR_SREV_9287_11_OR_LATER(ah)) {
+			if (freq == 2484) {
+				/* Enable channel spreading for channel 14 */
+				REG_WRITE_ARRAY(&ah->iniCckfirJapan2484,
+						1, regWrites);
+			} else {
+				REG_WRITE_ARRAY(&ah->iniCckfirNormal,
+						1, regWrites);
+			}
+		} else {
+			txctl = REG_READ(ah, AR_PHY_CCK_TX_CTRL);
+			if (freq == 2484) {
+				/* Enable channel spreading for channel 14 */
+				REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
+					  txctl | AR_PHY_CCK_TX_CTRL_JAPAN);
+			} else {
+				REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
+					  txctl & ~AR_PHY_CCK_TX_CTRL_JAPAN);
+			}
+		}
+	} else {
+		bMode = 0;
+		fracMode = 0;
+
+		switch (ah->eep_ops->get_eeprom(ah, EEP_FRAC_N_5G)) {
+		case 0:
+			if ((freq % 20) == 0)
+				aModeRefSel = 3;
+			else if ((freq % 10) == 0)
+				aModeRefSel = 2;
+			if (aModeRefSel)
+				break;
+		case 1:
+		default:
+			aModeRefSel = 0;
+			/*
+			 * Enable 2G (fractional) mode for channels
+			 * which are 5MHz spaced.
+			 */
+			fracMode = 1;
+			refDivA = 1;
+			channelSel = (freq * 0x8000) / 15;
+
+			/* RefDivA setting */
+			REG_RMW_FIELD(ah, AR_AN_SYNTH9,
+				      AR_AN_SYNTH9_REFDIVA, refDivA);
+
+		}
+
+		if (!fracMode) {
+			ndiv = (freq * (refDivA >> aModeRefSel)) / 60;
+			channelSel = ndiv & 0x1ff;
+			channelFrac = (ndiv & 0xfffffe00) * 2;
+			channelSel = (channelSel << 17) | channelFrac;
+		}
+	}
+
+	reg32 = reg32 |
+	    (bMode << 29) |
+	    (fracMode << 28) | (aModeRefSel << 26) | (channelSel);
+
+	REG_WRITE(ah, AR_PHY_SYNTH_CONTROL, reg32);
+
+	ah->curchan = chan;
+	ah->curchan_rad_index = -1;
+
+	return 0;
+}
+
+/**
+ * ar9002_hw_spur_mitigate - convert baseband spur frequency
+ * @ah: atheros hardware structure
+ * @chan:
+ *
+ * For single-chip solutions. Converts to baseband spur frequency given the
+ * input channel frequency and compute register settings below.
+ */
+static void ar9002_hw_spur_mitigate(struct ath_hw *ah,
+				    struct ath9k_channel *chan)
+{
+	int bb_spur = AR_NO_SPUR;
+	int freq;
+	int bin, cur_bin;
+	int bb_spur_off, spur_subchannel_sd;
+	int spur_freq_sd;
+	int spur_delta_phase;
+	int denominator;
+	int upper, lower, cur_vit_mask;
+	int tmp, newVal;
+	int i;
+	int pilot_mask_reg[4] = { AR_PHY_TIMING7, AR_PHY_TIMING8,
+			  AR_PHY_PILOT_MASK_01_30, AR_PHY_PILOT_MASK_31_60
+	};
+	int chan_mask_reg[4] = { AR_PHY_TIMING9, AR_PHY_TIMING10,
+			 AR_PHY_CHANNEL_MASK_01_30, AR_PHY_CHANNEL_MASK_31_60
+	};
+	int inc[4] = { 0, 100, 0, 0 };
+	struct chan_centers centers;
+
+	int8_t mask_m[123];
+	int8_t mask_p[123];
+	int8_t mask_amt;
+	int tmp_mask;
+	int cur_bb_spur;
+	bool is2GHz = IS_CHAN_2GHZ(chan);
+
+	memset(&mask_m, 0, sizeof(int8_t) * 123);
+	memset(&mask_p, 0, sizeof(int8_t) * 123);
+
+	ath9k_hw_get_channel_centers(ah, chan, &centers);
+	freq = centers.synth_center;
+
+	ah->config.spurmode = SPUR_ENABLE_EEPROM;
+	for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
+		cur_bb_spur = ah->eep_ops->get_spur_channel(ah, i, is2GHz);
+
+		if (is2GHz)
+			cur_bb_spur = (cur_bb_spur / 10) + AR_BASE_FREQ_2GHZ;
+		else
+			cur_bb_spur = (cur_bb_spur / 10) + AR_BASE_FREQ_5GHZ;
+
+		if (AR_NO_SPUR == cur_bb_spur)
+			break;
+		cur_bb_spur = cur_bb_spur - freq;
+
+		if (IS_CHAN_HT40(chan)) {
+			if ((cur_bb_spur > -AR_SPUR_FEEQ_BOUND_HT40) &&
+			    (cur_bb_spur < AR_SPUR_FEEQ_BOUND_HT40)) {
+				bb_spur = cur_bb_spur;
+				break;
+			}
+		} else if ((cur_bb_spur > -AR_SPUR_FEEQ_BOUND_HT20) &&
+			   (cur_bb_spur < AR_SPUR_FEEQ_BOUND_HT20)) {
+			bb_spur = cur_bb_spur;
+			break;
+		}
+	}
+
+	if (AR_NO_SPUR == bb_spur) {
+		REG_CLR_BIT(ah, AR_PHY_FORCE_CLKEN_CCK,
+			    AR_PHY_FORCE_CLKEN_CCK_MRC_MUX);
+		return;
+	} else {
+		REG_CLR_BIT(ah, AR_PHY_FORCE_CLKEN_CCK,
+			    AR_PHY_FORCE_CLKEN_CCK_MRC_MUX);
+	}
+
+	bin = bb_spur * 320;
+
+	tmp = REG_READ(ah, AR_PHY_TIMING_CTRL4(0));
+
+	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);
+}
+
+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;
+	}
+}
+
+void ar9002_hw_attach_phy_ops(struct ath_hw *ah)
+{
+	struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
+
+	priv_ops->set_rf_regs = NULL;
+	priv_ops->rf_alloc_ext_banks = NULL;
+	priv_ops->rf_free_ext_banks = NULL;
+	priv_ops->rf_set_freq = ar9002_hw_set_channel;
+	priv_ops->spur_mitigate_freq = ar9002_hw_spur_mitigate;
+	priv_ops->olc_init = ar9002_olc_init;
+}
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_phy.h b/drivers/net/wireless/ath/ath9k/ar9002_phy.h
new file mode 100644
index 0000000..4fe204e
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/ar9002_phy.h
@@ -0,0 +1,581 @@
+/*
+ * Copyright (c) 2008-2010 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+#ifndef AR9002_PHY_H
+#define AR9002_PHY_H
+
+#define AR_PHY_TEST             0x9800
+#define PHY_AGC_CLR             0x10000000
+#define RFSILENT_BB             0x00002000
+
+#define AR_PHY_TURBO                0x9804
+#define AR_PHY_FC_TURBO_MODE        0x00000001
+#define AR_PHY_FC_TURBO_SHORT       0x00000002
+#define AR_PHY_FC_DYN2040_EN        0x00000004
+#define AR_PHY_FC_DYN2040_PRI_ONLY  0x00000008
+#define AR_PHY_FC_DYN2040_PRI_CH    0x00000010
+/* For 25 MHz channel spacing -- not used but supported by hw */
+#define AR_PHY_FC_DYN2040_EXT_CH    0x00000020
+#define AR_PHY_FC_HT_EN             0x00000040
+#define AR_PHY_FC_SHORT_GI_40       0x00000080
+#define AR_PHY_FC_WALSH             0x00000100
+#define AR_PHY_FC_SINGLE_HT_LTF1    0x00000200
+#define AR_PHY_FC_ENABLE_DAC_FIFO   0x00000800
+
+#define AR_PHY_TEST2			0x9808
+
+#define AR_PHY_TIMING2           0x9810
+#define AR_PHY_TIMING3           0x9814
+#define AR_PHY_TIMING3_DSC_MAN   0xFFFE0000
+#define AR_PHY_TIMING3_DSC_MAN_S 17
+#define AR_PHY_TIMING3_DSC_EXP   0x0001E000
+#define AR_PHY_TIMING3_DSC_EXP_S 13
+
+#define AR_PHY_CHIP_ID_REV_0      0x80
+#define AR_PHY_CHIP_ID_REV_1      0x81
+#define AR_PHY_CHIP_ID_9160_REV_0 0xb0
+
+#define AR_PHY_ACTIVE       0x981C
+#define AR_PHY_ACTIVE_EN    0x00000001
+#define AR_PHY_ACTIVE_DIS   0x00000000
+
+#define AR_PHY_RF_CTL2             0x9824
+#define AR_PHY_TX_END_DATA_START   0x000000FF
+#define AR_PHY_TX_END_DATA_START_S 0
+#define AR_PHY_TX_END_PA_ON        0x0000FF00
+#define AR_PHY_TX_END_PA_ON_S      8
+
+#define AR_PHY_RF_CTL3                  0x9828
+#define AR_PHY_TX_END_TO_A2_RX_ON       0x00FF0000
+#define AR_PHY_TX_END_TO_A2_RX_ON_S     16
+
+#define AR_PHY_ADC_CTL                  0x982C
+#define AR_PHY_ADC_CTL_OFF_INBUFGAIN    0x00000003
+#define AR_PHY_ADC_CTL_OFF_INBUFGAIN_S  0
+#define AR_PHY_ADC_CTL_OFF_PWDDAC       0x00002000
+#define AR_PHY_ADC_CTL_OFF_PWDBANDGAP   0x00004000
+#define AR_PHY_ADC_CTL_OFF_PWDADC       0x00008000
+#define AR_PHY_ADC_CTL_ON_INBUFGAIN     0x00030000
+#define AR_PHY_ADC_CTL_ON_INBUFGAIN_S   16
+
+#define AR_PHY_ADC_SERIAL_CTL       0x9830
+#define AR_PHY_SEL_INTERNAL_ADDAC   0x00000000
+#define AR_PHY_SEL_EXTERNAL_RADIO   0x00000001
+
+#define AR_PHY_RF_CTL4                    0x9834
+#define AR_PHY_RF_CTL4_TX_END_XPAB_OFF    0xFF000000
+#define AR_PHY_RF_CTL4_TX_END_XPAB_OFF_S  24
+#define AR_PHY_RF_CTL4_TX_END_XPAA_OFF    0x00FF0000
+#define AR_PHY_RF_CTL4_TX_END_XPAA_OFF_S  16
+#define AR_PHY_RF_CTL4_FRAME_XPAB_ON      0x0000FF00
+#define AR_PHY_RF_CTL4_FRAME_XPAB_ON_S    8
+#define AR_PHY_RF_CTL4_FRAME_XPAA_ON      0x000000FF
+#define AR_PHY_RF_CTL4_FRAME_XPAA_ON_S    0
+
+#define AR_PHY_TSTDAC_CONST               0x983c
+
+#define AR_PHY_SETTLING          0x9844
+#define AR_PHY_SETTLING_SWITCH   0x00003F80
+#define AR_PHY_SETTLING_SWITCH_S 7
+
+#define AR_PHY_RXGAIN                   0x9848
+#define AR_PHY_RXGAIN_TXRX_ATTEN        0x0003F000
+#define AR_PHY_RXGAIN_TXRX_ATTEN_S      12
+#define AR_PHY_RXGAIN_TXRX_RF_MAX       0x007C0000
+#define AR_PHY_RXGAIN_TXRX_RF_MAX_S     18
+#define AR9280_PHY_RXGAIN_TXRX_ATTEN    0x00003F80
+#define AR9280_PHY_RXGAIN_TXRX_ATTEN_S  7
+#define AR9280_PHY_RXGAIN_TXRX_MARGIN   0x001FC000
+#define AR9280_PHY_RXGAIN_TXRX_MARGIN_S 14
+
+#define AR_PHY_DESIRED_SZ           0x9850
+#define AR_PHY_DESIRED_SZ_ADC       0x000000FF
+#define AR_PHY_DESIRED_SZ_ADC_S     0
+#define AR_PHY_DESIRED_SZ_PGA       0x0000FF00
+#define AR_PHY_DESIRED_SZ_PGA_S     8
+#define AR_PHY_DESIRED_SZ_TOT_DES   0x0FF00000
+#define AR_PHY_DESIRED_SZ_TOT_DES_S 20
+
+#define AR_PHY_FIND_SIG           0x9858
+#define AR_PHY_FIND_SIG_FIRSTEP   0x0003F000
+#define AR_PHY_FIND_SIG_FIRSTEP_S 12
+#define AR_PHY_FIND_SIG_FIRPWR    0x03FC0000
+#define AR_PHY_FIND_SIG_FIRPWR_S  18
+
+#define AR_PHY_AGC_CTL1                  0x985C
+#define AR_PHY_AGC_CTL1_COARSE_LOW       0x00007F80
+#define AR_PHY_AGC_CTL1_COARSE_LOW_S     7
+#define AR_PHY_AGC_CTL1_COARSE_HIGH      0x003F8000
+#define AR_PHY_AGC_CTL1_COARSE_HIGH_S    15
+
+#define AR_PHY_AGC_CONTROL               0x9860
+#define AR_PHY_AGC_CONTROL_CAL           0x00000001
+#define AR_PHY_AGC_CONTROL_NF            0x00000002
+#define AR_PHY_AGC_CONTROL_ENABLE_NF     0x00008000
+#define AR_PHY_AGC_CONTROL_FLTR_CAL      0x00010000
+#define AR_PHY_AGC_CONTROL_NO_UPDATE_NF  0x00020000
+
+#define AR_PHY_CCA                  0x9864
+#define AR_PHY_MINCCA_PWR           0x0FF80000
+#define AR_PHY_MINCCA_PWR_S         19
+#define AR_PHY_CCA_THRESH62         0x0007F000
+#define AR_PHY_CCA_THRESH62_S       12
+#define AR9280_PHY_MINCCA_PWR       0x1FF00000
+#define AR9280_PHY_MINCCA_PWR_S     20
+#define AR9280_PHY_CCA_THRESH62     0x000FF000
+#define AR9280_PHY_CCA_THRESH62_S   12
+
+#define AR_PHY_SFCORR_LOW                    0x986C
+#define AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW  0x00000001
+#define AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW    0x00003F00
+#define AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW_S  8
+#define AR_PHY_SFCORR_LOW_M1_THRESH_LOW      0x001FC000
+#define AR_PHY_SFCORR_LOW_M1_THRESH_LOW_S    14
+#define AR_PHY_SFCORR_LOW_M2_THRESH_LOW      0x0FE00000
+#define AR_PHY_SFCORR_LOW_M2_THRESH_LOW_S    21
+
+#define AR_PHY_SFCORR                0x9868
+#define AR_PHY_SFCORR_M2COUNT_THR    0x0000001F
+#define AR_PHY_SFCORR_M2COUNT_THR_S  0
+#define AR_PHY_SFCORR_M1_THRESH      0x00FE0000
+#define AR_PHY_SFCORR_M1_THRESH_S    17
+#define AR_PHY_SFCORR_M2_THRESH      0x7F000000
+#define AR_PHY_SFCORR_M2_THRESH_S    24
+
+#define AR_PHY_SLEEP_CTR_CONTROL    0x9870
+#define AR_PHY_SLEEP_CTR_LIMIT      0x9874
+#define AR_PHY_SYNTH_CONTROL        0x9874
+#define AR_PHY_SLEEP_SCAL           0x9878
+
+#define AR_PHY_PLL_CTL          0x987c
+#define AR_PHY_PLL_CTL_40       0xaa
+#define AR_PHY_PLL_CTL_40_5413  0x04
+#define AR_PHY_PLL_CTL_44       0xab
+#define AR_PHY_PLL_CTL_44_2133  0xeb
+#define AR_PHY_PLL_CTL_40_2133  0xea
+
+#define AR_PHY_SPECTRAL_SCAN			0x9910  /* AR9280 spectral scan configuration register */
+#define	AR_PHY_SPECTRAL_SCAN_ENABLE		0x1
+#define AR_PHY_SPECTRAL_SCAN_ENA		0x00000001  /* Enable spectral scan, reg 68, bit 0 */
+#define AR_PHY_SPECTRAL_SCAN_ENA_S		0  /* Enable spectral scan, reg 68, bit 0 */
+#define AR_PHY_SPECTRAL_SCAN_ACTIVE		0x00000002  /* Activate spectral scan reg 68, bit 1*/
+#define AR_PHY_SPECTRAL_SCAN_ACTIVE_S		1  /* Activate spectral scan reg 68, bit 1*/
+#define AR_PHY_SPECTRAL_SCAN_FFT_PERIOD		0x000000F0  /* Interval for FFT reports, reg 68, bits 4-7*/
+#define AR_PHY_SPECTRAL_SCAN_FFT_PERIOD_S	4
+#define AR_PHY_SPECTRAL_SCAN_PERIOD		0x0000FF00  /* Interval for FFT reports, reg 68, bits 8-15*/
+#define AR_PHY_SPECTRAL_SCAN_PERIOD_S		8
+#define AR_PHY_SPECTRAL_SCAN_COUNT		0x00FF0000  /* Number of reports, reg 68, bits 16-23*/
+#define AR_PHY_SPECTRAL_SCAN_COUNT_S		16
+#define AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT	0x01000000  /* Short repeat, reg 68, bit 24*/
+#define AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT_S	24  /* Short repeat, reg 68, bit 24*/
+
+#define AR_PHY_RX_DELAY           0x9914
+#define AR_PHY_SEARCH_START_DELAY 0x9918
+#define AR_PHY_RX_DELAY_DELAY     0x00003FFF
+
+#define AR_PHY_TIMING_CTRL4(_i)     (0x9920 + ((_i) << 12))
+#define AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF 0x01F
+#define AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF_S   0
+#define AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF 0x7E0
+#define AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF_S   5
+#define AR_PHY_TIMING_CTRL4_IQCORR_ENABLE   0x800
+#define AR_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX 0xF000
+#define AR_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX_S   12
+#define AR_PHY_TIMING_CTRL4_DO_CAL    0x10000
+
+#define AR_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI	0x80000000
+#define	AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER	0x40000000
+#define	AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK	0x20000000
+#define	AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK	0x10000000
+
+#define AR_PHY_TIMING5               0x9924
+#define AR_PHY_TIMING5_CYCPWR_THR1   0x000000FE
+#define AR_PHY_TIMING5_CYCPWR_THR1_S 1
+
+#define AR_PHY_POWER_TX_RATE1               0x9934
+#define AR_PHY_POWER_TX_RATE2               0x9938
+#define AR_PHY_POWER_TX_RATE_MAX            0x993c
+#define AR_PHY_POWER_TX_RATE_MAX_TPC_ENABLE 0x00000040
+
+#define AR_PHY_FRAME_CTL            0x9944
+#define AR_PHY_FRAME_CTL_TX_CLIP    0x00000038
+#define AR_PHY_FRAME_CTL_TX_CLIP_S  3
+
+#define AR_PHY_TXPWRADJ                   0x994C
+#define AR_PHY_TXPWRADJ_CCK_GAIN_DELTA    0x00000FC0
+#define AR_PHY_TXPWRADJ_CCK_GAIN_DELTA_S  6
+#define AR_PHY_TXPWRADJ_CCK_PCDAC_INDEX   0x00FC0000
+#define AR_PHY_TXPWRADJ_CCK_PCDAC_INDEX_S 18
+
+#define AR_PHY_RADAR_EXT      0x9940
+#define AR_PHY_RADAR_EXT_ENA  0x00004000
+
+#define AR_PHY_RADAR_0          0x9954
+#define AR_PHY_RADAR_0_ENA      0x00000001
+#define AR_PHY_RADAR_0_FFT_ENA  0x80000000
+#define AR_PHY_RADAR_0_INBAND   0x0000003e
+#define AR_PHY_RADAR_0_INBAND_S 1
+#define AR_PHY_RADAR_0_PRSSI    0x00000FC0
+#define AR_PHY_RADAR_0_PRSSI_S  6
+#define AR_PHY_RADAR_0_HEIGHT   0x0003F000
+#define AR_PHY_RADAR_0_HEIGHT_S 12
+#define AR_PHY_RADAR_0_RRSSI    0x00FC0000
+#define AR_PHY_RADAR_0_RRSSI_S  18
+#define AR_PHY_RADAR_0_FIRPWR   0x7F000000
+#define AR_PHY_RADAR_0_FIRPWR_S 24
+
+#define AR_PHY_RADAR_1                  0x9958
+#define AR_PHY_RADAR_1_RELPWR_ENA       0x00800000
+#define AR_PHY_RADAR_1_USE_FIR128       0x00400000
+#define AR_PHY_RADAR_1_RELPWR_THRESH    0x003F0000
+#define AR_PHY_RADAR_1_RELPWR_THRESH_S  16
+#define AR_PHY_RADAR_1_BLOCK_CHECK      0x00008000
+#define AR_PHY_RADAR_1_MAX_RRSSI        0x00004000
+#define AR_PHY_RADAR_1_RELSTEP_CHECK    0x00002000
+#define AR_PHY_RADAR_1_RELSTEP_THRESH   0x00001F00
+#define AR_PHY_RADAR_1_RELSTEP_THRESH_S 8
+#define AR_PHY_RADAR_1_MAXLEN           0x000000FF
+#define AR_PHY_RADAR_1_MAXLEN_S         0
+
+#define AR_PHY_SWITCH_CHAIN_0     0x9960
+#define AR_PHY_SWITCH_COM         0x9964
+
+#define AR_PHY_SIGMA_DELTA            0x996C
+#define AR_PHY_SIGMA_DELTA_ADC_SEL    0x00000003
+#define AR_PHY_SIGMA_DELTA_ADC_SEL_S  0
+#define AR_PHY_SIGMA_DELTA_FILT2      0x000000F8
+#define AR_PHY_SIGMA_DELTA_FILT2_S    3
+#define AR_PHY_SIGMA_DELTA_FILT1      0x00001F00
+#define AR_PHY_SIGMA_DELTA_FILT1_S    8
+#define AR_PHY_SIGMA_DELTA_ADC_CLIP   0x01FFE000
+#define AR_PHY_SIGMA_DELTA_ADC_CLIP_S 13
+
+#define AR_PHY_RESTART          0x9970
+#define AR_PHY_RESTART_DIV_GC   0x001C0000
+#define AR_PHY_RESTART_DIV_GC_S 18
+
+#define AR_PHY_RFBUS_REQ        0x997C
+#define AR_PHY_RFBUS_REQ_EN     0x00000001
+
+#define	AR_PHY_TIMING7		        0x9980
+#define	AR_PHY_TIMING8		        0x9984
+#define	AR_PHY_TIMING8_PILOT_MASK_2	0x000FFFFF
+#define	AR_PHY_TIMING8_PILOT_MASK_2_S	0
+
+#define	AR_PHY_BIN_MASK2_1	0x9988
+#define	AR_PHY_BIN_MASK2_2	0x998c
+#define	AR_PHY_BIN_MASK2_3	0x9990
+#define	AR_PHY_BIN_MASK2_4	0x9994
+
+#define	AR_PHY_BIN_MASK_1	0x9900
+#define	AR_PHY_BIN_MASK_2	0x9904
+#define	AR_PHY_BIN_MASK_3	0x9908
+
+#define	AR_PHY_MASK_CTL		0x990c
+
+#define	AR_PHY_BIN_MASK2_4_MASK_4	0x00003FFF
+#define	AR_PHY_BIN_MASK2_4_MASK_4_S	0
+
+#define	AR_PHY_TIMING9		        0x9998
+#define	AR_PHY_TIMING10		        0x999c
+#define	AR_PHY_TIMING10_PILOT_MASK_2	0x000FFFFF
+#define	AR_PHY_TIMING10_PILOT_MASK_2_S	0
+
+#define	AR_PHY_TIMING11			        0x99a0
+#define	AR_PHY_TIMING11_SPUR_DELTA_PHASE	0x000FFFFF
+#define	AR_PHY_TIMING11_SPUR_DELTA_PHASE_S	0
+#define	AR_PHY_TIMING11_SPUR_FREQ_SD		0x3FF00000
+#define	AR_PHY_TIMING11_SPUR_FREQ_SD_S		20
+#define AR_PHY_TIMING11_USE_SPUR_IN_AGC		0x40000000
+#define AR_PHY_TIMING11_USE_SPUR_IN_SELFCOR	0x80000000
+
+#define AR_PHY_RX_CHAINMASK     0x99a4
+#define AR_PHY_NEW_ADC_DC_GAIN_CORR(_i) (0x99b4 + ((_i) << 12))
+#define AR_PHY_NEW_ADC_GAIN_CORR_ENABLE 0x40000000
+#define AR_PHY_NEW_ADC_DC_OFFSET_CORR_ENABLE 0x80000000
+
+#define AR_PHY_MULTICHAIN_GAIN_CTL          0x99ac
+#define AR_PHY_9285_ANT_DIV_CTL_ALL         0x7f000000
+#define AR_PHY_9285_ANT_DIV_CTL             0x01000000
+#define AR_PHY_9285_ANT_DIV_CTL_S           24
+#define AR_PHY_9285_ANT_DIV_ALT_LNACONF     0x06000000
+#define AR_PHY_9285_ANT_DIV_ALT_LNACONF_S   25
+#define AR_PHY_9285_ANT_DIV_MAIN_LNACONF    0x18000000
+#define AR_PHY_9285_ANT_DIV_MAIN_LNACONF_S  27
+#define AR_PHY_9285_ANT_DIV_ALT_GAINTB      0x20000000
+#define AR_PHY_9285_ANT_DIV_ALT_GAINTB_S    29
+#define AR_PHY_9285_ANT_DIV_MAIN_GAINTB     0x40000000
+#define AR_PHY_9285_ANT_DIV_MAIN_GAINTB_S   30
+#define AR_PHY_9285_ANT_DIV_LNA1            2
+#define AR_PHY_9285_ANT_DIV_LNA2            1
+#define AR_PHY_9285_ANT_DIV_LNA1_PLUS_LNA2  3
+#define AR_PHY_9285_ANT_DIV_LNA1_MINUS_LNA2 0
+#define AR_PHY_9285_ANT_DIV_GAINTB_0        0
+#define AR_PHY_9285_ANT_DIV_GAINTB_1        1
+
+#define AR_PHY_EXT_CCA0             0x99b8
+#define AR_PHY_EXT_CCA0_THRESH62    0x000000FF
+#define AR_PHY_EXT_CCA0_THRESH62_S  0
+
+#define AR_PHY_EXT_CCA                  0x99bc
+#define AR_PHY_EXT_CCA_CYCPWR_THR1      0x0000FE00
+#define AR_PHY_EXT_CCA_CYCPWR_THR1_S    9
+#define AR_PHY_EXT_CCA_THRESH62         0x007F0000
+#define AR_PHY_EXT_CCA_THRESH62_S       16
+#define AR_PHY_EXT_MINCCA_PWR           0xFF800000
+#define AR_PHY_EXT_MINCCA_PWR_S         23
+#define AR9280_PHY_EXT_MINCCA_PWR       0x01FF0000
+#define AR9280_PHY_EXT_MINCCA_PWR_S     16
+
+#define AR_PHY_SFCORR_EXT                 0x99c0
+#define AR_PHY_SFCORR_EXT_M1_THRESH       0x0000007F
+#define AR_PHY_SFCORR_EXT_M1_THRESH_S     0
+#define AR_PHY_SFCORR_EXT_M2_THRESH       0x00003F80
+#define AR_PHY_SFCORR_EXT_M2_THRESH_S     7
+#define AR_PHY_SFCORR_EXT_M1_THRESH_LOW   0x001FC000
+#define AR_PHY_SFCORR_EXT_M1_THRESH_LOW_S 14
+#define AR_PHY_SFCORR_EXT_M2_THRESH_LOW   0x0FE00000
+#define AR_PHY_SFCORR_EXT_M2_THRESH_LOW_S 21
+#define AR_PHY_SFCORR_SPUR_SUBCHNL_SD_S   28
+
+#define AR_PHY_HALFGI           0x99D0
+#define AR_PHY_HALFGI_DSC_MAN   0x0007FFF0
+#define AR_PHY_HALFGI_DSC_MAN_S 4
+#define AR_PHY_HALFGI_DSC_EXP   0x0000000F
+#define AR_PHY_HALFGI_DSC_EXP_S 0
+
+#define AR_PHY_CHAN_INFO_MEMORY               0x99DC
+#define AR_PHY_CHAN_INFO_MEMORY_CAPTURE_MASK  0x0001
+
+#define AR_PHY_HEAVY_CLIP_ENABLE         0x99E0
+
+#define AR_PHY_HEAVY_CLIP_FACTOR_RIFS    0x99EC
+#define AR_PHY_RIFS_INIT_DELAY         0x03ff0000
+
+#define AR_PHY_M_SLEEP      0x99f0
+#define AR_PHY_REFCLKDLY    0x99f4
+#define AR_PHY_REFCLKPD     0x99f8
+
+#define AR_PHY_CALMODE      0x99f0
+
+#define AR_PHY_CALMODE_IQ           0x00000000
+#define AR_PHY_CALMODE_ADC_GAIN     0x00000001
+#define AR_PHY_CALMODE_ADC_DC_PER   0x00000002
+#define AR_PHY_CALMODE_ADC_DC_INIT  0x00000003
+
+#define AR_PHY_CAL_MEAS_0(_i)     (0x9c10 + ((_i) << 12))
+#define AR_PHY_CAL_MEAS_1(_i)     (0x9c14 + ((_i) << 12))
+#define AR_PHY_CAL_MEAS_2(_i)     (0x9c18 + ((_i) << 12))
+#define AR_PHY_CAL_MEAS_3(_i)     (0x9c1c + ((_i) << 12))
+
+#define AR_PHY_CURRENT_RSSI 0x9c1c
+#define AR9280_PHY_CURRENT_RSSI 0x9c3c
+
+#define AR_PHY_RFBUS_GRANT       0x9C20
+#define AR_PHY_RFBUS_GRANT_EN    0x00000001
+
+#define AR_PHY_CHAN_INFO_GAIN_DIFF             0x9CF4
+#define AR_PHY_CHAN_INFO_GAIN_DIFF_UPPER_LIMIT 320
+
+#define AR_PHY_CHAN_INFO_GAIN          0x9CFC
+
+#define AR_PHY_MODE         0xA200
+#define AR_PHY_MODE_ASYNCFIFO 0x80
+#define AR_PHY_MODE_AR2133  0x08
+#define AR_PHY_MODE_AR5111  0x00
+#define AR_PHY_MODE_AR5112  0x08
+#define AR_PHY_MODE_DYNAMIC 0x04
+#define AR_PHY_MODE_RF2GHZ  0x02
+#define AR_PHY_MODE_RF5GHZ  0x00
+#define AR_PHY_MODE_CCK     0x01
+#define AR_PHY_MODE_OFDM    0x00
+#define AR_PHY_MODE_DYN_CCK_DISABLE 0x100
+
+#define AR_PHY_CCK_TX_CTRL       0xA204
+#define AR_PHY_CCK_TX_CTRL_JAPAN 0x00000010
+#define AR_PHY_CCK_TX_CTRL_TX_DAC_SCALE_CCK         0x0000000C
+#define AR_PHY_CCK_TX_CTRL_TX_DAC_SCALE_CCK_S       2
+
+#define AR_PHY_CCK_DETECT                           0xA208
+#define AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK          0x0000003F
+#define AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK_S        0
+/* [12:6] settling time for antenna switch */
+#define AR_PHY_CCK_DETECT_ANT_SWITCH_TIME           0x00001FC0
+#define AR_PHY_CCK_DETECT_ANT_SWITCH_TIME_S         6
+#define AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV    0x2000
+#define AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV_S  13
+
+#define AR_PHY_GAIN_2GHZ                0xA20C
+#define AR_PHY_GAIN_2GHZ_RXTX_MARGIN    0x00FC0000
+#define AR_PHY_GAIN_2GHZ_RXTX_MARGIN_S  18
+#define AR_PHY_GAIN_2GHZ_BSW_MARGIN     0x00003C00
+#define AR_PHY_GAIN_2GHZ_BSW_MARGIN_S   10
+#define AR_PHY_GAIN_2GHZ_BSW_ATTEN      0x0000001F
+#define AR_PHY_GAIN_2GHZ_BSW_ATTEN_S    0
+
+#define AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN     0x003E0000
+#define AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN_S   17
+#define AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN     0x0001F000
+#define AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN_S   12
+#define AR_PHY_GAIN_2GHZ_XATTEN2_DB         0x00000FC0
+#define AR_PHY_GAIN_2GHZ_XATTEN2_DB_S       6
+#define AR_PHY_GAIN_2GHZ_XATTEN1_DB         0x0000003F
+#define AR_PHY_GAIN_2GHZ_XATTEN1_DB_S       0
+
+#define AR_PHY_CCK_RXCTRL4  0xA21C
+#define AR_PHY_CCK_RXCTRL4_FREQ_EST_SHORT   0x01F80000
+#define AR_PHY_CCK_RXCTRL4_FREQ_EST_SHORT_S 19
+
+#define AR_PHY_DAG_CTRLCCK  0xA228
+#define AR_PHY_DAG_CTRLCCK_EN_RSSI_THR  0x00000200
+#define AR_PHY_DAG_CTRLCCK_RSSI_THR     0x0001FC00
+#define AR_PHY_DAG_CTRLCCK_RSSI_THR_S   10
+
+#define AR_PHY_FORCE_CLKEN_CCK              0xA22C
+#define AR_PHY_FORCE_CLKEN_CCK_MRC_MUX      0x00000040
+
+#define AR_PHY_POWER_TX_RATE3   0xA234
+#define AR_PHY_POWER_TX_RATE4   0xA238
+
+#define AR_PHY_SCRM_SEQ_XR       0xA23C
+#define AR_PHY_HEADER_DETECT_XR  0xA240
+#define AR_PHY_CHIRP_DETECTED_XR 0xA244
+#define AR_PHY_BLUETOOTH         0xA254
+
+#define AR_PHY_TPCRG1   0xA258
+#define AR_PHY_TPCRG1_NUM_PD_GAIN   0x0000c000
+#define AR_PHY_TPCRG1_NUM_PD_GAIN_S 14
+
+#define AR_PHY_TPCRG1_PD_GAIN_1    0x00030000
+#define AR_PHY_TPCRG1_PD_GAIN_1_S  16
+#define AR_PHY_TPCRG1_PD_GAIN_2    0x000C0000
+#define AR_PHY_TPCRG1_PD_GAIN_2_S  18
+#define AR_PHY_TPCRG1_PD_GAIN_3    0x00300000
+#define AR_PHY_TPCRG1_PD_GAIN_3_S  20
+
+#define AR_PHY_TPCRG1_PD_CAL_ENABLE   0x00400000
+#define AR_PHY_TPCRG1_PD_CAL_ENABLE_S 22
+
+#define AR_PHY_TX_PWRCTRL4       0xa264
+#define AR_PHY_TX_PWRCTRL_PD_AVG_VALID     0x00000001
+#define AR_PHY_TX_PWRCTRL_PD_AVG_VALID_S   0
+#define AR_PHY_TX_PWRCTRL_PD_AVG_OUT       0x000001FE
+#define AR_PHY_TX_PWRCTRL_PD_AVG_OUT_S     1
+
+#define AR_PHY_TX_PWRCTRL6_0     0xa270
+#define AR_PHY_TX_PWRCTRL6_1     0xb270
+#define AR_PHY_TX_PWRCTRL_ERR_EST_MODE     0x03000000
+#define AR_PHY_TX_PWRCTRL_ERR_EST_MODE_S   24
+
+#define AR_PHY_TX_PWRCTRL7       0xa274
+#define AR_PHY_TX_PWRCTRL_INIT_TX_GAIN     0x01F80000
+#define AR_PHY_TX_PWRCTRL_INIT_TX_GAIN_S   19
+
+#define AR_PHY_TX_PWRCTRL9       0xa27C
+#define AR_PHY_TX_DESIRED_SCALE_CCK        0x00007C00
+#define AR_PHY_TX_DESIRED_SCALE_CCK_S      10
+#define AR_PHY_TX_PWRCTRL9_RES_DC_REMOVAL  0x80000000
+#define AR_PHY_TX_PWRCTRL9_RES_DC_REMOVAL_S 31
+
+#define AR_PHY_TX_GAIN_TBL1      0xa300
+#define AR_PHY_TX_GAIN                     0x0007F000
+#define AR_PHY_TX_GAIN_S                   12
+
+#define AR_PHY_CH0_TX_PWRCTRL11  0xa398
+#define AR_PHY_CH1_TX_PWRCTRL11  0xb398
+#define AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP   0x0000FC00
+#define AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP_S 10
+
+#define AR_PHY_VIT_MASK2_M_46_61 0xa3a0
+#define AR_PHY_MASK2_M_31_45     0xa3a4
+#define AR_PHY_MASK2_M_16_30     0xa3a8
+#define AR_PHY_MASK2_M_00_15     0xa3ac
+#define AR_PHY_MASK2_P_15_01     0xa3b8
+#define AR_PHY_MASK2_P_30_16     0xa3bc
+#define AR_PHY_MASK2_P_45_31     0xa3c0
+#define AR_PHY_MASK2_P_61_45     0xa3c4
+#define AR_PHY_SPUR_REG          0x994c
+
+#define AR_PHY_SPUR_REG_MASK_RATE_CNTL       (0xFF << 18)
+#define AR_PHY_SPUR_REG_MASK_RATE_CNTL_S     18
+
+#define AR_PHY_SPUR_REG_ENABLE_MASK_PPM      0x20000
+#define AR_PHY_SPUR_REG_MASK_RATE_SELECT     (0xFF << 9)
+#define AR_PHY_SPUR_REG_MASK_RATE_SELECT_S   9
+#define AR_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI 0x100
+#define AR_PHY_SPUR_REG_SPUR_RSSI_THRESH     0x7F
+#define AR_PHY_SPUR_REG_SPUR_RSSI_THRESH_S   0
+
+#define AR_PHY_PILOT_MASK_01_30   0xa3b0
+#define AR_PHY_PILOT_MASK_31_60   0xa3b4
+
+#define AR_PHY_CHANNEL_MASK_01_30 0x99d4
+#define AR_PHY_CHANNEL_MASK_31_60 0x99d8
+
+#define AR_PHY_ANALOG_SWAP      0xa268
+#define AR_PHY_SWAP_ALT_CHAIN   0x00000040
+
+#define AR_PHY_TPCRG5   0xA26C
+#define AR_PHY_TPCRG5_PD_GAIN_OVERLAP       0x0000000F
+#define AR_PHY_TPCRG5_PD_GAIN_OVERLAP_S     0
+#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1    0x000003F0
+#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1_S  4
+#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2    0x0000FC00
+#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2_S  10
+#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3    0x003F0000
+#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3_S  16
+#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4    0x0FC00000
+#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4_S  22
+
+/* Carrier leak calibration control, do it after AGC calibration */
+#define AR_PHY_CL_CAL_CTL       0xA358
+#define AR_PHY_CL_CAL_ENABLE    0x00000002
+#define AR_PHY_PARALLEL_CAL_ENABLE    0x00000001
+
+#define AR_PHY_POWER_TX_RATE5   0xA38C
+#define AR_PHY_POWER_TX_RATE6   0xA390
+
+#define AR_PHY_CAL_CHAINMASK    0xA39C
+
+#define AR_PHY_POWER_TX_SUB     0xA3C8
+#define AR_PHY_POWER_TX_RATE7   0xA3CC
+#define AR_PHY_POWER_TX_RATE8   0xA3D0
+#define AR_PHY_POWER_TX_RATE9   0xA3D4
+
+#define AR_PHY_XPA_CFG		0xA3D8
+#define AR_PHY_FORCE_XPA_CFG	0x000000001
+#define AR_PHY_FORCE_XPA_CFG_S	0
+
+#define AR_PHY_CH1_CCA          0xa864
+#define AR_PHY_CH1_MINCCA_PWR   0x0FF80000
+#define AR_PHY_CH1_MINCCA_PWR_S 19
+#define AR9280_PHY_CH1_MINCCA_PWR   0x1FF00000
+#define AR9280_PHY_CH1_MINCCA_PWR_S 20
+
+#define AR_PHY_CH2_CCA          0xb864
+#define AR_PHY_CH2_MINCCA_PWR   0x0FF80000
+#define AR_PHY_CH2_MINCCA_PWR_S 19
+
+#define AR_PHY_CH1_EXT_CCA          0xa9bc
+#define AR_PHY_CH1_EXT_MINCCA_PWR   0xFF800000
+#define AR_PHY_CH1_EXT_MINCCA_PWR_S 23
+#define AR9280_PHY_CH1_EXT_MINCCA_PWR   0x01FF0000
+#define AR9280_PHY_CH1_EXT_MINCCA_PWR_S 16
+
+#define AR_PHY_CH2_EXT_CCA          0xb9bc
+#define AR_PHY_CH2_EXT_MINCCA_PWR   0xFF800000
+#define AR_PHY_CH2_EXT_MINCCA_PWR_S 23
+
+#endif
diff --git a/drivers/net/wireless/ath/ath9k/calib.c b/drivers/net/wireless/ath/ath9k/calib.c
index 064f5b5..eba85ad 100644
--- a/drivers/net/wireless/ath/ath9k/calib.c
+++ b/drivers/net/wireless/ath/ath9k/calib.c
@@ -15,6 +15,7 @@
  */
 
 #include "hw.h"
+#include "ar9002_phy.h"
 
 /* We can tune this as we go by monitoring really low values */
 #define ATH9K_NF_TOO_LOW	-60
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_4k.c b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
index 0354fe5..97279a5 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
@@ -15,6 +15,7 @@
  */
 
 #include "hw.h"
+#include "ar9002_phy.h"
 
 static int ath9k_hw_4k_get_eeprom_ver(struct ath_hw *ah)
 {
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_9287.c b/drivers/net/wireless/ath/ath9k/eeprom_9287.c
index d8ca94c..e57c5b4 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom_9287.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom_9287.c
@@ -15,6 +15,7 @@
  */
 
 #include "hw.h"
+#include "ar9002_phy.h"
 
 static int ath9k_hw_AR9287_get_eeprom_ver(struct ath_hw *ah)
 {
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_def.c b/drivers/net/wireless/ath/ath9k/eeprom_def.c
index 404a034..99f16a3 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom_def.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom_def.c
@@ -15,6 +15,7 @@
  */
 
 #include "hw.h"
+#include "ar9002_phy.h"
 
 static void ath9k_get_txgain_index(struct ath_hw *ah,
 		struct ath9k_channel *chan,
diff --git a/drivers/net/wireless/ath/ath9k/hw-ops.h b/drivers/net/wireless/ath/ath9k/hw-ops.h
index ee33146..81f3d03 100644
--- a/drivers/net/wireless/ath/ath9k/hw-ops.h
+++ b/drivers/net/wireless/ath/ath9k/hw-ops.h
@@ -28,4 +28,117 @@ static inline void ath9k_hw_configpcipowersave(struct ath_hw *ah,
 	ath9k_hw_ops(ah)->config_pci_powersave(ah, restore, power_off);
 }
 
+/* Private hardware call ops */
+
+/* PHY ops */
+
+static inline int ath9k_hw_rf_set_freq(struct ath_hw *ah,
+				       struct ath9k_channel *chan)
+{
+	return ath9k_hw_private_ops(ah)->rf_set_freq(ah, chan);
+}
+
+static inline void ath9k_hw_spur_mitigate_freq(struct ath_hw *ah,
+					       struct ath9k_channel *chan)
+{
+	ath9k_hw_private_ops(ah)->spur_mitigate_freq(ah, chan);
+}
+
+static inline int ath9k_hw_rf_alloc_ext_banks(struct ath_hw *ah)
+{
+	if (!ath9k_hw_private_ops(ah)->rf_alloc_ext_banks)
+		return 0;
+
+	return ath9k_hw_private_ops(ah)->rf_alloc_ext_banks(ah);
+}
+
+static inline void ath9k_hw_rf_free_ext_banks(struct ath_hw *ah)
+{
+	if (!ath9k_hw_private_ops(ah)->rf_free_ext_banks)
+		return;
+
+	ath9k_hw_private_ops(ah)->rf_free_ext_banks(ah);
+}
+
+static inline bool ath9k_hw_set_rf_regs(struct ath_hw *ah,
+					struct ath9k_channel *chan,
+					u16 modesIndex)
+{
+	if (!ath9k_hw_private_ops(ah)->set_rf_regs)
+		return true;
+
+	return ath9k_hw_private_ops(ah)->set_rf_regs(ah, chan, modesIndex);
+}
+
+static inline void ath9k_hw_init_bb(struct ath_hw *ah,
+				    struct ath9k_channel *chan)
+{
+	return ath9k_hw_private_ops(ah)->init_bb(ah, chan);
+}
+
+static inline void ath9k_hw_set_channel_regs(struct ath_hw *ah,
+					     struct ath9k_channel *chan)
+{
+	return ath9k_hw_private_ops(ah)->set_channel_regs(ah, chan);
+}
+
+static inline int ath9k_hw_process_ini(struct ath_hw *ah,
+					struct ath9k_channel *chan)
+{
+	return ath9k_hw_private_ops(ah)->process_ini(ah, chan);
+}
+
+static inline void ath9k_olc_init(struct ath_hw *ah)
+{
+	if (!ath9k_hw_private_ops(ah)->olc_init)
+		return;
+
+	return ath9k_hw_private_ops(ah)->olc_init(ah);
+}
+
+static inline void ath9k_hw_set_rfmode(struct ath_hw *ah,
+				       struct ath9k_channel *chan)
+{
+	return ath9k_hw_private_ops(ah)->set_rfmode(ah, chan);
+}
+
+static inline void ath9k_hw_mark_phy_inactive(struct ath_hw *ah)
+{
+	return ath9k_hw_private_ops(ah)->mark_phy_inactive(ah);
+}
+
+static inline void ath9k_hw_set_delta_slope(struct ath_hw *ah,
+					    struct ath9k_channel *chan)
+{
+	return ath9k_hw_private_ops(ah)->set_delta_slope(ah, chan);
+}
+
+static inline bool ath9k_hw_rfbus_req(struct ath_hw *ah)
+{
+	return ath9k_hw_private_ops(ah)->rfbus_req(ah);
+}
+
+static inline void ath9k_hw_rfbus_done(struct ath_hw *ah)
+{
+	return ath9k_hw_private_ops(ah)->rfbus_done(ah);
+}
+
+static inline void ath9k_enable_rfkill(struct ath_hw *ah)
+{
+	return ath9k_hw_private_ops(ah)->enable_rfkill(ah);
+}
+
+static inline void ath9k_hw_restore_chainmask(struct ath_hw *ah)
+{
+	if (!ath9k_hw_private_ops(ah)->restore_chainmask)
+		return;
+
+	return ath9k_hw_private_ops(ah)->restore_chainmask(ah);
+}
+
+static inline void ath9k_hw_set_diversity(struct ath_hw *ah, bool value)
+{
+	return ath9k_hw_private_ops(ah)->set_diversity(ah, value);
+}
+
 #endif /* ATH9K_HW_OPS_H */
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index f81e273..060451f 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -30,7 +30,6 @@
 static void ar9002_hw_attach_ops(struct ath_hw *ah);
 
 static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type);
-static void ath9k_hw_set_regs(struct ath_hw *ah, struct ath9k_channel *chan);
 
 MODULE_AUTHOR("Atheros Communications");
 MODULE_DESCRIPTION("Support for Atheros 802.11n wireless LAN cards.");
@@ -536,14 +535,12 @@ static int ath9k_hw_post_init(struct ath_hw *ah)
 		  ah->eep_ops->get_eeprom_ver(ah),
 		  ah->eep_ops->get_eeprom_rev(ah));
 
-        if (!AR_SREV_9280_10_OR_LATER(ah)) {
-		ecode = ath9k_hw_rf_alloc_ext_banks(ah);
-		if (ecode) {
-			ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL,
-				  "Failed allocating banks for "
-				  "external radio\n");
-			return ecode;
-		}
+	ecode = ath9k_hw_rf_alloc_ext_banks(ah);
+	if (ecode) {
+		ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL,
+			  "Failed allocating banks for "
+			  "external radio\n");
+		return ecode;
 	}
 
 	if (!AR_SREV_9100(ah)) {
@@ -914,20 +911,12 @@ static int __ath9k_hw_init(struct ath_hw *ah)
 	if (AR_SREV_9271(ah))
 		ah->is_pciexpress = false;
 
-	/* XXX: move this to its own hw op */
 	ah->hw_version.phyRev = REG_READ(ah, AR_PHY_CHIP_ID);
-
 	ath9k_hw_init_cal_settings(ah);
 
 	ah->ani_function = ATH9K_ANI_ALL;
-	if (AR_SREV_9280_10_OR_LATER(ah)) {
+	if (AR_SREV_9280_10_OR_LATER(ah))
 		ah->ani_function &= ~ATH9K_ANI_NOISE_IMMUNITY_LEVEL;
-		ah->ath9k_hw_rf_set_freq = &ath9k_hw_ar9280_set_channel;
-		ah->ath9k_hw_spur_mitigate_freq = &ath9k_hw_9280_spur_mitigate;
-	} else {
-		ah->ath9k_hw_rf_set_freq = &ath9k_hw_set_channel;
-		ah->ath9k_hw_spur_mitigate_freq = &ath9k_hw_spur_mitigate;
-	}
 
 	ath9k_hw_init_mode_regs(ah);
 
@@ -1015,22 +1004,6 @@ int ath9k_hw_init(struct ath_hw *ah)
 }
 EXPORT_SYMBOL(ath9k_hw_init);
 
-static void ath9k_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 ath9k_hw_init_qos(struct ath_hw *ah)
 {
 	REG_WRITE(ah, AR_MIC_QOS_CONTROL, 0x100aa);
@@ -1122,43 +1095,6 @@ static void ath9k_hw_init_pll(struct ath_hw *ah,
 	REG_WRITE(ah, AR_RTC_SLEEP_CLK, AR_RTC_FORCE_DERIVED_CLK);
 }
 
-static void ath9k_hw_init_chain_masks(struct ath_hw *ah)
-{
-	int rx_chainmask, tx_chainmask;
-
-	rx_chainmask = ah->rxchainmask;
-	tx_chainmask = ah->txchainmask;
-
-	switch (rx_chainmask) {
-	case 0x5:
-		REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP,
-			    AR_PHY_SWAP_ALT_CHAIN);
-	case 0x3:
-		if (ah->hw_version.macVersion == AR_SREV_REVISION_5416_10) {
-			REG_WRITE(ah, AR_PHY_RX_CHAINMASK, 0x7);
-			REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, 0x7);
-			break;
-		}
-	case 0x1:
-	case 0x2:
-	case 0x7:
-		REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx_chainmask);
-		REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx_chainmask);
-		break;
-	default:
-		break;
-	}
-
-	REG_WRITE(ah, AR_SELFGEN_MASK, tx_chainmask);
-	if (tx_chainmask == 0x5) {
-		REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP,
-			    AR_PHY_SWAP_ALT_CHAIN);
-	}
-	if (AR_SREV_9100(ah))
-		REG_WRITE(ah, AR_PHY_ANALOG_SWAP,
-			  REG_READ(ah, AR_PHY_ANALOG_SWAP) | 0x00000001);
-}
-
 static void ath9k_hw_init_interrupt_masks(struct ath_hw *ah,
 					  enum nl80211_iftype opmode)
 {
@@ -1278,8 +1214,7 @@ void ath9k_hw_deinit(struct ath_hw *ah)
 	ath9k_hw_setpower(ah, ATH9K_PM_FULL_SLEEP);
 
 free_hw:
-	if (!AR_SREV_9280_10_OR_LATER(ah))
-		ath9k_hw_rf_free_ext_banks(ah);
+	ath9k_hw_rf_free_ext_banks(ah);
 }
 EXPORT_SYMBOL(ath9k_hw_deinit);
 
@@ -1287,73 +1222,7 @@ EXPORT_SYMBOL(ath9k_hw_deinit);
 /* INI */
 /*******/
 
-static void ath9k_hw_override_ini(struct ath_hw *ah,
-				  struct ath9k_channel *chan)
-{
-	u32 val;
-
-	/*
-	 * Set the RX_ABORT and RX_DIS and clear if off only after
-	 * RXE is set for MAC. This prevents frames with corrupted
-	 * descriptor status.
-	 */
-	REG_SET_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
-
-	if (AR_SREV_9280_10_OR_LATER(ah)) {
-		val = REG_READ(ah, AR_PCU_MISC_MODE2);
-
-		if (!AR_SREV_9271(ah))
-			val &= ~AR_PCU_MISC_MODE2_HWWAR1;
-
-		if (AR_SREV_9287_10_OR_LATER(ah))
-			val = val & (~AR_PCU_MISC_MODE2_HWWAR2);
-
-		REG_WRITE(ah, AR_PCU_MISC_MODE2, val);
-	}
-
-	if (!AR_SREV_5416_20_OR_LATER(ah) ||
-	    AR_SREV_9280_10_OR_LATER(ah))
-		return;
-	/*
-	 * Disable BB clock gating
-	 * Necessary to avoid issues on AR5416 2.0
-	 */
-	REG_WRITE(ah, 0x9800 + (651 << 2), 0x11);
-
-	/*
-	 * Disable RIFS search on some chips to avoid baseband
-	 * hang issues.
-	 */
-	if (AR_SREV_9100(ah) || AR_SREV_9160(ah)) {
-		val = REG_READ(ah, AR_PHY_HEAVY_CLIP_FACTOR_RIFS);
-		val &= ~AR_PHY_RIFS_INIT_DELAY;
-		REG_WRITE(ah, AR_PHY_HEAVY_CLIP_FACTOR_RIFS, val);
-	}
-}
-
-static void ath9k_olc_init(struct ath_hw *ah)
-{
-	u32 i;
-
-	if (OLC_FOR_AR9287_10_LATER) {
-		REG_SET_BIT(ah, AR_PHY_TX_PWRCTRL9,
-				AR_PHY_TX_PWRCTRL9_RES_DC_REMOVAL);
-		ath9k_hw_analog_shift_rmw(ah, AR9287_AN_TXPC0,
-				AR9287_AN_TXPC0_TXPCMODE,
-				AR9287_AN_TXPC0_TXPCMODE_S,
-				AR9287_AN_TXPC0_TXPCMODE_TEMPSENSE);
-		udelay(100);
-	} else {
-		for (i = 0; i < AR9280_TX_GAIN_TABLE_SIZE; i++)
-			ah->originalGain[i] =
-				MS(REG_READ(ah, AR_PHY_TX_GAIN_TBL1 + i * 4),
-						AR_PHY_TX_GAIN);
-		ah->PDADCdelta = 0;
-	}
-}
-
-static u32 ath9k_regd_get_ctl(struct ath_regulatory *reg,
-			      struct ath9k_channel *chan)
+u32 ath9k_regd_get_ctl(struct ath_regulatory *reg, struct ath9k_channel *chan)
 {
 	u32 ctl = ath_regd_get_band_ctl(reg, chan->chan->band);
 
@@ -1367,184 +1236,10 @@ static u32 ath9k_regd_get_ctl(struct ath_regulatory *reg,
 	return ctl;
 }
 
-static int ath9k_hw_process_ini(struct ath_hw *ah,
-				struct ath9k_channel *chan)
-{
-	struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
-	int i, regWrites = 0;
-	struct ieee80211_channel *channel = chan->chan;
-	u32 modesIndex, freqIndex;
-
-	switch (chan->chanmode) {
-	case CHANNEL_A:
-	case CHANNEL_A_HT20:
-		modesIndex = 1;
-		freqIndex = 1;
-		break;
-	case CHANNEL_A_HT40PLUS:
-	case CHANNEL_A_HT40MINUS:
-		modesIndex = 2;
-		freqIndex = 1;
-		break;
-	case CHANNEL_G:
-	case CHANNEL_G_HT20:
-	case CHANNEL_B:
-		modesIndex = 4;
-		freqIndex = 2;
-		break;
-	case CHANNEL_G_HT40PLUS:
-	case CHANNEL_G_HT40MINUS:
-		modesIndex = 3;
-		freqIndex = 2;
-		break;
-
-	default:
-		return -EINVAL;
-	}
-
-	/* Set correct baseband to analog shift setting to access analog chips */
-	REG_WRITE(ah, AR_PHY(0), 0x00000007);
-
-	/* Write ADDAC shifts */
-	REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_EXTERNAL_RADIO);
-	ah->eep_ops->set_addac(ah, chan);
-
-	if (AR_SREV_5416_22_OR_LATER(ah)) {
-		REG_WRITE_ARRAY(&ah->iniAddac, 1, regWrites);
-	} else {
-		struct ar5416IniArray temp;
-		u32 addacSize =
-			sizeof(u32) * ah->iniAddac.ia_rows *
-			ah->iniAddac.ia_columns;
-
-		/* For AR5416 2.0/2.1 */
-		memcpy(ah->addac5416_21,
-		       ah->iniAddac.ia_array, addacSize);
-
-		/* override CLKDRV value at [row, column] = [31, 1] */
-		(ah->addac5416_21)[31 * ah->iniAddac.ia_columns + 1] = 0;
-
-		temp.ia_array = ah->addac5416_21;
-		temp.ia_columns = ah->iniAddac.ia_columns;
-		temp.ia_rows = ah->iniAddac.ia_rows;
-		REG_WRITE_ARRAY(&temp, 1, regWrites);
-	}
-
-	REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_INTERNAL_ADDAC);
-
-	for (i = 0; i < ah->iniModes.ia_rows; i++) {
-		u32 reg = INI_RA(&ah->iniModes, i, 0);
-		u32 val = INI_RA(&ah->iniModes, i, modesIndex);
-
-		if (reg == AR_AN_TOP2 && ah->need_an_top2_fixup)
-			val &= ~AR_AN_TOP2_PWDCLKIND;
-
-		REG_WRITE(ah, reg, val);
-
-		if (reg >= 0x7800 && reg < 0x78a0
-		    && ah->config.analog_shiftreg) {
-			udelay(100);
-		}
-
-		DO_DELAY(regWrites);
-	}
-
-	if (AR_SREV_9280(ah) || AR_SREV_9287_10_OR_LATER(ah))
-		REG_WRITE_ARRAY(&ah->iniModesRxGain, modesIndex, regWrites);
-
-	if (AR_SREV_9280(ah) || AR_SREV_9285_12_OR_LATER(ah) ||
-	    AR_SREV_9287_10_OR_LATER(ah))
-		REG_WRITE_ARRAY(&ah->iniModesTxGain, modesIndex, regWrites);
-
-	if (AR_SREV_9271_10(ah))
-		REG_WRITE_ARRAY(&ah->iniModes_9271_1_0_only,
-				modesIndex, regWrites);
-
-	/* Write common array parameters */
-	for (i = 0; i < ah->iniCommon.ia_rows; i++) {
-		u32 reg = INI_RA(&ah->iniCommon, i, 0);
-		u32 val = INI_RA(&ah->iniCommon, i, 1);
-
-		REG_WRITE(ah, reg, val);
-
-		if (reg >= 0x7800 && reg < 0x78a0
-		    && ah->config.analog_shiftreg) {
-			udelay(100);
-		}
-
-		DO_DELAY(regWrites);
-	}
-
-	if (AR_SREV_9271(ah)) {
-		if (ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE) == 1)
-			REG_WRITE_ARRAY(&ah->iniModes_high_power_tx_gain_9271,
-					modesIndex, regWrites);
-		else
-			REG_WRITE_ARRAY(&ah->iniModes_normal_power_tx_gain_9271,
-					modesIndex, regWrites);
-	}
-
-	REG_WRITE_ARRAY(&ah->iniBB_RfGain, freqIndex, regWrites);
-
-	if (AR_SREV_9280_20(ah) && IS_CHAN_A_5MHZ_SPACED(chan)) {
-		REG_WRITE_ARRAY(&ah->iniModesAdditional, modesIndex,
-				regWrites);
-	}
-
-	ath9k_hw_override_ini(ah, chan);
-	ath9k_hw_set_regs(ah, chan);
-	ath9k_hw_init_chain_masks(ah);
-
-	if (OLC_FOR_AR9280_20_LATER)
-		ath9k_olc_init(ah);
-
-	/* Set TX power */
-	ah->eep_ops->set_txpower(ah, chan,
-				 ath9k_regd_get_ctl(regulatory, chan),
-				 channel->max_antenna_gain * 2,
-				 channel->max_power * 2,
-				 min((u32) MAX_RATE_POWER,
-				 (u32) regulatory->power_limit));
-
-	/* Write analog registers */
-	if (!ath9k_hw_set_rf_regs(ah, chan, freqIndex)) {
-		ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL,
-			  "ar5416SetRfRegs failed\n");
-		return -EIO;
-	}
-
-	return 0;
-}
-
 /****************************************/
 /* Reset and Channel Switching Routines */
 /****************************************/
 
-static void ath9k_hw_set_rfmode(struct ath_hw *ah, struct ath9k_channel *chan)
-{
-	u32 rfMode = 0;
-
-	if (chan == NULL)
-		return;
-
-	rfMode |= (IS_CHAN_B(chan) || IS_CHAN_G(chan))
-		? AR_PHY_MODE_DYNAMIC : AR_PHY_MODE_OFDM;
-
-	if (!AR_SREV_9280_10_OR_LATER(ah))
-		rfMode |= (IS_CHAN_5GHZ(chan)) ?
-			AR_PHY_MODE_RF5GHZ : AR_PHY_MODE_RF2GHZ;
-
-	if (AR_SREV_9280_20(ah) && IS_CHAN_A_5MHZ_SPACED(chan))
-		rfMode |= (AR_PHY_MODE_DYNAMIC | AR_PHY_MODE_DYN_CCK_DISABLE);
-
-	REG_WRITE(ah, AR_PHY_MODE, rfMode);
-}
-
-static void ath9k_hw_mark_phy_inactive(struct ath_hw *ah)
-{
-	REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS);
-}
-
 static inline void ath9k_hw_set_dma(struct ath_hw *ah)
 {
 	u32 regval;
@@ -1621,10 +1316,8 @@ static void ath9k_hw_set_operating_mode(struct ath_hw *ah, int opmode)
 	}
 }
 
-static inline void ath9k_hw_get_delta_slope_vals(struct ath_hw *ah,
-						 u32 coef_scaled,
-						 u32 *coef_mantissa,
-						 u32 *coef_exponent)
+void ath9k_hw_get_delta_slope_vals(struct ath_hw *ah, u32 coef_scaled,
+				   u32 *coef_mantissa, u32 *coef_exponent)
 {
 	u32 coef_exp, coef_man;
 
@@ -1640,40 +1333,6 @@ static inline void ath9k_hw_get_delta_slope_vals(struct ath_hw *ah,
 	*coef_exponent = coef_exp - 16;
 }
 
-static void ath9k_hw_set_delta_slope(struct ath_hw *ah,
-				     struct ath9k_channel *chan)
-{
-	u32 coef_scaled, ds_coef_exp, ds_coef_man;
-	u32 clockMhzScaled = 0x64000000;
-	struct chan_centers centers;
-
-	if (IS_CHAN_HALF_RATE(chan))
-		clockMhzScaled = clockMhzScaled >> 1;
-	else if (IS_CHAN_QUARTER_RATE(chan))
-		clockMhzScaled = clockMhzScaled >> 2;
-
-	ath9k_hw_get_channel_centers(ah, chan, &centers);
-	coef_scaled = clockMhzScaled / centers.synth_center;
-
-	ath9k_hw_get_delta_slope_vals(ah, coef_scaled, &ds_coef_man,
-				      &ds_coef_exp);
-
-	REG_RMW_FIELD(ah, AR_PHY_TIMING3,
-		      AR_PHY_TIMING3_DSC_MAN, ds_coef_man);
-	REG_RMW_FIELD(ah, AR_PHY_TIMING3,
-		      AR_PHY_TIMING3_DSC_EXP, ds_coef_exp);
-
-	coef_scaled = (9 * coef_scaled) / 10;
-
-	ath9k_hw_get_delta_slope_vals(ah, coef_scaled, &ds_coef_man,
-				      &ds_coef_exp);
-
-	REG_RMW_FIELD(ah, AR_PHY_HALFGI,
-		      AR_PHY_HALFGI_DSC_MAN, ds_coef_man);
-	REG_RMW_FIELD(ah, AR_PHY_HALFGI,
-		      AR_PHY_HALFGI_DSC_EXP, ds_coef_exp);
-}
-
 static bool ath9k_hw_set_reset(struct ath_hw *ah, int type)
 {
 	u32 rst_flags;
@@ -1780,34 +1439,6 @@ static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type)
 	}
 }
 
-static void ath9k_hw_set_regs(struct ath_hw *ah, struct ath9k_channel *chan)
-{
-	u32 phymode;
-	u32 enableDacFifo = 0;
-
-	if (AR_SREV_9285_10_OR_LATER(ah))
-		enableDacFifo = (REG_READ(ah, AR_PHY_TURBO) &
-					 AR_PHY_FC_ENABLE_DAC_FIFO);
-
-	phymode = AR_PHY_FC_HT_EN | AR_PHY_FC_SHORT_GI_40
-		| AR_PHY_FC_SINGLE_HT_LTF1 | AR_PHY_FC_WALSH | enableDacFifo;
-
-	if (IS_CHAN_HT40(chan)) {
-		phymode |= AR_PHY_FC_DYN2040_EN;
-
-		if ((chan->chanmode == CHANNEL_A_HT40PLUS) ||
-		    (chan->chanmode == CHANNEL_G_HT40PLUS))
-			phymode |= AR_PHY_FC_DYN2040_PRI_CH;
-
-	}
-	REG_WRITE(ah, AR_PHY_TURBO, phymode);
-
-	ath9k_hw_set11nmac2040(ah);
-
-	REG_WRITE(ah, AR_GTXTO, 25 << AR_GTXTO_TIMEOUT_LIMIT_S);
-	REG_WRITE(ah, AR_CST, 0xF << AR_CST_TIMEOUT_LIMIT_S);
-}
-
 static bool ath9k_hw_chip_reset(struct ath_hw *ah,
 				struct ath9k_channel *chan)
 {
@@ -1833,7 +1464,7 @@ static bool ath9k_hw_channel_change(struct ath_hw *ah,
 	struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
 	struct ath_common *common = ath9k_hw_common(ah);
 	struct ieee80211_channel *channel = chan->chan;
-	u32 synthDelay, qnum;
+	u32 qnum;
 	int r;
 
 	for (qnum = 0; qnum < AR_NUM_QCU; qnum++) {
@@ -1845,17 +1476,15 @@ static bool ath9k_hw_channel_change(struct ath_hw *ah,
 		}
 	}
 
-	REG_WRITE(ah, AR_PHY_RFBUS_REQ, AR_PHY_RFBUS_REQ_EN);
-	if (!ath9k_hw_wait(ah, AR_PHY_RFBUS_GRANT, AR_PHY_RFBUS_GRANT_EN,
-			   AR_PHY_RFBUS_GRANT_EN, AH_WAIT_TIMEOUT)) {
+	if (!ath9k_hw_rfbus_req(ah)) {
 		ath_print(common, ATH_DBG_FATAL,
 			  "Could not kill baseband RX\n");
 		return false;
 	}
 
-	ath9k_hw_set_regs(ah, chan);
+	ath9k_hw_set_channel_regs(ah, chan);
 
-	r = ah->ath9k_hw_rf_set_freq(ah, chan);
+	r = ath9k_hw_rf_set_freq(ah, chan);
 	if (r) {
 		ath_print(common, ATH_DBG_FATAL,
 			  "Failed to set channel\n");
@@ -1869,20 +1498,12 @@ static bool ath9k_hw_channel_change(struct ath_hw *ah,
 			     min((u32) MAX_RATE_POWER,
 			     (u32) regulatory->power_limit));
 
-	synthDelay = REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY;
-	if (IS_CHAN_B(chan))
-		synthDelay = (4 * synthDelay) / 22;
-	else
-		synthDelay /= 10;
-
-	udelay(synthDelay + BASE_ACTIVATE_DELAY);
-
-	REG_WRITE(ah, AR_PHY_RFBUS_REQ, 0);
+	ath9k_hw_rfbus_done(ah);
 
 	if (IS_CHAN_OFDM(chan) || IS_CHAN_HT(chan))
 		ath9k_hw_set_delta_slope(ah, chan);
 
-	ah->ath9k_hw_spur_mitigate_freq(ah, chan);
+	ath9k_hw_spur_mitigate_freq(ah, chan);
 
 	if (!chan->oneTimeCalsDone)
 		chan->oneTimeCalsDone = true;
@@ -1890,18 +1511,6 @@ static bool ath9k_hw_channel_change(struct ath_hw *ah,
 	return true;
 }
 
-static void ath9k_enable_rfkill(struct ath_hw *ah)
-{
-	REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL,
-		    AR_GPIO_INPUT_EN_VAL_RFSILENT_BB);
-
-	REG_CLR_BIT(ah, AR_GPIO_INPUT_MUX2,
-		    AR_GPIO_INPUT_MUX2_RFSILENT);
-
-	ath9k_hw_cfg_gpio_input(ah, ah->rfkill_gpio);
-	REG_SET_BIT(ah, AR_PHY_TEST, RFSILENT_BB);
-}
-
 int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
 		    bool bChannelChange)
 {
@@ -1911,7 +1520,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
 	u32 saveDefAntenna;
 	u32 macStaId1;
 	u64 tsf = 0;
-	int i, rx_chainmask, r;
+	int i, r;
 
 	ah->txchainmask = common->tx_chainmask;
 	ah->rxchainmask = common->rx_chainmask;
@@ -1983,16 +1592,6 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
 	if (AR_SREV_9280_10_OR_LATER(ah))
 		REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL, AR_GPIO_JTAG_DISABLE);
 
-	if (AR_SREV_9287_12_OR_LATER(ah)) {
-		/* Enable ASYNC FIFO */
-		REG_SET_BIT(ah, AR_MAC_PCU_ASYNC_FIFO_REG3,
-				AR_MAC_PCU_ASYNC_FIFO_REG3_DATAPATH_SEL);
-		REG_SET_BIT(ah, AR_PHY_MODE, AR_PHY_MODE_ASYNCFIFO);
-		REG_CLR_BIT(ah, AR_MAC_PCU_ASYNC_FIFO_REG3,
-				AR_MAC_PCU_ASYNC_FIFO_REG3_SOFT_RESET);
-		REG_SET_BIT(ah, AR_MAC_PCU_ASYNC_FIFO_REG3,
-				AR_MAC_PCU_ASYNC_FIFO_REG3_SOFT_RESET);
-	}
 	r = ath9k_hw_process_ini(ah, chan);
 	if (r)
 		return r;
@@ -2017,7 +1616,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
 	if (IS_CHAN_OFDM(chan) || IS_CHAN_HT(chan))
 		ath9k_hw_set_delta_slope(ah, chan);
 
-	ah->ath9k_hw_spur_mitigate_freq(ah, chan);
+	ath9k_hw_spur_mitigate_freq(ah, chan);
 	ah->eep_ops->set_board_values(ah, chan);
 
 	REG_WRITE(ah, AR_STA_ID0, get_unaligned_le32(common->macaddr));
@@ -2039,7 +1638,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
 
 	REG_WRITE(ah, AR_RSSI_THR, INIT_RSSI_THR);
 
-	r = ah->ath9k_hw_rf_set_freq(ah, chan);
+	r = ath9k_hw_rf_set_freq(ah, chan);
 	if (r)
 		return r;
 
@@ -2096,12 +1695,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
 	if (!ath9k_hw_init_cal(ah, chan))
 		return -EIO;
 
-	rx_chainmask = ah->rxchainmask;
-	if ((rx_chainmask == 0x5) || (rx_chainmask == 0x3)) {
-		REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx_chainmask);
-		REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx_chainmask);
-	}
-
+	ath9k_hw_restore_chainmask(ah);
 	REG_WRITE(ah, AR_CFG_LED, saveLedState | AR_CFG_SCLK_32KHZ);
 
 	/*
@@ -3323,10 +2917,6 @@ bool ath9k_hw_getcapability(struct ath_hw *ah, enum ath9k_capability_type type,
 	case ATH9K_CAP_TKIP_SPLIT:
 		return (ah->misc_mode & AR_PCU_MIC_NEW_LOC_ENA) ?
 			false : true;
-	case ATH9K_CAP_DIVERSITY:
-		return (REG_READ(ah, AR_PHY_CCK_DETECT) &
-			AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV) ?
-			true : false;
 	case ATH9K_CAP_MCAST_KEYSRCH:
 		switch (capability) {
 		case 0:
@@ -3369,8 +2959,6 @@ EXPORT_SYMBOL(ath9k_hw_getcapability);
 bool ath9k_hw_setcapability(struct ath_hw *ah, enum ath9k_capability_type type,
 			    u32 capability, u32 setting, int *status)
 {
-	u32 v;
-
 	switch (type) {
 	case ATH9K_CAP_TKIP_MIC:
 		if (setting)
@@ -3380,14 +2968,6 @@ bool ath9k_hw_setcapability(struct ath_hw *ah, enum ath9k_capability_type type,
 			ah->sta_id1_defaults &=
 				~AR_STA_ID1_CRPT_MIC_ENABLE;
 		return true;
-	case ATH9K_CAP_DIVERSITY:
-		v = REG_READ(ah, AR_PHY_CCK_DETECT);
-		if (setting)
-			v |= AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV;
-		else
-			v &= ~AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV;
-		REG_WRITE(ah, AR_PHY_CCK_DETECT, v);
-		return true;
 	case ATH9K_CAP_MCAST_KEYSRCH:
 		if (setting)
 			ah->sta_id1_defaults |= AR_STA_ID1_MCAST_KSRCH;
@@ -3982,4 +3562,9 @@ static void ar9002_hw_attach_ops(struct ath_hw *ah)
 	priv_ops->macversion_supported = ar9002_hw_macversion_supported;
 
 	ops->config_pci_powersave = ar9002_hw_configpcipowersave;
+
+	if (AR_SREV_9280_10_OR_LATER(ah))
+		ar9002_hw_attach_phy_ops(ah);
+	else
+		ar5008_hw_attach_phy_ops(ah);
 }
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index dfe8502..d740e9c 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -171,7 +171,6 @@ enum ath9k_capability_type {
 	ATH9K_CAP_CIPHER = 0,
 	ATH9K_CAP_TKIP_MIC,
 	ATH9K_CAP_TKIP_SPLIT,
-	ATH9K_CAP_DIVERSITY,
 	ATH9K_CAP_TXPOW,
 	ATH9K_CAP_MCAST_KEYSRCH,
 	ATH9K_CAP_DS
@@ -449,11 +448,41 @@ struct ath_gen_timer_table {
  * @init_cal_settings: Initializes calibration settings
  * @init_mode_regs: Initializes mode registers
  * @macversion_supported: If this specific mac revision is supported
+ *
+ * @rf_set_freq: change frequency
+ * @spur_mitigate_freq: spur mitigation
+ * @rf_alloc_ext_banks:
+ * @rf_free_ext_banks:
+ * @set_rf_regs:
  */
 struct ath_hw_private_ops {
 	void (*init_cal_settings)(struct ath_hw *ah);
 	void (*init_mode_regs)(struct ath_hw *ah);
 	bool (*macversion_supported)(u32 macversion);
+
+	/* PHY ops */
+	int (*rf_set_freq)(struct ath_hw *ah,
+			   struct ath9k_channel *chan);
+	void (*spur_mitigate_freq)(struct ath_hw *ah,
+				   struct ath9k_channel *chan);
+	int (*rf_alloc_ext_banks)(struct ath_hw *ah);
+	void (*rf_free_ext_banks)(struct ath_hw *ah);
+	bool (*set_rf_regs)(struct ath_hw *ah,
+			    struct ath9k_channel *chan,
+			    u16 modesIndex);
+	void (*set_channel_regs)(struct ath_hw *ah, struct ath9k_channel *chan);
+	void (*init_bb)(struct ath_hw *ah,
+			struct ath9k_channel *chan);
+	int (*process_ini)(struct ath_hw *ah, struct ath9k_channel *chan);
+	void (*olc_init)(struct ath_hw *ah);
+	void (*set_rfmode)(struct ath_hw *ah, struct ath9k_channel *chan);
+	void (*mark_phy_inactive)(struct ath_hw *ah);
+	void (*set_delta_slope)(struct ath_hw *ah, struct ath9k_channel *chan);
+	bool (*rfbus_req)(struct ath_hw *ah);
+	void (*rfbus_done)(struct ath_hw *ah);
+	void (*enable_rfkill)(struct ath_hw *ah);
+	void (*restore_chainmask)(struct ath_hw *ah);
+	void (*set_diversity)(struct ath_hw *ah, bool value);
 };
 
 /**
@@ -563,13 +592,6 @@ struct ath_hw {
 		DONT_USE_32KHZ,
 	} enable_32kHz_clock;
 
-	/* Callback for radio frequency change */
-	int (*ath9k_hw_rf_set_freq)(struct ath_hw *ah, struct ath9k_channel *chan);
-
-	/* Callback for baseband spur frequency */
-	void (*ath9k_hw_spur_mitigate_freq)(struct ath_hw *ah,
-					    struct ath9k_channel *chan);
-
 	/* Private to hardware code */
 	struct ath_hw_private_ops private_ops;
 	/* Accessed by the lower level driver */
@@ -675,6 +697,7 @@ bool ath9k_hw_getcapability(struct ath_hw *ah, enum ath9k_capability_type type,
 			    u32 capability, u32 *result);
 bool ath9k_hw_setcapability(struct ath_hw *ah, enum ath9k_capability_type type,
 			    u32 capability, u32 setting, int *status);
+u32 ath9k_regd_get_ctl(struct ath_regulatory *reg, struct ath9k_channel *chan);
 
 /* Key Cache Management */
 bool ath9k_hw_keyreset(struct ath_hw *ah, u16 entry);
@@ -752,6 +775,13 @@ 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);
+
+void ar9002_hw_attach_phy_ops(struct ath_hw *ah);
+void ar5008_hw_attach_phy_ops(struct ath_hw *ah);
+
 #define ATH_PCIE_CAP_LINK_CTRL	0x70
 #define ATH_PCIE_CAP_LINK_L0S	1
 #define ATH_PCIE_CAP_LINK_L1	2
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index d769759..9779646 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -514,7 +514,7 @@ static void ath9k_init_misc(struct ath_softc *sc)
 	common->tx_chainmask = sc->sc_ah->caps.tx_chainmask;
 	common->rx_chainmask = sc->sc_ah->caps.rx_chainmask;
 
-	ath9k_hw_setcapability(sc->sc_ah, ATH9K_CAP_DIVERSITY, 1, true, NULL);
+	ath9k_hw_set_diversity(sc->sc_ah, true);
 	sc->rx.defant = ath9k_hw_getdefantenna(sc->sc_ah);
 
 	if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK)
diff --git a/drivers/net/wireless/ath/ath9k/phy.h b/drivers/net/wireless/ath/ath9k/phy.h
index 4b6e494..b908152 100644
--- a/drivers/net/wireless/ath/ath9k/phy.h
+++ b/drivers/net/wireless/ath/ath9k/phy.h
@@ -17,501 +17,11 @@
 #ifndef PHY_H
 #define PHY_H
 
-/* Single chip radio settings */
-int ath9k_hw_ar9280_set_channel(struct ath_hw *ah, struct ath9k_channel *chan);
-void ath9k_hw_9280_spur_mitigate(struct ath_hw *ah, struct ath9k_channel *chan);
-
-/* Routines below are for non single-chip solutions */
-int ath9k_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan);
-void ath9k_hw_spur_mitigate(struct ath_hw *ah, struct ath9k_channel *chan);
-
-int ath9k_hw_rf_alloc_ext_banks(struct ath_hw *ah);
-void ath9k_hw_rf_free_ext_banks(struct ath_hw *ah);
-
-bool ath9k_hw_set_rf_regs(struct ath_hw *ah,
-			  struct ath9k_channel *chan,
-			  u16 modesIndex);
-
 #define AR_PHY_BASE     0x9800
 #define AR_PHY(_n)      (AR_PHY_BASE + ((_n)<<2))
 
-#define AR_PHY_TEST             0x9800
-#define PHY_AGC_CLR             0x10000000
-#define RFSILENT_BB             0x00002000
-
-#define AR_PHY_TURBO                0x9804
-#define AR_PHY_FC_TURBO_MODE        0x00000001
-#define AR_PHY_FC_TURBO_SHORT       0x00000002
-#define AR_PHY_FC_DYN2040_EN        0x00000004
-#define AR_PHY_FC_DYN2040_PRI_ONLY  0x00000008
-#define AR_PHY_FC_DYN2040_PRI_CH    0x00000010
-/* For 25 MHz channel spacing -- not used but supported by hw */
-#define AR_PHY_FC_DYN2040_EXT_CH    0x00000020
-#define AR_PHY_FC_HT_EN             0x00000040
-#define AR_PHY_FC_SHORT_GI_40       0x00000080
-#define AR_PHY_FC_WALSH             0x00000100
-#define AR_PHY_FC_SINGLE_HT_LTF1    0x00000200
-#define AR_PHY_FC_ENABLE_DAC_FIFO   0x00000800
-
-#define AR_PHY_TEST2 		    0x9808
-
-#define AR_PHY_TIMING2           0x9810
-#define AR_PHY_TIMING3           0x9814
-#define AR_PHY_TIMING3_DSC_MAN   0xFFFE0000
-#define AR_PHY_TIMING3_DSC_MAN_S 17
-#define AR_PHY_TIMING3_DSC_EXP   0x0001E000
-#define AR_PHY_TIMING3_DSC_EXP_S 13
-
-#define AR_PHY_CHIP_ID            0x9818
-#define AR_PHY_CHIP_ID_REV_0      0x80
-#define AR_PHY_CHIP_ID_REV_1      0x81
-#define AR_PHY_CHIP_ID_9160_REV_0 0xb0
-
-#define AR_PHY_ACTIVE       0x981C
-#define AR_PHY_ACTIVE_EN    0x00000001
-#define AR_PHY_ACTIVE_DIS   0x00000000
-
-#define AR_PHY_RF_CTL2             0x9824
-#define AR_PHY_TX_END_DATA_START   0x000000FF
-#define AR_PHY_TX_END_DATA_START_S 0
-#define AR_PHY_TX_END_PA_ON        0x0000FF00
-#define AR_PHY_TX_END_PA_ON_S      8
-
-#define AR_PHY_RF_CTL3                  0x9828
-#define AR_PHY_TX_END_TO_A2_RX_ON       0x00FF0000
-#define AR_PHY_TX_END_TO_A2_RX_ON_S     16
-
-#define AR_PHY_ADC_CTL                  0x982C
-#define AR_PHY_ADC_CTL_OFF_INBUFGAIN    0x00000003
-#define AR_PHY_ADC_CTL_OFF_INBUFGAIN_S  0
-#define AR_PHY_ADC_CTL_OFF_PWDDAC       0x00002000
-#define AR_PHY_ADC_CTL_OFF_PWDBANDGAP   0x00004000
-#define AR_PHY_ADC_CTL_OFF_PWDADC       0x00008000
-#define AR_PHY_ADC_CTL_ON_INBUFGAIN     0x00030000
-#define AR_PHY_ADC_CTL_ON_INBUFGAIN_S   16
-
-#define AR_PHY_ADC_SERIAL_CTL       0x9830
-#define AR_PHY_SEL_INTERNAL_ADDAC   0x00000000
-#define AR_PHY_SEL_EXTERNAL_RADIO   0x00000001
-
-#define AR_PHY_RF_CTL4                    0x9834
-#define AR_PHY_RF_CTL4_TX_END_XPAB_OFF    0xFF000000
-#define AR_PHY_RF_CTL4_TX_END_XPAB_OFF_S  24
-#define AR_PHY_RF_CTL4_TX_END_XPAA_OFF    0x00FF0000
-#define AR_PHY_RF_CTL4_TX_END_XPAA_OFF_S  16
-#define AR_PHY_RF_CTL4_FRAME_XPAB_ON      0x0000FF00
-#define AR_PHY_RF_CTL4_FRAME_XPAB_ON_S    8
-#define AR_PHY_RF_CTL4_FRAME_XPAA_ON      0x000000FF
-#define AR_PHY_RF_CTL4_FRAME_XPAA_ON_S    0
-
-#define AR_PHY_TSTDAC_CONST               0x983c
-
-#define AR_PHY_SETTLING          0x9844
-#define AR_PHY_SETTLING_SWITCH   0x00003F80
-#define AR_PHY_SETTLING_SWITCH_S 7
-
-#define AR_PHY_RXGAIN                   0x9848
-#define AR_PHY_RXGAIN_TXRX_ATTEN        0x0003F000
-#define AR_PHY_RXGAIN_TXRX_ATTEN_S      12
-#define AR_PHY_RXGAIN_TXRX_RF_MAX       0x007C0000
-#define AR_PHY_RXGAIN_TXRX_RF_MAX_S     18
-#define AR9280_PHY_RXGAIN_TXRX_ATTEN    0x00003F80
-#define AR9280_PHY_RXGAIN_TXRX_ATTEN_S  7
-#define AR9280_PHY_RXGAIN_TXRX_MARGIN   0x001FC000
-#define AR9280_PHY_RXGAIN_TXRX_MARGIN_S 14
-
-#define AR_PHY_DESIRED_SZ           0x9850
-#define AR_PHY_DESIRED_SZ_ADC       0x000000FF
-#define AR_PHY_DESIRED_SZ_ADC_S     0
-#define AR_PHY_DESIRED_SZ_PGA       0x0000FF00
-#define AR_PHY_DESIRED_SZ_PGA_S     8
-#define AR_PHY_DESIRED_SZ_TOT_DES   0x0FF00000
-#define AR_PHY_DESIRED_SZ_TOT_DES_S 20
-
-#define AR_PHY_FIND_SIG           0x9858
-#define AR_PHY_FIND_SIG_FIRSTEP   0x0003F000
-#define AR_PHY_FIND_SIG_FIRSTEP_S 12
-#define AR_PHY_FIND_SIG_FIRPWR    0x03FC0000
-#define AR_PHY_FIND_SIG_FIRPWR_S  18
-
-#define AR_PHY_AGC_CTL1                  0x985C
-#define AR_PHY_AGC_CTL1_COARSE_LOW       0x00007F80
-#define AR_PHY_AGC_CTL1_COARSE_LOW_S     7
-#define AR_PHY_AGC_CTL1_COARSE_HIGH      0x003F8000
-#define AR_PHY_AGC_CTL1_COARSE_HIGH_S    15
-
-#define AR_PHY_AGC_CONTROL               0x9860
-#define AR_PHY_AGC_CONTROL_CAL           0x00000001
-#define AR_PHY_AGC_CONTROL_NF            0x00000002
-#define AR_PHY_AGC_CONTROL_ENABLE_NF     0x00008000
-#define AR_PHY_AGC_CONTROL_FLTR_CAL      0x00010000
-#define AR_PHY_AGC_CONTROL_NO_UPDATE_NF  0x00020000
-
-#define AR_PHY_CCA                  0x9864
-#define AR_PHY_MINCCA_PWR           0x0FF80000
-#define AR_PHY_MINCCA_PWR_S         19
-#define AR_PHY_CCA_THRESH62         0x0007F000
-#define AR_PHY_CCA_THRESH62_S       12
-#define AR9280_PHY_MINCCA_PWR       0x1FF00000
-#define AR9280_PHY_MINCCA_PWR_S     20
-#define AR9280_PHY_CCA_THRESH62     0x000FF000
-#define AR9280_PHY_CCA_THRESH62_S   12
-
-#define AR_PHY_SFCORR_LOW                    0x986C
-#define AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW  0x00000001
-#define AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW    0x00003F00
-#define AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW_S  8
-#define AR_PHY_SFCORR_LOW_M1_THRESH_LOW      0x001FC000
-#define AR_PHY_SFCORR_LOW_M1_THRESH_LOW_S    14
-#define AR_PHY_SFCORR_LOW_M2_THRESH_LOW      0x0FE00000
-#define AR_PHY_SFCORR_LOW_M2_THRESH_LOW_S    21
-
-#define AR_PHY_SFCORR                0x9868
-#define AR_PHY_SFCORR_M2COUNT_THR    0x0000001F
-#define AR_PHY_SFCORR_M2COUNT_THR_S  0
-#define AR_PHY_SFCORR_M1_THRESH      0x00FE0000
-#define AR_PHY_SFCORR_M1_THRESH_S    17
-#define AR_PHY_SFCORR_M2_THRESH      0x7F000000
-#define AR_PHY_SFCORR_M2_THRESH_S    24
-
-#define AR_PHY_SLEEP_CTR_CONTROL    0x9870
-#define AR_PHY_SLEEP_CTR_LIMIT      0x9874
-#define AR_PHY_SYNTH_CONTROL        0x9874
-#define AR_PHY_SLEEP_SCAL           0x9878
-
-#define AR_PHY_PLL_CTL          0x987c
-#define AR_PHY_PLL_CTL_40       0xaa
-#define AR_PHY_PLL_CTL_40_5413  0x04
-#define AR_PHY_PLL_CTL_44       0xab
-#define AR_PHY_PLL_CTL_44_2133  0xeb
-#define AR_PHY_PLL_CTL_40_2133  0xea
-
-#define AR_PHY_SPECTRAL_SCAN			0x9910  /* AR9280 spectral scan configuration register */
-#define	AR_PHY_SPECTRAL_SCAN_ENABLE		0x1
-#define AR_PHY_SPECTRAL_SCAN_ENA		0x00000001  /* Enable spectral scan, reg 68, bit 0 */
-#define AR_PHY_SPECTRAL_SCAN_ENA_S		0  /* Enable spectral scan, reg 68, bit 0 */
-#define AR_PHY_SPECTRAL_SCAN_ACTIVE		0x00000002  /* Activate spectral scan reg 68, bit 1*/
-#define AR_PHY_SPECTRAL_SCAN_ACTIVE_S		1  /* Activate spectral scan reg 68, bit 1*/
-#define AR_PHY_SPECTRAL_SCAN_FFT_PERIOD		0x000000F0  /* Interval for FFT reports, reg 68, bits 4-7*/
-#define AR_PHY_SPECTRAL_SCAN_FFT_PERIOD_S	4
-#define AR_PHY_SPECTRAL_SCAN_PERIOD		0x0000FF00  /* Interval for FFT reports, reg 68, bits 8-15*/
-#define AR_PHY_SPECTRAL_SCAN_PERIOD_S		8
-#define AR_PHY_SPECTRAL_SCAN_COUNT		0x00FF0000  /* Number of reports, reg 68, bits 16-23*/
-#define AR_PHY_SPECTRAL_SCAN_COUNT_S		16
-#define AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT	0x01000000  /* Short repeat, reg 68, bit 24*/
-#define AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT_S	24  /* Short repeat, reg 68, bit 24*/
-
-#define AR_PHY_RX_DELAY           0x9914
-#define AR_PHY_SEARCH_START_DELAY 0x9918
-#define AR_PHY_RX_DELAY_DELAY     0x00003FFF
-
-#define AR_PHY_TIMING_CTRL4(_i)     (0x9920 + ((_i) << 12))
-#define AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF 0x01F
-#define AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF_S   0
-#define AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF 0x7E0
-#define AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF_S   5
-#define AR_PHY_TIMING_CTRL4_IQCORR_ENABLE   0x800
-#define AR_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX 0xF000
-#define AR_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX_S   12
-#define AR_PHY_TIMING_CTRL4_DO_CAL    0x10000
-
-#define AR_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI	0x80000000
-#define	AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER	0x40000000
-#define	AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK	0x20000000
-#define	AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK	0x10000000
-
-#define AR_PHY_TIMING5               0x9924
-#define AR_PHY_TIMING5_CYCPWR_THR1   0x000000FE
-#define AR_PHY_TIMING5_CYCPWR_THR1_S 1
-
-#define AR_PHY_POWER_TX_RATE1               0x9934
-#define AR_PHY_POWER_TX_RATE2               0x9938
-#define AR_PHY_POWER_TX_RATE_MAX            0x993c
-#define AR_PHY_POWER_TX_RATE_MAX_TPC_ENABLE 0x00000040
-
-#define AR_PHY_FRAME_CTL            0x9944
-#define AR_PHY_FRAME_CTL_TX_CLIP    0x00000038
-#define AR_PHY_FRAME_CTL_TX_CLIP_S  3
-
-#define AR_PHY_TXPWRADJ                   0x994C
-#define AR_PHY_TXPWRADJ_CCK_GAIN_DELTA    0x00000FC0
-#define AR_PHY_TXPWRADJ_CCK_GAIN_DELTA_S  6
-#define AR_PHY_TXPWRADJ_CCK_PCDAC_INDEX   0x00FC0000
-#define AR_PHY_TXPWRADJ_CCK_PCDAC_INDEX_S 18
-
-#define AR_PHY_RADAR_EXT      0x9940
-#define AR_PHY_RADAR_EXT_ENA  0x00004000
-
-#define AR_PHY_RADAR_0          0x9954
-#define AR_PHY_RADAR_0_ENA      0x00000001
-#define AR_PHY_RADAR_0_FFT_ENA  0x80000000
-#define AR_PHY_RADAR_0_INBAND   0x0000003e
-#define AR_PHY_RADAR_0_INBAND_S 1
-#define AR_PHY_RADAR_0_PRSSI    0x00000FC0
-#define AR_PHY_RADAR_0_PRSSI_S  6
-#define AR_PHY_RADAR_0_HEIGHT   0x0003F000
-#define AR_PHY_RADAR_0_HEIGHT_S 12
-#define AR_PHY_RADAR_0_RRSSI    0x00FC0000
-#define AR_PHY_RADAR_0_RRSSI_S  18
-#define AR_PHY_RADAR_0_FIRPWR   0x7F000000
-#define AR_PHY_RADAR_0_FIRPWR_S 24
-
-#define AR_PHY_RADAR_1                  0x9958
-#define AR_PHY_RADAR_1_RELPWR_ENA       0x00800000
-#define AR_PHY_RADAR_1_USE_FIR128       0x00400000
-#define AR_PHY_RADAR_1_RELPWR_THRESH    0x003F0000
-#define AR_PHY_RADAR_1_RELPWR_THRESH_S  16
-#define AR_PHY_RADAR_1_BLOCK_CHECK      0x00008000
-#define AR_PHY_RADAR_1_MAX_RRSSI        0x00004000
-#define AR_PHY_RADAR_1_RELSTEP_CHECK    0x00002000
-#define AR_PHY_RADAR_1_RELSTEP_THRESH   0x00001F00
-#define AR_PHY_RADAR_1_RELSTEP_THRESH_S 8
-#define AR_PHY_RADAR_1_MAXLEN           0x000000FF
-#define AR_PHY_RADAR_1_MAXLEN_S         0
-
-#define AR_PHY_SWITCH_CHAIN_0     0x9960
-#define AR_PHY_SWITCH_COM         0x9964
-
-#define AR_PHY_SIGMA_DELTA            0x996C
-#define AR_PHY_SIGMA_DELTA_ADC_SEL    0x00000003
-#define AR_PHY_SIGMA_DELTA_ADC_SEL_S  0
-#define AR_PHY_SIGMA_DELTA_FILT2      0x000000F8
-#define AR_PHY_SIGMA_DELTA_FILT2_S    3
-#define AR_PHY_SIGMA_DELTA_FILT1      0x00001F00
-#define AR_PHY_SIGMA_DELTA_FILT1_S    8
-#define AR_PHY_SIGMA_DELTA_ADC_CLIP   0x01FFE000
-#define AR_PHY_SIGMA_DELTA_ADC_CLIP_S 13
-
-#define AR_PHY_RESTART          0x9970
-#define AR_PHY_RESTART_DIV_GC   0x001C0000
-#define AR_PHY_RESTART_DIV_GC_S 18
-
-#define AR_PHY_RFBUS_REQ        0x997C
-#define AR_PHY_RFBUS_REQ_EN     0x00000001
-
-#define	AR_PHY_TIMING7		        0x9980
-#define	AR_PHY_TIMING8		        0x9984
-#define	AR_PHY_TIMING8_PILOT_MASK_2	0x000FFFFF
-#define	AR_PHY_TIMING8_PILOT_MASK_2_S	0
-
-#define	AR_PHY_BIN_MASK2_1	0x9988
-#define	AR_PHY_BIN_MASK2_2	0x998c
-#define	AR_PHY_BIN_MASK2_3	0x9990
-#define	AR_PHY_BIN_MASK2_4	0x9994
-
-#define	AR_PHY_BIN_MASK_1	0x9900
-#define	AR_PHY_BIN_MASK_2	0x9904
-#define	AR_PHY_BIN_MASK_3	0x9908
-
-#define	AR_PHY_MASK_CTL		0x990c
-
-#define	AR_PHY_BIN_MASK2_4_MASK_4	0x00003FFF
-#define	AR_PHY_BIN_MASK2_4_MASK_4_S	0
-
-#define	AR_PHY_TIMING9		        0x9998
-#define	AR_PHY_TIMING10		        0x999c
-#define	AR_PHY_TIMING10_PILOT_MASK_2	0x000FFFFF
-#define	AR_PHY_TIMING10_PILOT_MASK_2_S	0
-
-#define	AR_PHY_TIMING11			        0x99a0
-#define	AR_PHY_TIMING11_SPUR_DELTA_PHASE	0x000FFFFF
-#define	AR_PHY_TIMING11_SPUR_DELTA_PHASE_S	0
-#define	AR_PHY_TIMING11_SPUR_FREQ_SD		0x3FF00000
-#define	AR_PHY_TIMING11_SPUR_FREQ_SD_S		20
-#define AR_PHY_TIMING11_USE_SPUR_IN_AGC		0x40000000
-#define AR_PHY_TIMING11_USE_SPUR_IN_SELFCOR	0x80000000
-
-#define AR_PHY_RX_CHAINMASK     0x99a4
-#define AR_PHY_NEW_ADC_DC_GAIN_CORR(_i) (0x99b4 + ((_i) << 12))
-#define AR_PHY_NEW_ADC_GAIN_CORR_ENABLE 0x40000000
-#define AR_PHY_NEW_ADC_DC_OFFSET_CORR_ENABLE 0x80000000
-
-#define AR_PHY_MULTICHAIN_GAIN_CTL          0x99ac
-#define AR_PHY_9285_ANT_DIV_CTL_ALL         0x7f000000
-#define AR_PHY_9285_ANT_DIV_CTL             0x01000000
-#define AR_PHY_9285_ANT_DIV_CTL_S           24
-#define AR_PHY_9285_ANT_DIV_ALT_LNACONF     0x06000000
-#define AR_PHY_9285_ANT_DIV_ALT_LNACONF_S   25
-#define AR_PHY_9285_ANT_DIV_MAIN_LNACONF    0x18000000
-#define AR_PHY_9285_ANT_DIV_MAIN_LNACONF_S  27
-#define AR_PHY_9285_ANT_DIV_ALT_GAINTB      0x20000000
-#define AR_PHY_9285_ANT_DIV_ALT_GAINTB_S    29
-#define AR_PHY_9285_ANT_DIV_MAIN_GAINTB     0x40000000
-#define AR_PHY_9285_ANT_DIV_MAIN_GAINTB_S   30
-#define AR_PHY_9285_ANT_DIV_LNA1            2
-#define AR_PHY_9285_ANT_DIV_LNA2            1
-#define AR_PHY_9285_ANT_DIV_LNA1_PLUS_LNA2  3
-#define AR_PHY_9285_ANT_DIV_LNA1_MINUS_LNA2 0
-#define AR_PHY_9285_ANT_DIV_GAINTB_0        0
-#define AR_PHY_9285_ANT_DIV_GAINTB_1        1
-
-#define AR_PHY_EXT_CCA0             0x99b8
-#define AR_PHY_EXT_CCA0_THRESH62    0x000000FF
-#define AR_PHY_EXT_CCA0_THRESH62_S  0
-
-#define AR_PHY_EXT_CCA                  0x99bc
-#define AR_PHY_EXT_CCA_CYCPWR_THR1      0x0000FE00
-#define AR_PHY_EXT_CCA_CYCPWR_THR1_S    9
-#define AR_PHY_EXT_CCA_THRESH62         0x007F0000
-#define AR_PHY_EXT_CCA_THRESH62_S       16
-#define AR_PHY_EXT_MINCCA_PWR           0xFF800000
-#define AR_PHY_EXT_MINCCA_PWR_S         23
-#define AR9280_PHY_EXT_MINCCA_PWR       0x01FF0000
-#define AR9280_PHY_EXT_MINCCA_PWR_S     16
-
-#define AR_PHY_SFCORR_EXT                 0x99c0
-#define AR_PHY_SFCORR_EXT_M1_THRESH       0x0000007F
-#define AR_PHY_SFCORR_EXT_M1_THRESH_S     0
-#define AR_PHY_SFCORR_EXT_M2_THRESH       0x00003F80
-#define AR_PHY_SFCORR_EXT_M2_THRESH_S     7
-#define AR_PHY_SFCORR_EXT_M1_THRESH_LOW   0x001FC000
-#define AR_PHY_SFCORR_EXT_M1_THRESH_LOW_S 14
-#define AR_PHY_SFCORR_EXT_M2_THRESH_LOW   0x0FE00000
-#define AR_PHY_SFCORR_EXT_M2_THRESH_LOW_S 21
-#define AR_PHY_SFCORR_SPUR_SUBCHNL_SD_S   28
-
-#define AR_PHY_HALFGI           0x99D0
-#define AR_PHY_HALFGI_DSC_MAN   0x0007FFF0
-#define AR_PHY_HALFGI_DSC_MAN_S 4
-#define AR_PHY_HALFGI_DSC_EXP   0x0000000F
-#define AR_PHY_HALFGI_DSC_EXP_S 0
-
-#define AR_PHY_CHAN_INFO_MEMORY               0x99DC
-#define AR_PHY_CHAN_INFO_MEMORY_CAPTURE_MASK  0x0001
-
-#define AR_PHY_HEAVY_CLIP_ENABLE         0x99E0
-
-#define AR_PHY_HEAVY_CLIP_FACTOR_RIFS    0x99EC
-#define AR_PHY_RIFS_INIT_DELAY         0x03ff0000
-
-#define AR_PHY_M_SLEEP      0x99f0
-#define AR_PHY_REFCLKDLY    0x99f4
-#define AR_PHY_REFCLKPD     0x99f8
-
-#define AR_PHY_CALMODE      0x99f0
-
-#define AR_PHY_CALMODE_IQ           0x00000000
-#define AR_PHY_CALMODE_ADC_GAIN     0x00000001
-#define AR_PHY_CALMODE_ADC_DC_PER   0x00000002
-#define AR_PHY_CALMODE_ADC_DC_INIT  0x00000003
-
-#define AR_PHY_CAL_MEAS_0(_i)     (0x9c10 + ((_i) << 12))
-#define AR_PHY_CAL_MEAS_1(_i)     (0x9c14 + ((_i) << 12))
-#define AR_PHY_CAL_MEAS_2(_i)     (0x9c18 + ((_i) << 12))
-#define AR_PHY_CAL_MEAS_3(_i)     (0x9c1c + ((_i) << 12))
-
-#define AR_PHY_CURRENT_RSSI 0x9c1c
-#define AR9280_PHY_CURRENT_RSSI 0x9c3c
-
-#define AR_PHY_RFBUS_GRANT       0x9C20
-#define AR_PHY_RFBUS_GRANT_EN    0x00000001
-
-#define AR_PHY_CHAN_INFO_GAIN_DIFF             0x9CF4
-#define AR_PHY_CHAN_INFO_GAIN_DIFF_UPPER_LIMIT 320
-
-#define AR_PHY_CHAN_INFO_GAIN          0x9CFC
-
-#define AR_PHY_MODE         0xA200
-#define AR_PHY_MODE_ASYNCFIFO 0x80
-#define AR_PHY_MODE_AR2133  0x08
-#define AR_PHY_MODE_AR5111  0x00
-#define AR_PHY_MODE_AR5112  0x08
-#define AR_PHY_MODE_DYNAMIC 0x04
-#define AR_PHY_MODE_RF2GHZ  0x02
-#define AR_PHY_MODE_RF5GHZ  0x00
-#define AR_PHY_MODE_CCK     0x01
-#define AR_PHY_MODE_OFDM    0x00
-#define AR_PHY_MODE_DYN_CCK_DISABLE 0x100
-
-#define AR_PHY_CCK_TX_CTRL       0xA204
-#define AR_PHY_CCK_TX_CTRL_JAPAN 0x00000010
-#define AR_PHY_CCK_TX_CTRL_TX_DAC_SCALE_CCK         0x0000000C
-#define AR_PHY_CCK_TX_CTRL_TX_DAC_SCALE_CCK_S       2
-
-#define AR_PHY_CCK_DETECT                           0xA208
-#define AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK          0x0000003F
-#define AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK_S        0
-/* [12:6] settling time for antenna switch */
-#define AR_PHY_CCK_DETECT_ANT_SWITCH_TIME           0x00001FC0
-#define AR_PHY_CCK_DETECT_ANT_SWITCH_TIME_S         6
-#define AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV    0x2000
-#define AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV_S  13
-
-#define AR_PHY_GAIN_2GHZ                0xA20C
-#define AR_PHY_GAIN_2GHZ_RXTX_MARGIN    0x00FC0000
-#define AR_PHY_GAIN_2GHZ_RXTX_MARGIN_S  18
-#define AR_PHY_GAIN_2GHZ_BSW_MARGIN     0x00003C00
-#define AR_PHY_GAIN_2GHZ_BSW_MARGIN_S   10
-#define AR_PHY_GAIN_2GHZ_BSW_ATTEN      0x0000001F
-#define AR_PHY_GAIN_2GHZ_BSW_ATTEN_S    0
-
-#define AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN     0x003E0000
-#define AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN_S   17
-#define AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN     0x0001F000
-#define AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN_S   12
-#define AR_PHY_GAIN_2GHZ_XATTEN2_DB         0x00000FC0
-#define AR_PHY_GAIN_2GHZ_XATTEN2_DB_S       6
-#define AR_PHY_GAIN_2GHZ_XATTEN1_DB         0x0000003F
-#define AR_PHY_GAIN_2GHZ_XATTEN1_DB_S       0
-
-#define AR_PHY_CCK_RXCTRL4  0xA21C
-#define AR_PHY_CCK_RXCTRL4_FREQ_EST_SHORT   0x01F80000
-#define AR_PHY_CCK_RXCTRL4_FREQ_EST_SHORT_S 19
-
-#define AR_PHY_DAG_CTRLCCK  0xA228
-#define AR_PHY_DAG_CTRLCCK_EN_RSSI_THR  0x00000200
-#define AR_PHY_DAG_CTRLCCK_RSSI_THR     0x0001FC00
-#define AR_PHY_DAG_CTRLCCK_RSSI_THR_S   10
-
-#define AR_PHY_FORCE_CLKEN_CCK              0xA22C
-#define AR_PHY_FORCE_CLKEN_CCK_MRC_MUX      0x00000040
-
-#define AR_PHY_POWER_TX_RATE3   0xA234
-#define AR_PHY_POWER_TX_RATE4   0xA238
-
-#define AR_PHY_SCRM_SEQ_XR       0xA23C
-#define AR_PHY_HEADER_DETECT_XR  0xA240
-#define AR_PHY_CHIRP_DETECTED_XR 0xA244
-#define AR_PHY_BLUETOOTH         0xA254
-
-#define AR_PHY_TPCRG1   0xA258
-#define AR_PHY_TPCRG1_NUM_PD_GAIN   0x0000c000
-#define AR_PHY_TPCRG1_NUM_PD_GAIN_S 14
-
-#define AR_PHY_TPCRG1_PD_GAIN_1    0x00030000
-#define AR_PHY_TPCRG1_PD_GAIN_1_S  16
-#define AR_PHY_TPCRG1_PD_GAIN_2    0x000C0000
-#define AR_PHY_TPCRG1_PD_GAIN_2_S  18
-#define AR_PHY_TPCRG1_PD_GAIN_3    0x00300000
-#define AR_PHY_TPCRG1_PD_GAIN_3_S  20
-
-#define AR_PHY_TPCRG1_PD_CAL_ENABLE   0x00400000
-#define AR_PHY_TPCRG1_PD_CAL_ENABLE_S 22
-
-#define AR_PHY_TX_PWRCTRL4       0xa264
-#define AR_PHY_TX_PWRCTRL_PD_AVG_VALID     0x00000001
-#define AR_PHY_TX_PWRCTRL_PD_AVG_VALID_S   0
-#define AR_PHY_TX_PWRCTRL_PD_AVG_OUT       0x000001FE
-#define AR_PHY_TX_PWRCTRL_PD_AVG_OUT_S     1
-
-#define AR_PHY_TX_PWRCTRL6_0     0xa270
-#define AR_PHY_TX_PWRCTRL6_1     0xb270
-#define AR_PHY_TX_PWRCTRL_ERR_EST_MODE     0x03000000
-#define AR_PHY_TX_PWRCTRL_ERR_EST_MODE_S   24
-
-#define AR_PHY_TX_PWRCTRL7       0xa274
 #define AR_PHY_TX_PWRCTRL_TX_GAIN_TAB_MAX   0x0007E000
 #define AR_PHY_TX_PWRCTRL_TX_GAIN_TAB_MAX_S 13
-#define AR_PHY_TX_PWRCTRL_INIT_TX_GAIN     0x01F80000
-#define AR_PHY_TX_PWRCTRL_INIT_TX_GAIN_S   19
-
-#define AR_PHY_TX_PWRCTRL9       0xa27C
-#define AR_PHY_TX_DESIRED_SCALE_CCK        0x00007C00
-#define AR_PHY_TX_DESIRED_SCALE_CCK_S      10
-#define AR_PHY_TX_PWRCTRL9_RES_DC_REMOVAL  0x80000000
-#define AR_PHY_TX_PWRCTRL9_RES_DC_REMOVAL_S 31
-
-#define AR_PHY_TX_GAIN_TBL1      0xa300
 #define AR_PHY_TX_GAIN_CLC       0x0000001E
 #define AR_PHY_TX_GAIN_CLC_S     1
 #define AR_PHY_TX_GAIN           0x0007F000
@@ -523,91 +33,6 @@ bool ath9k_hw_set_rf_regs(struct ath_hw *ah,
 #define AR_PHY_CLC_Q0        0x0000ffd0
 #define AR_PHY_CLC_Q0_S      5
 
-#define AR_PHY_CH0_TX_PWRCTRL11  0xa398
-#define AR_PHY_CH1_TX_PWRCTRL11  0xb398
-#define AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP   0x0000FC00
-#define AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP_S 10
-
-#define AR_PHY_VIT_MASK2_M_46_61 0xa3a0
-#define AR_PHY_MASK2_M_31_45     0xa3a4
-#define AR_PHY_MASK2_M_16_30     0xa3a8
-#define AR_PHY_MASK2_M_00_15     0xa3ac
-#define AR_PHY_MASK2_P_15_01     0xa3b8
-#define AR_PHY_MASK2_P_30_16     0xa3bc
-#define AR_PHY_MASK2_P_45_31     0xa3c0
-#define AR_PHY_MASK2_P_61_45     0xa3c4
-#define AR_PHY_SPUR_REG          0x994c
-
-#define AR_PHY_SPUR_REG_MASK_RATE_CNTL       (0xFF << 18)
-#define AR_PHY_SPUR_REG_MASK_RATE_CNTL_S     18
-
-#define AR_PHY_SPUR_REG_ENABLE_MASK_PPM      0x20000
-#define AR_PHY_SPUR_REG_MASK_RATE_SELECT     (0xFF << 9)
-#define AR_PHY_SPUR_REG_MASK_RATE_SELECT_S   9
-#define AR_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI 0x100
-#define AR_PHY_SPUR_REG_SPUR_RSSI_THRESH     0x7F
-#define AR_PHY_SPUR_REG_SPUR_RSSI_THRESH_S   0
-
-#define AR_PHY_PILOT_MASK_01_30   0xa3b0
-#define AR_PHY_PILOT_MASK_31_60   0xa3b4
-
-#define AR_PHY_CHANNEL_MASK_01_30 0x99d4
-#define AR_PHY_CHANNEL_MASK_31_60 0x99d8
-
-#define AR_PHY_ANALOG_SWAP      0xa268
-#define AR_PHY_SWAP_ALT_CHAIN   0x00000040
-
-#define AR_PHY_TPCRG5   0xA26C
-#define AR_PHY_TPCRG5_PD_GAIN_OVERLAP       0x0000000F
-#define AR_PHY_TPCRG5_PD_GAIN_OVERLAP_S     0
-#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1    0x000003F0
-#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1_S  4
-#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2    0x0000FC00
-#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2_S  10
-#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3    0x003F0000
-#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3_S  16
-#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4    0x0FC00000
-#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4_S  22
-
-/* Carrier leak calibration control, do it after AGC calibration */
-#define AR_PHY_CL_CAL_CTL       0xA358
-#define AR_PHY_CL_CAL_ENABLE    0x00000002
-#define AR_PHY_PARALLEL_CAL_ENABLE    0x00000001
-
-#define AR_PHY_POWER_TX_RATE5   0xA38C
-#define AR_PHY_POWER_TX_RATE6   0xA390
-
-#define AR_PHY_CAL_CHAINMASK    0xA39C
-
-#define AR_PHY_POWER_TX_SUB     0xA3C8
-#define AR_PHY_POWER_TX_RATE7   0xA3CC
-#define AR_PHY_POWER_TX_RATE8   0xA3D0
-#define AR_PHY_POWER_TX_RATE9   0xA3D4
-
-#define AR_PHY_XPA_CFG  	0xA3D8
-#define AR_PHY_FORCE_XPA_CFG	0x000000001
-#define AR_PHY_FORCE_XPA_CFG_S	0
-
-#define AR_PHY_CH1_CCA          0xa864
-#define AR_PHY_CH1_MINCCA_PWR   0x0FF80000
-#define AR_PHY_CH1_MINCCA_PWR_S 19
-#define AR9280_PHY_CH1_MINCCA_PWR   0x1FF00000
-#define AR9280_PHY_CH1_MINCCA_PWR_S 20
-
-#define AR_PHY_CH2_CCA          0xb864
-#define AR_PHY_CH2_MINCCA_PWR   0x0FF80000
-#define AR_PHY_CH2_MINCCA_PWR_S 19
-
-#define AR_PHY_CH1_EXT_CCA          0xa9bc
-#define AR_PHY_CH1_EXT_MINCCA_PWR   0xFF800000
-#define AR_PHY_CH1_EXT_MINCCA_PWR_S 23
-#define AR9280_PHY_CH1_EXT_MINCCA_PWR   0x01FF0000
-#define AR9280_PHY_CH1_EXT_MINCCA_PWR_S 16
-
-#define AR_PHY_CH2_EXT_CCA          0xb9bc
-#define AR_PHY_CH2_EXT_MINCCA_PWR   0xFF800000
-#define AR_PHY_CH2_EXT_MINCCA_PWR_S 23
-
 #define REG_WRITE_RF_ARRAY(iniarray, regData, regWr) do {               \
 		int r;							\
 		for (r = 0; r < ((iniarray)->ia_rows); r++) {		\
@@ -622,6 +47,7 @@ bool ath9k_hw_set_rf_regs(struct ath_hw *ah,
 #define ANTSWAP_AB 0x0001
 #define REDUCE_CHAIN_0 0x00000050
 #define REDUCE_CHAIN_1 0x00000051
+#define AR_PHY_CHIP_ID 0x9818
 
 #define RF_BANK_SETUP(_bank, _iniarray, _col) do {			\
 		int i;							\
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 103+ messages in thread

* [PATCH v3 10/97] ath9k_hw: skip PLL initialization on AR9003 on Power-On-Reset
  2010-04-15 21:38 [PATCH v3 00/97] ath9k: add AR9003 support Luis R. Rodriguez
                   ` (8 preceding siblings ...)
  2010-04-15 21:38 ` [PATCH v3 09/97] ath9k_hw: Move some RF ops to the private callbacks Luis R. Rodriguez
@ 2010-04-15 21:38 ` Luis R. Rodriguez
  2010-04-15 21:38 ` [PATCH v3 11/97] ath9k_hw: add some comments for ath9k_set_power_network_sleep() Luis R. Rodriguez
                   ` (86 subsequent siblings)
  96 siblings, 0 replies; 103+ messages in thread
From: Luis R. Rodriguez @ 2010-04-15 21:38 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Luis R. Rodriguez

This is not required for the AR9003 family.

Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/hw.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 060451f..dd37e90 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -2065,7 +2065,8 @@ static bool ath9k_hw_set_power_awake(struct ath_hw *ah, int setChip)
 					   ATH9K_RESET_POWER_ON) != true) {
 				return false;
 			}
-			ath9k_hw_init_pll(ah, NULL);
+			if (!AR_SREV_9300_20_OR_LATER(ah))
+				ath9k_hw_init_pll(ah, NULL);
 		}
 		if (AR_SREV_9100(ah))
 			REG_SET_BIT(ah, AR_RTC_RESET,
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 103+ messages in thread

* [PATCH v3 11/97] ath9k_hw: add some comments for ath9k_set_power_network_sleep()
  2010-04-15 21:38 [PATCH v3 00/97] ath9k: add AR9003 support Luis R. Rodriguez
                   ` (9 preceding siblings ...)
  2010-04-15 21:38 ` [PATCH v3 10/97] ath9k_hw: skip PLL initialization on AR9003 on Power-On-Reset Luis R. Rodriguez
@ 2010-04-15 21:38 ` Luis R. Rodriguez
  2010-04-15 21:38 ` [PATCH v3 12/97] ath9k_hw: add a private callback for PLL control computation Luis R. Rodriguez
                   ` (85 subsequent siblings)
  96 siblings, 0 replies; 103+ messages in thread
From: Luis R. Rodriguez @ 2010-04-15 21:38 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Luis R. Rodriguez

Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/hw.c |   10 ++++++++++
 1 files changed, 10 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index dd37e90..8aa1684 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -2037,6 +2037,11 @@ static void ath9k_set_power_sleep(struct ath_hw *ah, int setChip)
 	}
 }
 
+/*
+ * Notify Power Management is enabled in self-generating
+ * frames. If request, set power mode of chip to
+ * auto/normal.  Duration in units of 128us (1/8 TU).
+ */
 static void ath9k_set_power_network_sleep(struct ath_hw *ah, int setChip)
 {
 	REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV);
@@ -2044,9 +2049,14 @@ static void ath9k_set_power_network_sleep(struct ath_hw *ah, int setChip)
 		struct ath9k_hw_capabilities *pCap = &ah->caps;
 
 		if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) {
+			/* Set WakeOnInterrupt bit; clear ForceWake bit */
 			REG_WRITE(ah, AR_RTC_FORCE_WAKE,
 				  AR_RTC_FORCE_WAKE_ON_INT);
 		} else {
+			/*
+			 * Clear the RTC force wake bit to allow the
+			 * mac to go to sleep.
+			 */
 			REG_CLR_BIT(ah, AR_RTC_FORCE_WAKE,
 				    AR_RTC_FORCE_WAKE_EN);
 		}
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 103+ messages in thread

* [PATCH v3 12/97] ath9k_hw: add a private callback for PLL control computation
  2010-04-15 21:38 [PATCH v3 00/97] ath9k: add AR9003 support Luis R. Rodriguez
                   ` (10 preceding siblings ...)
  2010-04-15 21:38 ` [PATCH v3 11/97] ath9k_hw: add some comments for ath9k_set_power_network_sleep() Luis R. Rodriguez
@ 2010-04-15 21:38 ` Luis R. Rodriguez
  2010-04-15 21:38 ` [PATCH v3 13/97] ath9k_hw: Add the PCI IDs for AR9300 and fill up the pci_id_tables Luis R. Rodriguez
                   ` (84 subsequent siblings)
  96 siblings, 0 replies; 103+ messages in thread
From: Luis R. Rodriguez @ 2010-04-15 21:38 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Luis R. Rodriguez

The PLL control computation used to program the AR_RTC_PLL_CONTROL
register varies between our harware so just add a private callback for it.
AR9003 will use its own callback.

Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/ar5008_phy.c |   55 +++++++++++++++++++++++
 drivers/net/wireless/ath/ath9k/ar9002_phy.c |   31 +++++++++++++
 drivers/net/wireless/ath/ath9k/hw.c         |   64 +++------------------------
 drivers/net/wireless/ath/ath9k/hw.h         |    4 ++
 4 files changed, 97 insertions(+), 57 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
index 982b0d3..9685f4c 100644
--- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
@@ -967,6 +967,54 @@ static void ar5008_set_diversity(struct ath_hw *ah, bool value)
 	REG_WRITE(ah, AR_PHY_CCK_DETECT, v);
 }
 
+static u32 ar9100_hw_compute_pll_control(struct ath_hw *ah,
+					 struct ath9k_channel *chan)
+{
+	if (chan && IS_CHAN_5GHZ(chan))
+		return 0x1450;
+	return 0x1458;
+}
+
+static u32 ar9160_hw_compute_pll_control(struct ath_hw *ah,
+					 struct ath9k_channel *chan)
+{
+	u32 pll;
+
+	pll = SM(0x5, AR_RTC_9160_PLL_REFDIV);
+
+	if (chan && IS_CHAN_HALF_RATE(chan))
+		pll |= SM(0x1, AR_RTC_9160_PLL_CLKSEL);
+	else if (chan && IS_CHAN_QUARTER_RATE(chan))
+		pll |= SM(0x2, AR_RTC_9160_PLL_CLKSEL);
+
+	if (chan && IS_CHAN_5GHZ(chan))
+		pll |= SM(0x50, AR_RTC_9160_PLL_DIV);
+	else
+		pll |= SM(0x58, AR_RTC_9160_PLL_DIV);
+
+	return pll;
+}
+
+static u32 ar5008_hw_compute_pll_control(struct ath_hw *ah,
+					 struct ath9k_channel *chan)
+{
+	u32 pll;
+
+	pll = AR_RTC_PLL_REFDIV_5 | AR_RTC_PLL_DIV2;
+
+	if (chan && IS_CHAN_HALF_RATE(chan))
+		pll |= SM(0x1, AR_RTC_PLL_CLKSEL);
+	else if (chan && IS_CHAN_QUARTER_RATE(chan))
+		pll |= SM(0x2, AR_RTC_PLL_CLKSEL);
+
+	if (chan && IS_CHAN_5GHZ(chan))
+		pll |= SM(0xa, AR_RTC_PLL_DIV);
+	else
+		pll |= SM(0xb, AR_RTC_PLL_DIV);
+
+	return pll;
+}
+
 void ar5008_hw_attach_phy_ops(struct ath_hw *ah)
 {
 	struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
@@ -988,4 +1036,11 @@ void ar5008_hw_attach_phy_ops(struct ath_hw *ah)
 	priv_ops->enable_rfkill = ar5008_hw_enable_rfkill;
 	priv_ops->restore_chainmask = ar5008_restore_chainmask;
 	priv_ops->set_diversity = ar5008_set_diversity;
+
+	if (AR_SREV_9100(ah))
+		priv_ops->compute_pll_control = ar9100_hw_compute_pll_control;
+	else if (AR_SREV_9160_10_OR_LATER(ah))
+		priv_ops->compute_pll_control = ar9160_hw_compute_pll_control;
+	else
+		priv_ops->compute_pll_control = ar5008_hw_compute_pll_control;
 }
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_phy.c b/drivers/net/wireless/ath/ath9k/ar9002_phy.c
index 29b50ca..87541a8 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9002_phy.c
@@ -437,6 +437,36 @@ static void ar9002_olc_init(struct ath_hw *ah)
 	}
 }
 
+static u32 ar9002_hw_compute_pll_control(struct ath_hw *ah,
+					 struct ath9k_channel *chan)
+{
+	u32 pll;
+
+	pll = SM(0x5, AR_RTC_9160_PLL_REFDIV);
+
+	if (chan && IS_CHAN_HALF_RATE(chan))
+		pll |= SM(0x1, AR_RTC_9160_PLL_CLKSEL);
+	else if (chan && IS_CHAN_QUARTER_RATE(chan))
+		pll |= SM(0x2, AR_RTC_9160_PLL_CLKSEL);
+
+	if (chan && IS_CHAN_5GHZ(chan)) {
+		pll |= SM(0x28, AR_RTC_9160_PLL_DIV);
+
+
+		if (AR_SREV_9280_20(ah)) {
+			if (((chan->channel % 20) == 0)
+			    || ((chan->channel % 10) == 0))
+				pll = 0x2850;
+			else
+				pll = 0x142c;
+		}
+	} else {
+		pll |= SM(0x2c, AR_RTC_9160_PLL_DIV);
+	}
+
+	return pll;
+}
+
 void ar9002_hw_attach_phy_ops(struct ath_hw *ah)
 {
 	struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
@@ -447,4 +477,5 @@ void ar9002_hw_attach_phy_ops(struct ath_hw *ah)
 	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;
 }
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 8aa1684..245e678 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -67,6 +67,12 @@ static bool ath9k_hw_macversion_supported(struct ath_hw *ah)
 	return priv_ops->macversion_supported(ah->hw_version.macVersion);
 }
 
+static u32 ath9k_hw_compute_pll_control(struct ath_hw *ah,
+					struct ath9k_channel *chan)
+{
+	return ath9k_hw_private_ops(ah)->compute_pll_control(ah, chan);
+}
+
 /********************/
 /* Helper Functions */
 /********************/
@@ -1024,64 +1030,8 @@ static void ath9k_hw_init_qos(struct ath_hw *ah)
 static void ath9k_hw_init_pll(struct ath_hw *ah,
 			      struct ath9k_channel *chan)
 {
-	u32 pll;
-
-	if (AR_SREV_9100(ah)) {
-		if (chan && IS_CHAN_5GHZ(chan))
-			pll = 0x1450;
-		else
-			pll = 0x1458;
-	} else {
-		if (AR_SREV_9280_10_OR_LATER(ah)) {
-			pll = SM(0x5, AR_RTC_9160_PLL_REFDIV);
-
-			if (chan && IS_CHAN_HALF_RATE(chan))
-				pll |= SM(0x1, AR_RTC_9160_PLL_CLKSEL);
-			else if (chan && IS_CHAN_QUARTER_RATE(chan))
-				pll |= SM(0x2, AR_RTC_9160_PLL_CLKSEL);
-
-			if (chan && IS_CHAN_5GHZ(chan)) {
-				pll |= SM(0x28, AR_RTC_9160_PLL_DIV);
-
-
-				if (AR_SREV_9280_20(ah)) {
-					if (((chan->channel % 20) == 0)
-					    || ((chan->channel % 10) == 0))
-						pll = 0x2850;
-					else
-						pll = 0x142c;
-				}
-			} else {
-				pll |= SM(0x2c, AR_RTC_9160_PLL_DIV);
-			}
-
-		} else if (AR_SREV_9160_10_OR_LATER(ah)) {
-
-			pll = SM(0x5, AR_RTC_9160_PLL_REFDIV);
-
-			if (chan && IS_CHAN_HALF_RATE(chan))
-				pll |= SM(0x1, AR_RTC_9160_PLL_CLKSEL);
-			else if (chan && IS_CHAN_QUARTER_RATE(chan))
-				pll |= SM(0x2, AR_RTC_9160_PLL_CLKSEL);
-
-			if (chan && IS_CHAN_5GHZ(chan))
-				pll |= SM(0x50, AR_RTC_9160_PLL_DIV);
-			else
-				pll |= SM(0x58, AR_RTC_9160_PLL_DIV);
-		} else {
-			pll = AR_RTC_PLL_REFDIV_5 | AR_RTC_PLL_DIV2;
-
-			if (chan && IS_CHAN_HALF_RATE(chan))
-				pll |= SM(0x1, AR_RTC_PLL_CLKSEL);
-			else if (chan && IS_CHAN_QUARTER_RATE(chan))
-				pll |= SM(0x2, AR_RTC_PLL_CLKSEL);
+	u32 pll = ath9k_hw_compute_pll_control(ah, chan);
 
-			if (chan && IS_CHAN_5GHZ(chan))
-				pll |= SM(0xa, AR_RTC_PLL_DIV);
-			else
-				pll |= SM(0xb, AR_RTC_PLL_DIV);
-		}
-	}
 	REG_WRITE(ah, AR_RTC_PLL_CONTROL, pll);
 
 	/* Switch the core clock for ar9271 to 117Mhz */
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index d740e9c..79b938b 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -454,6 +454,8 @@ struct ath_gen_timer_table {
  * @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
  */
 struct ath_hw_private_ops {
 	void (*init_cal_settings)(struct ath_hw *ah);
@@ -483,6 +485,8 @@ struct ath_hw_private_ops {
 	void (*enable_rfkill)(struct ath_hw *ah);
 	void (*restore_chainmask)(struct ath_hw *ah);
 	void (*set_diversity)(struct ath_hw *ah, bool value);
+	u32 (*compute_pll_control)(struct ath_hw *ah,
+				   struct ath9k_channel *chan);
 };
 
 /**
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 103+ messages in thread

* [PATCH v3 13/97] ath9k_hw: Add the PCI IDs for AR9300 and fill up the pci_id_tables
  2010-04-15 21:38 [PATCH v3 00/97] ath9k: add AR9003 support Luis R. Rodriguez
                   ` (11 preceding siblings ...)
  2010-04-15 21:38 ` [PATCH v3 12/97] ath9k_hw: add a private callback for PLL control computation Luis R. Rodriguez
@ 2010-04-15 21:38 ` Luis R. Rodriguez
  2010-04-15 21:38 ` [PATCH v3 14/97] ath9k_hw: Add AR9003 PHY support Luis R. Rodriguez
                   ` (83 subsequent siblings)
  96 siblings, 0 replies; 103+ messages in thread
From: Luis R. Rodriguez @ 2010-04-15 21:38 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Senthil Balasubramanian

From: Senthil Balasubramanian <senthilkumar@atheros.com>

Also, clean up and reorganize the AR9287 macro to have better
ordering. We won't add the PCI ID to the supported device list
until we have some functional code for it.

Signed-off-by: Senthil Balasubramanian <senthilkumar@atheros.com>
---
 drivers/net/wireless/ath/ath9k/hw.c |    5 +++--
 drivers/net/wireless/ath/ath9k/hw.h |    6 +++---
 2 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 245e678..b4becc6 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -985,9 +985,10 @@ int ath9k_hw_init(struct ath_hw *ah)
 	case AR9280_DEVID_PCI:
 	case AR9280_DEVID_PCIE:
 	case AR9285_DEVID_PCIE:
-	case AR5416_DEVID_AR9287_PCI:
-	case AR5416_DEVID_AR9287_PCIE:
+	case AR9287_DEVID_PCI:
+	case AR9287_DEVID_PCIE:
 	case AR2427_DEVID_PCIE:
+	case AR9300_DEVID_PCIE:
 		break;
 	default:
 		if (common->bus_ops->ath_bus_type == ATH_USB)
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 79b938b..a1ce79d 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -41,6 +41,9 @@
 #define AR9280_DEVID_PCIE	0x002a
 #define AR9285_DEVID_PCIE	0x002b
 #define AR2427_DEVID_PCIE	0x002c
+#define AR9287_DEVID_PCI	0x002d
+#define AR9287_DEVID_PCIE	0x002e
+#define AR9300_DEVID_PCIE	0x0030
 
 #define AR5416_AR9100_DEVID	0x000b
 
@@ -48,9 +51,6 @@
 #define AR_SUBVENDOR_ID_NEW_A	0x7065
 #define AR5416_MAGIC		0x19641014
 
-#define AR5416_DEVID_AR9287_PCI  0x002D
-#define AR5416_DEVID_AR9287_PCIE 0x002E
-
 #define AR9280_COEX2WIRE_SUBSYSID	0x309b
 #define AT9285_COEX3WIRE_SA_SUBSYSID	0x30aa
 #define AT9285_COEX3WIRE_DA_SUBSYSID	0x30ab
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 103+ messages in thread

* [PATCH v3 14/97] ath9k_hw: Add AR9003 PHY support
  2010-04-15 21:38 [PATCH v3 00/97] ath9k: add AR9003 support Luis R. Rodriguez
                   ` (12 preceding siblings ...)
  2010-04-15 21:38 ` [PATCH v3 13/97] ath9k_hw: Add the PCI IDs for AR9300 and fill up the pci_id_tables Luis R. Rodriguez
@ 2010-04-15 21:38 ` Luis R. Rodriguez
  2010-04-15 21:38 ` [PATCH v3 15/97] ath9k_hw: move init config and default after chip is up Luis R. Rodriguez
                   ` (82 subsequent siblings)
  96 siblings, 0 replies; 103+ messages in thread
From: Luis R. Rodriguez @ 2010-04-15 21:38 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Luis R. Rodriguez, Felix Fietkau

This add stubs for PHY support for the AR9003 hardware family.

Signed-off-by: Felix Fietkau <nbd@openwrt.org>
Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/Makefile     |    1 +
 drivers/net/wireless/ath/ath9k/ar9003_phy.c |  147 +++++++++++++++++++++++++++
 drivers/net/wireless/ath/ath9k/hw.c         |   20 +++-
 drivers/net/wireless/ath/ath9k/hw.h         |    3 +-
 4 files changed, 167 insertions(+), 4 deletions(-)
 create mode 100644 drivers/net/wireless/ath/ath9k/ar9003_phy.c

diff --git a/drivers/net/wireless/ath/ath9k/Makefile b/drivers/net/wireless/ath/ath9k/Makefile
index db63ba2..ecf3f8c 100644
--- a/drivers/net/wireless/ath/ath9k/Makefile
+++ b/drivers/net/wireless/ath/ath9k/Makefile
@@ -14,6 +14,7 @@ ath9k-$(CONFIG_ATH9K_DEBUGFS) += debug.o
 obj-$(CONFIG_ATH9K) += ath9k.o
 
 ath9k_hw-y:=	hw.o \
+		ar9003_phy.o \
 		ar9002_phy.o \
 		ar5008_phy.o \
 		eeprom.o \
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
new file mode 100644
index 0000000..c4511b8
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 2010 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "hw.h"
+
+/**
+ * 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)
+{
+	/* TODO */
+	return 0;
+}
+
+/**
+ * ar9003_hw_spur_mitigate - convert baseband spur frequency
+ * @ah: atheros hardware structure
+ * @chan:
+ *
+ * For single-chip solutions. Converts to baseband spur frequency given the
+ * input channel frequency and compute register settings below.
+ *
+ * Spur mitigation for MRC CCK
+ */
+static void ar9003_hw_spur_mitigate(struct ath_hw *ah,
+				    struct ath9k_channel *chan)
+{
+	/* TODO */
+}
+
+static u32 ar9003_hw_compute_pll_control(struct ath_hw *ah,
+					 struct ath9k_channel *chan)
+{
+	/* TODO */
+	return 0;
+}
+
+static void ar9003_hw_set_channel_regs(struct ath_hw *ah,
+				       struct ath9k_channel *chan)
+{
+	/* TODO */
+}
+
+static void ar9003_hw_init_bb(struct ath_hw *ah,
+			      struct ath9k_channel *chan)
+{
+	/* TODO */
+}
+
+static int ar9003_hw_process_ini(struct ath_hw *ah,
+				 struct ath9k_channel *chan)
+{
+	/* TODO */
+	return -1;
+}
+
+static void ar9003_hw_set_rfmode(struct ath_hw *ah,
+				 struct ath9k_channel *chan)
+{
+	/* TODO */
+}
+
+static void ar9003_hw_mark_phy_inactive(struct ath_hw *ah)
+{
+	/* TODO */
+}
+
+static void ar9003_hw_set_delta_slope(struct ath_hw *ah,
+				      struct ath9k_channel *chan)
+{
+	/* TODO */
+}
+
+static bool ar9003_hw_rfbus_req(struct ath_hw *ah)
+{
+	/* TODO */
+	return false;
+}
+
+static void ar9003_hw_rfbus_done(struct ath_hw *ah)
+{
+	/* TODO */
+}
+
+static void ar9003_hw_enable_rfkill(struct ath_hw *ah)
+{
+	/* TODO */
+}
+
+static void ar9003_hw_set_diversity(struct ath_hw *ah, bool value)
+{
+	/* TODO */
+}
+
+void ar9003_hw_attach_phy_ops(struct ath_hw *ah)
+{
+	struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
+
+	priv_ops->rf_set_freq = ar9003_hw_set_channel;
+	priv_ops->spur_mitigate_freq = ar9003_hw_spur_mitigate;
+	priv_ops->compute_pll_control = ar9003_hw_compute_pll_control;
+	priv_ops->set_channel_regs = ar9003_hw_set_channel_regs;
+	priv_ops->init_bb = ar9003_hw_init_bb;
+	priv_ops->process_ini = ar9003_hw_process_ini;
+	priv_ops->set_rfmode = ar9003_hw_set_rfmode;
+	priv_ops->mark_phy_inactive = ar9003_hw_mark_phy_inactive;
+	priv_ops->set_delta_slope = ar9003_hw_set_delta_slope;
+	priv_ops->rfbus_req = ar9003_hw_rfbus_req;
+	priv_ops->rfbus_done = ar9003_hw_rfbus_done;
+	priv_ops->enable_rfkill = ar9003_hw_enable_rfkill;
+	priv_ops->set_diversity = ar9003_hw_set_diversity;
+}
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index b4becc6..5dc7041 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -28,6 +28,7 @@
 #define ATH9K_CLOCK_RATE_2GHZ_OFDM	44
 
 static void ar9002_hw_attach_ops(struct ath_hw *ah);
+static void ar9003_hw_attach_ops(struct ath_hw *ah);
 
 static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type);
 
@@ -859,6 +860,14 @@ static void ath9k_hw_init_eeprom_fix(struct ath_hw *ah)
 			  "needs fixup for AR_AN_TOP2 register\n");
 }
 
+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)
 {
@@ -874,7 +883,7 @@ static int __ath9k_hw_init(struct ath_hw *ah)
 		return -EIO;
 	}
 
-	ar9002_hw_attach_ops(ah);
+	ath9k_hw_attach_ops(ah);
 
 	if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) {
 		ath_print(common, ATH_DBG_FATAL, "Couldn't wakeup chip\n");
@@ -3525,8 +3534,13 @@ static void ar9002_hw_attach_ops(struct ath_hw *ah)
 
 	ops->config_pci_powersave = ar9002_hw_configpcipowersave;
 
+	ar5008_hw_attach_phy_ops(ah);
 	if (AR_SREV_9280_10_OR_LATER(ah))
 		ar9002_hw_attach_phy_ops(ah);
-	else
-		ar5008_hw_attach_phy_ops(ah);
+}
+
+/* Sets up the AR9003 hardware familiy callbacks */
+static void ar9003_hw_attach_ops(struct ath_hw *ah)
+{
+	ar9003_hw_attach_phy_ops(ah);
 }
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index a1ce79d..3bc3621 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -783,8 +783,9 @@ void ath9k_hw_htc_resetinit(struct ath_hw *ah);
 void ath9k_hw_get_delta_slope_vals(struct ath_hw *ah, u32 coef_scaled,
 				   u32 *coef_mantissa, u32 *coef_exponent);
 
-void ar9002_hw_attach_phy_ops(struct ath_hw *ah);
 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);
 
 #define ATH_PCIE_CAP_LINK_CTRL	0x70
 #define ATH_PCIE_CAP_LINK_L0S	1
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 103+ messages in thread

* [PATCH v3 15/97] ath9k_hw: move init config and default after chip is up
  2010-04-15 21:38 [PATCH v3 00/97] ath9k: add AR9003 support Luis R. Rodriguez
                   ` (13 preceding siblings ...)
  2010-04-15 21:38 ` [PATCH v3 14/97] ath9k_hw: Add AR9003 PHY support Luis R. Rodriguez
@ 2010-04-15 21:38 ` Luis R. Rodriguez
  2010-04-15 21:38 ` [PATCH v3 16/97] ath9k_hw: add the AR9003 ar9003_hw_macversion_supported() Luis R. Rodriguez
                   ` (81 subsequent siblings)
  96 siblings, 0 replies; 103+ messages in thread
From: Luis R. Rodriguez @ 2010-04-15 21:38 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Luis R. Rodriguez, Felix Fietkau

This allows us to add SREV checks on these helpers.

Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
 drivers/net/wireless/ath/ath9k/hw.c |    9 +++++----
 1 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 5dc7041..7127166 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -410,8 +410,6 @@ static void ath9k_hw_init_defaults(struct ath_hw *ah)
 	ah->hw_version.subvendorid = 0;
 
 	ah->ah_flags = 0;
-	if (ah->hw_version.devid == AR5416_AR9100_DEVID)
-		ah->hw_version.macVersion = AR_SREV_VERSION_9100;
 	if (!AR_SREV_9100(ah))
 		ah->ah_flags = AH_USE_EEPROM;
 
@@ -874,8 +872,8 @@ static int __ath9k_hw_init(struct ath_hw *ah)
 	struct ath_common *common = ath9k_hw_common(ah);
 	int r = 0;
 
-	ath9k_hw_init_defaults(ah);
-	ath9k_hw_init_config(ah);
+	if (ah->hw_version.devid == AR5416_AR9100_DEVID)
+		ah->hw_version.macVersion = AR_SREV_VERSION_9100;
 
 	if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_POWER_ON)) {
 		ath_print(common, ATH_DBG_FATAL,
@@ -883,6 +881,9 @@ static int __ath9k_hw_init(struct ath_hw *ah)
 		return -EIO;
 	}
 
+	ath9k_hw_init_defaults(ah);
+	ath9k_hw_init_config(ah);
+
 	ath9k_hw_attach_ops(ah);
 
 	if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) {
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 103+ messages in thread

* [PATCH v3 16/97] ath9k_hw: add the AR9003 ar9003_hw_macversion_supported()
  2010-04-15 21:38 [PATCH v3 00/97] ath9k: add AR9003 support Luis R. Rodriguez
                   ` (14 preceding siblings ...)
  2010-04-15 21:38 ` [PATCH v3 15/97] ath9k_hw: move init config and default after chip is up Luis R. Rodriguez
@ 2010-04-15 21:38 ` Luis R. Rodriguez
  2010-04-15 21:38 ` [PATCH v3 17/97] ath9k_hw: disable ANI for AR9003 Luis R. Rodriguez
                   ` (80 subsequent siblings)
  96 siblings, 0 replies; 103+ messages in thread
From: Luis R. Rodriguez @ 2010-04-15 21:38 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Luis R. Rodriguez

Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/hw.c |   15 +++++++++++++++
 1 files changed, 15 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 7127166..0e78e35 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -574,6 +574,17 @@ static bool ar9002_hw_macversion_supported(u32 macversion)
 	return false;
 }
 
+static bool ar9003_hw_macversion_supported(u32 macversion)
+{
+	switch (macversion) {
+	case AR_SREV_VERSION_9300:
+		return true;
+	default:
+		break;
+	}
+	return false;
+}
+
 static void ar9002_hw_init_cal_settings(struct ath_hw *ah)
 {
 	if (AR_SREV_9160_10_OR_LATER(ah)) {
@@ -3543,5 +3554,9 @@ static void ar9002_hw_attach_ops(struct ath_hw *ah)
 /* Sets up the AR9003 hardware familiy callbacks */
 static void ar9003_hw_attach_ops(struct ath_hw *ah)
 {
+	struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
+
+	priv_ops->macversion_supported = ar9003_hw_macversion_supported;
+
 	ar9003_hw_attach_phy_ops(ah);
 }
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 103+ messages in thread

* [PATCH v3 17/97] ath9k_hw: disable ANI for AR9003
  2010-04-15 21:38 [PATCH v3 00/97] ath9k: add AR9003 support Luis R. Rodriguez
                   ` (15 preceding siblings ...)
  2010-04-15 21:38 ` [PATCH v3 16/97] ath9k_hw: add the AR9003 ar9003_hw_macversion_supported() Luis R. Rodriguez
@ 2010-04-15 21:38 ` Luis R. Rodriguez
  2010-04-15 21:38 ` [PATCH v3 18/97] ath9k: disable the MIB interrupt if ANI is disabled Luis R. Rodriguez
                   ` (79 subsequent siblings)
  96 siblings, 0 replies; 103+ messages in thread
From: Luis R. Rodriguez @ 2010-04-15 21:38 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Luis R. Rodriguez, Enis Akay

ANI is still being debugged on AR9003 by our systems team
so it should not yet be enabled yet. When ANI will be
enabled all ANI functionality is expected to be enabled
so fill the ANI functionality to all for AR9003 for now
as well.

Cc: Enis Akay <Enis.Akay@atheros.com>
Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/hw.c |   10 ++++++++--
 1 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 0e78e35..e54c76e 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -364,7 +364,13 @@ static void ath9k_hw_init_config(struct ath_hw *ah)
 	ah->config.ofdm_trig_high = 500;
 	ah->config.cck_trig_high = 200;
 	ah->config.cck_trig_low = 100;
-	ah->config.enable_ani = 1;
+
+	/*
+	 * For now ANI is disabled for AR9003, it is still
+	 * being tested.
+	 */
+	if (!AR_SREV_9300_20_OR_LATER(ah))
+		ah->config.enable_ani = 1;
 
 	for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
 		ah->config.spurchans[i][0] = AR_NO_SPUR;
@@ -942,7 +948,7 @@ static int __ath9k_hw_init(struct ath_hw *ah)
 	ath9k_hw_init_cal_settings(ah);
 
 	ah->ani_function = ATH9K_ANI_ALL;
-	if (AR_SREV_9280_10_OR_LATER(ah))
+	if (AR_SREV_9280_10_OR_LATER(ah) && !AR_SREV_9300_20_OR_LATER(ah))
 		ah->ani_function &= ~ATH9K_ANI_NOISE_IMMUNITY_LEVEL;
 
 	ath9k_hw_init_mode_regs(ah);
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 103+ messages in thread

* [PATCH v3 18/97] ath9k: disable the MIB interrupt if ANI is disabled
  2010-04-15 21:38 [PATCH v3 00/97] ath9k: add AR9003 support Luis R. Rodriguez
                   ` (16 preceding siblings ...)
  2010-04-15 21:38 ` [PATCH v3 17/97] ath9k_hw: disable ANI for AR9003 Luis R. Rodriguez
@ 2010-04-15 21:38 ` Luis R. Rodriguez
  2010-04-15 21:38 ` [PATCH v3 19/97] ath9k_hw: Add hw cap flag for EDMA for the AR9003 family Luis R. Rodriguez
                   ` (78 subsequent siblings)
  96 siblings, 0 replies; 103+ messages in thread
From: Luis R. Rodriguez @ 2010-04-15 21:38 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Luis R. Rodriguez

Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/main.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index f7ef114..494456c 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -1436,7 +1436,8 @@ static int ath9k_add_interface(struct ieee80211_hw *hw,
 	if ((vif->type == NL80211_IFTYPE_STATION) ||
 	    (vif->type == NL80211_IFTYPE_ADHOC) ||
 	    (vif->type == NL80211_IFTYPE_MESH_POINT)) {
-		ah->imask |= ATH9K_INT_MIB;
+		if (ah->config.enable_ani)
+			ah->imask |= ATH9K_INT_MIB;
 		ah->imask |= ATH9K_INT_TSFOOR;
 	}
 
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 103+ messages in thread

* [PATCH v3 19/97] ath9k_hw: Add hw cap flag for EDMA for the AR9003 family
  2010-04-15 21:38 [PATCH v3 00/97] ath9k: add AR9003 support Luis R. Rodriguez
                   ` (17 preceding siblings ...)
  2010-04-15 21:38 ` [PATCH v3 18/97] ath9k: disable the MIB interrupt if ANI is disabled Luis R. Rodriguez
@ 2010-04-15 21:38 ` Luis R. Rodriguez
  2010-04-15 21:38 ` [PATCH v3 20/97] ath9k_hw: Fill few hw cap for edma Luis R. Rodriguez
                   ` (77 subsequent siblings)
  96 siblings, 0 replies; 103+ messages in thread
From: Luis R. Rodriguez @ 2010-04-15 21:38 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Vasanthakumar Thiagarajan

From: Vasanthakumar Thiagarajan <vasanth@atheros.com>

AR9003 supports extended DMA (EDMA), this comes with some
bells and whistles on top of the legacy DMA that we are used
to. Mark AR9003 and later chips EDMA capable.

Signed-off-by: Vasanthakumar Thiagarajan <vasanth@atheros.com>
---
 drivers/net/wireless/ath/ath9k/hw.c |    3 +++
 drivers/net/wireless/ath/ath9k/hw.h |    1 +
 2 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index e54c76e..2a3ff65 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -2874,6 +2874,9 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
 		btcoex_hw->scheme = ATH_BTCOEX_CFG_NONE;
 	}
 
+	if (AR_SREV_9300_20_OR_LATER(ah))
+		pCap->hw_caps |= ATH9K_HW_CAP_EDMA;
+
 	return 0;
 }
 
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 3bc3621..d89af6e 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -165,6 +165,7 @@ enum ath9k_hw_caps {
 	ATH9K_HW_CAP_ENHANCEDPM                 = BIT(14),
 	ATH9K_HW_CAP_AUTOSLEEP                  = BIT(15),
 	ATH9K_HW_CAP_4KB_SPLITTRANS             = BIT(16),
+	ATH9K_HW_CAP_EDMA			= BIT(17),
 };
 
 enum ath9k_capability_type {
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 103+ messages in thread

* [PATCH v3 20/97] ath9k_hw: Fill few hw cap for edma
  2010-04-15 21:38 [PATCH v3 00/97] ath9k: add AR9003 support Luis R. Rodriguez
                   ` (18 preceding siblings ...)
  2010-04-15 21:38 ` [PATCH v3 19/97] ath9k_hw: Add hw cap flag for EDMA for the AR9003 family Luis R. Rodriguez
@ 2010-04-15 21:38 ` Luis R. Rodriguez
  2010-04-15 21:38 ` [PATCH v3 21/97] ath9k_hw: Add abstraction for rx enable Luis R. Rodriguez
                   ` (76 subsequent siblings)
  96 siblings, 0 replies; 103+ messages in thread
From: Luis R. Rodriguez @ 2010-04-15 21:38 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Vasanthakumar Thiagarajan, Felix Fietkau

From: Vasanthakumar Thiagarajan <vasanth@atheros.com>

HP & LP queue depth and rx status length.

Signed-off-by: Vasanthakumar Thiagarajan <vasanth@atheros.com>
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
 drivers/net/wireless/ath/ath9k/ar9003_mac.h |   35 +++++++++++++++++++++++++++
 drivers/net/wireless/ath/ath9k/hw.c         |    6 ++++-
 drivers/net/wireless/ath/ath9k/hw.h         |    7 +++++
 3 files changed, 47 insertions(+), 1 deletions(-)
 create mode 100644 drivers/net/wireless/ath/ath9k/ar9003_mac.h

diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.h b/drivers/net/wireless/ath/ath9k/ar9003_mac.h
new file mode 100644
index 0000000..dbf74eb
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2010 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef AR9003_MAC_H
+#define AR9003_MAC_H
+
+struct ar9003_rxs {
+	u32 ds_info;
+	u32 status1;
+	u32 status2;
+	u32 status3;
+	u32 status4;
+	u32 status5;
+	u32 status6;
+	u32 status7;
+	u32 status8;
+	u32 status9;
+	u32 status10;
+	u32 status11;
+} __packed;
+
+#endif
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 2a3ff65..36c0163 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -2874,8 +2874,12 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
 		btcoex_hw->scheme = ATH_BTCOEX_CFG_NONE;
 	}
 
-	if (AR_SREV_9300_20_OR_LATER(ah))
+	if (AR_SREV_9300_20_OR_LATER(ah)) {
 		pCap->hw_caps |= ATH9K_HW_CAP_EDMA;
+		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);
+	}
 
 	return 0;
 }
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index d89af6e..6bd87bf 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -28,6 +28,7 @@
 #include "reg.h"
 #include "phy.h"
 #include "btcoex.h"
+#include "ar9003_mac.h"
 
 #include "../regd.h"
 #include "../debug.h"
@@ -135,6 +136,9 @@
 
 #define TU_TO_USEC(_tu)             ((_tu) << 10)
 
+#define ATH9K_HW_RX_HP_QDEPTH	16
+#define ATH9K_HW_RX_LP_QDEPTH	128
+
 enum wireless_mode {
 	ATH9K_MODE_11A = 0,
 	ATH9K_MODE_11G,
@@ -192,6 +196,9 @@ struct ath9k_hw_capabilities {
 	u8 num_gpio_pins;
 	u8 num_antcfg_2ghz;
 	u8 num_antcfg_5ghz;
+	u8 rx_hp_qdepth;
+	u8 rx_lp_qdepth;
+	u8 rx_status_len;
 };
 
 struct ath9k_ops_config {
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 103+ messages in thread

* [PATCH v3 21/97] ath9k_hw: Add abstraction for rx enable
  2010-04-15 21:38 [PATCH v3 00/97] ath9k: add AR9003 support Luis R. Rodriguez
                   ` (19 preceding siblings ...)
  2010-04-15 21:38 ` [PATCH v3 20/97] ath9k_hw: Fill few hw cap for edma Luis R. Rodriguez
@ 2010-04-15 21:38 ` Luis R. Rodriguez
  2010-04-15 21:38 ` [PATCH v3 22/97] ath9k_hw: Fill rx_enable() for the AR9003 hardware family Luis R. Rodriguez
                   ` (75 subsequent siblings)
  96 siblings, 0 replies; 103+ messages in thread
From: Luis R. Rodriguez @ 2010-04-15 21:38 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Vasanthakumar Thiagarajan

From: Vasanthakumar Thiagarajan <vasanth@atheros.com>

Signed-off-by: Vasanthakumar Thiagarajan <vasanth@atheros.com>
---
 drivers/net/wireless/ath/ath9k/hw-ops.h |    5 +++++
 drivers/net/wireless/ath/ath9k/hw.c     |    2 ++
 drivers/net/wireless/ath/ath9k/hw.h     |    1 +
 drivers/net/wireless/ath/ath9k/mac.c    |   17 +++++++++++------
 drivers/net/wireless/ath/ath9k/mac.h    |    3 ++-
 5 files changed, 21 insertions(+), 7 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/hw-ops.h b/drivers/net/wireless/ath/ath9k/hw-ops.h
index 81f3d03..19259fb 100644
--- a/drivers/net/wireless/ath/ath9k/hw-ops.h
+++ b/drivers/net/wireless/ath/ath9k/hw-ops.h
@@ -28,6 +28,11 @@ static inline void ath9k_hw_configpcipowersave(struct ath_hw *ah,
 	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);
+}
+
 /* Private hardware call ops */
 
 /* PHY ops */
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 36c0163..0a4ccd8 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -1567,6 +1567,8 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
 	if (tsf && AR_SREV_9280(ah) && ah->eep_ops->get_eeprom(ah, EEP_OL_PWRCTRL))
 		ath9k_hw_settsf64(ah, tsf);
 
+	ar9002_hw_attach_mac_ops(ah);
+
 	if (AR_SREV_9280_10_OR_LATER(ah))
 		REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL, AR_GPIO_JTAG_DISABLE);
 
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 6bd87bf..b07ee8d 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -509,6 +509,7 @@ struct ath_hw_ops {
 	void (*config_pci_powersave)(struct ath_hw *ah,
 				     int restore,
 				     int power_off);
+	void (*rx_enable)(struct ath_hw *ah);
 };
 
 struct ath_hw {
diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c
index 4a2060e..ae9d54c 100644
--- a/drivers/net/wireless/ath/ath9k/mac.c
+++ b/drivers/net/wireless/ath/ath9k/mac.c
@@ -16,6 +16,17 @@
 
 #include "hw.h"
 
+static void ar9002_hw_rx_enable(struct ath_hw *ah)
+{
+	REG_WRITE(ah, AR_CR, AR_CR_RXE);
+}
+
+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;
+}
 static void ath9k_hw_set_txq_interrupts(struct ath_hw *ah,
 					struct ath9k_tx_queue_info *qi)
 {
@@ -999,12 +1010,6 @@ void ath9k_hw_putrxbuf(struct ath_hw *ah, u32 rxdp)
 }
 EXPORT_SYMBOL(ath9k_hw_putrxbuf);
 
-void ath9k_hw_rxena(struct ath_hw *ah)
-{
-	REG_WRITE(ah, AR_CR, AR_CR_RXE);
-}
-EXPORT_SYMBOL(ath9k_hw_rxena);
-
 void ath9k_hw_startpcureceive(struct ath_hw *ah)
 {
 	ath9k_enable_mib_counters(ah);
diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h
index 68dbd7a..9e8500a 100644
--- a/drivers/net/wireless/ath/ath9k/mac.h
+++ b/drivers/net/wireless/ath/ath9k/mac.h
@@ -729,10 +729,11 @@ void ath9k_hw_setuprxdesc(struct ath_hw *ah, struct ath_desc *ds,
 			  u32 size, u32 flags);
 bool ath9k_hw_setrxabort(struct ath_hw *ah, bool set);
 void ath9k_hw_putrxbuf(struct ath_hw *ah, u32 rxdp);
-void ath9k_hw_rxena(struct ath_hw *ah);
 void ath9k_hw_startpcureceive(struct ath_hw *ah);
 void ath9k_hw_stoppcurecv(struct ath_hw *ah);
 bool ath9k_hw_stopdmarecv(struct ath_hw *ah);
 int ath9k_hw_beaconq_setup(struct ath_hw *ah);
 
+void ar9002_hw_attach_mac_ops(struct ath_hw *ah);
+
 #endif /* MAC_H */
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 103+ messages in thread

* [PATCH v3 22/97] ath9k_hw: Fill rx_enable() for the AR9003 hardware family
  2010-04-15 21:38 [PATCH v3 00/97] ath9k: add AR9003 support Luis R. Rodriguez
                   ` (20 preceding siblings ...)
  2010-04-15 21:38 ` [PATCH v3 21/97] ath9k_hw: Add abstraction for rx enable Luis R. Rodriguez
@ 2010-04-15 21:38 ` Luis R. Rodriguez
  2010-04-15 21:38 ` [PATCH v3 23/97] ath9k_hw: Add few routines for rx edma support Luis R. Rodriguez
                   ` (74 subsequent siblings)
  96 siblings, 0 replies; 103+ messages in thread
From: Luis R. Rodriguez @ 2010-04-15 21:38 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Vasanthakumar Thiagarajan

From: Vasanthakumar Thiagarajan <vasanth@atheros.com>

Signed-off-by: Vasanthakumar Thiagarajan <vasanth@atheros.com>
---
 drivers/net/wireless/ath/ath9k/Makefile     |    1 +
 drivers/net/wireless/ath/ath9k/ar9003_mac.c |   28 +++++++++++++++++++++++++++
 drivers/net/wireless/ath/ath9k/ar9003_mac.h |    2 +
 drivers/net/wireless/ath/ath9k/hw.c         |    6 +++-
 4 files changed, 35 insertions(+), 2 deletions(-)
 create mode 100644 drivers/net/wireless/ath/ath9k/ar9003_mac.c

diff --git a/drivers/net/wireless/ath/ath9k/Makefile b/drivers/net/wireless/ath/ath9k/Makefile
index ecf3f8c..96af3d9 100644
--- a/drivers/net/wireless/ath/ath9k/Makefile
+++ b/drivers/net/wireless/ath/ath9k/Makefile
@@ -25,6 +25,7 @@ ath9k_hw-y:=	hw.o \
 		ani.o \
 		btcoex.o \
 		mac.o \
+		ar9003_mac.o
 
 obj-$(CONFIG_ATH9K_HW) += ath9k_hw.o
 
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.c b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
new file mode 100644
index 0000000..ee84e64
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2010 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+#include "hw.h"
+
+static void ar9003_hw_rx_enable(struct ath_hw *hw)
+{
+	REG_WRITE(hw, AR_CR, 0);
+}
+
+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;
+}
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.h b/drivers/net/wireless/ath/ath9k/ar9003_mac.h
index dbf74eb..2a9d80e 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_mac.h
+++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.h
@@ -32,4 +32,6 @@ struct ar9003_rxs {
 	u32 status11;
 } __packed;
 
+void ar9003_hw_attach_mac_ops(struct ath_hw *hw);
+
 #endif
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 0a4ccd8..0b89605 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -1567,8 +1567,6 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
 	if (tsf && AR_SREV_9280(ah) && ah->eep_ops->get_eeprom(ah, EEP_OL_PWRCTRL))
 		ath9k_hw_settsf64(ah, tsf);
 
-	ar9002_hw_attach_mac_ops(ah);
-
 	if (AR_SREV_9280_10_OR_LATER(ah))
 		REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL, AR_GPIO_JTAG_DISABLE);
 
@@ -3564,6 +3562,8 @@ static void ar9002_hw_attach_ops(struct ath_hw *ah)
 	ar5008_hw_attach_phy_ops(ah);
 	if (AR_SREV_9280_10_OR_LATER(ah))
 		ar9002_hw_attach_phy_ops(ah);
+
+	ar9002_hw_attach_mac_ops(ah);
 }
 
 /* Sets up the AR9003 hardware familiy callbacks */
@@ -3574,4 +3574,6 @@ static void ar9003_hw_attach_ops(struct ath_hw *ah)
 	priv_ops->macversion_supported = ar9003_hw_macversion_supported;
 
 	ar9003_hw_attach_phy_ops(ah);
+
+	ar9003_hw_attach_mac_ops(ah);
 }
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 103+ messages in thread

* [PATCH v3 23/97] ath9k_hw: Add few routines for rx edma support
  2010-04-15 21:38 [PATCH v3 00/97] ath9k: add AR9003 support Luis R. Rodriguez
                   ` (21 preceding siblings ...)
  2010-04-15 21:38 ` [PATCH v3 22/97] ath9k_hw: Fill rx_enable() for the AR9003 hardware family Luis R. Rodriguez
@ 2010-04-15 21:38 ` Luis R. Rodriguez
  2010-04-15 21:38 ` [PATCH v3 24/97] ath9k_hw: update the chip tests for AR9003 Luis R. Rodriguez
                   ` (73 subsequent siblings)
  96 siblings, 0 replies; 103+ messages in thread
From: Luis R. Rodriguez @ 2010-04-15 21:38 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Vasanthakumar Thiagarajan, Felix Fietkau

From: Vasanthakumar Thiagarajan <vasanth@atheros.com>

* Set rx buf size in register 0x60
* Set rxdp on the respective hw rx queue (HP and LP queues)
* Process rx descriptor

Signed-off-by: Vasanthakumar Thiagarajan <vasanth@atheros.com>
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
 drivers/net/wireless/ath/ath9k/ar9003_mac.c |   95 +++++++++++++++++++++++++++
 drivers/net/wireless/ath/ath9k/ar9003_mac.h |   12 ++++
 drivers/net/wireless/ath/ath9k/hw.h         |    6 ++
 drivers/net/wireless/ath/ath9k/mac.h        |    2 +
 drivers/net/wireless/ath/ath9k/reg.h        |    6 ++
 5 files changed, 121 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.c b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
index ee84e64..2089006 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
@@ -26,3 +26,98 @@ void ar9003_hw_attach_mac_ops(struct ath_hw *hw)
 
 	ops->rx_enable = ar9003_hw_rx_enable;
 }
+
+void ath9k_hw_set_rx_bufsize(struct ath_hw *ah, u16 buf_size)
+{
+	REG_WRITE(ah, AR_DATABUF_SIZE, buf_size & AR_DATABUF_SIZE_MASK);
+}
+EXPORT_SYMBOL(ath9k_hw_set_rx_bufsize);
+
+void ath9k_hw_addrxbuf_edma(struct ath_hw *ah, u32 rxdp,
+			    enum ath9k_rx_qtype qtype)
+{
+	if (qtype == ATH9K_RX_QUEUE_HP)
+		REG_WRITE(ah, AR_HP_RXDP, rxdp);
+	else
+		REG_WRITE(ah, AR_LP_RXDP, rxdp);
+}
+EXPORT_SYMBOL(ath9k_hw_addrxbuf_edma);
+
+int ath9k_hw_process_rxdesc_edma(struct ath_hw *ah, struct ath_rx_status *rxs,
+				 void *buf_addr)
+{
+	struct ar9003_rxs *rxsp = (struct ar9003_rxs *) buf_addr;
+	unsigned int phyerr;
+
+	/* TODO: byte swap on big endian for ar9300_10 */
+
+	if ((rxsp->status11 & AR_RxDone) == 0)
+		return -EINPROGRESS;
+
+	if (MS(rxsp->ds_info, AR_DescId) != 0x168c)
+		return -EINVAL;
+
+	if ((rxsp->ds_info & (AR_TxRxDesc | AR_CtrlStat)) != 0)
+		return -EINPROGRESS;
+
+	rxs->rs_status = 0;
+	rxs->rs_flags =  0;
+
+	rxs->rs_datalen = rxsp->status2 & AR_DataLen;
+	rxs->rs_tstamp =  rxsp->status3;
+
+	/* XXX: Keycache */
+	rxs->rs_rssi = MS(rxsp->status5, AR_RxRSSICombined);
+	rxs->rs_rssi_ctl0 = MS(rxsp->status1, AR_RxRSSIAnt00);
+	rxs->rs_rssi_ctl1 = MS(rxsp->status1, AR_RxRSSIAnt01);
+	rxs->rs_rssi_ctl2 = MS(rxsp->status1, AR_RxRSSIAnt02);
+	rxs->rs_rssi_ext0 = MS(rxsp->status5, AR_RxRSSIAnt10);
+	rxs->rs_rssi_ext1 = MS(rxsp->status5, AR_RxRSSIAnt11);
+	rxs->rs_rssi_ext2 = MS(rxsp->status5, AR_RxRSSIAnt12);
+
+	if (rxsp->status11 & AR_RxKeyIdxValid)
+		rxs->rs_keyix = MS(rxsp->status11, AR_KeyIdx);
+	else
+		rxs->rs_keyix = ATH9K_RXKEYIX_INVALID;
+
+	rxs->rs_rate = MS(rxsp->status1, AR_RxRate);
+	rxs->rs_more = (rxsp->status2 & AR_RxMore) ? 1 : 0;
+
+	rxs->rs_isaggr = (rxsp->status11 & AR_RxAggr) ? 1 : 0;
+	rxs->rs_moreaggr = (rxsp->status11 & AR_RxMoreAggr) ? 1 : 0;
+	rxs->rs_antenna = (MS(rxsp->status4, AR_RxAntenna) & 0x7);
+	rxs->rs_flags  = (rxsp->status4 & AR_GI) ? ATH9K_RX_GI : 0;
+	rxs->rs_flags  |= (rxsp->status4 & AR_2040) ? ATH9K_RX_2040 : 0;
+
+	rxs->evm0 = rxsp->status6;
+	rxs->evm1 = rxsp->status7;
+	rxs->evm2 = rxsp->status8;
+	rxs->evm3 = rxsp->status9;
+	rxs->evm4 = (rxsp->status10 & 0xffff);
+
+	if (rxsp->status11 & AR_PreDelimCRCErr)
+		rxs->rs_flags |= ATH9K_RX_DELIM_CRC_PRE;
+
+	if (rxsp->status11 & AR_PostDelimCRCErr)
+		rxs->rs_flags |= ATH9K_RX_DELIM_CRC_POST;
+
+	if (rxsp->status11 & AR_DecryptBusyErr)
+		rxs->rs_flags |= ATH9K_RX_DECRYPT_BUSY;
+
+	if ((rxsp->status11 & AR_RxFrameOK) == 0) {
+		if (rxsp->status11 & AR_CRCErr) {
+			rxs->rs_status |= ATH9K_RXERR_CRC;
+		} else if (rxsp->status11 & AR_PHYErr) {
+			rxs->rs_status |= ATH9K_RXERR_PHY;
+			phyerr = MS(rxsp->status11, AR_PHYErrCode);
+			rxs->rs_phyerr = phyerr;
+		} else if (rxsp->status11 & AR_DecryptCRCErr) {
+			rxs->rs_status |= ATH9K_RXERR_DECRYPT;
+		} else if (rxsp->status11 & AR_MichaelErr) {
+			rxs->rs_status |= ATH9K_RXERR_MIC;
+		}
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(ath9k_hw_process_rxdesc_edma);
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.h b/drivers/net/wireless/ath/ath9k/ar9003_mac.h
index 2a9d80e..b22f78c 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_mac.h
+++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.h
@@ -17,6 +17,11 @@
 #ifndef AR9003_MAC_H
 #define AR9003_MAC_H
 
+#define AR_DescId	0xffff0000
+#define AR_DescId_S	16
+#define AR_CtrlStat	0x00004000
+#define AR_TxRxDesc	0x00008000
+
 struct ar9003_rxs {
 	u32 ds_info;
 	u32 status1;
@@ -33,5 +38,12 @@ struct ar9003_rxs {
 } __packed;
 
 void ar9003_hw_attach_mac_ops(struct ath_hw *hw);
+void ath9k_hw_set_rx_bufsize(struct ath_hw *ah, u16 buf_size);
+void ath9k_hw_addrxbuf_edma(struct ath_hw *ah, u32 rxdp,
+			    enum ath9k_rx_qtype qtype);
+
+int ath9k_hw_process_rxdesc_edma(struct ath_hw *ah,
+				 struct ath_rx_status *rxs,
+				 void *buf_addr);
 
 #endif
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index b07ee8d..d713ff2 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -370,6 +370,12 @@ enum ser_reg_mode {
 	SER_REG_MODE_AUTO = 2,
 };
 
+enum ath9k_rx_qtype {
+	ATH9K_RX_QUEUE_HP,
+	ATH9K_RX_QUEUE_LP,
+	ATH9K_RX_QUEUE_MAX,
+};
+
 struct ath9k_beacon_state {
 	u32 bs_nexttbtt;
 	u32 bs_nextdtim;
diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h
index 9e8500a..126a403 100644
--- a/drivers/net/wireless/ath/ath9k/mac.h
+++ b/drivers/net/wireless/ath/ath9k/mac.h
@@ -148,6 +148,8 @@ struct ath_rx_status {
 	u32 evm0;
 	u32 evm1;
 	u32 evm2;
+	u32 evm3;
+	u32 evm4;
 };
 
 struct ath_htc_rx_status {
diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h
index d524891..bc48bc9 100644
--- a/drivers/net/wireless/ath/ath9k/reg.h
+++ b/drivers/net/wireless/ath/ath9k/reg.h
@@ -144,6 +144,9 @@
 #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
@@ -160,6 +163,9 @@
 #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
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 103+ messages in thread

* [PATCH v3 24/97] ath9k_hw: update the chip tests for AR9003
  2010-04-15 21:38 [PATCH v3 00/97] ath9k: add AR9003 support Luis R. Rodriguez
                   ` (22 preceding siblings ...)
  2010-04-15 21:38 ` [PATCH v3 23/97] ath9k_hw: Add few routines for rx edma support Luis R. Rodriguez
@ 2010-04-15 21:38 ` Luis R. Rodriguez
  2010-04-15 21:38 ` [PATCH v3 25/97] ath9k_hw: prevent reset control register zeroing on AR9003 reset Luis R. Rodriguez
                   ` (72 subsequent siblings)
  96 siblings, 0 replies; 103+ messages in thread
From: Luis R. Rodriguez @ 2010-04-15 21:38 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Senthil Balasubramanian, Luis R. Rodriguez

From: Senthil Balasubramanian <senthilkumar@atheros.com>

The AR9003 family requires a change on the loop and can also skip
testing the PHY timing registers. This chip test can now be used
by all Atheros hardware families, including legacy. We can
eventually move this out to the generic ath module.

Signed-off-by: Senthil Balasubramanian <senthilkumar@atheros.com>
Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/hw.c |   13 ++++++++++---
 1 files changed, 10 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 0b89605..bf7a85f 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -298,18 +298,25 @@ static void ath9k_hw_disablepcie(struct ath_hw *ah)
 	REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
 }
 
+/* This should work for all families including legacy */
 static bool ath9k_hw_chip_test(struct ath_hw *ah)
 {
 	struct ath_common *common = ath9k_hw_common(ah);
-	u32 regAddr[2] = { AR_STA_ID0, AR_PHY_BASE + (8 << 2) };
+	u32 regAddr[2] = { AR_STA_ID0 };
 	u32 regHold[2];
 	u32 patternData[4] = { 0x55555555,
 			       0xaaaaaaaa,
 			       0x66666666,
 			       0x99999999 };
-	int i, j;
+	int i, j, loop_max;
 
-	for (i = 0; i < 2; i++) {
+	if (!AR_SREV_9300_20_OR_LATER(ah)) {
+		loop_max = 2;
+		regAddr[1] = AR_PHY_BASE + (8 << 2);
+	} else
+		loop_max = 1;
+
+	for (i = 0; i < loop_max; i++) {
 		u32 addr = regAddr[i];
 		u32 wrData, rdData;
 
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 103+ messages in thread

* [PATCH v3 25/97] ath9k_hw: prevent reset control register zeroing on AR9003 reset
  2010-04-15 21:38 [PATCH v3 00/97] ath9k: add AR9003 support Luis R. Rodriguez
                   ` (23 preceding siblings ...)
  2010-04-15 21:38 ` [PATCH v3 24/97] ath9k_hw: update the chip tests for AR9003 Luis R. Rodriguez
@ 2010-04-15 21:38 ` Luis R. Rodriguez
  2010-04-15 21:38 ` [PATCH v3 26/97] ath9k_hw: Add AR9003 PHY register definitions Luis R. Rodriguez
                   ` (71 subsequent siblings)
  96 siblings, 0 replies; 103+ messages in thread
From: Luis R. Rodriguez @ 2010-04-15 21:38 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Senthil Balasubramanian, Luis R. Rodriguez

From: Senthil Balasubramanian <senthilkumar@atheros.com>

Also, no need for the udelay(2) on AR9003 hardware.

Signed-off-by: Senthil Balasubramanian <senthilkumar@atheros.com>
Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/hw.c |    6 ++++--
 1 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index bf7a85f..f695437 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -1386,9 +1386,11 @@ static bool ath9k_hw_set_reset_power_on(struct ath_hw *ah)
 		REG_WRITE(ah, AR_RC, AR_RC_AHB);
 
 	REG_WRITE(ah, AR_RTC_RESET, 0);
-	udelay(2);
 
-	if (!AR_SREV_9100(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);
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 103+ messages in thread

* [PATCH v3 26/97] ath9k_hw: Add AR9003 PHY register definitions
  2010-04-15 21:38 [PATCH v3 00/97] ath9k: add AR9003 support Luis R. Rodriguez
                   ` (24 preceding siblings ...)
  2010-04-15 21:38 ` [PATCH v3 25/97] ath9k_hw: prevent reset control register zeroing on AR9003 reset Luis R. Rodriguez
@ 2010-04-15 21:38 ` Luis R. Rodriguez
  2010-04-15 21:38 ` [PATCH v3 27/97] ath9k_hw: add common channel select helpers for ar900[23] Luis R. Rodriguez
                   ` (70 subsequent siblings)
  96 siblings, 0 replies; 103+ messages in thread
From: Luis R. Rodriguez @ 2010-04-15 21:38 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Felix Fietkau

From: Felix Fietkau <nbd@openwrt.org>

Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
 drivers/net/wireless/ath/ath9k/ar9003_phy.c |    1 +
 drivers/net/wireless/ath/ath9k/ar9003_phy.h |  804 +++++++++++++++++++++++++++
 2 files changed, 805 insertions(+), 0 deletions(-)
 create mode 100644 drivers/net/wireless/ath/ath9k/ar9003_phy.h

diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
index c4511b8..084b0f9 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
@@ -15,6 +15,7 @@
  */
 
 #include "hw.h"
+#include "ar9003_phy.h"
 
 /**
  * ar9003_hw_set_channel - set channel on single-chip device
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.h b/drivers/net/wireless/ath/ath9k/ar9003_phy.h
new file mode 100644
index 0000000..2e51e57
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.h
@@ -0,0 +1,804 @@
+/*
+ * Copyright (c) 2002-2010 Atheros Communications, Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef AR9003_PHY_H
+#define AR9003_PHY_H
+
+/*
+ * Channel Register Map
+ */
+#define AR_CHAN_BASE	0x9800
+
+#define AR_PHY_TIMING1      (AR_CHAN_BASE + 0x0)
+#define AR_PHY_TIMING2      (AR_CHAN_BASE + 0x4)
+#define AR_PHY_TIMING3      (AR_CHAN_BASE + 0x8)
+#define AR_PHY_TIMING4      (AR_CHAN_BASE + 0xc)
+#define AR_PHY_TIMING5      (AR_CHAN_BASE + 0x10)
+#define AR_PHY_TIMING6      (AR_CHAN_BASE + 0x14)
+#define AR_PHY_TIMING11     (AR_CHAN_BASE + 0x18)
+#define AR_PHY_SPUR_REG     (AR_CHAN_BASE + 0x1c)
+#define AR_PHY_RX_IQCAL_CORR_B0    (AR_CHAN_BASE + 0xdc)
+#define AR_PHY_TX_IQCAL_CONTROL_3  (AR_CHAN_BASE + 0xb0)
+
+#define AR_PHY_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_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_SPUR_SUBCHNL_SD_S   28
+#define AR_PHY_EXT_CCA_THRESH62 0x007F0000
+#define AR_PHY_EXT_CCA_THRESH62_S       16
+#define AR_PHY_EXT_MINCCA_PWR   0x01FF0000
+#define AR_PHY_EXT_MINCCA_PWR_S 16
+#define AR_PHY_TIMING5_CYCPWR_THR1  0x000000FE
+#define AR_PHY_TIMING5_CYCPWR_THR1_S    1
+#define AR_PHY_TIMING5_CYCPWR_THR1_ENABLE  0x00000001
+#define AR_PHY_TIMING5_CYCPWR_THR1_ENABLE_S    0
+#define AR_PHY_TIMING5_CYCPWR_THR1A  0x007F0000
+#define AR_PHY_TIMING5_CYCPWR_THR1A_S    16
+#define AR_PHY_TIMING5_RSSI_THR1A     (0x7F << 16)
+#define AR_PHY_TIMING5_RSSI_THR1A_S   16
+#define AR_PHY_TIMING5_RSSI_THR1A_ENA (0x1 << 15)
+#define AR_PHY_RADAR_0_ENA  0x00000001
+#define AR_PHY_RADAR_0_FFT_ENA  0x80000000
+#define AR_PHY_RADAR_0_INBAND   0x0000003e
+#define AR_PHY_RADAR_0_INBAND_S 1
+#define AR_PHY_RADAR_0_PRSSI    0x00000FC0
+#define AR_PHY_RADAR_0_PRSSI_S  6
+#define AR_PHY_RADAR_0_HEIGHT   0x0003F000
+#define AR_PHY_RADAR_0_HEIGHT_S 12
+#define AR_PHY_RADAR_0_RRSSI    0x00FC0000
+#define AR_PHY_RADAR_0_RRSSI_S  18
+#define AR_PHY_RADAR_0_FIRPWR   0x7F000000
+#define AR_PHY_RADAR_0_FIRPWR_S 24
+#define AR_PHY_RADAR_1_RELPWR_ENA       0x00800000
+#define AR_PHY_RADAR_1_USE_FIR128       0x00400000
+#define AR_PHY_RADAR_1_RELPWR_THRESH    0x003F0000
+#define AR_PHY_RADAR_1_RELPWR_THRESH_S  16
+#define AR_PHY_RADAR_1_BLOCK_CHECK      0x00008000
+#define AR_PHY_RADAR_1_MAX_RRSSI        0x00004000
+#define AR_PHY_RADAR_1_RELSTEP_CHECK    0x00002000
+#define AR_PHY_RADAR_1_RELSTEP_THRESH   0x00001F00
+#define AR_PHY_RADAR_1_RELSTEP_THRESH_S 8
+#define AR_PHY_RADAR_1_MAXLEN           0x000000FF
+#define AR_PHY_RADAR_1_MAXLEN_S         0
+#define AR_PHY_RADAR_EXT_ENA            0x00004000
+#define AR_PHY_RADAR_DC_PWR_THRESH      0x007f8000
+#define AR_PHY_RADAR_DC_PWR_THRESH_S    15
+#define AR_PHY_RADAR_LB_DC_CAP          0x7f800000
+#define AR_PHY_RADAR_LB_DC_CAP_S        23
+#define AR_PHY_FIND_SIG_LOW_FIRSTEP_LOW (0x3f << 6)
+#define AR_PHY_FIND_SIG_LOW_FIRSTEP_LOW_S   6
+#define AR_PHY_FIND_SIG_LOW_FIRPWR      (0x7f << 12)
+#define AR_PHY_FIND_SIG_LOW_FIRPWR_S    12
+#define AR_PHY_FIND_SIG_LOW_FIRPWR_SIGN_BIT 19
+#define AR_PHY_FIND_SIG_LOW_RELSTEP     0x1f
+#define AR_PHY_FIND_SIG_LOW_RELSTEP_S   0
+#define AR_PHY_FIND_SIG_LOW_RELSTEP_SIGN_BIT 5
+#define AR_PHY_CHAN_INFO_TAB_S2_READ    0x00000008
+#define AR_PHY_CHAN_INFO_TAB_S2_READ_S           3
+#define AR_PHY_RX_IQCAL_CORR_IQCORR_Q_Q_COFF 0x0000007F
+#define AR_PHY_RX_IQCAL_CORR_IQCORR_Q_Q_COFF_S   0
+#define AR_PHY_RX_IQCAL_CORR_IQCORR_Q_I_COFF 0x00003F80
+#define AR_PHY_RX_IQCAL_CORR_IQCORR_Q_I_COFF_S   7
+#define AR_PHY_RX_IQCAL_CORR_IQCORR_ENABLE   0x00004000
+#define AR_PHY_RX_IQCAL_CORR_LOOPBACK_IQCORR_Q_Q_COFF   0x003f8000
+#define AR_PHY_RX_IQCAL_CORR_LOOPBACK_IQCORR_Q_Q_COFF_S 15
+#define AR_PHY_RX_IQCAL_CORR_LOOPBACK_IQCORR_Q_I_COFF   0x1fc00000
+#define AR_PHY_RX_IQCAL_CORR_LOOPBACK_IQCORR_Q_I_COFF_S 22
+
+/*
+ * MRC Register Map
+ */
+#define AR_MRC_BASE	0x9c00
+
+#define AR_PHY_TIMING_3A       (AR_MRC_BASE + 0x0)
+#define AR_PHY_LDPC_CNTL1      (AR_MRC_BASE + 0x4)
+#define AR_PHY_LDPC_CNTL2      (AR_MRC_BASE + 0x8)
+#define AR_PHY_PILOT_SPUR_MASK (AR_MRC_BASE + 0xc)
+#define AR_PHY_CHAN_SPUR_MASK  (AR_MRC_BASE + 0x10)
+#define AR_PHY_SGI_DELTA       (AR_MRC_BASE + 0x14)
+#define AR_PHY_ML_CNTL_1       (AR_MRC_BASE + 0x18)
+#define AR_PHY_ML_CNTL_2       (AR_MRC_BASE + 0x1c)
+#define AR_PHY_TST_ADC         (AR_MRC_BASE + 0x20)
+
+/*
+ * MRC Feild Definitions
+ */
+#define AR_PHY_SGI_DSC_MAN   0x0007FFF0
+#define AR_PHY_SGI_DSC_MAN_S 4
+#define AR_PHY_SGI_DSC_EXP   0x0000000F
+#define AR_PHY_SGI_DSC_EXP_S 0
+/*
+ * BBB Register Map
+ */
+#define AR_BBB_BASE	0x9d00
+
+/*
+ * AGC Register Map
+ */
+#define AR_AGC_BASE	0x9e00
+
+#define AR_PHY_SETTLING         (AR_AGC_BASE + 0x0)
+#define AR_PHY_FORCEMAX_GAINS_0 (AR_AGC_BASE + 0x4)
+#define AR_PHY_GAINS_MINOFF0    (AR_AGC_BASE + 0x8)
+#define AR_PHY_DESIRED_SZ       (AR_AGC_BASE + 0xc)
+#define AR_PHY_FIND_SIG         (AR_AGC_BASE + 0x10)
+#define AR_PHY_AGC              (AR_AGC_BASE + 0x14)
+#define AR_PHY_EXT_ATTEN_CTL_0  (AR_AGC_BASE + 0x18)
+#define AR_PHY_CCA_0            (AR_AGC_BASE + 0x1c)
+#define AR_PHY_EXT_CCA0         (AR_AGC_BASE + 0x20)
+#define AR_PHY_RESTART          (AR_AGC_BASE + 0x24)
+#define AR_PHY_MC_GAIN_CTRL     (AR_AGC_BASE + 0x28)
+#define AR_PHY_EXTCHN_PWRTHR1   (AR_AGC_BASE + 0x2c)
+#define AR_PHY_EXT_CHN_WIN      (AR_AGC_BASE + 0x30)
+#define AR_PHY_20_40_DET_THR    (AR_AGC_BASE + 0x34)
+#define AR_PHY_RIFS_SRCH        (AR_AGC_BASE + 0x38)
+#define AR_PHY_PEAK_DET_CTRL_1  (AR_AGC_BASE + 0x3c)
+#define AR_PHY_PEAK_DET_CTRL_2  (AR_AGC_BASE + 0x40)
+#define AR_PHY_RX_GAIN_BOUNDS_1 (AR_AGC_BASE + 0x44)
+#define AR_PHY_RX_GAIN_BOUNDS_2 (AR_AGC_BASE + 0x48)
+#define AR_PHY_RSSI_0           (AR_AGC_BASE + 0x180)
+#define AR_PHY_SPUR_CCK_REP0    (AR_AGC_BASE + 0x184)
+#define AR_PHY_CCK_DETECT       (AR_AGC_BASE + 0x1c0)
+#define AR_PHY_DAG_CTRLCCK      (AR_AGC_BASE + 0x1c4)
+#define AR_PHY_IQCORR_CTRL_CCK  (AR_AGC_BASE + 0x1c8)
+
+#define AR_PHY_CCK_SPUR_MIT     (AR_AGC_BASE + 0x1cc)
+#define AR_PHY_CCK_SPUR_MIT_SPUR_RSSI_THR                           0x000001fe
+#define AR_PHY_CCK_SPUR_MIT_SPUR_RSSI_THR_S                                  1
+#define AR_PHY_CCK_SPUR_MIT_SPUR_FILTER_TYPE                        0x60000000
+#define AR_PHY_CCK_SPUR_MIT_SPUR_FILTER_TYPE_S                              29
+#define AR_PHY_CCK_SPUR_MIT_USE_CCK_SPUR_MIT                        0x00000001
+#define AR_PHY_CCK_SPUR_MIT_USE_CCK_SPUR_MIT_S                               0
+#define AR_PHY_CCK_SPUR_MIT_CCK_SPUR_FREQ                           0x1ffffe00
+#define AR_PHY_CCK_SPUR_MIT_CCK_SPUR_FREQ_S                                  9
+
+#define AR_PHY_RX_OCGAIN        (AR_AGC_BASE + 0x200)
+
+#define AR_PHY_CCA_NOM_VAL_9300_2GHZ          -110
+#define AR_PHY_CCA_NOM_VAL_9300_5GHZ          -115
+#define AR_PHY_CCA_MIN_GOOD_VAL_9300_2GHZ     -125
+#define AR_PHY_CCA_MIN_GOOD_VAL_9300_5GHZ     -125
+#define AR_PHY_CCA_MAX_GOOD_VAL_9300_2GHZ     -95
+#define AR_PHY_CCA_MAX_GOOD_VAL_9300_5GHZ     -100
+
+/*
+ * AGC Field Definitions
+ */
+#define AR_PHY_EXT_ATTEN_CTL_RXTX_MARGIN    0x00FC0000
+#define AR_PHY_EXT_ATTEN_CTL_RXTX_MARGIN_S  18
+#define AR_PHY_EXT_ATTEN_CTL_BSW_MARGIN     0x00003C00
+#define AR_PHY_EXT_ATTEN_CTL_BSW_MARGIN_S   10
+#define AR_PHY_EXT_ATTEN_CTL_BSW_ATTEN      0x0000001F
+#define AR_PHY_EXT_ATTEN_CTL_BSW_ATTEN_S    0
+#define AR_PHY_EXT_ATTEN_CTL_XATTEN2_MARGIN     0x003E0000
+#define AR_PHY_EXT_ATTEN_CTL_XATTEN2_MARGIN_S   17
+#define AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN     0x0001F000
+#define AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN_S   12
+#define AR_PHY_EXT_ATTEN_CTL_XATTEN2_DB         0x00000FC0
+#define AR_PHY_EXT_ATTEN_CTL_XATTEN2_DB_S       6
+#define AR_PHY_EXT_ATTEN_CTL_XATTEN1_DB         0x0000003F
+#define AR_PHY_EXT_ATTEN_CTL_XATTEN1_DB_S       0
+#define AR_PHY_RXGAIN_TXRX_ATTEN    0x0003F000
+#define AR_PHY_RXGAIN_TXRX_ATTEN_S  12
+#define AR_PHY_RXGAIN_TXRX_RF_MAX   0x007C0000
+#define AR_PHY_RXGAIN_TXRX_RF_MAX_S 18
+#define AR9280_PHY_RXGAIN_TXRX_ATTEN    0x00003F80
+#define AR9280_PHY_RXGAIN_TXRX_ATTEN_S  7
+#define AR9280_PHY_RXGAIN_TXRX_MARGIN   0x001FC000
+#define AR9280_PHY_RXGAIN_TXRX_MARGIN_S 14
+#define AR_PHY_SETTLING_SWITCH  0x00003F80
+#define AR_PHY_SETTLING_SWITCH_S    7
+#define AR_PHY_DESIRED_SZ_ADC       0x000000FF
+#define AR_PHY_DESIRED_SZ_ADC_S     0
+#define AR_PHY_DESIRED_SZ_PGA       0x0000FF00
+#define AR_PHY_DESIRED_SZ_PGA_S     8
+#define AR_PHY_DESIRED_SZ_TOT_DES   0x0FF00000
+#define AR_PHY_DESIRED_SZ_TOT_DES_S 20
+#define AR_PHY_MINCCA_PWR       0x1FF00000
+#define AR_PHY_MINCCA_PWR_S     20
+#define AR_PHY_CCA_THRESH62     0x0007F000
+#define AR_PHY_CCA_THRESH62_S   12
+#define AR9280_PHY_MINCCA_PWR       0x1FF00000
+#define AR9280_PHY_MINCCA_PWR_S     20
+#define AR9280_PHY_CCA_THRESH62     0x000FF000
+#define AR9280_PHY_CCA_THRESH62_S   12
+#define AR_PHY_EXT_CCA0_THRESH62    0x000000FF
+#define AR_PHY_EXT_CCA0_THRESH62_S  0
+#define AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK          0x0000003F
+#define AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK_S        0
+#define AR_PHY_CCK_DETECT_ANT_SWITCH_TIME           0x00001FC0
+#define AR_PHY_CCK_DETECT_ANT_SWITCH_TIME_S         6
+#define AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV    0x2000
+
+#define AR_PHY_DAG_CTRLCCK_EN_RSSI_THR  0x00000200
+#define AR_PHY_DAG_CTRLCCK_EN_RSSI_THR_S  9
+#define AR_PHY_DAG_CTRLCCK_RSSI_THR 0x0001FC00
+#define AR_PHY_DAG_CTRLCCK_RSSI_THR_S   10
+
+#define AR_PHY_RIFS_INIT_DELAY         0x3ff0000
+#define AR_PHY_AGC_COARSE_LOW       0x00007F80
+#define AR_PHY_AGC_COARSE_LOW_S     7
+#define AR_PHY_AGC_COARSE_HIGH      0x003F8000
+#define AR_PHY_AGC_COARSE_HIGH_S    15
+#define AR_PHY_AGC_COARSE_PWR_CONST 0x0000007F
+#define AR_PHY_AGC_COARSE_PWR_CONST_S   0
+#define AR_PHY_FIND_SIG_FIRSTEP  0x0003F000
+#define AR_PHY_FIND_SIG_FIRSTEP_S        12
+#define AR_PHY_FIND_SIG_FIRPWR   0x03FC0000
+#define AR_PHY_FIND_SIG_FIRPWR_S         18
+#define AR_PHY_FIND_SIG_FIRPWR_SIGN_BIT  25
+#define AR_PHY_FIND_SIG_RELPWR   (0x1f << 6)
+#define AR_PHY_FIND_SIG_RELPWR_S          6
+#define AR_PHY_FIND_SIG_RELPWR_SIGN_BIT  11
+#define AR_PHY_FIND_SIG_RELSTEP        0x1f
+#define AR_PHY_FIND_SIG_RELSTEP_S         0
+#define AR_PHY_FIND_SIG_RELSTEP_SIGN_BIT  5
+#define AR_PHY_RESTART_DIV_GC   0x001C0000
+#define AR_PHY_RESTART_DIV_GC_S 18
+#define AR_PHY_RESTART_ENA      0x01
+#define AR_PHY_DC_RESTART_DIS   0x40000000
+
+#define AR_PHY_TPC_OLPC_GAIN_DELTA_PAL_ON       0xFF000000
+#define AR_PHY_TPC_OLPC_GAIN_DELTA_PAL_ON_S     24
+#define AR_PHY_TPC_OLPC_GAIN_DELTA              0x00FF0000
+#define AR_PHY_TPC_OLPC_GAIN_DELTA_S            16
+
+#define AR_PHY_TPC_6_ERROR_EST_MODE             0x03000000
+#define AR_PHY_TPC_6_ERROR_EST_MODE_S           24
+
+/*
+ * SM Register Map
+ */
+#define AR_SM_BASE	0xa200
+
+#define AR_PHY_D2_CHIP_ID        (AR_SM_BASE + 0x0)
+#define AR_PHY_GEN_CTRL          (AR_SM_BASE + 0x4)
+#define AR_PHY_MODE              (AR_SM_BASE + 0x8)
+#define AR_PHY_ACTIVE            (AR_SM_BASE + 0xc)
+#define AR_PHY_SPUR_MASK_A       (AR_SM_BASE + 0x20)
+#define AR_PHY_SPUR_MASK_B       (AR_SM_BASE + 0x24)
+#define AR_PHY_SPECTRAL_SCAN     (AR_SM_BASE + 0x28)
+#define AR_PHY_RADAR_BW_FILTER   (AR_SM_BASE + 0x2c)
+#define AR_PHY_SEARCH_START_DELAY (AR_SM_BASE + 0x30)
+#define AR_PHY_MAX_RX_LEN        (AR_SM_BASE + 0x34)
+#define AR_PHY_FRAME_CTL         (AR_SM_BASE + 0x38)
+#define AR_PHY_RFBUS_REQ         (AR_SM_BASE + 0x3c)
+#define AR_PHY_RFBUS_GRANT       (AR_SM_BASE + 0x40)
+#define AR_PHY_RIFS              (AR_SM_BASE + 0x44)
+#define AR_PHY_RX_CLR_DELAY      (AR_SM_BASE + 0x50)
+#define AR_PHY_RX_DELAY          (AR_SM_BASE + 0x54)
+
+#define AR_PHY_XPA_TIMING_CTL    (AR_SM_BASE + 0x64)
+#define AR_PHY_MISC_PA_CTL       (AR_SM_BASE + 0x80)
+#define AR_PHY_SWITCH_CHAIN_0    (AR_SM_BASE + 0x84)
+#define AR_PHY_SWITCH_COM        (AR_SM_BASE + 0x88)
+#define AR_PHY_SWITCH_COM_2      (AR_SM_BASE + 0x8c)
+#define AR_PHY_RX_CHAINMASK      (AR_SM_BASE + 0xa0)
+#define AR_PHY_CAL_CHAINMASK     (AR_SM_BASE + 0xc0)
+#define AR_PHY_AGC_CONTROL       (AR_SM_BASE + 0xc4)
+#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_TEST              (AR_SM_BASE + 0x160)
+
+#define AR_PHY_TEST_BBB_OBS_SEL       0x780000
+#define AR_PHY_TEST_BBB_OBS_SEL_S     19
+
+#define AR_PHY_TEST_RX_OBS_SEL_BIT5_S 23
+#define AR_PHY_TEST_RX_OBS_SEL_BIT5   (1 << AR_PHY_TEST_RX_OBS_SEL_BIT5_S)
+
+#define AR_PHY_TEST_CHAIN_SEL      0xC0000000
+#define AR_PHY_TEST_CHAIN_SEL_S    30
+
+#define AR_PHY_TEST_CTL_STATUS   (AR_SM_BASE + 0x164)
+#define AR_PHY_TEST_CTL_TSTDAC_EN         0x1
+#define AR_PHY_TEST_CTL_TSTDAC_EN_S       0
+#define AR_PHY_TEST_CTL_TX_OBS_SEL        0x1C
+#define AR_PHY_TEST_CTL_TX_OBS_SEL_S      2
+#define AR_PHY_TEST_CTL_TX_OBS_MUX_SEL    0x60
+#define AR_PHY_TEST_CTL_TX_OBS_MUX_SEL_S  5
+#define AR_PHY_TEST_CTL_TSTADC_EN         0x100
+#define AR_PHY_TEST_CTL_TSTADC_EN_S       8
+#define AR_PHY_TEST_CTL_RX_OBS_SEL        0x3C00
+#define AR_PHY_TEST_CTL_RX_OBS_SEL_S      10
+
+
+#define AR_PHY_TSTDAC            (AR_SM_BASE + 0x168)
+
+#define AR_PHY_CHAN_STATUS       (AR_SM_BASE + 0x16c)
+#define AR_PHY_CHAN_INFO_MEMORY  (AR_SM_BASE + 0x170)
+#define AR_PHY_CHNINFO_NOISEPWR  (AR_SM_BASE + 0x174)
+#define AR_PHY_CHNINFO_GAINDIFF  (AR_SM_BASE + 0x178)
+#define AR_PHY_CHNINFO_FINETIM   (AR_SM_BASE + 0x17c)
+#define AR_PHY_CHAN_INFO_GAIN_0  (AR_SM_BASE + 0x180)
+#define AR_PHY_SCRAMBLER_SEED    (AR_SM_BASE + 0x190)
+#define AR_PHY_CCK_TX_CTRL       (AR_SM_BASE + 0x194)
+
+#define AR_PHY_HEAVYCLIP_CTL     (AR_SM_BASE + 0x1a4)
+#define AR_PHY_HEAVYCLIP_20      (AR_SM_BASE + 0x1a8)
+#define AR_PHY_HEAVYCLIP_40      (AR_SM_BASE + 0x1ac)
+#define AR_PHY_ILLEGAL_TXRATE    (AR_SM_BASE + 0x1b0)
+
+#define AR_PHY_PWRTX_MAX         (AR_SM_BASE + 0x1f0)
+#define AR_PHY_POWER_TX_SUB      (AR_SM_BASE + 0x1f4)
+
+#define AR_PHY_TPC_4_B0          (AR_SM_BASE + 0x204)
+#define AR_PHY_TPC_5_B0          (AR_SM_BASE + 0x208)
+#define AR_PHY_TPC_6_B0          (AR_SM_BASE + 0x20c)
+#define AR_PHY_TPC_11_B0         (AR_SM_BASE + 0x220)
+#define AR_PHY_TPC_18            (AR_SM_BASE + 0x23c)
+#define AR_PHY_TPC_19            (AR_SM_BASE + 0x240)
+
+#define AR_PHY_TX_FORCED_GAIN    (AR_SM_BASE + 0x258)
+
+#define AR_PHY_PDADC_TAB_0       (AR_SM_BASE + 0x280)
+
+#define AR_PHY_TX_IQCAL_CONTROL_1   (AR_SM_BASE + 0x448)
+#define AR_PHY_TX_IQCAL_START       (AR_SM_BASE + 0x440)
+#define AR_PHY_TX_IQCAL_STATUS_B0   (AR_SM_BASE + 0x48c)
+#define AR_PHY_TX_IQCAL_CORR_COEFF_01_B0    (AR_SM_BASE + 0x450)
+
+#define AR_PHY_PANIC_WD_STATUS      (AR_SM_BASE + 0x5c0)
+#define AR_PHY_PANIC_WD_CTL_1       (AR_SM_BASE + 0x5c4)
+#define AR_PHY_PANIC_WD_CTL_2       (AR_SM_BASE + 0x5c8)
+#define AR_PHY_BT_CTL               (AR_SM_BASE + 0x5cc)
+#define AR_PHY_ONLY_WARMRESET       (AR_SM_BASE + 0x5d0)
+#define AR_PHY_ONLY_CTL             (AR_SM_BASE + 0x5d4)
+#define AR_PHY_ECO_CTRL             (AR_SM_BASE + 0x5dc)
+#define AR_PHY_BB_THERM_ADC_1       (AR_SM_BASE + 0x248)
+
+#define AR_PHY_65NM_CH0_SYNTH4      0x1608c
+#define AR_PHY_SYNTH4_LONG_SHIFT_SELECT   0x00000002
+#define AR_PHY_SYNTH4_LONG_SHIFT_SELECT_S 1
+#define AR_PHY_65NM_CH0_SYNTH7      0x16098
+#define AR_PHY_65NM_CH0_BIAS1       0x160c0
+#define AR_PHY_65NM_CH0_BIAS2       0x160c4
+#define AR_PHY_65NM_CH0_BIAS4       0x160cc
+#define AR_PHY_65NM_CH0_RXTX4       0x1610c
+#define AR_PHY_65NM_CH0_THERM       0x16290
+
+#define AR_PHY_65NM_CH0_THERM_LOCAL   0x80000000
+#define AR_PHY_65NM_CH0_THERM_LOCAL_S 31
+#define AR_PHY_65NM_CH0_THERM_START   0x20000000
+#define AR_PHY_65NM_CH0_THERM_START_S 29
+#define AR_PHY_65NM_CH0_THERM_SAR_ADC_OUT   0x0000ff00
+#define AR_PHY_65NM_CH0_THERM_SAR_ADC_OUT_S 8
+
+#define AR_PHY_65NM_CH0_RXTX1       0x16100
+#define AR_PHY_65NM_CH0_RXTX2       0x16104
+#define AR_PHY_65NM_CH1_RXTX1       0x16500
+#define AR_PHY_65NM_CH1_RXTX2       0x16504
+#define AR_PHY_65NM_CH2_RXTX1       0x16900
+#define AR_PHY_65NM_CH2_RXTX2       0x16904
+
+#define AR_PHY_RX1DB_BIQUAD_LONG_SHIFT		0x00380000
+#define AR_PHY_RX1DB_BIQUAD_LONG_SHIFT_S	19
+#define AR_PHY_RX6DB_BIQUAD_LONG_SHIFT		0x00c00000
+#define AR_PHY_RX6DB_BIQUAD_LONG_SHIFT_S	22
+#define AR_PHY_LNAGAIN_LONG_SHIFT		0xe0000000
+#define AR_PHY_LNAGAIN_LONG_SHIFT_S		29
+#define AR_PHY_MXRGAIN_LONG_SHIFT		0x03000000
+#define AR_PHY_MXRGAIN_LONG_SHIFT_S		24
+#define AR_PHY_VGAGAIN_LONG_SHIFT		0x1c000000
+#define AR_PHY_VGAGAIN_LONG_SHIFT_S		26
+#define AR_PHY_SCFIR_GAIN_LONG_SHIFT		0x00000001
+#define AR_PHY_SCFIR_GAIN_LONG_SHIFT_S		0
+#define AR_PHY_MANRXGAIN_LONG_SHIFT		0x00000002
+#define AR_PHY_MANRXGAIN_LONG_SHIFT_S		1
+
+/*
+ * SM Field Definitions
+ */
+#define AR_PHY_CL_CAL_ENABLE          0x00000002
+#define AR_PHY_PARALLEL_CAL_ENABLE    0x00000001
+#define AR_PHY_TPCRG1_PD_CAL_ENABLE   0x00400000
+#define AR_PHY_TPCRG1_PD_CAL_ENABLE_S 22
+
+#define AR_PHY_ADDAC_PARACTL_OFF_PWDADC 0x00008000
+
+#define AR_PHY_FCAL20_CAP_STATUS_0    0x01f00000
+#define AR_PHY_FCAL20_CAP_STATUS_0_S  20
+
+#define AR_PHY_RFBUS_REQ_EN     0x00000001  /* request for RF bus */
+#define AR_PHY_RFBUS_GRANT_EN   0x00000001  /* RF bus granted */
+#define AR_PHY_GC_TURBO_MODE       0x00000001  /* set turbo mode bits */
+#define AR_PHY_GC_TURBO_SHORT      0x00000002  /* set short symbols to turbo mode setting */
+#define AR_PHY_GC_DYN2040_EN       0x00000004  /* enable dyn 20/40 mode */
+#define AR_PHY_GC_DYN2040_PRI_ONLY 0x00000008  /* dyn 20/40 - primary only */
+#define AR_PHY_GC_DYN2040_PRI_CH   0x00000010  /* dyn 20/40 - primary ch offset (0=+10MHz, 1=-10MHz)*/
+#define AR_PHY_GC_DYN2040_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_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
+
+#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_HALF            0x00000020
+#define AR_PHY_MODE_QUARTER         0x00000040
+#define AR_PHY_MAC_CLK_MODE         0x00000080
+#define AR_PHY_MODE_DYN_CCK_DISABLE 0x00000100
+#define AR_PHY_MODE_SVD_HALF        0x00000200
+#define AR_PHY_ACTIVE_EN    0x00000001
+#define AR_PHY_ACTIVE_DIS   0x00000000
+#define AR_PHY_FORCE_XPA_CFG    0x000000001
+#define AR_PHY_FORCE_XPA_CFG_S  0
+#define AR_PHY_XPA_TIMING_CTL_TX_END_XPAB_OFF    0xFF000000
+#define AR_PHY_XPA_TIMING_CTL_TX_END_XPAB_OFF_S  24
+#define AR_PHY_XPA_TIMING_CTL_TX_END_XPAA_OFF    0x00FF0000
+#define AR_PHY_XPA_TIMING_CTL_TX_END_XPAA_OFF_S  16
+#define AR_PHY_XPA_TIMING_CTL_FRAME_XPAB_ON      0x0000FF00
+#define AR_PHY_XPA_TIMING_CTL_FRAME_XPAB_ON_S    8
+#define AR_PHY_XPA_TIMING_CTL_FRAME_XPAA_ON      0x000000FF
+#define AR_PHY_XPA_TIMING_CTL_FRAME_XPAA_ON_S    0
+#define AR_PHY_TX_END_TO_A2_RX_ON       0x00FF0000
+#define AR_PHY_TX_END_TO_A2_RX_ON_S     16
+#define AR_PHY_TX_END_DATA_START  0x000000FF
+#define AR_PHY_TX_END_DATA_START_S  0
+#define AR_PHY_TX_END_PA_ON       0x0000FF00
+#define AR_PHY_TX_END_PA_ON_S       8
+#define AR_PHY_TPCRG5_PD_GAIN_OVERLAP   0x0000000F
+#define AR_PHY_TPCRG5_PD_GAIN_OVERLAP_S     0
+#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1    0x000003F0
+#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1_S  4
+#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2    0x0000FC00
+#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2_S  10
+#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3    0x003F0000
+#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3_S  16
+#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4    0x0FC00000
+#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4_S  22
+#define AR_PHY_TPCRG1_NUM_PD_GAIN   0x0000c000
+#define AR_PHY_TPCRG1_NUM_PD_GAIN_S 14
+#define AR_PHY_TPCRG1_PD_GAIN_1    0x00030000
+#define AR_PHY_TPCRG1_PD_GAIN_1_S  16
+#define AR_PHY_TPCRG1_PD_GAIN_2    0x000C0000
+#define AR_PHY_TPCRG1_PD_GAIN_2_S  18
+#define AR_PHY_TPCRG1_PD_GAIN_3    0x00300000
+#define AR_PHY_TPCRG1_PD_GAIN_3_S  20
+#define AR_PHY_TPCGR1_FORCED_DAC_GAIN   0x0000003e
+#define AR_PHY_TPCGR1_FORCED_DAC_GAIN_S 1
+#define AR_PHY_TPCGR1_FORCE_DAC_GAIN    0x00000001
+#define AR_PHY_TXGAIN_FORCE               0x00000001
+#define AR_PHY_TXGAIN_FORCED_PADVGNRA     0x00003c00
+#define AR_PHY_TXGAIN_FORCED_PADVGNRA_S   10
+#define AR_PHY_TXGAIN_FORCED_PADVGNRB     0x0003c000
+#define AR_PHY_TXGAIN_FORCED_PADVGNRB_S   14
+#define AR_PHY_TXGAIN_FORCED_PADVGNRD     0x00c00000
+#define AR_PHY_TXGAIN_FORCED_PADVGNRD_S   22
+#define AR_PHY_TXGAIN_FORCED_TXMXRGAIN    0x000003c0
+#define AR_PHY_TXGAIN_FORCED_TXMXRGAIN_S  6
+#define AR_PHY_TXGAIN_FORCED_TXBB1DBGAIN  0x0000000e
+#define AR_PHY_TXGAIN_FORCED_TXBB1DBGAIN_S 1
+
+#define AR_PHY_POWER_TX_RATE1   0x9934
+#define AR_PHY_POWER_TX_RATE2   0x9938
+#define AR_PHY_POWER_TX_RATE_MAX    0x993c
+#define AR_PHY_POWER_TX_RATE_MAX_TPC_ENABLE 0x00000040
+#define PHY_AGC_CLR             0x10000000
+#define RFSILENT_BB             0x00002000
+#define AR_PHY_CHAN_INFO_GAIN_DIFF_PPM_MASK          0xFFF
+#define AR_PHY_CHAN_INFO_GAIN_DIFF_PPM_SIGNED_BIT    0x800
+#define AR_PHY_CHAN_INFO_GAIN_DIFF_UPPER_LIMIT         320
+#define AR_PHY_CHAN_INFO_MEMORY_CAPTURE_MASK         0x0001
+#define AR_PHY_RX_DELAY_DELAY   0x00003FFF
+#define AR_PHY_CCK_TX_CTRL_JAPAN    0x00000010
+#define AR_PHY_SPECTRAL_SCAN_ENABLE         0x00000001
+#define AR_PHY_SPECTRAL_SCAN_ENABLE_S       0
+#define AR_PHY_SPECTRAL_SCAN_ACTIVE         0x00000002
+#define AR_PHY_SPECTRAL_SCAN_ACTIVE_S       1
+#define AR_PHY_SPECTRAL_SCAN_FFT_PERIOD     0x000000F0
+#define AR_PHY_SPECTRAL_SCAN_FFT_PERIOD_S   4
+#define AR_PHY_SPECTRAL_SCAN_PERIOD         0x0000FF00
+#define AR_PHY_SPECTRAL_SCAN_PERIOD_S       8
+#define AR_PHY_SPECTRAL_SCAN_COUNT          0x00FF0000
+#define AR_PHY_SPECTRAL_SCAN_COUNT_S        16
+#define AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT   0x01000000
+#define AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT_S 24
+#define AR_PHY_CHANNEL_STATUS_RX_CLEAR      0x00000004
+#define AR_PHY_TX_IQCAQL_CONTROL_1_IQCORR_I_Q_COFF_DELPT             0x01fc0000
+#define AR_PHY_TX_IQCAQL_CONTROL_1_IQCORR_I_Q_COFF_DELPT_S                   18
+#define AR_PHY_TX_IQCAL_START_DO_CAL        0x00000001
+#define AR_PHY_TX_IQCAL_START_DO_CAL_S      0
+
+#define AR_PHY_TX_IQCAL_STATUS_FAILED    0x00000001
+#define AR_PHY_TX_IQCAL_CORR_COEFF_01_COEFF_TABLE      0x00003fff
+#define AR_PHY_TX_IQCAL_CORR_COEFF_01_COEFF_TABLE_S    0
+
+#define AR_PHY_TPC_18_THERM_CAL_VALUE           0xff
+#define AR_PHY_TPC_18_THERM_CAL_VALUE_S         0
+#define AR_PHY_TPC_19_ALPHA_THERM               0xff
+#define AR_PHY_TPC_19_ALPHA_THERM_S             0
+
+#define AR_PHY_65NM_CH0_RXTX4_THERM_ON          0x10000000
+#define AR_PHY_65NM_CH0_RXTX4_THERM_ON_S        28
+
+#define AR_PHY_BB_THERM_ADC_1_INIT_THERM        0x000000ff
+#define AR_PHY_BB_THERM_ADC_1_INIT_THERM_S      0
+
+/*
+ * Channel 1 Register Map
+ */
+#define AR_CHAN1_BASE	0xa800
+
+#define AR_PHY_EXT_CCA_1            (AR_CHAN1_BASE + 0x30)
+#define AR_PHY_TX_PHASE_RAMP_1      (AR_CHAN1_BASE + 0xd0)
+#define AR_PHY_ADC_GAIN_DC_CORR_1   (AR_CHAN1_BASE + 0xd4)
+
+#define AR_PHY_SPUR_REPORT_1        (AR_CHAN1_BASE + 0xa8)
+#define AR_PHY_CHAN_INFO_TAB_1      (AR_CHAN1_BASE + 0x300)
+#define AR_PHY_RX_IQCAL_CORR_B1     (AR_CHAN1_BASE + 0xdc)
+
+/*
+ * Channel 1 Field Definitions
+ */
+#define AR_PHY_CH1_EXT_MINCCA_PWR   0x01FF0000
+#define AR_PHY_CH1_EXT_MINCCA_PWR_S 16
+
+/*
+ * AGC 1 Register Map
+ */
+#define AR_AGC1_BASE	0xae00
+
+#define AR_PHY_FORCEMAX_GAINS_1      (AR_AGC1_BASE + 0x4)
+#define AR_PHY_EXT_ATTEN_CTL_1       (AR_AGC1_BASE + 0x18)
+#define AR_PHY_CCA_1                 (AR_AGC1_BASE + 0x1c)
+#define AR_PHY_CCA_CTRL_1            (AR_AGC1_BASE + 0x20)
+#define AR_PHY_RSSI_1                (AR_AGC1_BASE + 0x180)
+#define AR_PHY_SPUR_CCK_REP_1        (AR_AGC1_BASE + 0x184)
+#define AR_PHY_RX_OCGAIN_2           (AR_AGC1_BASE + 0x200)
+
+/*
+ * AGC 1 Field Definitions
+ */
+#define AR_PHY_CH1_MINCCA_PWR   0x1FF00000
+#define AR_PHY_CH1_MINCCA_PWR_S 20
+
+/*
+ * SM 1 Register Map
+ */
+#define AR_SM1_BASE	0xb200
+
+#define AR_PHY_SWITCH_CHAIN_1    (AR_SM1_BASE + 0x84)
+#define AR_PHY_FCAL_2_1          (AR_SM1_BASE + 0xd0)
+#define AR_PHY_DFT_TONE_CTL_1    (AR_SM1_BASE + 0xd4)
+#define AR_PHY_CL_TAB_1          (AR_SM1_BASE + 0x100)
+#define AR_PHY_CHAN_INFO_GAIN_1  (AR_SM1_BASE + 0x180)
+#define AR_PHY_TPC_4_B1          (AR_SM1_BASE + 0x204)
+#define AR_PHY_TPC_5_B1          (AR_SM1_BASE + 0x208)
+#define AR_PHY_TPC_6_B1          (AR_SM1_BASE + 0x20c)
+#define AR_PHY_TPC_11_B1         (AR_SM1_BASE + 0x220)
+#define AR_PHY_PDADC_TAB_1       (AR_SM1_BASE + 0x240)
+#define AR_PHY_TX_IQCAL_STATUS_B1   (AR_SM1_BASE + 0x48c)
+#define AR_PHY_TX_IQCAL_CORR_COEFF_01_B1    (AR_SM1_BASE + 0x450)
+
+/*
+ * Channel 2 Register Map
+ */
+#define AR_CHAN2_BASE	0xb800
+
+#define AR_PHY_EXT_CCA_2            (AR_CHAN2_BASE + 0x30)
+#define AR_PHY_TX_PHASE_RAMP_2      (AR_CHAN2_BASE + 0xd0)
+#define AR_PHY_ADC_GAIN_DC_CORR_2   (AR_CHAN2_BASE + 0xd4)
+
+#define AR_PHY_SPUR_REPORT_2        (AR_CHAN2_BASE + 0xa8)
+#define AR_PHY_CHAN_INFO_TAB_2      (AR_CHAN2_BASE + 0x300)
+#define AR_PHY_RX_IQCAL_CORR_B2     (AR_CHAN2_BASE + 0xdc)
+
+/*
+ * Channel 2 Field Definitions
+ */
+#define AR_PHY_CH2_EXT_MINCCA_PWR   0x01FF0000
+#define AR_PHY_CH2_EXT_MINCCA_PWR_S 16
+/*
+ * AGC 2 Register Map
+ */
+#define AR_AGC2_BASE	0xbe00
+
+#define AR_PHY_FORCEMAX_GAINS_2      (AR_AGC2_BASE + 0x4)
+#define AR_PHY_EXT_ATTEN_CTL_2       (AR_AGC2_BASE + 0x18)
+#define AR_PHY_CCA_2                 (AR_AGC2_BASE + 0x1c)
+#define AR_PHY_CCA_CTRL_2            (AR_AGC2_BASE + 0x20)
+#define AR_PHY_RSSI_2                (AR_AGC2_BASE + 0x180)
+
+/*
+ * AGC 2 Field Definitions
+ */
+#define AR_PHY_CH2_MINCCA_PWR   0x1FF00000
+#define AR_PHY_CH2_MINCCA_PWR_S 20
+
+/*
+ * SM 2 Register Map
+ */
+#define AR_SM2_BASE	0xc200
+
+#define AR_PHY_SWITCH_CHAIN_2    (AR_SM2_BASE + 0x84)
+#define AR_PHY_FCAL_2_2          (AR_SM2_BASE + 0xd0)
+#define AR_PHY_DFT_TONE_CTL_2    (AR_SM2_BASE + 0xd4)
+#define AR_PHY_CL_TAB_2          (AR_SM2_BASE + 0x100)
+#define AR_PHY_CHAN_INFO_GAIN_2  (AR_SM2_BASE + 0x180)
+#define AR_PHY_TPC_4_B2          (AR_SM2_BASE + 0x204)
+#define AR_PHY_TPC_5_B2          (AR_SM2_BASE + 0x208)
+#define AR_PHY_TPC_6_B2          (AR_SM2_BASE + 0x20c)
+#define AR_PHY_TPC_11_B2         (AR_SM2_BASE + 0x220)
+#define AR_PHY_PDADC_TAB_2       (AR_SM2_BASE + 0x240)
+#define AR_PHY_TX_IQCAL_STATUS_B2   (AR_SM2_BASE + 0x48c)
+#define AR_PHY_TX_IQCAL_CORR_COEFF_01_B2    (AR_SM2_BASE + 0x450)
+
+#define AR_PHY_TX_IQCAL_STATUS_B2_FAILED    0x00000001
+
+/*
+ * AGC 3 Register Map
+ */
+#define AR_AGC3_BASE	0xce00
+
+#define AR_PHY_RSSI_3            (AR_AGC3_BASE + 0x180)
+
+/*
+ * Misc helper defines
+ */
+#define AR_PHY_CHAIN_OFFSET     (AR_CHAN1_BASE - AR_CHAN_BASE)
+
+#define AR_PHY_NEW_ADC_DC_GAIN_CORR(_i) (AR_PHY_ADC_GAIN_DC_CORR_0 + (AR_PHY_CHAIN_OFFSET * (_i)))
+#define AR_PHY_NEW_ADC_DC_GAIN_CORR_9300_10(_i) (AR_PHY_ADC_GAIN_DC_CORR_0_9300_10 + (AR_PHY_CHAIN_OFFSET * (_i)))
+#define AR_PHY_SWITCH_CHAIN(_i)     (AR_PHY_SWITCH_CHAIN_0 + (AR_PHY_CHAIN_OFFSET * (_i)))
+#define AR_PHY_EXT_ATTEN_CTL(_i)    (AR_PHY_EXT_ATTEN_CTL_0 + (AR_PHY_CHAIN_OFFSET * (_i)))
+
+#define AR_PHY_RXGAIN(_i)           (AR_PHY_FORCEMAX_GAINS_0 + (AR_PHY_CHAIN_OFFSET * (_i)))
+#define AR_PHY_TPCRG5(_i)           (AR_PHY_TPC_5_B0 + (AR_PHY_CHAIN_OFFSET * (_i)))
+#define AR_PHY_PDADC_TAB(_i)        (AR_PHY_PDADC_TAB_0 + (AR_PHY_CHAIN_OFFSET * (_i)))
+
+#define AR_PHY_CAL_MEAS_0(_i)       (AR_PHY_IQ_ADC_MEAS_0_B0 + (AR_PHY_CHAIN_OFFSET * (_i)))
+#define AR_PHY_CAL_MEAS_1(_i)       (AR_PHY_IQ_ADC_MEAS_1_B0 + (AR_PHY_CHAIN_OFFSET * (_i)))
+#define AR_PHY_CAL_MEAS_2(_i)       (AR_PHY_IQ_ADC_MEAS_2_B0 + (AR_PHY_CHAIN_OFFSET * (_i)))
+#define AR_PHY_CAL_MEAS_3(_i)       (AR_PHY_IQ_ADC_MEAS_3_B0 + (AR_PHY_CHAIN_OFFSET * (_i)))
+#define AR_PHY_CAL_MEAS_0_9300_10(_i) (AR_PHY_IQ_ADC_MEAS_0_B0_9300_10 + (AR_PHY_CHAIN_OFFSET * (_i)))
+#define AR_PHY_CAL_MEAS_1_9300_10(_i) (AR_PHY_IQ_ADC_MEAS_1_B0_9300_10 + (AR_PHY_CHAIN_OFFSET * (_i)))
+#define AR_PHY_CAL_MEAS_2_9300_10(_i) (AR_PHY_IQ_ADC_MEAS_2_B0_9300_10 + (AR_PHY_CHAIN_OFFSET * (_i)))
+#define AR_PHY_CAL_MEAS_3_9300_10(_i) (AR_PHY_IQ_ADC_MEAS_3_B0_9300_10 + (AR_PHY_CHAIN_OFFSET * (_i)))
+
+#define AR_PHY_BB_PANIC_NON_IDLE_ENABLE 0x00000001
+#define AR_PHY_BB_PANIC_IDLE_ENABLE     0x00000002
+#define AR_PHY_BB_PANIC_IDLE_MASK       0xFFFF0000
+#define AR_PHY_BB_PANIC_NON_IDLE_MASK   0x0000FFFC
+
+#define AR_PHY_BB_PANIC_RST_ENABLE      0x00000002
+#define AR_PHY_BB_PANIC_IRQ_ENABLE      0x00000004
+#define AR_PHY_BB_PANIC_CNTL2_MASK      0xFFFFFFF9
+
+#define AR_PHY_BB_WD_STATUS             0x00000007
+#define AR_PHY_BB_WD_STATUS_S           0
+#define AR_PHY_BB_WD_DET_HANG           0x00000008
+#define AR_PHY_BB_WD_DET_HANG_S         3
+#define AR_PHY_BB_WD_RADAR_SM           0x000000F0
+#define AR_PHY_BB_WD_RADAR_SM_S         4
+#define AR_PHY_BB_WD_RX_OFDM_SM         0x00000F00
+#define AR_PHY_BB_WD_RX_OFDM_SM_S       8
+#define AR_PHY_BB_WD_RX_CCK_SM          0x0000F000
+#define AR_PHY_BB_WD_RX_CCK_SM_S        12
+#define AR_PHY_BB_WD_TX_OFDM_SM         0x000F0000
+#define AR_PHY_BB_WD_TX_OFDM_SM_S       16
+#define AR_PHY_BB_WD_TX_CCK_SM          0x00F00000
+#define AR_PHY_BB_WD_TX_CCK_SM_S        20
+#define AR_PHY_BB_WD_AGC_SM             0x0F000000
+#define AR_PHY_BB_WD_AGC_SM_S           24
+#define AR_PHY_BB_WD_SRCH_SM            0xF0000000
+#define AR_PHY_BB_WD_SRCH_SM_S          28
+
+#define AR_PHY_BB_WD_STATUS_CLR         0x00000008
+
+#endif  /* AR9003_PHY_H */
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 103+ messages in thread

* [PATCH v3 27/97] ath9k_hw: add common channel select helpers for ar900[23]
  2010-04-15 21:38 [PATCH v3 00/97] ath9k: add AR9003 support Luis R. Rodriguez
                   ` (25 preceding siblings ...)
  2010-04-15 21:38 ` [PATCH v3 26/97] ath9k_hw: Add AR9003 PHY register definitions Luis R. Rodriguez
@ 2010-04-15 21:38 ` Luis R. Rodriguez
  2010-04-15 21:38 ` [PATCH v3 28/97] ath9k_hw: Set the channel on AR9003 Luis R. Rodriguez
                   ` (69 subsequent siblings)
  96 siblings, 0 replies; 103+ messages in thread
From: Luis R. Rodriguez @ 2010-04-15 21:38 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Luis R. Rodriguez

Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/ar9002_phy.c |    4 ++--
 drivers/net/wireless/ath/ath9k/phy.h        |    4 ++++
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ar9002_phy.c b/drivers/net/wireless/ath/ath9k/ar9002_phy.c
index 87541a8..1f8ac0a 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9002_phy.c
@@ -83,7 +83,7 @@ static int ar9002_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan)
 		bMode = 1;
 		fracMode = 1;
 		aModeRefSel = 0;
-		channelSel = (freq * 0x10000) / 15;
+		channelSel = CHANSEL_2G(freq);
 
 		if (AR_SREV_9287_11_OR_LATER(ah)) {
 			if (freq == 2484) {
@@ -126,7 +126,7 @@ static int ar9002_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan)
 			 */
 			fracMode = 1;
 			refDivA = 1;
-			channelSel = (freq * 0x8000) / 15;
+			channelSel = CHANSEL_5G(freq);
 
 			/* RefDivA setting */
 			REG_RMW_FIELD(ah, AR_AN_SYNTH9,
diff --git a/drivers/net/wireless/ath/ath9k/phy.h b/drivers/net/wireless/ath/ath9k/phy.h
index b908152..7d397fd 100644
--- a/drivers/net/wireless/ath/ath9k/phy.h
+++ b/drivers/net/wireless/ath/ath9k/phy.h
@@ -17,6 +17,10 @@
 #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))
 
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 103+ messages in thread

* [PATCH v3 28/97] ath9k_hw: Set the channel on AR9003
  2010-04-15 21:38 [PATCH v3 00/97] ath9k: add AR9003 support Luis R. Rodriguez
                   ` (26 preceding siblings ...)
  2010-04-15 21:38 ` [PATCH v3 27/97] ath9k_hw: add common channel select helpers for ar900[23] Luis R. Rodriguez
@ 2010-04-15 21:38 ` Luis R. Rodriguez
  2010-04-15 21:38 ` [PATCH v3 29/97] ath9k_hw: Implement PLL control " Luis R. Rodriguez
                   ` (68 subsequent siblings)
  96 siblings, 0 replies; 103+ messages in thread
From: Luis R. Rodriguez @ 2010-04-15 21:38 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Felix Fietkau, Luis R. Rodriguez

From: Felix Fietkau <nbd@openwrt.org>

Signed-off-by: Felix Fietkau <nbd@openwrt.org>
Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/ar9003_phy.c |   47 ++++++++++++++++++++++++++-
 1 files changed, 46 insertions(+), 1 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
index 084b0f9..f1632ab 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
@@ -44,7 +44,52 @@
  */
 static int ar9003_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan)
 {
-	/* TODO */
+	u16 bMode, fracMode = 0, aModeRefSel = 0;
+	u32 freq, channelSel = 0, reg32 = 0;
+	struct chan_centers centers;
+	int loadSynthChannel;
+
+	ath9k_hw_get_channel_centers(ah, chan, &centers);
+	freq = centers.synth_center;
+
+	if (freq < 4800) {     /* 2 GHz, fractional mode */
+		channelSel = CHANSEL_2G(freq);
+		/* Set to 2G mode */
+		bMode = 1;
+	} else {
+		channelSel = CHANSEL_5G(freq);
+		/* Doubler is ON, so, divide channelSel by 2. */
+		channelSel >>= 1;
+		/* Set to 5G mode */
+		bMode = 0;
+	}
+
+	/* Enable fractional mode for all channels */
+	fracMode = 1;
+	aModeRefSel = 0;
+	loadSynthChannel = 0;
+
+	reg32 = (bMode << 29);
+	REG_WRITE(ah, AR_PHY_SYNTH_CONTROL, reg32);
+
+	/* Enable Long shift Select for Synthesizer */
+	REG_RMW_FIELD(ah, AR_PHY_65NM_CH0_SYNTH4,
+		      AR_PHY_SYNTH4_LONG_SHIFT_SELECT, 1);
+
+	/* Program Synth. setting */
+	reg32 = (channelSel << 2) | (fracMode << 30) |
+		(aModeRefSel << 28) | (loadSynthChannel << 31);
+	REG_WRITE(ah, AR_PHY_65NM_CH0_SYNTH7, reg32);
+
+	/* Toggle Load Synth channel bit */
+	loadSynthChannel = 1;
+	reg32 = (channelSel << 2) | (fracMode << 30) |
+		(aModeRefSel << 28) | (loadSynthChannel << 31);
+	REG_WRITE(ah, AR_PHY_65NM_CH0_SYNTH7, reg32);
+
+	ah->curchan = chan;
+	ah->curchan_rad_index = -1;
+
 	return 0;
 }
 
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 103+ messages in thread

* [PATCH v3 29/97] ath9k_hw: Implement PLL control on AR9003
  2010-04-15 21:38 [PATCH v3 00/97] ath9k: add AR9003 support Luis R. Rodriguez
                   ` (27 preceding siblings ...)
  2010-04-15 21:38 ` [PATCH v3 28/97] ath9k_hw: Set the channel on AR9003 Luis R. Rodriguez
@ 2010-04-15 21:38 ` Luis R. Rodriguez
  2010-04-15 21:38 ` [PATCH v3 30/97] ath9k_hw: Implement spur mitigation " Luis R. Rodriguez
                   ` (67 subsequent siblings)
  96 siblings, 0 replies; 103+ messages in thread
From: Luis R. Rodriguez @ 2010-04-15 21:38 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Felix Fietkau, Luis R. Rodriguez

From: Felix Fietkau <nbd@openwrt.org>

Signed-off-by: Felix Fietkau <nbd@openwrt.org>
Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/ar9003_phy.c |   23 +++++++++++++++++++++--
 drivers/net/wireless/ath/ath9k/reg.h        |    6 ++++++
 2 files changed, 27 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
index f1632ab..9767265 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
@@ -112,8 +112,27 @@ static void ar9003_hw_spur_mitigate(struct ath_hw *ah,
 static u32 ar9003_hw_compute_pll_control(struct ath_hw *ah,
 					 struct ath9k_channel *chan)
 {
-	/* TODO */
-	return 0;
+	u32 pll;
+
+	pll = SM(0x5, AR_RTC_9300_PLL_REFDIV);
+
+	if (chan && IS_CHAN_HALF_RATE(chan))
+		pll |= SM(0x1, AR_RTC_9300_PLL_CLKSEL);
+	else if (chan && IS_CHAN_QUARTER_RATE(chan))
+		pll |= SM(0x2, AR_RTC_9300_PLL_CLKSEL);
+
+	if (chan && IS_CHAN_5GHZ(chan)) {
+		pll |= SM(0x28, AR_RTC_9300_PLL_DIV);
+
+		/*
+		 * When doing fast clock, set PLL to 0x142c
+		 */
+		if (IS_CHAN_A_5MHZ_SPACED(chan))
+			pll = 0x142c;
+	} else
+		pll |= SM(0x2c, AR_RTC_9300_PLL_DIV);
+
+	return pll;
 }
 
 static void ar9003_hw_set_channel_regs(struct ath_hw *ah,
diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h
index bc48bc9..9d63286 100644
--- a/drivers/net/wireless/ath/ath9k/reg.h
+++ b/drivers/net/wireless/ath/ath9k/reg.h
@@ -1040,6 +1040,12 @@ enum {
 #define AR_PCIE_MSI                              (AR_SREV_9300_20_OR_LATER(ah) ? 0x40a4 : 0x4094)
 #define AR_PCIE_MSI_ENABLE                       0x00000001
 
+#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
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 103+ messages in thread

* [PATCH v3 30/97] ath9k_hw: Implement spur mitigation on AR9003
  2010-04-15 21:38 [PATCH v3 00/97] ath9k: add AR9003 support Luis R. Rodriguez
                   ` (28 preceding siblings ...)
  2010-04-15 21:38 ` [PATCH v3 29/97] ath9k_hw: Implement PLL control " Luis R. Rodriguez
@ 2010-04-15 21:38 ` Luis R. Rodriguez
  2010-04-15 21:38 ` [PATCH v3 31/97] ath9k_hw: split initvals.h by hardware family Luis R. Rodriguez
                   ` (66 subsequent siblings)
  96 siblings, 0 replies; 103+ messages in thread
From: Luis R. Rodriguez @ 2010-04-15 21:38 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Felix Fietkau, Luis R. Rodriguez

From: Felix Fietkau <nbd@openwrt.org>

Signed-off-by: Felix Fietkau <nbd@openwrt.org>
Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/ar9003_phy.c |   50 ++++++++++++++++++++++++++-
 1 files changed, 49 insertions(+), 1 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
index 9767265..3e3472e 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
@@ -106,7 +106,55 @@ static int ar9003_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan)
 static void ar9003_hw_spur_mitigate(struct ath_hw *ah,
 				    struct ath9k_channel *chan)
 {
-	/* TODO */
+	u32 spur_freq[4] = { 2420, 2440, 2464, 2480 };
+	int cur_bb_spur, negative = 0, cck_spur_freq;
+	int i;
+
+	/*
+	 * Need to verify range +/- 10 MHz in control channel, otherwise spur
+	 * is out-of-band and can be ignored.
+	 */
+
+	for (i = 0; i < 4; i++) {
+		negative = 0;
+		cur_bb_spur = spur_freq[i] - chan->channel;
+
+		if (cur_bb_spur < 0) {
+			negative = 1;
+			cur_bb_spur = -cur_bb_spur;
+		}
+		if (cur_bb_spur < 10) {
+			cck_spur_freq = (int)((cur_bb_spur << 19) / 11);
+
+			if (negative == 1)
+				cck_spur_freq = -cck_spur_freq;
+
+			cck_spur_freq = cck_spur_freq & 0xfffff;
+
+			REG_RMW_FIELD(ah, AR_PHY_AGC_CONTROL,
+				      AR_PHY_AGC_CONTROL_YCOK_MAX, 0x7);
+			REG_RMW_FIELD(ah, AR_PHY_CCK_SPUR_MIT,
+				      AR_PHY_CCK_SPUR_MIT_SPUR_RSSI_THR, 0x7f);
+			REG_RMW_FIELD(ah, AR_PHY_CCK_SPUR_MIT,
+				      AR_PHY_CCK_SPUR_MIT_SPUR_FILTER_TYPE,
+				      0x2);
+			REG_RMW_FIELD(ah, AR_PHY_CCK_SPUR_MIT,
+				      AR_PHY_CCK_SPUR_MIT_USE_CCK_SPUR_MIT,
+				      0x1);
+			REG_RMW_FIELD(ah, AR_PHY_CCK_SPUR_MIT,
+				      AR_PHY_CCK_SPUR_MIT_CCK_SPUR_FREQ,
+				      cck_spur_freq);
+
+			return;
+		}
+	}
+
+	REG_RMW_FIELD(ah, AR_PHY_AGC_CONTROL,
+		      AR_PHY_AGC_CONTROL_YCOK_MAX, 0x5);
+	REG_RMW_FIELD(ah, AR_PHY_CCK_SPUR_MIT,
+		      AR_PHY_CCK_SPUR_MIT_USE_CCK_SPUR_MIT, 0x0);
+	REG_RMW_FIELD(ah, AR_PHY_CCK_SPUR_MIT,
+		      AR_PHY_CCK_SPUR_MIT_CCK_SPUR_FREQ, 0x0);
 }
 
 static u32 ar9003_hw_compute_pll_control(struct ath_hw *ah,
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 103+ messages in thread

* [PATCH v3 31/97] ath9k_hw: split initvals.h by hardware family
  2010-04-15 21:38 [PATCH v3 00/97] ath9k: add AR9003 support Luis R. Rodriguez
                   ` (29 preceding siblings ...)
  2010-04-15 21:38 ` [PATCH v3 30/97] ath9k_hw: Implement spur mitigation " Luis R. Rodriguez
@ 2010-04-15 21:38 ` Luis R. Rodriguez
  2010-04-15 21:38 ` [PATCH v3 32/97] ath9k_hw: add initvals for the AR9003 " Luis R. Rodriguez
                   ` (65 subsequent siblings)
  96 siblings, 0 replies; 103+ messages in thread
From: Luis R. Rodriguez @ 2010-04-15 21:38 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Luis R. Rodriguez

The initvals.h file is over 7000 lines now, so instead of adding
AR9003 initvals to it instead lets split the current initvals.h by
hardware family: AR5008, AR9001, AR9002

The AR9003 family will have its own initval file later.

Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/ar5008_initvals.h   |  742 ++++++++
 drivers/net/wireless/ath/ath9k/ar9001_initvals.h   | 1254 +++++++++++++
 .../ath/ath9k/{initvals.h => ar9002_initvals.h}    | 1984 +-------------------
 drivers/net/wireless/ath/ath9k/hw.c                |    4 +-
 4 files changed, 2006 insertions(+), 1978 deletions(-)
 create mode 100644 drivers/net/wireless/ath/ath9k/ar5008_initvals.h
 create mode 100644 drivers/net/wireless/ath/ath9k/ar9001_initvals.h
 rename drivers/net/wireless/ath/ath9k/{initvals.h => ar9002_initvals.h} (79%)

diff --git a/drivers/net/wireless/ath/ath9k/ar5008_initvals.h b/drivers/net/wireless/ath/ath9k/ar5008_initvals.h
new file mode 100644
index 0000000..cd953f6
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/ar5008_initvals.h
@@ -0,0 +1,742 @@
+/*
+ * Copyright (c) 2008-2009 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef INITVALS_AR5008_H
+#define INITVALS_AR5008_H
+
+static const u32 ar5416Modes[][6] = {
+    { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 },
+    { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 },
+    { 0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180 },
+    { 0x000010f0, 0x0000a000, 0x00014000, 0x00016000, 0x0000b000, 0x00014008 },
+    { 0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00, 0x06e006e0 },
+    { 0x0000801c, 0x128d93a7, 0x128d93cf, 0x12e013d7, 0x12e013ab, 0x098813cf },
+    { 0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810, 0x08f04810 },
+    { 0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a, 0x0000320a },
+    { 0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303 },
+    { 0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200 },
+    { 0x00009824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
+    { 0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001 },
+    { 0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
+    { 0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007 },
+    { 0x00009844, 0x1372161e, 0x1372161e, 0x137216a0, 0x137216a0, 0x137216a0 },
+    { 0x00009848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
+    { 0x0000a848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
+    { 0x0000b848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
+    { 0x00009850, 0x6c48b4e0, 0x6d48b4e0, 0x6d48b0de, 0x6c48b0de, 0x6c48b0de },
+    { 0x00009858, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e },
+    { 0x0000985c, 0x31395d5e, 0x3139605e, 0x3139605e, 0x31395d5e, 0x31395d5e },
+    { 0x00009860, 0x00049d18, 0x00049d18, 0x00049d18, 0x00049d18, 0x00049d18 },
+    { 0x00009864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00 },
+    { 0x00009868, 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190 },
+    { 0x0000986c, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 },
+    { 0x00009914, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898, 0x000007d0 },
+    { 0x00009918, 0x000001b8, 0x00000370, 0x00000268, 0x00000134, 0x00000134 },
+    { 0x00009924, 0xd0058a0b, 0xd0058a0b, 0xd0058a0b, 0xd0058a0b, 0xd0058a0b },
+    { 0x00009944, 0xffb81020, 0xffb81020, 0xffb81020, 0xffb81020, 0xffb81020 },
+    { 0x00009960, 0x00000900, 0x00000900, 0x00012d80, 0x00012d80, 0x00012d80 },
+    { 0x0000a960, 0x00000900, 0x00000900, 0x00012d80, 0x00012d80, 0x00012d80 },
+    { 0x0000b960, 0x00000900, 0x00000900, 0x00012d80, 0x00012d80, 0x00012d80 },
+    { 0x00009964, 0x00000000, 0x00000000, 0x00001120, 0x00001120, 0x00001120 },
+    { 0x000099bc, 0x001a0a00, 0x001a0a00, 0x001a0a00, 0x001a0a00, 0x001a0a00 },
+    { 0x000099c0, 0x038919be, 0x038919be, 0x038919be, 0x038919be, 0x038919be },
+    { 0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77 },
+    { 0x000099c8, 0x6af6532c, 0x6af6532c, 0x6af6532c, 0x6af6532c, 0x6af6532c },
+    { 0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8 },
+    { 0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, 0x00046384 },
+    { 0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+    { 0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+    { 0x0000a204, 0x00000880, 0x00000880, 0x00000880, 0x00000880, 0x00000880 },
+    { 0x0000a208, 0xd6be4788, 0xd6be4788, 0xd03e4788, 0xd03e4788, 0xd03e4788 },
+    { 0x0000a20c, 0x002ec1e0, 0x002ec1e0, 0x002ac120, 0x002ac120, 0x002ac120 },
+    { 0x0000b20c, 0x002ec1e0, 0x002ec1e0, 0x002ac120, 0x002ac120, 0x002ac120 },
+    { 0x0000c20c, 0x002ec1e0, 0x002ec1e0, 0x002ac120, 0x002ac120, 0x002ac120 },
+    { 0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a },
+    { 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000 },
+    { 0x0000a274, 0x0a1a9caa, 0x0a1a9caa, 0x0a1a7caa, 0x0a1a7caa, 0x0a1a7caa },
+    { 0x0000a300, 0x18010000, 0x18010000, 0x18010000, 0x18010000, 0x18010000 },
+    { 0x0000a304, 0x30032602, 0x30032602, 0x2e032402, 0x2e032402, 0x2e032402 },
+    { 0x0000a308, 0x48073e06, 0x48073e06, 0x4a0a3c06, 0x4a0a3c06, 0x4a0a3c06 },
+    { 0x0000a30c, 0x560b4c0a, 0x560b4c0a, 0x621a540b, 0x621a540b, 0x621a540b },
+    { 0x0000a310, 0x641a600f, 0x641a600f, 0x764f6c1b, 0x764f6c1b, 0x764f6c1b },
+    { 0x0000a314, 0x7a4f6e1b, 0x7a4f6e1b, 0x845b7a5a, 0x845b7a5a, 0x845b7a5a },
+    { 0x0000a318, 0x8c5b7e5a, 0x8c5b7e5a, 0x950f8ccf, 0x950f8ccf, 0x950f8ccf },
+    { 0x0000a31c, 0x9d0f96cf, 0x9d0f96cf, 0xa5cf9b4f, 0xa5cf9b4f, 0xa5cf9b4f },
+    { 0x0000a320, 0xb51fa69f, 0xb51fa69f, 0xbddfaf1f, 0xbddfaf1f, 0xbddfaf1f },
+    { 0x0000a324, 0xcb3fbd07, 0xcb3fbcbf, 0xd1ffc93f, 0xd1ffc93f, 0xd1ffc93f },
+    { 0x0000a328, 0x0000d7bf, 0x0000d7bf, 0x00000000, 0x00000000, 0x00000000 },
+    { 0x0000a32c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+    { 0x0000a330, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+    { 0x0000a334, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+};
+
+static const u32 ar5416Common[][2] = {
+    { 0x0000000c, 0x00000000 },
+    { 0x00000030, 0x00020015 },
+    { 0x00000034, 0x00000005 },
+    { 0x00000040, 0x00000000 },
+    { 0x00000044, 0x00000008 },
+    { 0x00000048, 0x00000008 },
+    { 0x0000004c, 0x00000010 },
+    { 0x00000050, 0x00000000 },
+    { 0x00000054, 0x0000001f },
+    { 0x00000800, 0x00000000 },
+    { 0x00000804, 0x00000000 },
+    { 0x00000808, 0x00000000 },
+    { 0x0000080c, 0x00000000 },
+    { 0x00000810, 0x00000000 },
+    { 0x00000814, 0x00000000 },
+    { 0x00000818, 0x00000000 },
+    { 0x0000081c, 0x00000000 },
+    { 0x00000820, 0x00000000 },
+    { 0x00000824, 0x00000000 },
+    { 0x00001040, 0x002ffc0f },
+    { 0x00001044, 0x002ffc0f },
+    { 0x00001048, 0x002ffc0f },
+    { 0x0000104c, 0x002ffc0f },
+    { 0x00001050, 0x002ffc0f },
+    { 0x00001054, 0x002ffc0f },
+    { 0x00001058, 0x002ffc0f },
+    { 0x0000105c, 0x002ffc0f },
+    { 0x00001060, 0x002ffc0f },
+    { 0x00001064, 0x002ffc0f },
+    { 0x00001230, 0x00000000 },
+    { 0x00001270, 0x00000000 },
+    { 0x00001038, 0x00000000 },
+    { 0x00001078, 0x00000000 },
+    { 0x000010b8, 0x00000000 },
+    { 0x000010f8, 0x00000000 },
+    { 0x00001138, 0x00000000 },
+    { 0x00001178, 0x00000000 },
+    { 0x000011b8, 0x00000000 },
+    { 0x000011f8, 0x00000000 },
+    { 0x00001238, 0x00000000 },
+    { 0x00001278, 0x00000000 },
+    { 0x000012b8, 0x00000000 },
+    { 0x000012f8, 0x00000000 },
+    { 0x00001338, 0x00000000 },
+    { 0x00001378, 0x00000000 },
+    { 0x000013b8, 0x00000000 },
+    { 0x000013f8, 0x00000000 },
+    { 0x00001438, 0x00000000 },
+    { 0x00001478, 0x00000000 },
+    { 0x000014b8, 0x00000000 },
+    { 0x000014f8, 0x00000000 },
+    { 0x00001538, 0x00000000 },
+    { 0x00001578, 0x00000000 },
+    { 0x000015b8, 0x00000000 },
+    { 0x000015f8, 0x00000000 },
+    { 0x00001638, 0x00000000 },
+    { 0x00001678, 0x00000000 },
+    { 0x000016b8, 0x00000000 },
+    { 0x000016f8, 0x00000000 },
+    { 0x00001738, 0x00000000 },
+    { 0x00001778, 0x00000000 },
+    { 0x000017b8, 0x00000000 },
+    { 0x000017f8, 0x00000000 },
+    { 0x0000103c, 0x00000000 },
+    { 0x0000107c, 0x00000000 },
+    { 0x000010bc, 0x00000000 },
+    { 0x000010fc, 0x00000000 },
+    { 0x0000113c, 0x00000000 },
+    { 0x0000117c, 0x00000000 },
+    { 0x000011bc, 0x00000000 },
+    { 0x000011fc, 0x00000000 },
+    { 0x0000123c, 0x00000000 },
+    { 0x0000127c, 0x00000000 },
+    { 0x000012bc, 0x00000000 },
+    { 0x000012fc, 0x00000000 },
+    { 0x0000133c, 0x00000000 },
+    { 0x0000137c, 0x00000000 },
+    { 0x000013bc, 0x00000000 },
+    { 0x000013fc, 0x00000000 },
+    { 0x0000143c, 0x00000000 },
+    { 0x0000147c, 0x00000000 },
+    { 0x00004030, 0x00000002 },
+    { 0x0000403c, 0x00000002 },
+    { 0x00007010, 0x00000000 },
+    { 0x00007038, 0x000004c2 },
+    { 0x00008004, 0x00000000 },
+    { 0x00008008, 0x00000000 },
+    { 0x0000800c, 0x00000000 },
+    { 0x00008018, 0x00000700 },
+    { 0x00008020, 0x00000000 },
+    { 0x00008038, 0x00000000 },
+    { 0x0000803c, 0x00000000 },
+    { 0x00008048, 0x40000000 },
+    { 0x00008054, 0x00000000 },
+    { 0x00008058, 0x00000000 },
+    { 0x0000805c, 0x000fc78f },
+    { 0x00008060, 0x0000000f },
+    { 0x00008064, 0x00000000 },
+    { 0x000080c0, 0x2a82301a },
+    { 0x000080c4, 0x05dc01e0 },
+    { 0x000080c8, 0x1f402710 },
+    { 0x000080cc, 0x01f40000 },
+    { 0x000080d0, 0x00001e00 },
+    { 0x000080d4, 0x00000000 },
+    { 0x000080d8, 0x00400000 },
+    { 0x000080e0, 0xffffffff },
+    { 0x000080e4, 0x0000ffff },
+    { 0x000080e8, 0x003f3f3f },
+    { 0x000080ec, 0x00000000 },
+    { 0x000080f0, 0x00000000 },
+    { 0x000080f4, 0x00000000 },
+    { 0x000080f8, 0x00000000 },
+    { 0x000080fc, 0x00020000 },
+    { 0x00008100, 0x00020000 },
+    { 0x00008104, 0x00000001 },
+    { 0x00008108, 0x00000052 },
+    { 0x0000810c, 0x00000000 },
+    { 0x00008110, 0x00000168 },
+    { 0x00008118, 0x000100aa },
+    { 0x0000811c, 0x00003210 },
+    { 0x00008124, 0x00000000 },
+    { 0x00008128, 0x00000000 },
+    { 0x0000812c, 0x00000000 },
+    { 0x00008130, 0x00000000 },
+    { 0x00008134, 0x00000000 },
+    { 0x00008138, 0x00000000 },
+    { 0x0000813c, 0x00000000 },
+    { 0x00008144, 0xffffffff },
+    { 0x00008168, 0x00000000 },
+    { 0x0000816c, 0x00000000 },
+    { 0x00008170, 0x32143320 },
+    { 0x00008174, 0xfaa4fa50 },
+    { 0x00008178, 0x00000100 },
+    { 0x0000817c, 0x00000000 },
+    { 0x000081c4, 0x00000000 },
+    { 0x000081ec, 0x00000000 },
+    { 0x000081f0, 0x00000000 },
+    { 0x000081f4, 0x00000000 },
+    { 0x000081f8, 0x00000000 },
+    { 0x000081fc, 0x00000000 },
+    { 0x00008200, 0x00000000 },
+    { 0x00008204, 0x00000000 },
+    { 0x00008208, 0x00000000 },
+    { 0x0000820c, 0x00000000 },
+    { 0x00008210, 0x00000000 },
+    { 0x00008214, 0x00000000 },
+    { 0x00008218, 0x00000000 },
+    { 0x0000821c, 0x00000000 },
+    { 0x00008220, 0x00000000 },
+    { 0x00008224, 0x00000000 },
+    { 0x00008228, 0x00000000 },
+    { 0x0000822c, 0x00000000 },
+    { 0x00008230, 0x00000000 },
+    { 0x00008234, 0x00000000 },
+    { 0x00008238, 0x00000000 },
+    { 0x0000823c, 0x00000000 },
+    { 0x00008240, 0x00100000 },
+    { 0x00008244, 0x0010f400 },
+    { 0x00008248, 0x00000100 },
+    { 0x0000824c, 0x0001e800 },
+    { 0x00008250, 0x00000000 },
+    { 0x00008254, 0x00000000 },
+    { 0x00008258, 0x00000000 },
+    { 0x0000825c, 0x400000ff },
+    { 0x00008260, 0x00080922 },
+    { 0x00008264, 0xa8000010 },
+    { 0x00008270, 0x00000000 },
+    { 0x00008274, 0x40000000 },
+    { 0x00008278, 0x003e4180 },
+    { 0x0000827c, 0x00000000 },
+    { 0x00008284, 0x0000002c },
+    { 0x00008288, 0x0000002c },
+    { 0x0000828c, 0x00000000 },
+    { 0x00008294, 0x00000000 },
+    { 0x00008298, 0x00000000 },
+    { 0x00008300, 0x00000000 },
+    { 0x00008304, 0x00000000 },
+    { 0x00008308, 0x00000000 },
+    { 0x0000830c, 0x00000000 },
+    { 0x00008310, 0x00000000 },
+    { 0x00008314, 0x00000000 },
+    { 0x00008318, 0x00000000 },
+    { 0x00008328, 0x00000000 },
+    { 0x0000832c, 0x00000007 },
+    { 0x00008330, 0x00000302 },
+    { 0x00008334, 0x00000e00 },
+    { 0x00008338, 0x00070000 },
+    { 0x0000833c, 0x00000000 },
+    { 0x00008340, 0x000107ff },
+    { 0x00009808, 0x00000000 },
+    { 0x0000980c, 0xad848e19 },
+    { 0x00009810, 0x7d14e000 },
+    { 0x00009814, 0x9c0a9f6b },
+    { 0x0000981c, 0x00000000 },
+    { 0x0000982c, 0x0000a000 },
+    { 0x00009830, 0x00000000 },
+    { 0x0000983c, 0x00200400 },
+    { 0x00009840, 0x206a002e },
+    { 0x0000984c, 0x1284233c },
+    { 0x00009854, 0x00000859 },
+    { 0x00009900, 0x00000000 },
+    { 0x00009904, 0x00000000 },
+    { 0x00009908, 0x00000000 },
+    { 0x0000990c, 0x00000000 },
+    { 0x0000991c, 0x10000fff },
+    { 0x00009920, 0x05100000 },
+    { 0x0000a920, 0x05100000 },
+    { 0x0000b920, 0x05100000 },
+    { 0x00009928, 0x00000001 },
+    { 0x0000992c, 0x00000004 },
+    { 0x00009934, 0x1e1f2022 },
+    { 0x00009938, 0x0a0b0c0d },
+    { 0x0000993c, 0x00000000 },
+    { 0x00009948, 0x9280b212 },
+    { 0x0000994c, 0x00020028 },
+    { 0x00009954, 0x5d50e188 },
+    { 0x00009958, 0x00081fff },
+    { 0x0000c95c, 0x004b6a8e },
+    { 0x0000c968, 0x000003ce },
+    { 0x00009970, 0x190fb515 },
+    { 0x00009974, 0x00000000 },
+    { 0x00009978, 0x00000001 },
+    { 0x0000997c, 0x00000000 },
+    { 0x00009980, 0x00000000 },
+    { 0x00009984, 0x00000000 },
+    { 0x00009988, 0x00000000 },
+    { 0x0000998c, 0x00000000 },
+    { 0x00009990, 0x00000000 },
+    { 0x00009994, 0x00000000 },
+    { 0x00009998, 0x00000000 },
+    { 0x0000999c, 0x00000000 },
+    { 0x000099a0, 0x00000000 },
+    { 0x000099a4, 0x00000001 },
+    { 0x000099a8, 0x001fff00 },
+    { 0x000099ac, 0x00000000 },
+    { 0x000099b0, 0x03051000 },
+    { 0x000099dc, 0x00000000 },
+    { 0x000099e0, 0x00000200 },
+    { 0x000099e4, 0xaaaaaaaa },
+    { 0x000099e8, 0x3c466478 },
+    { 0x000099ec, 0x000000aa },
+    { 0x000099fc, 0x00001042 },
+    { 0x00009b00, 0x00000000 },
+    { 0x00009b04, 0x00000001 },
+    { 0x00009b08, 0x00000002 },
+    { 0x00009b0c, 0x00000003 },
+    { 0x00009b10, 0x00000004 },
+    { 0x00009b14, 0x00000005 },
+    { 0x00009b18, 0x00000008 },
+    { 0x00009b1c, 0x00000009 },
+    { 0x00009b20, 0x0000000a },
+    { 0x00009b24, 0x0000000b },
+    { 0x00009b28, 0x0000000c },
+    { 0x00009b2c, 0x0000000d },
+    { 0x00009b30, 0x00000010 },
+    { 0x00009b34, 0x00000011 },
+    { 0x00009b38, 0x00000012 },
+    { 0x00009b3c, 0x00000013 },
+    { 0x00009b40, 0x00000014 },
+    { 0x00009b44, 0x00000015 },
+    { 0x00009b48, 0x00000018 },
+    { 0x00009b4c, 0x00000019 },
+    { 0x00009b50, 0x0000001a },
+    { 0x00009b54, 0x0000001b },
+    { 0x00009b58, 0x0000001c },
+    { 0x00009b5c, 0x0000001d },
+    { 0x00009b60, 0x00000020 },
+    { 0x00009b64, 0x00000021 },
+    { 0x00009b68, 0x00000022 },
+    { 0x00009b6c, 0x00000023 },
+    { 0x00009b70, 0x00000024 },
+    { 0x00009b74, 0x00000025 },
+    { 0x00009b78, 0x00000028 },
+    { 0x00009b7c, 0x00000029 },
+    { 0x00009b80, 0x0000002a },
+    { 0x00009b84, 0x0000002b },
+    { 0x00009b88, 0x0000002c },
+    { 0x00009b8c, 0x0000002d },
+    { 0x00009b90, 0x00000030 },
+    { 0x00009b94, 0x00000031 },
+    { 0x00009b98, 0x00000032 },
+    { 0x00009b9c, 0x00000033 },
+    { 0x00009ba0, 0x00000034 },
+    { 0x00009ba4, 0x00000035 },
+    { 0x00009ba8, 0x00000035 },
+    { 0x00009bac, 0x00000035 },
+    { 0x00009bb0, 0x00000035 },
+    { 0x00009bb4, 0x00000035 },
+    { 0x00009bb8, 0x00000035 },
+    { 0x00009bbc, 0x00000035 },
+    { 0x00009bc0, 0x00000035 },
+    { 0x00009bc4, 0x00000035 },
+    { 0x00009bc8, 0x00000035 },
+    { 0x00009bcc, 0x00000035 },
+    { 0x00009bd0, 0x00000035 },
+    { 0x00009bd4, 0x00000035 },
+    { 0x00009bd8, 0x00000035 },
+    { 0x00009bdc, 0x00000035 },
+    { 0x00009be0, 0x00000035 },
+    { 0x00009be4, 0x00000035 },
+    { 0x00009be8, 0x00000035 },
+    { 0x00009bec, 0x00000035 },
+    { 0x00009bf0, 0x00000035 },
+    { 0x00009bf4, 0x00000035 },
+    { 0x00009bf8, 0x00000010 },
+    { 0x00009bfc, 0x0000001a },
+    { 0x0000a210, 0x40806333 },
+    { 0x0000a214, 0x00106c10 },
+    { 0x0000a218, 0x009c4060 },
+    { 0x0000a220, 0x018830c6 },
+    { 0x0000a224, 0x00000400 },
+    { 0x0000a228, 0x00000bb5 },
+    { 0x0000a22c, 0x00000011 },
+    { 0x0000a234, 0x20202020 },
+    { 0x0000a238, 0x20202020 },
+    { 0x0000a23c, 0x13c889af },
+    { 0x0000a240, 0x38490a20 },
+    { 0x0000a244, 0x00007bb6 },
+    { 0x0000a248, 0x0fff3ffc },
+    { 0x0000a24c, 0x00000001 },
+    { 0x0000a250, 0x0000a000 },
+    { 0x0000a254, 0x00000000 },
+    { 0x0000a258, 0x0cc75380 },
+    { 0x0000a25c, 0x0f0f0f01 },
+    { 0x0000a260, 0xdfa91f01 },
+    { 0x0000a268, 0x00000000 },
+    { 0x0000a26c, 0x0e79e5c6 },
+    { 0x0000b26c, 0x0e79e5c6 },
+    { 0x0000c26c, 0x0e79e5c6 },
+    { 0x0000d270, 0x00820820 },
+    { 0x0000a278, 0x1ce739ce },
+    { 0x0000a27c, 0x051701ce },
+    { 0x0000a338, 0x00000000 },
+    { 0x0000a33c, 0x00000000 },
+    { 0x0000a340, 0x00000000 },
+    { 0x0000a344, 0x00000000 },
+    { 0x0000a348, 0x3fffffff },
+    { 0x0000a34c, 0x3fffffff },
+    { 0x0000a350, 0x3fffffff },
+    { 0x0000a354, 0x0003ffff },
+    { 0x0000a358, 0x79a8aa1f },
+    { 0x0000d35c, 0x07ffffef },
+    { 0x0000d360, 0x0fffffe7 },
+    { 0x0000d364, 0x17ffffe5 },
+    { 0x0000d368, 0x1fffffe4 },
+    { 0x0000d36c, 0x37ffffe3 },
+    { 0x0000d370, 0x3fffffe3 },
+    { 0x0000d374, 0x57ffffe3 },
+    { 0x0000d378, 0x5fffffe2 },
+    { 0x0000d37c, 0x7fffffe2 },
+    { 0x0000d380, 0x7f3c7bba },
+    { 0x0000d384, 0xf3307ff0 },
+    { 0x0000a388, 0x08000000 },
+    { 0x0000a38c, 0x20202020 },
+    { 0x0000a390, 0x20202020 },
+    { 0x0000a394, 0x1ce739ce },
+    { 0x0000a398, 0x000001ce },
+    { 0x0000a39c, 0x00000001 },
+    { 0x0000a3a0, 0x00000000 },
+    { 0x0000a3a4, 0x00000000 },
+    { 0x0000a3a8, 0x00000000 },
+    { 0x0000a3ac, 0x00000000 },
+    { 0x0000a3b0, 0x00000000 },
+    { 0x0000a3b4, 0x00000000 },
+    { 0x0000a3b8, 0x00000000 },
+    { 0x0000a3bc, 0x00000000 },
+    { 0x0000a3c0, 0x00000000 },
+    { 0x0000a3c4, 0x00000000 },
+    { 0x0000a3c8, 0x00000246 },
+    { 0x0000a3cc, 0x20202020 },
+    { 0x0000a3d0, 0x20202020 },
+    { 0x0000a3d4, 0x20202020 },
+    { 0x0000a3dc, 0x1ce739ce },
+    { 0x0000a3e0, 0x000001ce },
+};
+
+static const u32 ar5416Bank0[][2] = {
+    { 0x000098b0, 0x1e5795e5 },
+    { 0x000098e0, 0x02008020 },
+};
+
+static const u32 ar5416BB_RfGain[][3] = {
+    { 0x00009a00, 0x00000000, 0x00000000 },
+    { 0x00009a04, 0x00000040, 0x00000040 },
+    { 0x00009a08, 0x00000080, 0x00000080 },
+    { 0x00009a0c, 0x000001a1, 0x00000141 },
+    { 0x00009a10, 0x000001e1, 0x00000181 },
+    { 0x00009a14, 0x00000021, 0x000001c1 },
+    { 0x00009a18, 0x00000061, 0x00000001 },
+    { 0x00009a1c, 0x00000168, 0x00000041 },
+    { 0x00009a20, 0x000001a8, 0x000001a8 },
+    { 0x00009a24, 0x000001e8, 0x000001e8 },
+    { 0x00009a28, 0x00000028, 0x00000028 },
+    { 0x00009a2c, 0x00000068, 0x00000068 },
+    { 0x00009a30, 0x00000189, 0x000000a8 },
+    { 0x00009a34, 0x000001c9, 0x00000169 },
+    { 0x00009a38, 0x00000009, 0x000001a9 },
+    { 0x00009a3c, 0x00000049, 0x000001e9 },
+    { 0x00009a40, 0x00000089, 0x00000029 },
+    { 0x00009a44, 0x00000170, 0x00000069 },
+    { 0x00009a48, 0x000001b0, 0x00000190 },
+    { 0x00009a4c, 0x000001f0, 0x000001d0 },
+    { 0x00009a50, 0x00000030, 0x00000010 },
+    { 0x00009a54, 0x00000070, 0x00000050 },
+    { 0x00009a58, 0x00000191, 0x00000090 },
+    { 0x00009a5c, 0x000001d1, 0x00000151 },
+    { 0x00009a60, 0x00000011, 0x00000191 },
+    { 0x00009a64, 0x00000051, 0x000001d1 },
+    { 0x00009a68, 0x00000091, 0x00000011 },
+    { 0x00009a6c, 0x000001b8, 0x00000051 },
+    { 0x00009a70, 0x000001f8, 0x00000198 },
+    { 0x00009a74, 0x00000038, 0x000001d8 },
+    { 0x00009a78, 0x00000078, 0x00000018 },
+    { 0x00009a7c, 0x00000199, 0x00000058 },
+    { 0x00009a80, 0x000001d9, 0x00000098 },
+    { 0x00009a84, 0x00000019, 0x00000159 },
+    { 0x00009a88, 0x00000059, 0x00000199 },
+    { 0x00009a8c, 0x00000099, 0x000001d9 },
+    { 0x00009a90, 0x000000d9, 0x00000019 },
+    { 0x00009a94, 0x000000f9, 0x00000059 },
+    { 0x00009a98, 0x000000f9, 0x00000099 },
+    { 0x00009a9c, 0x000000f9, 0x000000d9 },
+    { 0x00009aa0, 0x000000f9, 0x000000f9 },
+    { 0x00009aa4, 0x000000f9, 0x000000f9 },
+    { 0x00009aa8, 0x000000f9, 0x000000f9 },
+    { 0x00009aac, 0x000000f9, 0x000000f9 },
+    { 0x00009ab0, 0x000000f9, 0x000000f9 },
+    { 0x00009ab4, 0x000000f9, 0x000000f9 },
+    { 0x00009ab8, 0x000000f9, 0x000000f9 },
+    { 0x00009abc, 0x000000f9, 0x000000f9 },
+    { 0x00009ac0, 0x000000f9, 0x000000f9 },
+    { 0x00009ac4, 0x000000f9, 0x000000f9 },
+    { 0x00009ac8, 0x000000f9, 0x000000f9 },
+    { 0x00009acc, 0x000000f9, 0x000000f9 },
+    { 0x00009ad0, 0x000000f9, 0x000000f9 },
+    { 0x00009ad4, 0x000000f9, 0x000000f9 },
+    { 0x00009ad8, 0x000000f9, 0x000000f9 },
+    { 0x00009adc, 0x000000f9, 0x000000f9 },
+    { 0x00009ae0, 0x000000f9, 0x000000f9 },
+    { 0x00009ae4, 0x000000f9, 0x000000f9 },
+    { 0x00009ae8, 0x000000f9, 0x000000f9 },
+    { 0x00009aec, 0x000000f9, 0x000000f9 },
+    { 0x00009af0, 0x000000f9, 0x000000f9 },
+    { 0x00009af4, 0x000000f9, 0x000000f9 },
+    { 0x00009af8, 0x000000f9, 0x000000f9 },
+    { 0x00009afc, 0x000000f9, 0x000000f9 },
+};
+
+static const u32 ar5416Bank1[][2] = {
+    { 0x000098b0, 0x02108421 },
+    { 0x000098ec, 0x00000008 },
+};
+
+static const u32 ar5416Bank2[][2] = {
+    { 0x000098b0, 0x0e73ff17 },
+    { 0x000098e0, 0x00000420 },
+};
+
+static const u32 ar5416Bank3[][3] = {
+    { 0x000098f0, 0x01400018, 0x01c00018 },
+};
+
+static const u32 ar5416Bank6[][3] = {
+
+    { 0x0000989c, 0x00000000, 0x00000000 },
+    { 0x0000989c, 0x00000000, 0x00000000 },
+    { 0x0000989c, 0x00000000, 0x00000000 },
+    { 0x0000989c, 0x00e00000, 0x00e00000 },
+    { 0x0000989c, 0x005e0000, 0x005e0000 },
+    { 0x0000989c, 0x00120000, 0x00120000 },
+    { 0x0000989c, 0x00620000, 0x00620000 },
+    { 0x0000989c, 0x00020000, 0x00020000 },
+    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
+    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
+    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
+    { 0x0000989c, 0x40ff0000, 0x40ff0000 },
+    { 0x0000989c, 0x005f0000, 0x005f0000 },
+    { 0x0000989c, 0x00870000, 0x00870000 },
+    { 0x0000989c, 0x00f90000, 0x00f90000 },
+    { 0x0000989c, 0x007b0000, 0x007b0000 },
+    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
+    { 0x0000989c, 0x00f50000, 0x00f50000 },
+    { 0x0000989c, 0x00dc0000, 0x00dc0000 },
+    { 0x0000989c, 0x00110000, 0x00110000 },
+    { 0x0000989c, 0x006100a8, 0x006100a8 },
+    { 0x0000989c, 0x004210a2, 0x004210a2 },
+    { 0x0000989c, 0x0014008f, 0x0014008f },
+    { 0x0000989c, 0x00c40003, 0x00c40003 },
+    { 0x0000989c, 0x003000f2, 0x003000f2 },
+    { 0x0000989c, 0x00440016, 0x00440016 },
+    { 0x0000989c, 0x00410040, 0x00410040 },
+    { 0x0000989c, 0x0001805e, 0x0001805e },
+    { 0x0000989c, 0x0000c0ab, 0x0000c0ab },
+    { 0x0000989c, 0x000000f1, 0x000000f1 },
+    { 0x0000989c, 0x00002081, 0x00002081 },
+    { 0x0000989c, 0x000000d4, 0x000000d4 },
+    { 0x000098d0, 0x0000000f, 0x0010000f },
+};
+
+static const u32 ar5416Bank6TPC[][3] = {
+    { 0x0000989c, 0x00000000, 0x00000000 },
+    { 0x0000989c, 0x00000000, 0x00000000 },
+    { 0x0000989c, 0x00000000, 0x00000000 },
+    { 0x0000989c, 0x00e00000, 0x00e00000 },
+    { 0x0000989c, 0x005e0000, 0x005e0000 },
+    { 0x0000989c, 0x00120000, 0x00120000 },
+    { 0x0000989c, 0x00620000, 0x00620000 },
+    { 0x0000989c, 0x00020000, 0x00020000 },
+    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
+    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
+    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
+    { 0x0000989c, 0x40ff0000, 0x40ff0000 },
+    { 0x0000989c, 0x005f0000, 0x005f0000 },
+    { 0x0000989c, 0x00870000, 0x00870000 },
+    { 0x0000989c, 0x00f90000, 0x00f90000 },
+    { 0x0000989c, 0x007b0000, 0x007b0000 },
+    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
+    { 0x0000989c, 0x00f50000, 0x00f50000 },
+    { 0x0000989c, 0x00dc0000, 0x00dc0000 },
+    { 0x0000989c, 0x00110000, 0x00110000 },
+    { 0x0000989c, 0x006100a8, 0x006100a8 },
+    { 0x0000989c, 0x00423022, 0x00423022 },
+    { 0x0000989c, 0x201400df, 0x201400df },
+    { 0x0000989c, 0x00c40002, 0x00c40002 },
+    { 0x0000989c, 0x003000f2, 0x003000f2 },
+    { 0x0000989c, 0x00440016, 0x00440016 },
+    { 0x0000989c, 0x00410040, 0x00410040 },
+    { 0x0000989c, 0x0001805e, 0x0001805e },
+    { 0x0000989c, 0x0000c0ab, 0x0000c0ab },
+    { 0x0000989c, 0x000000e1, 0x000000e1 },
+    { 0x0000989c, 0x00007081, 0x00007081 },
+    { 0x0000989c, 0x000000d4, 0x000000d4 },
+    { 0x000098d0, 0x0000000f, 0x0010000f },
+};
+
+static const u32 ar5416Bank7[][2] = {
+    { 0x0000989c, 0x00000500 },
+    { 0x0000989c, 0x00000800 },
+    { 0x000098cc, 0x0000000e },
+};
+
+static const u32 ar5416Addac[][2] = {
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000003 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x0000000c },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000030 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000060 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000058 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x000098cc,  0x00000000 },
+};
+
+static const u32 ar5416Modes_9100[][6] = {
+    { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 },
+    { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 },
+    { 0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180 },
+    { 0x000010f0, 0x0000a000, 0x00014000, 0x00016000, 0x0000b000, 0x00014008 },
+    { 0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00, 0x06e006e0 },
+    { 0x0000801c, 0x128d93a7, 0x128d93cf, 0x12e013d7, 0x12e013ab, 0x098813cf },
+    { 0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303 },
+    { 0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200 },
+    { 0x00009824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
+    { 0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001 },
+    { 0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
+    { 0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007 },
+    { 0x00009844, 0x0372161e, 0x0372161e, 0x037216a0, 0x037216a0, 0x037216a0 },
+    { 0x00009848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
+    { 0x0000a848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
+    { 0x0000b848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
+    { 0x00009850, 0x6d48b4e2, 0x6d48b4e2, 0x6d48b0e2, 0x6d48b0e2, 0x6d48b0e2 },
+    { 0x00009858, 0x7ec82d2e, 0x7ec82d2e, 0x7ec86d2e, 0x7ec84d2e, 0x7ec82d2e },
+    { 0x0000985c, 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e },
+    { 0x00009860, 0x00048d18, 0x00048d18, 0x00048d20, 0x00048d20, 0x00048d18 },
+    { 0x0000c864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00 },
+    { 0x00009868, 0x409a40d0, 0x409a40d0, 0x409a40d0, 0x409a40d0, 0x409a40d0 },
+    { 0x0000986c, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 },
+    { 0x00009914, 0x000007d0, 0x000007d0, 0x00000898, 0x00000898, 0x000007d0 },
+    { 0x00009918, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b, 0x00000016 },
+    { 0x00009924, 0xd00a8a07, 0xd00a8a07, 0xd00a8a11, 0xd00a8a0d, 0xd00a8a0d },
+    { 0x00009940, 0x00754604, 0x00754604, 0xfff81204, 0xfff81204, 0xfff81204 },
+    { 0x00009944, 0xdfb81020, 0xdfb81020, 0xdfb81020, 0xdfb81020, 0xdfb81020 },
+    { 0x00009954, 0x5f3ca3de, 0x5f3ca3de, 0xe250a51e, 0xe250a51e, 0xe250a51e },
+    { 0x00009958, 0x2108ecff, 0x2108ecff, 0x3388ffff, 0x3388ffff, 0x3388ffff },
+#ifdef TB243
+    { 0x00009960, 0x00000900, 0x00000900, 0x00009b40, 0x00009b40, 0x00012d80 },
+    { 0x0000a960, 0x00000900, 0x00000900, 0x00009b40, 0x00009b40, 0x00012d80 },
+    { 0x0000b960, 0x00000900, 0x00000900, 0x00009b40, 0x00009b40, 0x00012d80 },
+    { 0x00009964, 0x00000000, 0x00000000, 0x00002210, 0x00002210, 0x00001120 },
+#else
+    { 0x00009960, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0 },
+    { 0x0000a960, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0 },
+    { 0x0000b960, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0 },
+    { 0x00009964, 0x00001120, 0x00001120, 0x00001120, 0x00001120, 0x00001120 },
+#endif
+    { 0x0000c9bc, 0x001a0600, 0x001a0600, 0x001a1000, 0x001a0c00, 0x001a0c00 },
+    { 0x000099c0, 0x038919be, 0x038919be, 0x038919be, 0x038919be, 0x038919be },
+    { 0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77 },
+    { 0x000099c8, 0x60f65329, 0x60f65329, 0x60f65329, 0x60f65329, 0x60f65329 },
+    { 0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8 },
+    { 0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, 0x00046384 },
+    { 0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+    { 0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+    { 0x0000a204, 0x00000880, 0x00000880, 0x00000880, 0x00000880, 0x00000880 },
+    { 0x0000a208, 0xd6be4788, 0xd6be4788, 0xd03e4788, 0xd03e4788, 0xd03e4788 },
+    { 0x0000a20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120 },
+    { 0x0000b20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120 },
+    { 0x0000c20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120 },
+    { 0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a },
+    { 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000 },
+    { 0x0000a274, 0x0a1a9caa, 0x0a1a9caa, 0x0a1a7caa, 0x0a1a7caa, 0x0a1a7caa },
+    { 0x0000a300, 0x18010000, 0x18010000, 0x18010000, 0x18010000, 0x18010000 },
+    { 0x0000a304, 0x30032602, 0x30032602, 0x2e032402, 0x2e032402, 0x2e032402 },
+    { 0x0000a308, 0x48073e06, 0x48073e06, 0x4a0a3c06, 0x4a0a3c06, 0x4a0a3c06 },
+    { 0x0000a30c, 0x560b4c0a, 0x560b4c0a, 0x621a540b, 0x621a540b, 0x621a540b },
+    { 0x0000a310, 0x641a600f, 0x641a600f, 0x764f6c1b, 0x764f6c1b, 0x764f6c1b },
+    { 0x0000a314, 0x7a4f6e1b, 0x7a4f6e1b, 0x845b7a5a, 0x845b7a5a, 0x845b7a5a },
+    { 0x0000a318, 0x8c5b7e5a, 0x8c5b7e5a, 0x950f8ccf, 0x950f8ccf, 0x950f8ccf },
+    { 0x0000a31c, 0x9d0f96cf, 0x9d0f96cf, 0xa5cf9b4f, 0xa5cf9b4f, 0xa5cf9b4f },
+    { 0x0000a320, 0xb51fa69f, 0xb51fa69f, 0xbddfaf1f, 0xbddfaf1f, 0xbddfaf1f },
+    { 0x0000a324, 0xcb3fbd07, 0xcb3fbcbf, 0xd1ffc93f, 0xd1ffc93f, 0xd1ffc93f },
+    { 0x0000a328, 0x0000d7bf, 0x0000d7bf, 0x00000000, 0x00000000, 0x00000000 },
+    { 0x0000a32c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+    { 0x0000a330, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+    { 0x0000a334, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+};
+
+#endif /* INITVALS_AR5008_H */
diff --git a/drivers/net/wireless/ath/ath9k/ar9001_initvals.h b/drivers/net/wireless/ath/ath9k/ar9001_initvals.h
new file mode 100644
index 0000000..20abffe
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/ar9001_initvals.h
@@ -0,0 +1,1254 @@
+
+static const u32 ar5416Common_9100[][2] = {
+    { 0x0000000c, 0x00000000 },
+    { 0x00000030, 0x00020015 },
+    { 0x00000034, 0x00000005 },
+    { 0x00000040, 0x00000000 },
+    { 0x00000044, 0x00000008 },
+    { 0x00000048, 0x00000008 },
+    { 0x0000004c, 0x00000010 },
+    { 0x00000050, 0x00000000 },
+    { 0x00000054, 0x0000001f },
+    { 0x00000800, 0x00000000 },
+    { 0x00000804, 0x00000000 },
+    { 0x00000808, 0x00000000 },
+    { 0x0000080c, 0x00000000 },
+    { 0x00000810, 0x00000000 },
+    { 0x00000814, 0x00000000 },
+    { 0x00000818, 0x00000000 },
+    { 0x0000081c, 0x00000000 },
+    { 0x00000820, 0x00000000 },
+    { 0x00000824, 0x00000000 },
+    { 0x00001040, 0x002ffc0f },
+    { 0x00001044, 0x002ffc0f },
+    { 0x00001048, 0x002ffc0f },
+    { 0x0000104c, 0x002ffc0f },
+    { 0x00001050, 0x002ffc0f },
+    { 0x00001054, 0x002ffc0f },
+    { 0x00001058, 0x002ffc0f },
+    { 0x0000105c, 0x002ffc0f },
+    { 0x00001060, 0x002ffc0f },
+    { 0x00001064, 0x002ffc0f },
+    { 0x00001230, 0x00000000 },
+    { 0x00001270, 0x00000000 },
+    { 0x00001038, 0x00000000 },
+    { 0x00001078, 0x00000000 },
+    { 0x000010b8, 0x00000000 },
+    { 0x000010f8, 0x00000000 },
+    { 0x00001138, 0x00000000 },
+    { 0x00001178, 0x00000000 },
+    { 0x000011b8, 0x00000000 },
+    { 0x000011f8, 0x00000000 },
+    { 0x00001238, 0x00000000 },
+    { 0x00001278, 0x00000000 },
+    { 0x000012b8, 0x00000000 },
+    { 0x000012f8, 0x00000000 },
+    { 0x00001338, 0x00000000 },
+    { 0x00001378, 0x00000000 },
+    { 0x000013b8, 0x00000000 },
+    { 0x000013f8, 0x00000000 },
+    { 0x00001438, 0x00000000 },
+    { 0x00001478, 0x00000000 },
+    { 0x000014b8, 0x00000000 },
+    { 0x000014f8, 0x00000000 },
+    { 0x00001538, 0x00000000 },
+    { 0x00001578, 0x00000000 },
+    { 0x000015b8, 0x00000000 },
+    { 0x000015f8, 0x00000000 },
+    { 0x00001638, 0x00000000 },
+    { 0x00001678, 0x00000000 },
+    { 0x000016b8, 0x00000000 },
+    { 0x000016f8, 0x00000000 },
+    { 0x00001738, 0x00000000 },
+    { 0x00001778, 0x00000000 },
+    { 0x000017b8, 0x00000000 },
+    { 0x000017f8, 0x00000000 },
+    { 0x0000103c, 0x00000000 },
+    { 0x0000107c, 0x00000000 },
+    { 0x000010bc, 0x00000000 },
+    { 0x000010fc, 0x00000000 },
+    { 0x0000113c, 0x00000000 },
+    { 0x0000117c, 0x00000000 },
+    { 0x000011bc, 0x00000000 },
+    { 0x000011fc, 0x00000000 },
+    { 0x0000123c, 0x00000000 },
+    { 0x0000127c, 0x00000000 },
+    { 0x000012bc, 0x00000000 },
+    { 0x000012fc, 0x00000000 },
+    { 0x0000133c, 0x00000000 },
+    { 0x0000137c, 0x00000000 },
+    { 0x000013bc, 0x00000000 },
+    { 0x000013fc, 0x00000000 },
+    { 0x0000143c, 0x00000000 },
+    { 0x0000147c, 0x00000000 },
+    { 0x00020010, 0x00000003 },
+    { 0x00020038, 0x000004c2 },
+    { 0x00008004, 0x00000000 },
+    { 0x00008008, 0x00000000 },
+    { 0x0000800c, 0x00000000 },
+    { 0x00008018, 0x00000700 },
+    { 0x00008020, 0x00000000 },
+    { 0x00008038, 0x00000000 },
+    { 0x0000803c, 0x00000000 },
+    { 0x00008048, 0x40000000 },
+    { 0x00008054, 0x00004000 },
+    { 0x00008058, 0x00000000 },
+    { 0x0000805c, 0x000fc78f },
+    { 0x00008060, 0x0000000f },
+    { 0x00008064, 0x00000000 },
+    { 0x000080c0, 0x2a82301a },
+    { 0x000080c4, 0x05dc01e0 },
+    { 0x000080c8, 0x1f402710 },
+    { 0x000080cc, 0x01f40000 },
+    { 0x000080d0, 0x00001e00 },
+    { 0x000080d4, 0x00000000 },
+    { 0x000080d8, 0x00400000 },
+    { 0x000080e0, 0xffffffff },
+    { 0x000080e4, 0x0000ffff },
+    { 0x000080e8, 0x003f3f3f },
+    { 0x000080ec, 0x00000000 },
+    { 0x000080f0, 0x00000000 },
+    { 0x000080f4, 0x00000000 },
+    { 0x000080f8, 0x00000000 },
+    { 0x000080fc, 0x00020000 },
+    { 0x00008100, 0x00020000 },
+    { 0x00008104, 0x00000001 },
+    { 0x00008108, 0x00000052 },
+    { 0x0000810c, 0x00000000 },
+    { 0x00008110, 0x00000168 },
+    { 0x00008118, 0x000100aa },
+    { 0x0000811c, 0x00003210 },
+    { 0x00008120, 0x08f04800 },
+    { 0x00008124, 0x00000000 },
+    { 0x00008128, 0x00000000 },
+    { 0x0000812c, 0x00000000 },
+    { 0x00008130, 0x00000000 },
+    { 0x00008134, 0x00000000 },
+    { 0x00008138, 0x00000000 },
+    { 0x0000813c, 0x00000000 },
+    { 0x00008144, 0x00000000 },
+    { 0x00008168, 0x00000000 },
+    { 0x0000816c, 0x00000000 },
+    { 0x00008170, 0x32143320 },
+    { 0x00008174, 0xfaa4fa50 },
+    { 0x00008178, 0x00000100 },
+    { 0x0000817c, 0x00000000 },
+    { 0x000081c4, 0x00000000 },
+    { 0x000081d0, 0x00003210 },
+    { 0x000081ec, 0x00000000 },
+    { 0x000081f0, 0x00000000 },
+    { 0x000081f4, 0x00000000 },
+    { 0x000081f8, 0x00000000 },
+    { 0x000081fc, 0x00000000 },
+    { 0x00008200, 0x00000000 },
+    { 0x00008204, 0x00000000 },
+    { 0x00008208, 0x00000000 },
+    { 0x0000820c, 0x00000000 },
+    { 0x00008210, 0x00000000 },
+    { 0x00008214, 0x00000000 },
+    { 0x00008218, 0x00000000 },
+    { 0x0000821c, 0x00000000 },
+    { 0x00008220, 0x00000000 },
+    { 0x00008224, 0x00000000 },
+    { 0x00008228, 0x00000000 },
+    { 0x0000822c, 0x00000000 },
+    { 0x00008230, 0x00000000 },
+    { 0x00008234, 0x00000000 },
+    { 0x00008238, 0x00000000 },
+    { 0x0000823c, 0x00000000 },
+    { 0x00008240, 0x00100000 },
+    { 0x00008244, 0x0010f400 },
+    { 0x00008248, 0x00000100 },
+    { 0x0000824c, 0x0001e800 },
+    { 0x00008250, 0x00000000 },
+    { 0x00008254, 0x00000000 },
+    { 0x00008258, 0x00000000 },
+    { 0x0000825c, 0x400000ff },
+    { 0x00008260, 0x00080922 },
+    { 0x00008270, 0x00000000 },
+    { 0x00008274, 0x40000000 },
+    { 0x00008278, 0x003e4180 },
+    { 0x0000827c, 0x00000000 },
+    { 0x00008284, 0x0000002c },
+    { 0x00008288, 0x0000002c },
+    { 0x0000828c, 0x00000000 },
+    { 0x00008294, 0x00000000 },
+    { 0x00008298, 0x00000000 },
+    { 0x00008300, 0x00000000 },
+    { 0x00008304, 0x00000000 },
+    { 0x00008308, 0x00000000 },
+    { 0x0000830c, 0x00000000 },
+    { 0x00008310, 0x00000000 },
+    { 0x00008314, 0x00000000 },
+    { 0x00008318, 0x00000000 },
+    { 0x00008328, 0x00000000 },
+    { 0x0000832c, 0x00000007 },
+    { 0x00008330, 0x00000302 },
+    { 0x00008334, 0x00000e00 },
+    { 0x00008338, 0x00000000 },
+    { 0x0000833c, 0x00000000 },
+    { 0x00008340, 0x000107ff },
+    { 0x00009808, 0x00000000 },
+    { 0x0000980c, 0xad848e19 },
+    { 0x00009810, 0x7d14e000 },
+    { 0x00009814, 0x9c0a9f6b },
+    { 0x0000981c, 0x00000000 },
+    { 0x0000982c, 0x0000a000 },
+    { 0x00009830, 0x00000000 },
+    { 0x0000983c, 0x00200400 },
+    { 0x00009840, 0x206a01ae },
+    { 0x0000984c, 0x1284233c },
+    { 0x00009854, 0x00000859 },
+    { 0x00009900, 0x00000000 },
+    { 0x00009904, 0x00000000 },
+    { 0x00009908, 0x00000000 },
+    { 0x0000990c, 0x00000000 },
+    { 0x0000991c, 0x10000fff },
+    { 0x00009920, 0x05100000 },
+    { 0x0000a920, 0x05100000 },
+    { 0x0000b920, 0x05100000 },
+    { 0x00009928, 0x00000001 },
+    { 0x0000992c, 0x00000004 },
+    { 0x00009934, 0x1e1f2022 },
+    { 0x00009938, 0x0a0b0c0d },
+    { 0x0000993c, 0x00000000 },
+    { 0x00009948, 0x9280b212 },
+    { 0x0000994c, 0x00020028 },
+    { 0x0000c95c, 0x004b6a8e },
+    { 0x0000c968, 0x000003ce },
+    { 0x00009970, 0x190fb515 },
+    { 0x00009974, 0x00000000 },
+    { 0x00009978, 0x00000001 },
+    { 0x0000997c, 0x00000000 },
+    { 0x00009980, 0x00000000 },
+    { 0x00009984, 0x00000000 },
+    { 0x00009988, 0x00000000 },
+    { 0x0000998c, 0x00000000 },
+    { 0x00009990, 0x00000000 },
+    { 0x00009994, 0x00000000 },
+    { 0x00009998, 0x00000000 },
+    { 0x0000999c, 0x00000000 },
+    { 0x000099a0, 0x00000000 },
+    { 0x000099a4, 0x00000001 },
+    { 0x000099a8, 0x201fff00 },
+    { 0x000099ac, 0x006f0000 },
+    { 0x000099b0, 0x03051000 },
+    { 0x000099dc, 0x00000000 },
+    { 0x000099e0, 0x00000200 },
+    { 0x000099e4, 0xaaaaaaaa },
+    { 0x000099e8, 0x3c466478 },
+    { 0x000099ec, 0x0cc80caa },
+    { 0x000099fc, 0x00001042 },
+    { 0x00009b00, 0x00000000 },
+    { 0x00009b04, 0x00000001 },
+    { 0x00009b08, 0x00000002 },
+    { 0x00009b0c, 0x00000003 },
+    { 0x00009b10, 0x00000004 },
+    { 0x00009b14, 0x00000005 },
+    { 0x00009b18, 0x00000008 },
+    { 0x00009b1c, 0x00000009 },
+    { 0x00009b20, 0x0000000a },
+    { 0x00009b24, 0x0000000b },
+    { 0x00009b28, 0x0000000c },
+    { 0x00009b2c, 0x0000000d },
+    { 0x00009b30, 0x00000010 },
+    { 0x00009b34, 0x00000011 },
+    { 0x00009b38, 0x00000012 },
+    { 0x00009b3c, 0x00000013 },
+    { 0x00009b40, 0x00000014 },
+    { 0x00009b44, 0x00000015 },
+    { 0x00009b48, 0x00000018 },
+    { 0x00009b4c, 0x00000019 },
+    { 0x00009b50, 0x0000001a },
+    { 0x00009b54, 0x0000001b },
+    { 0x00009b58, 0x0000001c },
+    { 0x00009b5c, 0x0000001d },
+    { 0x00009b60, 0x00000020 },
+    { 0x00009b64, 0x00000021 },
+    { 0x00009b68, 0x00000022 },
+    { 0x00009b6c, 0x00000023 },
+    { 0x00009b70, 0x00000024 },
+    { 0x00009b74, 0x00000025 },
+    { 0x00009b78, 0x00000028 },
+    { 0x00009b7c, 0x00000029 },
+    { 0x00009b80, 0x0000002a },
+    { 0x00009b84, 0x0000002b },
+    { 0x00009b88, 0x0000002c },
+    { 0x00009b8c, 0x0000002d },
+    { 0x00009b90, 0x00000030 },
+    { 0x00009b94, 0x00000031 },
+    { 0x00009b98, 0x00000032 },
+    { 0x00009b9c, 0x00000033 },
+    { 0x00009ba0, 0x00000034 },
+    { 0x00009ba4, 0x00000035 },
+    { 0x00009ba8, 0x00000035 },
+    { 0x00009bac, 0x00000035 },
+    { 0x00009bb0, 0x00000035 },
+    { 0x00009bb4, 0x00000035 },
+    { 0x00009bb8, 0x00000035 },
+    { 0x00009bbc, 0x00000035 },
+    { 0x00009bc0, 0x00000035 },
+    { 0x00009bc4, 0x00000035 },
+    { 0x00009bc8, 0x00000035 },
+    { 0x00009bcc, 0x00000035 },
+    { 0x00009bd0, 0x00000035 },
+    { 0x00009bd4, 0x00000035 },
+    { 0x00009bd8, 0x00000035 },
+    { 0x00009bdc, 0x00000035 },
+    { 0x00009be0, 0x00000035 },
+    { 0x00009be4, 0x00000035 },
+    { 0x00009be8, 0x00000035 },
+    { 0x00009bec, 0x00000035 },
+    { 0x00009bf0, 0x00000035 },
+    { 0x00009bf4, 0x00000035 },
+    { 0x00009bf8, 0x00000010 },
+    { 0x00009bfc, 0x0000001a },
+    { 0x0000a210, 0x40806333 },
+    { 0x0000a214, 0x00106c10 },
+    { 0x0000a218, 0x009c4060 },
+    { 0x0000a220, 0x018830c6 },
+    { 0x0000a224, 0x00000400 },
+    { 0x0000a228, 0x001a0bb5 },
+    { 0x0000a22c, 0x00000000 },
+    { 0x0000a234, 0x20202020 },
+    { 0x0000a238, 0x20202020 },
+    { 0x0000a23c, 0x13c889ae },
+    { 0x0000a240, 0x38490a20 },
+    { 0x0000a244, 0x00007bb6 },
+    { 0x0000a248, 0x0fff3ffc },
+    { 0x0000a24c, 0x00000001 },
+    { 0x0000a250, 0x0000a000 },
+    { 0x0000a254, 0x00000000 },
+    { 0x0000a258, 0x0cc75380 },
+    { 0x0000a25c, 0x0f0f0f01 },
+    { 0x0000a260, 0xdfa91f01 },
+    { 0x0000a268, 0x00000001 },
+    { 0x0000a26c, 0x0ebae9c6 },
+    { 0x0000b26c, 0x0ebae9c6 },
+    { 0x0000c26c, 0x0ebae9c6 },
+    { 0x0000d270, 0x00820820 },
+    { 0x0000a278, 0x1ce739ce },
+    { 0x0000a27c, 0x050701ce },
+    { 0x0000a338, 0x00000000 },
+    { 0x0000a33c, 0x00000000 },
+    { 0x0000a340, 0x00000000 },
+    { 0x0000a344, 0x00000000 },
+    { 0x0000a348, 0x3fffffff },
+    { 0x0000a34c, 0x3fffffff },
+    { 0x0000a350, 0x3fffffff },
+    { 0x0000a354, 0x0003ffff },
+    { 0x0000a358, 0x79a8aa33 },
+    { 0x0000d35c, 0x07ffffef },
+    { 0x0000d360, 0x0fffffe7 },
+    { 0x0000d364, 0x17ffffe5 },
+    { 0x0000d368, 0x1fffffe4 },
+    { 0x0000d36c, 0x37ffffe3 },
+    { 0x0000d370, 0x3fffffe3 },
+    { 0x0000d374, 0x57ffffe3 },
+    { 0x0000d378, 0x5fffffe2 },
+    { 0x0000d37c, 0x7fffffe2 },
+    { 0x0000d380, 0x7f3c7bba },
+    { 0x0000d384, 0xf3307ff0 },
+    { 0x0000a388, 0x0c000000 },
+    { 0x0000a38c, 0x20202020 },
+    { 0x0000a390, 0x20202020 },
+    { 0x0000a394, 0x1ce739ce },
+    { 0x0000a398, 0x000001ce },
+    { 0x0000a39c, 0x00000001 },
+    { 0x0000a3a0, 0x00000000 },
+    { 0x0000a3a4, 0x00000000 },
+    { 0x0000a3a8, 0x00000000 },
+    { 0x0000a3ac, 0x00000000 },
+    { 0x0000a3b0, 0x00000000 },
+    { 0x0000a3b4, 0x00000000 },
+    { 0x0000a3b8, 0x00000000 },
+    { 0x0000a3bc, 0x00000000 },
+    { 0x0000a3c0, 0x00000000 },
+    { 0x0000a3c4, 0x00000000 },
+    { 0x0000a3c8, 0x00000246 },
+    { 0x0000a3cc, 0x20202020 },
+    { 0x0000a3d0, 0x20202020 },
+    { 0x0000a3d4, 0x20202020 },
+    { 0x0000a3dc, 0x1ce739ce },
+    { 0x0000a3e0, 0x000001ce },
+};
+
+static const u32 ar5416Bank0_9100[][2] = {
+    { 0x000098b0, 0x1e5795e5 },
+    { 0x000098e0, 0x02008020 },
+};
+
+static const u32 ar5416BB_RfGain_9100[][3] = {
+    { 0x00009a00, 0x00000000, 0x00000000 },
+    { 0x00009a04, 0x00000040, 0x00000040 },
+    { 0x00009a08, 0x00000080, 0x00000080 },
+    { 0x00009a0c, 0x000001a1, 0x00000141 },
+    { 0x00009a10, 0x000001e1, 0x00000181 },
+    { 0x00009a14, 0x00000021, 0x000001c1 },
+    { 0x00009a18, 0x00000061, 0x00000001 },
+    { 0x00009a1c, 0x00000168, 0x00000041 },
+    { 0x00009a20, 0x000001a8, 0x000001a8 },
+    { 0x00009a24, 0x000001e8, 0x000001e8 },
+    { 0x00009a28, 0x00000028, 0x00000028 },
+    { 0x00009a2c, 0x00000068, 0x00000068 },
+    { 0x00009a30, 0x00000189, 0x000000a8 },
+    { 0x00009a34, 0x000001c9, 0x00000169 },
+    { 0x00009a38, 0x00000009, 0x000001a9 },
+    { 0x00009a3c, 0x00000049, 0x000001e9 },
+    { 0x00009a40, 0x00000089, 0x00000029 },
+    { 0x00009a44, 0x00000170, 0x00000069 },
+    { 0x00009a48, 0x000001b0, 0x00000190 },
+    { 0x00009a4c, 0x000001f0, 0x000001d0 },
+    { 0x00009a50, 0x00000030, 0x00000010 },
+    { 0x00009a54, 0x00000070, 0x00000050 },
+    { 0x00009a58, 0x00000191, 0x00000090 },
+    { 0x00009a5c, 0x000001d1, 0x00000151 },
+    { 0x00009a60, 0x00000011, 0x00000191 },
+    { 0x00009a64, 0x00000051, 0x000001d1 },
+    { 0x00009a68, 0x00000091, 0x00000011 },
+    { 0x00009a6c, 0x000001b8, 0x00000051 },
+    { 0x00009a70, 0x000001f8, 0x00000198 },
+    { 0x00009a74, 0x00000038, 0x000001d8 },
+    { 0x00009a78, 0x00000078, 0x00000018 },
+    { 0x00009a7c, 0x00000199, 0x00000058 },
+    { 0x00009a80, 0x000001d9, 0x00000098 },
+    { 0x00009a84, 0x00000019, 0x00000159 },
+    { 0x00009a88, 0x00000059, 0x00000199 },
+    { 0x00009a8c, 0x00000099, 0x000001d9 },
+    { 0x00009a90, 0x000000d9, 0x00000019 },
+    { 0x00009a94, 0x000000f9, 0x00000059 },
+    { 0x00009a98, 0x000000f9, 0x00000099 },
+    { 0x00009a9c, 0x000000f9, 0x000000d9 },
+    { 0x00009aa0, 0x000000f9, 0x000000f9 },
+    { 0x00009aa4, 0x000000f9, 0x000000f9 },
+    { 0x00009aa8, 0x000000f9, 0x000000f9 },
+    { 0x00009aac, 0x000000f9, 0x000000f9 },
+    { 0x00009ab0, 0x000000f9, 0x000000f9 },
+    { 0x00009ab4, 0x000000f9, 0x000000f9 },
+    { 0x00009ab8, 0x000000f9, 0x000000f9 },
+    { 0x00009abc, 0x000000f9, 0x000000f9 },
+    { 0x00009ac0, 0x000000f9, 0x000000f9 },
+    { 0x00009ac4, 0x000000f9, 0x000000f9 },
+    { 0x00009ac8, 0x000000f9, 0x000000f9 },
+    { 0x00009acc, 0x000000f9, 0x000000f9 },
+    { 0x00009ad0, 0x000000f9, 0x000000f9 },
+    { 0x00009ad4, 0x000000f9, 0x000000f9 },
+    { 0x00009ad8, 0x000000f9, 0x000000f9 },
+    { 0x00009adc, 0x000000f9, 0x000000f9 },
+    { 0x00009ae0, 0x000000f9, 0x000000f9 },
+    { 0x00009ae4, 0x000000f9, 0x000000f9 },
+    { 0x00009ae8, 0x000000f9, 0x000000f9 },
+    { 0x00009aec, 0x000000f9, 0x000000f9 },
+    { 0x00009af0, 0x000000f9, 0x000000f9 },
+    { 0x00009af4, 0x000000f9, 0x000000f9 },
+    { 0x00009af8, 0x000000f9, 0x000000f9 },
+    { 0x00009afc, 0x000000f9, 0x000000f9 },
+};
+
+static const u32 ar5416Bank1_9100[][2] = {
+    { 0x000098b0, 0x02108421},
+    { 0x000098ec, 0x00000008},
+};
+
+static const u32 ar5416Bank2_9100[][2] = {
+    { 0x000098b0, 0x0e73ff17},
+    { 0x000098e0, 0x00000420},
+};
+
+static const u32 ar5416Bank3_9100[][3] = {
+    { 0x000098f0, 0x01400018, 0x01c00018 },
+};
+
+static const u32 ar5416Bank6_9100[][3] = {
+
+    { 0x0000989c, 0x00000000, 0x00000000 },
+    { 0x0000989c, 0x00000000, 0x00000000 },
+    { 0x0000989c, 0x00000000, 0x00000000 },
+    { 0x0000989c, 0x00e00000, 0x00e00000 },
+    { 0x0000989c, 0x005e0000, 0x005e0000 },
+    { 0x0000989c, 0x00120000, 0x00120000 },
+    { 0x0000989c, 0x00620000, 0x00620000 },
+    { 0x0000989c, 0x00020000, 0x00020000 },
+    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
+    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
+    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
+    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
+    { 0x0000989c, 0x005f0000, 0x005f0000 },
+    { 0x0000989c, 0x00870000, 0x00870000 },
+    { 0x0000989c, 0x00f90000, 0x00f90000 },
+    { 0x0000989c, 0x007b0000, 0x007b0000 },
+    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
+    { 0x0000989c, 0x00f50000, 0x00f50000 },
+    { 0x0000989c, 0x00dc0000, 0x00dc0000 },
+    { 0x0000989c, 0x00110000, 0x00110000 },
+    { 0x0000989c, 0x006100a8, 0x006100a8 },
+    { 0x0000989c, 0x004210a2, 0x004210a2 },
+    { 0x0000989c, 0x0014000f, 0x0014000f },
+    { 0x0000989c, 0x00c40002, 0x00c40002 },
+    { 0x0000989c, 0x003000f2, 0x003000f2 },
+    { 0x0000989c, 0x00440016, 0x00440016 },
+    { 0x0000989c, 0x00410040, 0x00410040 },
+    { 0x0000989c, 0x000180d6, 0x000180d6 },
+    { 0x0000989c, 0x0000c0aa, 0x0000c0aa },
+    { 0x0000989c, 0x000000b1, 0x000000b1 },
+    { 0x0000989c, 0x00002000, 0x00002000 },
+    { 0x0000989c, 0x000000d4, 0x000000d4 },
+    { 0x000098d0, 0x0000000f, 0x0010000f },
+};
+
+
+static const u32 ar5416Bank6TPC_9100[][3] = {
+
+    { 0x0000989c, 0x00000000, 0x00000000 },
+    { 0x0000989c, 0x00000000, 0x00000000 },
+    { 0x0000989c, 0x00000000, 0x00000000 },
+    { 0x0000989c, 0x00e00000, 0x00e00000 },
+    { 0x0000989c, 0x005e0000, 0x005e0000 },
+    { 0x0000989c, 0x00120000, 0x00120000 },
+    { 0x0000989c, 0x00620000, 0x00620000 },
+    { 0x0000989c, 0x00020000, 0x00020000 },
+    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
+    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
+    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
+    { 0x0000989c, 0x40ff0000, 0x40ff0000 },
+    { 0x0000989c, 0x005f0000, 0x005f0000 },
+    { 0x0000989c, 0x00870000, 0x00870000 },
+    { 0x0000989c, 0x00f90000, 0x00f90000 },
+    { 0x0000989c, 0x007b0000, 0x007b0000 },
+    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
+    { 0x0000989c, 0x00f50000, 0x00f50000 },
+    { 0x0000989c, 0x00dc0000, 0x00dc0000 },
+    { 0x0000989c, 0x00110000, 0x00110000 },
+    { 0x0000989c, 0x006100a8, 0x006100a8 },
+    { 0x0000989c, 0x00423022, 0x00423022 },
+    { 0x0000989c, 0x2014008f, 0x2014008f },
+    { 0x0000989c, 0x00c40002, 0x00c40002 },
+    { 0x0000989c, 0x003000f2, 0x003000f2 },
+    { 0x0000989c, 0x00440016, 0x00440016 },
+    { 0x0000989c, 0x00410040, 0x00410040 },
+    { 0x0000989c, 0x0001805e, 0x0001805e },
+    { 0x0000989c, 0x0000c0ab, 0x0000c0ab },
+    { 0x0000989c, 0x000000e1, 0x000000e1 },
+    { 0x0000989c, 0x00007080, 0x00007080 },
+    { 0x0000989c, 0x000000d4, 0x000000d4 },
+    { 0x000098d0, 0x0000000f, 0x0010000f },
+};
+
+static const u32 ar5416Bank7_9100[][2] = {
+    { 0x0000989c, 0x00000500 },
+    { 0x0000989c, 0x00000800 },
+    { 0x000098cc, 0x0000000e },
+};
+
+static const u32 ar5416Addac_9100[][2] = {
+    {0x0000989c, 0x00000000 },
+    {0x0000989c, 0x00000000 },
+    {0x0000989c, 0x00000000 },
+    {0x0000989c, 0x00000000 },
+    {0x0000989c, 0x00000000 },
+    {0x0000989c, 0x00000000 },
+    {0x0000989c, 0x00000000 },
+    {0x0000989c, 0x00000010 },
+    {0x0000989c, 0x00000000 },
+    {0x0000989c, 0x00000000 },
+    {0x0000989c, 0x00000000 },
+    {0x0000989c, 0x00000000 },
+    {0x0000989c, 0x00000000 },
+    {0x0000989c, 0x00000000 },
+    {0x0000989c, 0x00000000 },
+    {0x0000989c, 0x00000000 },
+    {0x0000989c, 0x00000000 },
+    {0x0000989c, 0x00000000 },
+    {0x0000989c, 0x00000000 },
+    {0x0000989c, 0x00000000 },
+    {0x0000989c, 0x00000000 },
+    {0x0000989c, 0x000000c0 },
+    {0x0000989c, 0x00000015 },
+    {0x0000989c, 0x00000000 },
+    {0x0000989c, 0x00000000 },
+    {0x0000989c, 0x00000000 },
+    {0x0000989c, 0x00000000 },
+    {0x0000989c, 0x00000000 },
+    {0x0000989c, 0x00000000 },
+    {0x0000989c, 0x00000000 },
+    {0x0000989c, 0x00000000 },
+    {0x000098cc, 0x00000000 },
+};
+
+static const u32 ar5416Modes_9160[][6] = {
+    { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 },
+    { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 },
+    { 0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180 },
+    { 0x000010f0, 0x0000a000, 0x00014000, 0x00016000, 0x0000b000, 0x00014008 },
+    { 0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00, 0x06e006e0 },
+    { 0x0000801c, 0x128d93a7, 0x128d93cf, 0x12e013d7, 0x12e013ab, 0x098813cf },
+    { 0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303 },
+    { 0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200 },
+    { 0x00009824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
+    { 0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001 },
+    { 0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
+    { 0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007 },
+    { 0x00009844, 0x0372161e, 0x0372161e, 0x037216a0, 0x037216a0, 0x037216a0 },
+    { 0x00009848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
+    { 0x0000a848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
+    { 0x0000b848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
+    { 0x00009850, 0x6c48b4e2, 0x6c48b4e2, 0x6c48b0e2, 0x6c48b0e2, 0x6c48b0e2 },
+    { 0x00009858, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e },
+    { 0x0000985c, 0x31395d5e, 0x31395d5e, 0x31395d5e, 0x31395d5e, 0x31395d5e },
+    { 0x00009860, 0x00048d18, 0x00048d18, 0x00048d20, 0x00048d20, 0x00048d18 },
+    { 0x0000c864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00 },
+    { 0x00009868, 0x409a40d0, 0x409a40d0, 0x409a40d0, 0x409a40d0, 0x409a40d0 },
+    { 0x0000986c, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 },
+    { 0x00009914, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898, 0x000007d0 },
+    { 0x00009918, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b, 0x00000016 },
+    { 0x00009924, 0xd00a8a07, 0xd00a8a07, 0xd00a8a0d, 0xd00a8a0d, 0xd00a8a0d },
+    { 0x00009944, 0xffb81020, 0xffb81020, 0xffb81020, 0xffb81020, 0xffb81020 },
+    { 0x00009960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40 },
+    { 0x0000a960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40 },
+    { 0x0000b960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40 },
+    { 0x00009964, 0x00001120, 0x00001120, 0x00001120, 0x00001120, 0x00001120 },
+    { 0x0000c968, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce, 0x000003ce },
+    { 0x0000c9bc, 0x001a0600, 0x001a0600, 0x001a0c00, 0x001a0c00, 0x001a0c00 },
+    { 0x000099c0, 0x038919be, 0x038919be, 0x038919be, 0x038919be, 0x038919be },
+    { 0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77 },
+    { 0x000099c8, 0x60f65329, 0x60f65329, 0x60f65329, 0x60f65329, 0x60f65329 },
+    { 0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8 },
+    { 0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, 0x00046384 },
+    { 0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+    { 0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+    { 0x0000a204, 0x00000880, 0x00000880, 0x00000880, 0x00000880, 0x00000880 },
+    { 0x0000a208, 0xd6be4788, 0xd6be4788, 0xd03e4788, 0xd03e4788, 0xd03e4788 },
+    { 0x0000a20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120 },
+    { 0x0000b20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120 },
+    { 0x0000c20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120 },
+    { 0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a },
+    { 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000 },
+    { 0x0000a274, 0x0a1a9caa, 0x0a1a9caa, 0x0a1a7caa, 0x0a1a7caa, 0x0a1a7caa },
+    { 0x0000a300, 0x18010000, 0x18010000, 0x18010000, 0x18010000, 0x18010000 },
+    { 0x0000a304, 0x30032602, 0x30032602, 0x2e032402, 0x2e032402, 0x2e032402 },
+    { 0x0000a308, 0x48073e06, 0x48073e06, 0x4a0a3c06, 0x4a0a3c06, 0x4a0a3c06 },
+    { 0x0000a30c, 0x560b4c0a, 0x560b4c0a, 0x621a540b, 0x621a540b, 0x621a540b },
+    { 0x0000a310, 0x641a600f, 0x641a600f, 0x764f6c1b, 0x764f6c1b, 0x764f6c1b },
+    { 0x0000a314, 0x7a4f6e1b, 0x7a4f6e1b, 0x845b7a5a, 0x845b7a5a, 0x845b7a5a },
+    { 0x0000a318, 0x8c5b7e5a, 0x8c5b7e5a, 0x950f8ccf, 0x950f8ccf, 0x950f8ccf },
+    { 0x0000a31c, 0x9d0f96cf, 0x9d0f96cf, 0xa5cf9b4f, 0xa5cf9b4f, 0xa5cf9b4f },
+    { 0x0000a320, 0xb51fa69f, 0xb51fa69f, 0xbddfaf1f, 0xbddfaf1f, 0xbddfaf1f },
+    { 0x0000a324, 0xcb3fbd07, 0xcb3fbcbf, 0xd1ffc93f, 0xd1ffc93f, 0xd1ffc93f },
+    { 0x0000a328, 0x0000d7bf, 0x0000d7bf, 0x00000000, 0x00000000, 0x00000000 },
+    { 0x0000a32c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+    { 0x0000a330, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+    { 0x0000a334, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+};
+
+static const u32 ar5416Common_9160[][2] = {
+    { 0x0000000c, 0x00000000 },
+    { 0x00000030, 0x00020015 },
+    { 0x00000034, 0x00000005 },
+    { 0x00000040, 0x00000000 },
+    { 0x00000044, 0x00000008 },
+    { 0x00000048, 0x00000008 },
+    { 0x0000004c, 0x00000010 },
+    { 0x00000050, 0x00000000 },
+    { 0x00000054, 0x0000001f },
+    { 0x00000800, 0x00000000 },
+    { 0x00000804, 0x00000000 },
+    { 0x00000808, 0x00000000 },
+    { 0x0000080c, 0x00000000 },
+    { 0x00000810, 0x00000000 },
+    { 0x00000814, 0x00000000 },
+    { 0x00000818, 0x00000000 },
+    { 0x0000081c, 0x00000000 },
+    { 0x00000820, 0x00000000 },
+    { 0x00000824, 0x00000000 },
+    { 0x00001040, 0x002ffc0f },
+    { 0x00001044, 0x002ffc0f },
+    { 0x00001048, 0x002ffc0f },
+    { 0x0000104c, 0x002ffc0f },
+    { 0x00001050, 0x002ffc0f },
+    { 0x00001054, 0x002ffc0f },
+    { 0x00001058, 0x002ffc0f },
+    { 0x0000105c, 0x002ffc0f },
+    { 0x00001060, 0x002ffc0f },
+    { 0x00001064, 0x002ffc0f },
+    { 0x00001230, 0x00000000 },
+    { 0x00001270, 0x00000000 },
+    { 0x00001038, 0x00000000 },
+    { 0x00001078, 0x00000000 },
+    { 0x000010b8, 0x00000000 },
+    { 0x000010f8, 0x00000000 },
+    { 0x00001138, 0x00000000 },
+    { 0x00001178, 0x00000000 },
+    { 0x000011b8, 0x00000000 },
+    { 0x000011f8, 0x00000000 },
+    { 0x00001238, 0x00000000 },
+    { 0x00001278, 0x00000000 },
+    { 0x000012b8, 0x00000000 },
+    { 0x000012f8, 0x00000000 },
+    { 0x00001338, 0x00000000 },
+    { 0x00001378, 0x00000000 },
+    { 0x000013b8, 0x00000000 },
+    { 0x000013f8, 0x00000000 },
+    { 0x00001438, 0x00000000 },
+    { 0x00001478, 0x00000000 },
+    { 0x000014b8, 0x00000000 },
+    { 0x000014f8, 0x00000000 },
+    { 0x00001538, 0x00000000 },
+    { 0x00001578, 0x00000000 },
+    { 0x000015b8, 0x00000000 },
+    { 0x000015f8, 0x00000000 },
+    { 0x00001638, 0x00000000 },
+    { 0x00001678, 0x00000000 },
+    { 0x000016b8, 0x00000000 },
+    { 0x000016f8, 0x00000000 },
+    { 0x00001738, 0x00000000 },
+    { 0x00001778, 0x00000000 },
+    { 0x000017b8, 0x00000000 },
+    { 0x000017f8, 0x00000000 },
+    { 0x0000103c, 0x00000000 },
+    { 0x0000107c, 0x00000000 },
+    { 0x000010bc, 0x00000000 },
+    { 0x000010fc, 0x00000000 },
+    { 0x0000113c, 0x00000000 },
+    { 0x0000117c, 0x00000000 },
+    { 0x000011bc, 0x00000000 },
+    { 0x000011fc, 0x00000000 },
+    { 0x0000123c, 0x00000000 },
+    { 0x0000127c, 0x00000000 },
+    { 0x000012bc, 0x00000000 },
+    { 0x000012fc, 0x00000000 },
+    { 0x0000133c, 0x00000000 },
+    { 0x0000137c, 0x00000000 },
+    { 0x000013bc, 0x00000000 },
+    { 0x000013fc, 0x00000000 },
+    { 0x0000143c, 0x00000000 },
+    { 0x0000147c, 0x00000000 },
+    { 0x00004030, 0x00000002 },
+    { 0x0000403c, 0x00000002 },
+    { 0x00007010, 0x00000020 },
+    { 0x00007038, 0x000004c2 },
+    { 0x00008004, 0x00000000 },
+    { 0x00008008, 0x00000000 },
+    { 0x0000800c, 0x00000000 },
+    { 0x00008018, 0x00000700 },
+    { 0x00008020, 0x00000000 },
+    { 0x00008038, 0x00000000 },
+    { 0x0000803c, 0x00000000 },
+    { 0x00008048, 0x40000000 },
+    { 0x00008054, 0x00000000 },
+    { 0x00008058, 0x00000000 },
+    { 0x0000805c, 0x000fc78f },
+    { 0x00008060, 0x0000000f },
+    { 0x00008064, 0x00000000 },
+    { 0x000080c0, 0x2a82301a },
+    { 0x000080c4, 0x05dc01e0 },
+    { 0x000080c8, 0x1f402710 },
+    { 0x000080cc, 0x01f40000 },
+    { 0x000080d0, 0x00001e00 },
+    { 0x000080d4, 0x00000000 },
+    { 0x000080d8, 0x00400000 },
+    { 0x000080e0, 0xffffffff },
+    { 0x000080e4, 0x0000ffff },
+    { 0x000080e8, 0x003f3f3f },
+    { 0x000080ec, 0x00000000 },
+    { 0x000080f0, 0x00000000 },
+    { 0x000080f4, 0x00000000 },
+    { 0x000080f8, 0x00000000 },
+    { 0x000080fc, 0x00020000 },
+    { 0x00008100, 0x00020000 },
+    { 0x00008104, 0x00000001 },
+    { 0x00008108, 0x00000052 },
+    { 0x0000810c, 0x00000000 },
+    { 0x00008110, 0x00000168 },
+    { 0x00008118, 0x000100aa },
+    { 0x0000811c, 0x00003210 },
+    { 0x00008120, 0x08f04800 },
+    { 0x00008124, 0x00000000 },
+    { 0x00008128, 0x00000000 },
+    { 0x0000812c, 0x00000000 },
+    { 0x00008130, 0x00000000 },
+    { 0x00008134, 0x00000000 },
+    { 0x00008138, 0x00000000 },
+    { 0x0000813c, 0x00000000 },
+    { 0x00008144, 0xffffffff },
+    { 0x00008168, 0x00000000 },
+    { 0x0000816c, 0x00000000 },
+    { 0x00008170, 0x32143320 },
+    { 0x00008174, 0xfaa4fa50 },
+    { 0x00008178, 0x00000100 },
+    { 0x0000817c, 0x00000000 },
+    { 0x000081c4, 0x00000000 },
+    { 0x000081d0, 0x00003210 },
+    { 0x000081ec, 0x00000000 },
+    { 0x000081f0, 0x00000000 },
+    { 0x000081f4, 0x00000000 },
+    { 0x000081f8, 0x00000000 },
+    { 0x000081fc, 0x00000000 },
+    { 0x00008200, 0x00000000 },
+    { 0x00008204, 0x00000000 },
+    { 0x00008208, 0x00000000 },
+    { 0x0000820c, 0x00000000 },
+    { 0x00008210, 0x00000000 },
+    { 0x00008214, 0x00000000 },
+    { 0x00008218, 0x00000000 },
+    { 0x0000821c, 0x00000000 },
+    { 0x00008220, 0x00000000 },
+    { 0x00008224, 0x00000000 },
+    { 0x00008228, 0x00000000 },
+    { 0x0000822c, 0x00000000 },
+    { 0x00008230, 0x00000000 },
+    { 0x00008234, 0x00000000 },
+    { 0x00008238, 0x00000000 },
+    { 0x0000823c, 0x00000000 },
+    { 0x00008240, 0x00100000 },
+    { 0x00008244, 0x0010f400 },
+    { 0x00008248, 0x00000100 },
+    { 0x0000824c, 0x0001e800 },
+    { 0x00008250, 0x00000000 },
+    { 0x00008254, 0x00000000 },
+    { 0x00008258, 0x00000000 },
+    { 0x0000825c, 0x400000ff },
+    { 0x00008260, 0x00080922 },
+    { 0x00008270, 0x00000000 },
+    { 0x00008274, 0x40000000 },
+    { 0x00008278, 0x003e4180 },
+    { 0x0000827c, 0x00000000 },
+    { 0x00008284, 0x0000002c },
+    { 0x00008288, 0x0000002c },
+    { 0x0000828c, 0x00000000 },
+    { 0x00008294, 0x00000000 },
+    { 0x00008298, 0x00000000 },
+    { 0x00008300, 0x00000000 },
+    { 0x00008304, 0x00000000 },
+    { 0x00008308, 0x00000000 },
+    { 0x0000830c, 0x00000000 },
+    { 0x00008310, 0x00000000 },
+    { 0x00008314, 0x00000000 },
+    { 0x00008318, 0x00000000 },
+    { 0x00008328, 0x00000000 },
+    { 0x0000832c, 0x00000007 },
+    { 0x00008330, 0x00000302 },
+    { 0x00008334, 0x00000e00 },
+    { 0x00008338, 0x00ff0000 },
+    { 0x0000833c, 0x00000000 },
+    { 0x00008340, 0x000107ff },
+    { 0x00009808, 0x00000000 },
+    { 0x0000980c, 0xad848e19 },
+    { 0x00009810, 0x7d14e000 },
+    { 0x00009814, 0x9c0a9f6b },
+    { 0x0000981c, 0x00000000 },
+    { 0x0000982c, 0x0000a000 },
+    { 0x00009830, 0x00000000 },
+    { 0x0000983c, 0x00200400 },
+    { 0x00009840, 0x206a01ae },
+    { 0x0000984c, 0x1284233c },
+    { 0x00009854, 0x00000859 },
+    { 0x00009900, 0x00000000 },
+    { 0x00009904, 0x00000000 },
+    { 0x00009908, 0x00000000 },
+    { 0x0000990c, 0x00000000 },
+    { 0x0000991c, 0x10000fff },
+    { 0x00009920, 0x05100000 },
+    { 0x0000a920, 0x05100000 },
+    { 0x0000b920, 0x05100000 },
+    { 0x00009928, 0x00000001 },
+    { 0x0000992c, 0x00000004 },
+    { 0x00009934, 0x1e1f2022 },
+    { 0x00009938, 0x0a0b0c0d },
+    { 0x0000993c, 0x00000000 },
+    { 0x00009948, 0x9280b212 },
+    { 0x0000994c, 0x00020028 },
+    { 0x00009954, 0x5f3ca3de },
+    { 0x00009958, 0x2108ecff },
+    { 0x00009940, 0x00750604 },
+    { 0x0000c95c, 0x004b6a8e },
+    { 0x00009970, 0x190fb515 },
+    { 0x00009974, 0x00000000 },
+    { 0x00009978, 0x00000001 },
+    { 0x0000997c, 0x00000000 },
+    { 0x00009980, 0x00000000 },
+    { 0x00009984, 0x00000000 },
+    { 0x00009988, 0x00000000 },
+    { 0x0000998c, 0x00000000 },
+    { 0x00009990, 0x00000000 },
+    { 0x00009994, 0x00000000 },
+    { 0x00009998, 0x00000000 },
+    { 0x0000999c, 0x00000000 },
+    { 0x000099a0, 0x00000000 },
+    { 0x000099a4, 0x00000001 },
+    { 0x000099a8, 0x201fff00 },
+    { 0x000099ac, 0x006f0000 },
+    { 0x000099b0, 0x03051000 },
+    { 0x000099dc, 0x00000000 },
+    { 0x000099e0, 0x00000200 },
+    { 0x000099e4, 0xaaaaaaaa },
+    { 0x000099e8, 0x3c466478 },
+    { 0x000099ec, 0x0cc80caa },
+    { 0x000099fc, 0x00001042 },
+    { 0x00009b00, 0x00000000 },
+    { 0x00009b04, 0x00000001 },
+    { 0x00009b08, 0x00000002 },
+    { 0x00009b0c, 0x00000003 },
+    { 0x00009b10, 0x00000004 },
+    { 0x00009b14, 0x00000005 },
+    { 0x00009b18, 0x00000008 },
+    { 0x00009b1c, 0x00000009 },
+    { 0x00009b20, 0x0000000a },
+    { 0x00009b24, 0x0000000b },
+    { 0x00009b28, 0x0000000c },
+    { 0x00009b2c, 0x0000000d },
+    { 0x00009b30, 0x00000010 },
+    { 0x00009b34, 0x00000011 },
+    { 0x00009b38, 0x00000012 },
+    { 0x00009b3c, 0x00000013 },
+    { 0x00009b40, 0x00000014 },
+    { 0x00009b44, 0x00000015 },
+    { 0x00009b48, 0x00000018 },
+    { 0x00009b4c, 0x00000019 },
+    { 0x00009b50, 0x0000001a },
+    { 0x00009b54, 0x0000001b },
+    { 0x00009b58, 0x0000001c },
+    { 0x00009b5c, 0x0000001d },
+    { 0x00009b60, 0x00000020 },
+    { 0x00009b64, 0x00000021 },
+    { 0x00009b68, 0x00000022 },
+    { 0x00009b6c, 0x00000023 },
+    { 0x00009b70, 0x00000024 },
+    { 0x00009b74, 0x00000025 },
+    { 0x00009b78, 0x00000028 },
+    { 0x00009b7c, 0x00000029 },
+    { 0x00009b80, 0x0000002a },
+    { 0x00009b84, 0x0000002b },
+    { 0x00009b88, 0x0000002c },
+    { 0x00009b8c, 0x0000002d },
+    { 0x00009b90, 0x00000030 },
+    { 0x00009b94, 0x00000031 },
+    { 0x00009b98, 0x00000032 },
+    { 0x00009b9c, 0x00000033 },
+    { 0x00009ba0, 0x00000034 },
+    { 0x00009ba4, 0x00000035 },
+    { 0x00009ba8, 0x00000035 },
+    { 0x00009bac, 0x00000035 },
+    { 0x00009bb0, 0x00000035 },
+    { 0x00009bb4, 0x00000035 },
+    { 0x00009bb8, 0x00000035 },
+    { 0x00009bbc, 0x00000035 },
+    { 0x00009bc0, 0x00000035 },
+    { 0x00009bc4, 0x00000035 },
+    { 0x00009bc8, 0x00000035 },
+    { 0x00009bcc, 0x00000035 },
+    { 0x00009bd0, 0x00000035 },
+    { 0x00009bd4, 0x00000035 },
+    { 0x00009bd8, 0x00000035 },
+    { 0x00009bdc, 0x00000035 },
+    { 0x00009be0, 0x00000035 },
+    { 0x00009be4, 0x00000035 },
+    { 0x00009be8, 0x00000035 },
+    { 0x00009bec, 0x00000035 },
+    { 0x00009bf0, 0x00000035 },
+    { 0x00009bf4, 0x00000035 },
+    { 0x00009bf8, 0x00000010 },
+    { 0x00009bfc, 0x0000001a },
+    { 0x0000a210, 0x40806333 },
+    { 0x0000a214, 0x00106c10 },
+    { 0x0000a218, 0x009c4060 },
+    { 0x0000a220, 0x018830c6 },
+    { 0x0000a224, 0x00000400 },
+    { 0x0000a228, 0x001a0bb5 },
+    { 0x0000a22c, 0x00000000 },
+    { 0x0000a234, 0x20202020 },
+    { 0x0000a238, 0x20202020 },
+    { 0x0000a23c, 0x13c889af },
+    { 0x0000a240, 0x38490a20 },
+    { 0x0000a244, 0x00007bb6 },
+    { 0x0000a248, 0x0fff3ffc },
+    { 0x0000a24c, 0x00000001 },
+    { 0x0000a250, 0x0000e000 },
+    { 0x0000a254, 0x00000000 },
+    { 0x0000a258, 0x0cc75380 },
+    { 0x0000a25c, 0x0f0f0f01 },
+    { 0x0000a260, 0xdfa91f01 },
+    { 0x0000a268, 0x00000001 },
+    { 0x0000a26c, 0x0ebae9c6 },
+    { 0x0000b26c, 0x0ebae9c6 },
+    { 0x0000c26c, 0x0ebae9c6 },
+    { 0x0000d270, 0x00820820 },
+    { 0x0000a278, 0x1ce739ce },
+    { 0x0000a27c, 0x050701ce },
+    { 0x0000a338, 0x00000000 },
+    { 0x0000a33c, 0x00000000 },
+    { 0x0000a340, 0x00000000 },
+    { 0x0000a344, 0x00000000 },
+    { 0x0000a348, 0x3fffffff },
+    { 0x0000a34c, 0x3fffffff },
+    { 0x0000a350, 0x3fffffff },
+    { 0x0000a354, 0x0003ffff },
+    { 0x0000a358, 0x79bfaa03 },
+    { 0x0000d35c, 0x07ffffef },
+    { 0x0000d360, 0x0fffffe7 },
+    { 0x0000d364, 0x17ffffe5 },
+    { 0x0000d368, 0x1fffffe4 },
+    { 0x0000d36c, 0x37ffffe3 },
+    { 0x0000d370, 0x3fffffe3 },
+    { 0x0000d374, 0x57ffffe3 },
+    { 0x0000d378, 0x5fffffe2 },
+    { 0x0000d37c, 0x7fffffe2 },
+    { 0x0000d380, 0x7f3c7bba },
+    { 0x0000d384, 0xf3307ff0 },
+    { 0x0000a388, 0x0c000000 },
+    { 0x0000a38c, 0x20202020 },
+    { 0x0000a390, 0x20202020 },
+    { 0x0000a394, 0x1ce739ce },
+    { 0x0000a398, 0x000001ce },
+    { 0x0000a39c, 0x00000001 },
+    { 0x0000a3a0, 0x00000000 },
+    { 0x0000a3a4, 0x00000000 },
+    { 0x0000a3a8, 0x00000000 },
+    { 0x0000a3ac, 0x00000000 },
+    { 0x0000a3b0, 0x00000000 },
+    { 0x0000a3b4, 0x00000000 },
+    { 0x0000a3b8, 0x00000000 },
+    { 0x0000a3bc, 0x00000000 },
+    { 0x0000a3c0, 0x00000000 },
+    { 0x0000a3c4, 0x00000000 },
+    { 0x0000a3c8, 0x00000246 },
+    { 0x0000a3cc, 0x20202020 },
+    { 0x0000a3d0, 0x20202020 },
+    { 0x0000a3d4, 0x20202020 },
+    { 0x0000a3dc, 0x1ce739ce },
+    { 0x0000a3e0, 0x000001ce },
+};
+
+static const u32 ar5416Bank0_9160[][2] = {
+    { 0x000098b0, 0x1e5795e5 },
+    { 0x000098e0, 0x02008020 },
+};
+
+static const u32 ar5416BB_RfGain_9160[][3] = {
+    { 0x00009a00, 0x00000000, 0x00000000 },
+    { 0x00009a04, 0x00000040, 0x00000040 },
+    { 0x00009a08, 0x00000080, 0x00000080 },
+    { 0x00009a0c, 0x000001a1, 0x00000141 },
+    { 0x00009a10, 0x000001e1, 0x00000181 },
+    { 0x00009a14, 0x00000021, 0x000001c1 },
+    { 0x00009a18, 0x00000061, 0x00000001 },
+    { 0x00009a1c, 0x00000168, 0x00000041 },
+    { 0x00009a20, 0x000001a8, 0x000001a8 },
+    { 0x00009a24, 0x000001e8, 0x000001e8 },
+    { 0x00009a28, 0x00000028, 0x00000028 },
+    { 0x00009a2c, 0x00000068, 0x00000068 },
+    { 0x00009a30, 0x00000189, 0x000000a8 },
+    { 0x00009a34, 0x000001c9, 0x00000169 },
+    { 0x00009a38, 0x00000009, 0x000001a9 },
+    { 0x00009a3c, 0x00000049, 0x000001e9 },
+    { 0x00009a40, 0x00000089, 0x00000029 },
+    { 0x00009a44, 0x00000170, 0x00000069 },
+    { 0x00009a48, 0x000001b0, 0x00000190 },
+    { 0x00009a4c, 0x000001f0, 0x000001d0 },
+    { 0x00009a50, 0x00000030, 0x00000010 },
+    { 0x00009a54, 0x00000070, 0x00000050 },
+    { 0x00009a58, 0x00000191, 0x00000090 },
+    { 0x00009a5c, 0x000001d1, 0x00000151 },
+    { 0x00009a60, 0x00000011, 0x00000191 },
+    { 0x00009a64, 0x00000051, 0x000001d1 },
+    { 0x00009a68, 0x00000091, 0x00000011 },
+    { 0x00009a6c, 0x000001b8, 0x00000051 },
+    { 0x00009a70, 0x000001f8, 0x00000198 },
+    { 0x00009a74, 0x00000038, 0x000001d8 },
+    { 0x00009a78, 0x00000078, 0x00000018 },
+    { 0x00009a7c, 0x00000199, 0x00000058 },
+    { 0x00009a80, 0x000001d9, 0x00000098 },
+    { 0x00009a84, 0x00000019, 0x00000159 },
+    { 0x00009a88, 0x00000059, 0x00000199 },
+    { 0x00009a8c, 0x00000099, 0x000001d9 },
+    { 0x00009a90, 0x000000d9, 0x00000019 },
+    { 0x00009a94, 0x000000f9, 0x00000059 },
+    { 0x00009a98, 0x000000f9, 0x00000099 },
+    { 0x00009a9c, 0x000000f9, 0x000000d9 },
+    { 0x00009aa0, 0x000000f9, 0x000000f9 },
+    { 0x00009aa4, 0x000000f9, 0x000000f9 },
+    { 0x00009aa8, 0x000000f9, 0x000000f9 },
+    { 0x00009aac, 0x000000f9, 0x000000f9 },
+    { 0x00009ab0, 0x000000f9, 0x000000f9 },
+    { 0x00009ab4, 0x000000f9, 0x000000f9 },
+    { 0x00009ab8, 0x000000f9, 0x000000f9 },
+    { 0x00009abc, 0x000000f9, 0x000000f9 },
+    { 0x00009ac0, 0x000000f9, 0x000000f9 },
+    { 0x00009ac4, 0x000000f9, 0x000000f9 },
+    { 0x00009ac8, 0x000000f9, 0x000000f9 },
+    { 0x00009acc, 0x000000f9, 0x000000f9 },
+    { 0x00009ad0, 0x000000f9, 0x000000f9 },
+    { 0x00009ad4, 0x000000f9, 0x000000f9 },
+    { 0x00009ad8, 0x000000f9, 0x000000f9 },
+    { 0x00009adc, 0x000000f9, 0x000000f9 },
+    { 0x00009ae0, 0x000000f9, 0x000000f9 },
+    { 0x00009ae4, 0x000000f9, 0x000000f9 },
+    { 0x00009ae8, 0x000000f9, 0x000000f9 },
+    { 0x00009aec, 0x000000f9, 0x000000f9 },
+    { 0x00009af0, 0x000000f9, 0x000000f9 },
+    { 0x00009af4, 0x000000f9, 0x000000f9 },
+    { 0x00009af8, 0x000000f9, 0x000000f9 },
+    { 0x00009afc, 0x000000f9, 0x000000f9 },
+};
+
+static const u32 ar5416Bank1_9160[][2] = {
+    { 0x000098b0, 0x02108421 },
+    { 0x000098ec, 0x00000008 },
+};
+
+static const u32 ar5416Bank2_9160[][2] = {
+    { 0x000098b0, 0x0e73ff17 },
+    { 0x000098e0, 0x00000420 },
+};
+
+static const u32 ar5416Bank3_9160[][3] = {
+    { 0x000098f0, 0x01400018, 0x01c00018 },
+};
+
+static const u32 ar5416Bank6_9160[][3] = {
+    { 0x0000989c, 0x00000000, 0x00000000 },
+    { 0x0000989c, 0x00000000, 0x00000000 },
+    { 0x0000989c, 0x00000000, 0x00000000 },
+    { 0x0000989c, 0x00e00000, 0x00e00000 },
+    { 0x0000989c, 0x005e0000, 0x005e0000 },
+    { 0x0000989c, 0x00120000, 0x00120000 },
+    { 0x0000989c, 0x00620000, 0x00620000 },
+    { 0x0000989c, 0x00020000, 0x00020000 },
+    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
+    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
+    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
+    { 0x0000989c, 0x40ff0000, 0x40ff0000 },
+    { 0x0000989c, 0x005f0000, 0x005f0000 },
+    { 0x0000989c, 0x00870000, 0x00870000 },
+    { 0x0000989c, 0x00f90000, 0x00f90000 },
+    { 0x0000989c, 0x007b0000, 0x007b0000 },
+    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
+    { 0x0000989c, 0x00f50000, 0x00f50000 },
+    { 0x0000989c, 0x00dc0000, 0x00dc0000 },
+    { 0x0000989c, 0x00110000, 0x00110000 },
+    { 0x0000989c, 0x006100a8, 0x006100a8 },
+    { 0x0000989c, 0x004210a2, 0x004210a2 },
+    { 0x0000989c, 0x0014008f, 0x0014008f },
+    { 0x0000989c, 0x00c40003, 0x00c40003 },
+    { 0x0000989c, 0x003000f2, 0x003000f2 },
+    { 0x0000989c, 0x00440016, 0x00440016 },
+    { 0x0000989c, 0x00410040, 0x00410040 },
+    { 0x0000989c, 0x0001805e, 0x0001805e },
+    { 0x0000989c, 0x0000c0ab, 0x0000c0ab },
+    { 0x0000989c, 0x000000f1, 0x000000f1 },
+    { 0x0000989c, 0x00002081, 0x00002081 },
+    { 0x0000989c, 0x000000d4, 0x000000d4 },
+    { 0x000098d0, 0x0000000f, 0x0010000f },
+};
+
+static const u32 ar5416Bank6TPC_9160[][3] = {
+    { 0x0000989c, 0x00000000, 0x00000000 },
+    { 0x0000989c, 0x00000000, 0x00000000 },
+    { 0x0000989c, 0x00000000, 0x00000000 },
+    { 0x0000989c, 0x00e00000, 0x00e00000 },
+    { 0x0000989c, 0x005e0000, 0x005e0000 },
+    { 0x0000989c, 0x00120000, 0x00120000 },
+    { 0x0000989c, 0x00620000, 0x00620000 },
+    { 0x0000989c, 0x00020000, 0x00020000 },
+    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
+    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
+    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
+    { 0x0000989c, 0x40ff0000, 0x40ff0000 },
+    { 0x0000989c, 0x005f0000, 0x005f0000 },
+    { 0x0000989c, 0x00870000, 0x00870000 },
+    { 0x0000989c, 0x00f90000, 0x00f90000 },
+    { 0x0000989c, 0x007b0000, 0x007b0000 },
+    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
+    { 0x0000989c, 0x00f50000, 0x00f50000 },
+    { 0x0000989c, 0x00dc0000, 0x00dc0000 },
+    { 0x0000989c, 0x00110000, 0x00110000 },
+    { 0x0000989c, 0x006100a8, 0x006100a8 },
+    { 0x0000989c, 0x00423022, 0x00423022 },
+    { 0x0000989c, 0x2014008f, 0x2014008f },
+    { 0x0000989c, 0x00c40002, 0x00c40002 },
+    { 0x0000989c, 0x003000f2, 0x003000f2 },
+    { 0x0000989c, 0x00440016, 0x00440016 },
+    { 0x0000989c, 0x00410040, 0x00410040 },
+    { 0x0000989c, 0x0001805e, 0x0001805e },
+    { 0x0000989c, 0x0000c0ab, 0x0000c0ab },
+    { 0x0000989c, 0x000000e1, 0x000000e1 },
+    { 0x0000989c, 0x00007080, 0x00007080 },
+    { 0x0000989c, 0x000000d4, 0x000000d4 },
+    { 0x000098d0, 0x0000000f, 0x0010000f },
+};
+
+static const u32 ar5416Bank7_9160[][2] = {
+    { 0x0000989c, 0x00000500 },
+    { 0x0000989c, 0x00000800 },
+    { 0x000098cc, 0x0000000e },
+};
+
+static u32 ar5416Addac_9160[][2] = {
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x000000c0 },
+    {0x0000989c,  0x00000018 },
+    {0x0000989c,  0x00000004 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x000000c0 },
+    {0x0000989c,  0x00000019 },
+    {0x0000989c,  0x00000004 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000004 },
+    {0x0000989c,  0x00000003 },
+    {0x0000989c,  0x00000008 },
+    {0x0000989c,  0x00000000 },
+    {0x000098cc,  0x00000000 },
+};
+
+static u32 ar5416Addac_91601_1[][2] = {
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x000000c0 },
+    {0x0000989c,  0x00000018 },
+    {0x0000989c,  0x00000004 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x000000c0 },
+    {0x0000989c,  0x00000019 },
+    {0x0000989c,  0x00000004 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x000098cc,  0x00000000 },
+};
+
diff --git a/drivers/net/wireless/ath/ath9k/initvals.h b/drivers/net/wireless/ath/ath9k/ar9002_initvals.h
similarity index 79%
rename from drivers/net/wireless/ath/ath9k/initvals.h
rename to drivers/net/wireless/ath/ath9k/ar9002_initvals.h
index 455e9d3..0f74ea7 100644
--- a/drivers/net/wireless/ath/ath9k/initvals.h
+++ b/drivers/net/wireless/ath/ath9k/ar9002_initvals.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008-2009 Atheros Communications Inc.
+ * Copyright (c) 2010 Atheros Communications Inc.
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -14,1982 +14,9 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-static const u32 ar5416Modes[][6] = {
-    { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 },
-    { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 },
-    { 0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180 },
-    { 0x000010f0, 0x0000a000, 0x00014000, 0x00016000, 0x0000b000, 0x00014008 },
-    { 0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00, 0x06e006e0 },
-    { 0x0000801c, 0x128d93a7, 0x128d93cf, 0x12e013d7, 0x12e013ab, 0x098813cf },
-    { 0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810, 0x08f04810 },
-    { 0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a, 0x0000320a },
-    { 0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303 },
-    { 0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200 },
-    { 0x00009824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
-    { 0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001 },
-    { 0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
-    { 0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007 },
-    { 0x00009844, 0x1372161e, 0x1372161e, 0x137216a0, 0x137216a0, 0x137216a0 },
-    { 0x00009848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
-    { 0x0000a848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
-    { 0x0000b848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
-    { 0x00009850, 0x6c48b4e0, 0x6d48b4e0, 0x6d48b0de, 0x6c48b0de, 0x6c48b0de },
-    { 0x00009858, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e },
-    { 0x0000985c, 0x31395d5e, 0x3139605e, 0x3139605e, 0x31395d5e, 0x31395d5e },
-    { 0x00009860, 0x00049d18, 0x00049d18, 0x00049d18, 0x00049d18, 0x00049d18 },
-    { 0x00009864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00 },
-    { 0x00009868, 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190 },
-    { 0x0000986c, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 },
-    { 0x00009914, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898, 0x000007d0 },
-    { 0x00009918, 0x000001b8, 0x00000370, 0x00000268, 0x00000134, 0x00000134 },
-    { 0x00009924, 0xd0058a0b, 0xd0058a0b, 0xd0058a0b, 0xd0058a0b, 0xd0058a0b },
-    { 0x00009944, 0xffb81020, 0xffb81020, 0xffb81020, 0xffb81020, 0xffb81020 },
-    { 0x00009960, 0x00000900, 0x00000900, 0x00012d80, 0x00012d80, 0x00012d80 },
-    { 0x0000a960, 0x00000900, 0x00000900, 0x00012d80, 0x00012d80, 0x00012d80 },
-    { 0x0000b960, 0x00000900, 0x00000900, 0x00012d80, 0x00012d80, 0x00012d80 },
-    { 0x00009964, 0x00000000, 0x00000000, 0x00001120, 0x00001120, 0x00001120 },
-    { 0x000099bc, 0x001a0a00, 0x001a0a00, 0x001a0a00, 0x001a0a00, 0x001a0a00 },
-    { 0x000099c0, 0x038919be, 0x038919be, 0x038919be, 0x038919be, 0x038919be },
-    { 0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77 },
-    { 0x000099c8, 0x6af6532c, 0x6af6532c, 0x6af6532c, 0x6af6532c, 0x6af6532c },
-    { 0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8 },
-    { 0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, 0x00046384 },
-    { 0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
-    { 0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
-    { 0x0000a204, 0x00000880, 0x00000880, 0x00000880, 0x00000880, 0x00000880 },
-    { 0x0000a208, 0xd6be4788, 0xd6be4788, 0xd03e4788, 0xd03e4788, 0xd03e4788 },
-    { 0x0000a20c, 0x002ec1e0, 0x002ec1e0, 0x002ac120, 0x002ac120, 0x002ac120 },
-    { 0x0000b20c, 0x002ec1e0, 0x002ec1e0, 0x002ac120, 0x002ac120, 0x002ac120 },
-    { 0x0000c20c, 0x002ec1e0, 0x002ec1e0, 0x002ac120, 0x002ac120, 0x002ac120 },
-    { 0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a },
-    { 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000 },
-    { 0x0000a274, 0x0a1a9caa, 0x0a1a9caa, 0x0a1a7caa, 0x0a1a7caa, 0x0a1a7caa },
-    { 0x0000a300, 0x18010000, 0x18010000, 0x18010000, 0x18010000, 0x18010000 },
-    { 0x0000a304, 0x30032602, 0x30032602, 0x2e032402, 0x2e032402, 0x2e032402 },
-    { 0x0000a308, 0x48073e06, 0x48073e06, 0x4a0a3c06, 0x4a0a3c06, 0x4a0a3c06 },
-    { 0x0000a30c, 0x560b4c0a, 0x560b4c0a, 0x621a540b, 0x621a540b, 0x621a540b },
-    { 0x0000a310, 0x641a600f, 0x641a600f, 0x764f6c1b, 0x764f6c1b, 0x764f6c1b },
-    { 0x0000a314, 0x7a4f6e1b, 0x7a4f6e1b, 0x845b7a5a, 0x845b7a5a, 0x845b7a5a },
-    { 0x0000a318, 0x8c5b7e5a, 0x8c5b7e5a, 0x950f8ccf, 0x950f8ccf, 0x950f8ccf },
-    { 0x0000a31c, 0x9d0f96cf, 0x9d0f96cf, 0xa5cf9b4f, 0xa5cf9b4f, 0xa5cf9b4f },
-    { 0x0000a320, 0xb51fa69f, 0xb51fa69f, 0xbddfaf1f, 0xbddfaf1f, 0xbddfaf1f },
-    { 0x0000a324, 0xcb3fbd07, 0xcb3fbcbf, 0xd1ffc93f, 0xd1ffc93f, 0xd1ffc93f },
-    { 0x0000a328, 0x0000d7bf, 0x0000d7bf, 0x00000000, 0x00000000, 0x00000000 },
-    { 0x0000a32c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
-    { 0x0000a330, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
-    { 0x0000a334, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
-};
-
-static const u32 ar5416Common[][2] = {
-    { 0x0000000c, 0x00000000 },
-    { 0x00000030, 0x00020015 },
-    { 0x00000034, 0x00000005 },
-    { 0x00000040, 0x00000000 },
-    { 0x00000044, 0x00000008 },
-    { 0x00000048, 0x00000008 },
-    { 0x0000004c, 0x00000010 },
-    { 0x00000050, 0x00000000 },
-    { 0x00000054, 0x0000001f },
-    { 0x00000800, 0x00000000 },
-    { 0x00000804, 0x00000000 },
-    { 0x00000808, 0x00000000 },
-    { 0x0000080c, 0x00000000 },
-    { 0x00000810, 0x00000000 },
-    { 0x00000814, 0x00000000 },
-    { 0x00000818, 0x00000000 },
-    { 0x0000081c, 0x00000000 },
-    { 0x00000820, 0x00000000 },
-    { 0x00000824, 0x00000000 },
-    { 0x00001040, 0x002ffc0f },
-    { 0x00001044, 0x002ffc0f },
-    { 0x00001048, 0x002ffc0f },
-    { 0x0000104c, 0x002ffc0f },
-    { 0x00001050, 0x002ffc0f },
-    { 0x00001054, 0x002ffc0f },
-    { 0x00001058, 0x002ffc0f },
-    { 0x0000105c, 0x002ffc0f },
-    { 0x00001060, 0x002ffc0f },
-    { 0x00001064, 0x002ffc0f },
-    { 0x00001230, 0x00000000 },
-    { 0x00001270, 0x00000000 },
-    { 0x00001038, 0x00000000 },
-    { 0x00001078, 0x00000000 },
-    { 0x000010b8, 0x00000000 },
-    { 0x000010f8, 0x00000000 },
-    { 0x00001138, 0x00000000 },
-    { 0x00001178, 0x00000000 },
-    { 0x000011b8, 0x00000000 },
-    { 0x000011f8, 0x00000000 },
-    { 0x00001238, 0x00000000 },
-    { 0x00001278, 0x00000000 },
-    { 0x000012b8, 0x00000000 },
-    { 0x000012f8, 0x00000000 },
-    { 0x00001338, 0x00000000 },
-    { 0x00001378, 0x00000000 },
-    { 0x000013b8, 0x00000000 },
-    { 0x000013f8, 0x00000000 },
-    { 0x00001438, 0x00000000 },
-    { 0x00001478, 0x00000000 },
-    { 0x000014b8, 0x00000000 },
-    { 0x000014f8, 0x00000000 },
-    { 0x00001538, 0x00000000 },
-    { 0x00001578, 0x00000000 },
-    { 0x000015b8, 0x00000000 },
-    { 0x000015f8, 0x00000000 },
-    { 0x00001638, 0x00000000 },
-    { 0x00001678, 0x00000000 },
-    { 0x000016b8, 0x00000000 },
-    { 0x000016f8, 0x00000000 },
-    { 0x00001738, 0x00000000 },
-    { 0x00001778, 0x00000000 },
-    { 0x000017b8, 0x00000000 },
-    { 0x000017f8, 0x00000000 },
-    { 0x0000103c, 0x00000000 },
-    { 0x0000107c, 0x00000000 },
-    { 0x000010bc, 0x00000000 },
-    { 0x000010fc, 0x00000000 },
-    { 0x0000113c, 0x00000000 },
-    { 0x0000117c, 0x00000000 },
-    { 0x000011bc, 0x00000000 },
-    { 0x000011fc, 0x00000000 },
-    { 0x0000123c, 0x00000000 },
-    { 0x0000127c, 0x00000000 },
-    { 0x000012bc, 0x00000000 },
-    { 0x000012fc, 0x00000000 },
-    { 0x0000133c, 0x00000000 },
-    { 0x0000137c, 0x00000000 },
-    { 0x000013bc, 0x00000000 },
-    { 0x000013fc, 0x00000000 },
-    { 0x0000143c, 0x00000000 },
-    { 0x0000147c, 0x00000000 },
-    { 0x00004030, 0x00000002 },
-    { 0x0000403c, 0x00000002 },
-    { 0x00007010, 0x00000000 },
-    { 0x00007038, 0x000004c2 },
-    { 0x00008004, 0x00000000 },
-    { 0x00008008, 0x00000000 },
-    { 0x0000800c, 0x00000000 },
-    { 0x00008018, 0x00000700 },
-    { 0x00008020, 0x00000000 },
-    { 0x00008038, 0x00000000 },
-    { 0x0000803c, 0x00000000 },
-    { 0x00008048, 0x40000000 },
-    { 0x00008054, 0x00000000 },
-    { 0x00008058, 0x00000000 },
-    { 0x0000805c, 0x000fc78f },
-    { 0x00008060, 0x0000000f },
-    { 0x00008064, 0x00000000 },
-    { 0x000080c0, 0x2a82301a },
-    { 0x000080c4, 0x05dc01e0 },
-    { 0x000080c8, 0x1f402710 },
-    { 0x000080cc, 0x01f40000 },
-    { 0x000080d0, 0x00001e00 },
-    { 0x000080d4, 0x00000000 },
-    { 0x000080d8, 0x00400000 },
-    { 0x000080e0, 0xffffffff },
-    { 0x000080e4, 0x0000ffff },
-    { 0x000080e8, 0x003f3f3f },
-    { 0x000080ec, 0x00000000 },
-    { 0x000080f0, 0x00000000 },
-    { 0x000080f4, 0x00000000 },
-    { 0x000080f8, 0x00000000 },
-    { 0x000080fc, 0x00020000 },
-    { 0x00008100, 0x00020000 },
-    { 0x00008104, 0x00000001 },
-    { 0x00008108, 0x00000052 },
-    { 0x0000810c, 0x00000000 },
-    { 0x00008110, 0x00000168 },
-    { 0x00008118, 0x000100aa },
-    { 0x0000811c, 0x00003210 },
-    { 0x00008124, 0x00000000 },
-    { 0x00008128, 0x00000000 },
-    { 0x0000812c, 0x00000000 },
-    { 0x00008130, 0x00000000 },
-    { 0x00008134, 0x00000000 },
-    { 0x00008138, 0x00000000 },
-    { 0x0000813c, 0x00000000 },
-    { 0x00008144, 0xffffffff },
-    { 0x00008168, 0x00000000 },
-    { 0x0000816c, 0x00000000 },
-    { 0x00008170, 0x32143320 },
-    { 0x00008174, 0xfaa4fa50 },
-    { 0x00008178, 0x00000100 },
-    { 0x0000817c, 0x00000000 },
-    { 0x000081c4, 0x00000000 },
-    { 0x000081ec, 0x00000000 },
-    { 0x000081f0, 0x00000000 },
-    { 0x000081f4, 0x00000000 },
-    { 0x000081f8, 0x00000000 },
-    { 0x000081fc, 0x00000000 },
-    { 0x00008200, 0x00000000 },
-    { 0x00008204, 0x00000000 },
-    { 0x00008208, 0x00000000 },
-    { 0x0000820c, 0x00000000 },
-    { 0x00008210, 0x00000000 },
-    { 0x00008214, 0x00000000 },
-    { 0x00008218, 0x00000000 },
-    { 0x0000821c, 0x00000000 },
-    { 0x00008220, 0x00000000 },
-    { 0x00008224, 0x00000000 },
-    { 0x00008228, 0x00000000 },
-    { 0x0000822c, 0x00000000 },
-    { 0x00008230, 0x00000000 },
-    { 0x00008234, 0x00000000 },
-    { 0x00008238, 0x00000000 },
-    { 0x0000823c, 0x00000000 },
-    { 0x00008240, 0x00100000 },
-    { 0x00008244, 0x0010f400 },
-    { 0x00008248, 0x00000100 },
-    { 0x0000824c, 0x0001e800 },
-    { 0x00008250, 0x00000000 },
-    { 0x00008254, 0x00000000 },
-    { 0x00008258, 0x00000000 },
-    { 0x0000825c, 0x400000ff },
-    { 0x00008260, 0x00080922 },
-    { 0x00008264, 0xa8000010 },
-    { 0x00008270, 0x00000000 },
-    { 0x00008274, 0x40000000 },
-    { 0x00008278, 0x003e4180 },
-    { 0x0000827c, 0x00000000 },
-    { 0x00008284, 0x0000002c },
-    { 0x00008288, 0x0000002c },
-    { 0x0000828c, 0x00000000 },
-    { 0x00008294, 0x00000000 },
-    { 0x00008298, 0x00000000 },
-    { 0x00008300, 0x00000000 },
-    { 0x00008304, 0x00000000 },
-    { 0x00008308, 0x00000000 },
-    { 0x0000830c, 0x00000000 },
-    { 0x00008310, 0x00000000 },
-    { 0x00008314, 0x00000000 },
-    { 0x00008318, 0x00000000 },
-    { 0x00008328, 0x00000000 },
-    { 0x0000832c, 0x00000007 },
-    { 0x00008330, 0x00000302 },
-    { 0x00008334, 0x00000e00 },
-    { 0x00008338, 0x00070000 },
-    { 0x0000833c, 0x00000000 },
-    { 0x00008340, 0x000107ff },
-    { 0x00009808, 0x00000000 },
-    { 0x0000980c, 0xad848e19 },
-    { 0x00009810, 0x7d14e000 },
-    { 0x00009814, 0x9c0a9f6b },
-    { 0x0000981c, 0x00000000 },
-    { 0x0000982c, 0x0000a000 },
-    { 0x00009830, 0x00000000 },
-    { 0x0000983c, 0x00200400 },
-    { 0x00009840, 0x206a002e },
-    { 0x0000984c, 0x1284233c },
-    { 0x00009854, 0x00000859 },
-    { 0x00009900, 0x00000000 },
-    { 0x00009904, 0x00000000 },
-    { 0x00009908, 0x00000000 },
-    { 0x0000990c, 0x00000000 },
-    { 0x0000991c, 0x10000fff },
-    { 0x00009920, 0x05100000 },
-    { 0x0000a920, 0x05100000 },
-    { 0x0000b920, 0x05100000 },
-    { 0x00009928, 0x00000001 },
-    { 0x0000992c, 0x00000004 },
-    { 0x00009934, 0x1e1f2022 },
-    { 0x00009938, 0x0a0b0c0d },
-    { 0x0000993c, 0x00000000 },
-    { 0x00009948, 0x9280b212 },
-    { 0x0000994c, 0x00020028 },
-    { 0x00009954, 0x5d50e188 },
-    { 0x00009958, 0x00081fff },
-    { 0x0000c95c, 0x004b6a8e },
-    { 0x0000c968, 0x000003ce },
-    { 0x00009970, 0x190fb515 },
-    { 0x00009974, 0x00000000 },
-    { 0x00009978, 0x00000001 },
-    { 0x0000997c, 0x00000000 },
-    { 0x00009980, 0x00000000 },
-    { 0x00009984, 0x00000000 },
-    { 0x00009988, 0x00000000 },
-    { 0x0000998c, 0x00000000 },
-    { 0x00009990, 0x00000000 },
-    { 0x00009994, 0x00000000 },
-    { 0x00009998, 0x00000000 },
-    { 0x0000999c, 0x00000000 },
-    { 0x000099a0, 0x00000000 },
-    { 0x000099a4, 0x00000001 },
-    { 0x000099a8, 0x001fff00 },
-    { 0x000099ac, 0x00000000 },
-    { 0x000099b0, 0x03051000 },
-    { 0x000099dc, 0x00000000 },
-    { 0x000099e0, 0x00000200 },
-    { 0x000099e4, 0xaaaaaaaa },
-    { 0x000099e8, 0x3c466478 },
-    { 0x000099ec, 0x000000aa },
-    { 0x000099fc, 0x00001042 },
-    { 0x00009b00, 0x00000000 },
-    { 0x00009b04, 0x00000001 },
-    { 0x00009b08, 0x00000002 },
-    { 0x00009b0c, 0x00000003 },
-    { 0x00009b10, 0x00000004 },
-    { 0x00009b14, 0x00000005 },
-    { 0x00009b18, 0x00000008 },
-    { 0x00009b1c, 0x00000009 },
-    { 0x00009b20, 0x0000000a },
-    { 0x00009b24, 0x0000000b },
-    { 0x00009b28, 0x0000000c },
-    { 0x00009b2c, 0x0000000d },
-    { 0x00009b30, 0x00000010 },
-    { 0x00009b34, 0x00000011 },
-    { 0x00009b38, 0x00000012 },
-    { 0x00009b3c, 0x00000013 },
-    { 0x00009b40, 0x00000014 },
-    { 0x00009b44, 0x00000015 },
-    { 0x00009b48, 0x00000018 },
-    { 0x00009b4c, 0x00000019 },
-    { 0x00009b50, 0x0000001a },
-    { 0x00009b54, 0x0000001b },
-    { 0x00009b58, 0x0000001c },
-    { 0x00009b5c, 0x0000001d },
-    { 0x00009b60, 0x00000020 },
-    { 0x00009b64, 0x00000021 },
-    { 0x00009b68, 0x00000022 },
-    { 0x00009b6c, 0x00000023 },
-    { 0x00009b70, 0x00000024 },
-    { 0x00009b74, 0x00000025 },
-    { 0x00009b78, 0x00000028 },
-    { 0x00009b7c, 0x00000029 },
-    { 0x00009b80, 0x0000002a },
-    { 0x00009b84, 0x0000002b },
-    { 0x00009b88, 0x0000002c },
-    { 0x00009b8c, 0x0000002d },
-    { 0x00009b90, 0x00000030 },
-    { 0x00009b94, 0x00000031 },
-    { 0x00009b98, 0x00000032 },
-    { 0x00009b9c, 0x00000033 },
-    { 0x00009ba0, 0x00000034 },
-    { 0x00009ba4, 0x00000035 },
-    { 0x00009ba8, 0x00000035 },
-    { 0x00009bac, 0x00000035 },
-    { 0x00009bb0, 0x00000035 },
-    { 0x00009bb4, 0x00000035 },
-    { 0x00009bb8, 0x00000035 },
-    { 0x00009bbc, 0x00000035 },
-    { 0x00009bc0, 0x00000035 },
-    { 0x00009bc4, 0x00000035 },
-    { 0x00009bc8, 0x00000035 },
-    { 0x00009bcc, 0x00000035 },
-    { 0x00009bd0, 0x00000035 },
-    { 0x00009bd4, 0x00000035 },
-    { 0x00009bd8, 0x00000035 },
-    { 0x00009bdc, 0x00000035 },
-    { 0x00009be0, 0x00000035 },
-    { 0x00009be4, 0x00000035 },
-    { 0x00009be8, 0x00000035 },
-    { 0x00009bec, 0x00000035 },
-    { 0x00009bf0, 0x00000035 },
-    { 0x00009bf4, 0x00000035 },
-    { 0x00009bf8, 0x00000010 },
-    { 0x00009bfc, 0x0000001a },
-    { 0x0000a210, 0x40806333 },
-    { 0x0000a214, 0x00106c10 },
-    { 0x0000a218, 0x009c4060 },
-    { 0x0000a220, 0x018830c6 },
-    { 0x0000a224, 0x00000400 },
-    { 0x0000a228, 0x00000bb5 },
-    { 0x0000a22c, 0x00000011 },
-    { 0x0000a234, 0x20202020 },
-    { 0x0000a238, 0x20202020 },
-    { 0x0000a23c, 0x13c889af },
-    { 0x0000a240, 0x38490a20 },
-    { 0x0000a244, 0x00007bb6 },
-    { 0x0000a248, 0x0fff3ffc },
-    { 0x0000a24c, 0x00000001 },
-    { 0x0000a250, 0x0000a000 },
-    { 0x0000a254, 0x00000000 },
-    { 0x0000a258, 0x0cc75380 },
-    { 0x0000a25c, 0x0f0f0f01 },
-    { 0x0000a260, 0xdfa91f01 },
-    { 0x0000a268, 0x00000000 },
-    { 0x0000a26c, 0x0e79e5c6 },
-    { 0x0000b26c, 0x0e79e5c6 },
-    { 0x0000c26c, 0x0e79e5c6 },
-    { 0x0000d270, 0x00820820 },
-    { 0x0000a278, 0x1ce739ce },
-    { 0x0000a27c, 0x051701ce },
-    { 0x0000a338, 0x00000000 },
-    { 0x0000a33c, 0x00000000 },
-    { 0x0000a340, 0x00000000 },
-    { 0x0000a344, 0x00000000 },
-    { 0x0000a348, 0x3fffffff },
-    { 0x0000a34c, 0x3fffffff },
-    { 0x0000a350, 0x3fffffff },
-    { 0x0000a354, 0x0003ffff },
-    { 0x0000a358, 0x79a8aa1f },
-    { 0x0000d35c, 0x07ffffef },
-    { 0x0000d360, 0x0fffffe7 },
-    { 0x0000d364, 0x17ffffe5 },
-    { 0x0000d368, 0x1fffffe4 },
-    { 0x0000d36c, 0x37ffffe3 },
-    { 0x0000d370, 0x3fffffe3 },
-    { 0x0000d374, 0x57ffffe3 },
-    { 0x0000d378, 0x5fffffe2 },
-    { 0x0000d37c, 0x7fffffe2 },
-    { 0x0000d380, 0x7f3c7bba },
-    { 0x0000d384, 0xf3307ff0 },
-    { 0x0000a388, 0x08000000 },
-    { 0x0000a38c, 0x20202020 },
-    { 0x0000a390, 0x20202020 },
-    { 0x0000a394, 0x1ce739ce },
-    { 0x0000a398, 0x000001ce },
-    { 0x0000a39c, 0x00000001 },
-    { 0x0000a3a0, 0x00000000 },
-    { 0x0000a3a4, 0x00000000 },
-    { 0x0000a3a8, 0x00000000 },
-    { 0x0000a3ac, 0x00000000 },
-    { 0x0000a3b0, 0x00000000 },
-    { 0x0000a3b4, 0x00000000 },
-    { 0x0000a3b8, 0x00000000 },
-    { 0x0000a3bc, 0x00000000 },
-    { 0x0000a3c0, 0x00000000 },
-    { 0x0000a3c4, 0x00000000 },
-    { 0x0000a3c8, 0x00000246 },
-    { 0x0000a3cc, 0x20202020 },
-    { 0x0000a3d0, 0x20202020 },
-    { 0x0000a3d4, 0x20202020 },
-    { 0x0000a3dc, 0x1ce739ce },
-    { 0x0000a3e0, 0x000001ce },
-};
-
-static const u32 ar5416Bank0[][2] = {
-    { 0x000098b0, 0x1e5795e5 },
-    { 0x000098e0, 0x02008020 },
-};
-
-static const u32 ar5416BB_RfGain[][3] = {
-    { 0x00009a00, 0x00000000, 0x00000000 },
-    { 0x00009a04, 0x00000040, 0x00000040 },
-    { 0x00009a08, 0x00000080, 0x00000080 },
-    { 0x00009a0c, 0x000001a1, 0x00000141 },
-    { 0x00009a10, 0x000001e1, 0x00000181 },
-    { 0x00009a14, 0x00000021, 0x000001c1 },
-    { 0x00009a18, 0x00000061, 0x00000001 },
-    { 0x00009a1c, 0x00000168, 0x00000041 },
-    { 0x00009a20, 0x000001a8, 0x000001a8 },
-    { 0x00009a24, 0x000001e8, 0x000001e8 },
-    { 0x00009a28, 0x00000028, 0x00000028 },
-    { 0x00009a2c, 0x00000068, 0x00000068 },
-    { 0x00009a30, 0x00000189, 0x000000a8 },
-    { 0x00009a34, 0x000001c9, 0x00000169 },
-    { 0x00009a38, 0x00000009, 0x000001a9 },
-    { 0x00009a3c, 0x00000049, 0x000001e9 },
-    { 0x00009a40, 0x00000089, 0x00000029 },
-    { 0x00009a44, 0x00000170, 0x00000069 },
-    { 0x00009a48, 0x000001b0, 0x00000190 },
-    { 0x00009a4c, 0x000001f0, 0x000001d0 },
-    { 0x00009a50, 0x00000030, 0x00000010 },
-    { 0x00009a54, 0x00000070, 0x00000050 },
-    { 0x00009a58, 0x00000191, 0x00000090 },
-    { 0x00009a5c, 0x000001d1, 0x00000151 },
-    { 0x00009a60, 0x00000011, 0x00000191 },
-    { 0x00009a64, 0x00000051, 0x000001d1 },
-    { 0x00009a68, 0x00000091, 0x00000011 },
-    { 0x00009a6c, 0x000001b8, 0x00000051 },
-    { 0x00009a70, 0x000001f8, 0x00000198 },
-    { 0x00009a74, 0x00000038, 0x000001d8 },
-    { 0x00009a78, 0x00000078, 0x00000018 },
-    { 0x00009a7c, 0x00000199, 0x00000058 },
-    { 0x00009a80, 0x000001d9, 0x00000098 },
-    { 0x00009a84, 0x00000019, 0x00000159 },
-    { 0x00009a88, 0x00000059, 0x00000199 },
-    { 0x00009a8c, 0x00000099, 0x000001d9 },
-    { 0x00009a90, 0x000000d9, 0x00000019 },
-    { 0x00009a94, 0x000000f9, 0x00000059 },
-    { 0x00009a98, 0x000000f9, 0x00000099 },
-    { 0x00009a9c, 0x000000f9, 0x000000d9 },
-    { 0x00009aa0, 0x000000f9, 0x000000f9 },
-    { 0x00009aa4, 0x000000f9, 0x000000f9 },
-    { 0x00009aa8, 0x000000f9, 0x000000f9 },
-    { 0x00009aac, 0x000000f9, 0x000000f9 },
-    { 0x00009ab0, 0x000000f9, 0x000000f9 },
-    { 0x00009ab4, 0x000000f9, 0x000000f9 },
-    { 0x00009ab8, 0x000000f9, 0x000000f9 },
-    { 0x00009abc, 0x000000f9, 0x000000f9 },
-    { 0x00009ac0, 0x000000f9, 0x000000f9 },
-    { 0x00009ac4, 0x000000f9, 0x000000f9 },
-    { 0x00009ac8, 0x000000f9, 0x000000f9 },
-    { 0x00009acc, 0x000000f9, 0x000000f9 },
-    { 0x00009ad0, 0x000000f9, 0x000000f9 },
-    { 0x00009ad4, 0x000000f9, 0x000000f9 },
-    { 0x00009ad8, 0x000000f9, 0x000000f9 },
-    { 0x00009adc, 0x000000f9, 0x000000f9 },
-    { 0x00009ae0, 0x000000f9, 0x000000f9 },
-    { 0x00009ae4, 0x000000f9, 0x000000f9 },
-    { 0x00009ae8, 0x000000f9, 0x000000f9 },
-    { 0x00009aec, 0x000000f9, 0x000000f9 },
-    { 0x00009af0, 0x000000f9, 0x000000f9 },
-    { 0x00009af4, 0x000000f9, 0x000000f9 },
-    { 0x00009af8, 0x000000f9, 0x000000f9 },
-    { 0x00009afc, 0x000000f9, 0x000000f9 },
-};
-
-static const u32 ar5416Bank1[][2] = {
-    { 0x000098b0, 0x02108421 },
-    { 0x000098ec, 0x00000008 },
-};
-
-static const u32 ar5416Bank2[][2] = {
-    { 0x000098b0, 0x0e73ff17 },
-    { 0x000098e0, 0x00000420 },
-};
-
-static const u32 ar5416Bank3[][3] = {
-    { 0x000098f0, 0x01400018, 0x01c00018 },
-};
-
-static const u32 ar5416Bank6[][3] = {
-
-    { 0x0000989c, 0x00000000, 0x00000000 },
-    { 0x0000989c, 0x00000000, 0x00000000 },
-    { 0x0000989c, 0x00000000, 0x00000000 },
-    { 0x0000989c, 0x00e00000, 0x00e00000 },
-    { 0x0000989c, 0x005e0000, 0x005e0000 },
-    { 0x0000989c, 0x00120000, 0x00120000 },
-    { 0x0000989c, 0x00620000, 0x00620000 },
-    { 0x0000989c, 0x00020000, 0x00020000 },
-    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
-    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
-    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
-    { 0x0000989c, 0x40ff0000, 0x40ff0000 },
-    { 0x0000989c, 0x005f0000, 0x005f0000 },
-    { 0x0000989c, 0x00870000, 0x00870000 },
-    { 0x0000989c, 0x00f90000, 0x00f90000 },
-    { 0x0000989c, 0x007b0000, 0x007b0000 },
-    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
-    { 0x0000989c, 0x00f50000, 0x00f50000 },
-    { 0x0000989c, 0x00dc0000, 0x00dc0000 },
-    { 0x0000989c, 0x00110000, 0x00110000 },
-    { 0x0000989c, 0x006100a8, 0x006100a8 },
-    { 0x0000989c, 0x004210a2, 0x004210a2 },
-    { 0x0000989c, 0x0014008f, 0x0014008f },
-    { 0x0000989c, 0x00c40003, 0x00c40003 },
-    { 0x0000989c, 0x003000f2, 0x003000f2 },
-    { 0x0000989c, 0x00440016, 0x00440016 },
-    { 0x0000989c, 0x00410040, 0x00410040 },
-    { 0x0000989c, 0x0001805e, 0x0001805e },
-    { 0x0000989c, 0x0000c0ab, 0x0000c0ab },
-    { 0x0000989c, 0x000000f1, 0x000000f1 },
-    { 0x0000989c, 0x00002081, 0x00002081 },
-    { 0x0000989c, 0x000000d4, 0x000000d4 },
-    { 0x000098d0, 0x0000000f, 0x0010000f },
-};
-
-static const u32 ar5416Bank6TPC[][3] = {
-    { 0x0000989c, 0x00000000, 0x00000000 },
-    { 0x0000989c, 0x00000000, 0x00000000 },
-    { 0x0000989c, 0x00000000, 0x00000000 },
-    { 0x0000989c, 0x00e00000, 0x00e00000 },
-    { 0x0000989c, 0x005e0000, 0x005e0000 },
-    { 0x0000989c, 0x00120000, 0x00120000 },
-    { 0x0000989c, 0x00620000, 0x00620000 },
-    { 0x0000989c, 0x00020000, 0x00020000 },
-    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
-    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
-    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
-    { 0x0000989c, 0x40ff0000, 0x40ff0000 },
-    { 0x0000989c, 0x005f0000, 0x005f0000 },
-    { 0x0000989c, 0x00870000, 0x00870000 },
-    { 0x0000989c, 0x00f90000, 0x00f90000 },
-    { 0x0000989c, 0x007b0000, 0x007b0000 },
-    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
-    { 0x0000989c, 0x00f50000, 0x00f50000 },
-    { 0x0000989c, 0x00dc0000, 0x00dc0000 },
-    { 0x0000989c, 0x00110000, 0x00110000 },
-    { 0x0000989c, 0x006100a8, 0x006100a8 },
-    { 0x0000989c, 0x00423022, 0x00423022 },
-    { 0x0000989c, 0x201400df, 0x201400df },
-    { 0x0000989c, 0x00c40002, 0x00c40002 },
-    { 0x0000989c, 0x003000f2, 0x003000f2 },
-    { 0x0000989c, 0x00440016, 0x00440016 },
-    { 0x0000989c, 0x00410040, 0x00410040 },
-    { 0x0000989c, 0x0001805e, 0x0001805e },
-    { 0x0000989c, 0x0000c0ab, 0x0000c0ab },
-    { 0x0000989c, 0x000000e1, 0x000000e1 },
-    { 0x0000989c, 0x00007081, 0x00007081 },
-    { 0x0000989c, 0x000000d4, 0x000000d4 },
-    { 0x000098d0, 0x0000000f, 0x0010000f },
-};
-
-static const u32 ar5416Bank7[][2] = {
-    { 0x0000989c, 0x00000500 },
-    { 0x0000989c, 0x00000800 },
-    { 0x000098cc, 0x0000000e },
-};
-
-static const u32 ar5416Addac[][2] = {
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000003 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x0000000c },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000030 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000060 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000058 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x000098cc,  0x00000000 },
-};
-
-static const u32 ar5416Modes_9100[][6] = {
-    { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 },
-    { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 },
-    { 0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180 },
-    { 0x000010f0, 0x0000a000, 0x00014000, 0x00016000, 0x0000b000, 0x00014008 },
-    { 0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00, 0x06e006e0 },
-    { 0x0000801c, 0x128d93a7, 0x128d93cf, 0x12e013d7, 0x12e013ab, 0x098813cf },
-    { 0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303 },
-    { 0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200 },
-    { 0x00009824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
-    { 0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001 },
-    { 0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
-    { 0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007 },
-    { 0x00009844, 0x0372161e, 0x0372161e, 0x037216a0, 0x037216a0, 0x037216a0 },
-    { 0x00009848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
-    { 0x0000a848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
-    { 0x0000b848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
-    { 0x00009850, 0x6d48b4e2, 0x6d48b4e2, 0x6d48b0e2, 0x6d48b0e2, 0x6d48b0e2 },
-    { 0x00009858, 0x7ec82d2e, 0x7ec82d2e, 0x7ec86d2e, 0x7ec84d2e, 0x7ec82d2e },
-    { 0x0000985c, 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e },
-    { 0x00009860, 0x00048d18, 0x00048d18, 0x00048d20, 0x00048d20, 0x00048d18 },
-    { 0x0000c864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00 },
-    { 0x00009868, 0x409a40d0, 0x409a40d0, 0x409a40d0, 0x409a40d0, 0x409a40d0 },
-    { 0x0000986c, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 },
-    { 0x00009914, 0x000007d0, 0x000007d0, 0x00000898, 0x00000898, 0x000007d0 },
-    { 0x00009918, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b, 0x00000016 },
-    { 0x00009924, 0xd00a8a07, 0xd00a8a07, 0xd00a8a11, 0xd00a8a0d, 0xd00a8a0d },
-    { 0x00009940, 0x00754604, 0x00754604, 0xfff81204, 0xfff81204, 0xfff81204 },
-    { 0x00009944, 0xdfb81020, 0xdfb81020, 0xdfb81020, 0xdfb81020, 0xdfb81020 },
-    { 0x00009954, 0x5f3ca3de, 0x5f3ca3de, 0xe250a51e, 0xe250a51e, 0xe250a51e },
-    { 0x00009958, 0x2108ecff, 0x2108ecff, 0x3388ffff, 0x3388ffff, 0x3388ffff },
-#ifdef TB243
-    { 0x00009960, 0x00000900, 0x00000900, 0x00009b40, 0x00009b40, 0x00012d80 },
-    { 0x0000a960, 0x00000900, 0x00000900, 0x00009b40, 0x00009b40, 0x00012d80 },
-    { 0x0000b960, 0x00000900, 0x00000900, 0x00009b40, 0x00009b40, 0x00012d80 },
-    { 0x00009964, 0x00000000, 0x00000000, 0x00002210, 0x00002210, 0x00001120 },
-#else
-    { 0x00009960, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0 },
-    { 0x0000a960, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0 },
-    { 0x0000b960, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0 },
-    { 0x00009964, 0x00001120, 0x00001120, 0x00001120, 0x00001120, 0x00001120 },
-#endif
-    { 0x0000c9bc, 0x001a0600, 0x001a0600, 0x001a1000, 0x001a0c00, 0x001a0c00 },
-    { 0x000099c0, 0x038919be, 0x038919be, 0x038919be, 0x038919be, 0x038919be },
-    { 0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77 },
-    { 0x000099c8, 0x60f65329, 0x60f65329, 0x60f65329, 0x60f65329, 0x60f65329 },
-    { 0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8 },
-    { 0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, 0x00046384 },
-    { 0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
-    { 0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
-    { 0x0000a204, 0x00000880, 0x00000880, 0x00000880, 0x00000880, 0x00000880 },
-    { 0x0000a208, 0xd6be4788, 0xd6be4788, 0xd03e4788, 0xd03e4788, 0xd03e4788 },
-    { 0x0000a20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120 },
-    { 0x0000b20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120 },
-    { 0x0000c20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120 },
-    { 0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a },
-    { 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000 },
-    { 0x0000a274, 0x0a1a9caa, 0x0a1a9caa, 0x0a1a7caa, 0x0a1a7caa, 0x0a1a7caa },
-    { 0x0000a300, 0x18010000, 0x18010000, 0x18010000, 0x18010000, 0x18010000 },
-    { 0x0000a304, 0x30032602, 0x30032602, 0x2e032402, 0x2e032402, 0x2e032402 },
-    { 0x0000a308, 0x48073e06, 0x48073e06, 0x4a0a3c06, 0x4a0a3c06, 0x4a0a3c06 },
-    { 0x0000a30c, 0x560b4c0a, 0x560b4c0a, 0x621a540b, 0x621a540b, 0x621a540b },
-    { 0x0000a310, 0x641a600f, 0x641a600f, 0x764f6c1b, 0x764f6c1b, 0x764f6c1b },
-    { 0x0000a314, 0x7a4f6e1b, 0x7a4f6e1b, 0x845b7a5a, 0x845b7a5a, 0x845b7a5a },
-    { 0x0000a318, 0x8c5b7e5a, 0x8c5b7e5a, 0x950f8ccf, 0x950f8ccf, 0x950f8ccf },
-    { 0x0000a31c, 0x9d0f96cf, 0x9d0f96cf, 0xa5cf9b4f, 0xa5cf9b4f, 0xa5cf9b4f },
-    { 0x0000a320, 0xb51fa69f, 0xb51fa69f, 0xbddfaf1f, 0xbddfaf1f, 0xbddfaf1f },
-    { 0x0000a324, 0xcb3fbd07, 0xcb3fbcbf, 0xd1ffc93f, 0xd1ffc93f, 0xd1ffc93f },
-    { 0x0000a328, 0x0000d7bf, 0x0000d7bf, 0x00000000, 0x00000000, 0x00000000 },
-    { 0x0000a32c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
-    { 0x0000a330, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
-    { 0x0000a334, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
-};
-
-static const u32 ar5416Common_9100[][2] = {
-    { 0x0000000c, 0x00000000 },
-    { 0x00000030, 0x00020015 },
-    { 0x00000034, 0x00000005 },
-    { 0x00000040, 0x00000000 },
-    { 0x00000044, 0x00000008 },
-    { 0x00000048, 0x00000008 },
-    { 0x0000004c, 0x00000010 },
-    { 0x00000050, 0x00000000 },
-    { 0x00000054, 0x0000001f },
-    { 0x00000800, 0x00000000 },
-    { 0x00000804, 0x00000000 },
-    { 0x00000808, 0x00000000 },
-    { 0x0000080c, 0x00000000 },
-    { 0x00000810, 0x00000000 },
-    { 0x00000814, 0x00000000 },
-    { 0x00000818, 0x00000000 },
-    { 0x0000081c, 0x00000000 },
-    { 0x00000820, 0x00000000 },
-    { 0x00000824, 0x00000000 },
-    { 0x00001040, 0x002ffc0f },
-    { 0x00001044, 0x002ffc0f },
-    { 0x00001048, 0x002ffc0f },
-    { 0x0000104c, 0x002ffc0f },
-    { 0x00001050, 0x002ffc0f },
-    { 0x00001054, 0x002ffc0f },
-    { 0x00001058, 0x002ffc0f },
-    { 0x0000105c, 0x002ffc0f },
-    { 0x00001060, 0x002ffc0f },
-    { 0x00001064, 0x002ffc0f },
-    { 0x00001230, 0x00000000 },
-    { 0x00001270, 0x00000000 },
-    { 0x00001038, 0x00000000 },
-    { 0x00001078, 0x00000000 },
-    { 0x000010b8, 0x00000000 },
-    { 0x000010f8, 0x00000000 },
-    { 0x00001138, 0x00000000 },
-    { 0x00001178, 0x00000000 },
-    { 0x000011b8, 0x00000000 },
-    { 0x000011f8, 0x00000000 },
-    { 0x00001238, 0x00000000 },
-    { 0x00001278, 0x00000000 },
-    { 0x000012b8, 0x00000000 },
-    { 0x000012f8, 0x00000000 },
-    { 0x00001338, 0x00000000 },
-    { 0x00001378, 0x00000000 },
-    { 0x000013b8, 0x00000000 },
-    { 0x000013f8, 0x00000000 },
-    { 0x00001438, 0x00000000 },
-    { 0x00001478, 0x00000000 },
-    { 0x000014b8, 0x00000000 },
-    { 0x000014f8, 0x00000000 },
-    { 0x00001538, 0x00000000 },
-    { 0x00001578, 0x00000000 },
-    { 0x000015b8, 0x00000000 },
-    { 0x000015f8, 0x00000000 },
-    { 0x00001638, 0x00000000 },
-    { 0x00001678, 0x00000000 },
-    { 0x000016b8, 0x00000000 },
-    { 0x000016f8, 0x00000000 },
-    { 0x00001738, 0x00000000 },
-    { 0x00001778, 0x00000000 },
-    { 0x000017b8, 0x00000000 },
-    { 0x000017f8, 0x00000000 },
-    { 0x0000103c, 0x00000000 },
-    { 0x0000107c, 0x00000000 },
-    { 0x000010bc, 0x00000000 },
-    { 0x000010fc, 0x00000000 },
-    { 0x0000113c, 0x00000000 },
-    { 0x0000117c, 0x00000000 },
-    { 0x000011bc, 0x00000000 },
-    { 0x000011fc, 0x00000000 },
-    { 0x0000123c, 0x00000000 },
-    { 0x0000127c, 0x00000000 },
-    { 0x000012bc, 0x00000000 },
-    { 0x000012fc, 0x00000000 },
-    { 0x0000133c, 0x00000000 },
-    { 0x0000137c, 0x00000000 },
-    { 0x000013bc, 0x00000000 },
-    { 0x000013fc, 0x00000000 },
-    { 0x0000143c, 0x00000000 },
-    { 0x0000147c, 0x00000000 },
-    { 0x00020010, 0x00000003 },
-    { 0x00020038, 0x000004c2 },
-    { 0x00008004, 0x00000000 },
-    { 0x00008008, 0x00000000 },
-    { 0x0000800c, 0x00000000 },
-    { 0x00008018, 0x00000700 },
-    { 0x00008020, 0x00000000 },
-    { 0x00008038, 0x00000000 },
-    { 0x0000803c, 0x00000000 },
-    { 0x00008048, 0x40000000 },
-    { 0x00008054, 0x00004000 },
-    { 0x00008058, 0x00000000 },
-    { 0x0000805c, 0x000fc78f },
-    { 0x00008060, 0x0000000f },
-    { 0x00008064, 0x00000000 },
-    { 0x000080c0, 0x2a82301a },
-    { 0x000080c4, 0x05dc01e0 },
-    { 0x000080c8, 0x1f402710 },
-    { 0x000080cc, 0x01f40000 },
-    { 0x000080d0, 0x00001e00 },
-    { 0x000080d4, 0x00000000 },
-    { 0x000080d8, 0x00400000 },
-    { 0x000080e0, 0xffffffff },
-    { 0x000080e4, 0x0000ffff },
-    { 0x000080e8, 0x003f3f3f },
-    { 0x000080ec, 0x00000000 },
-    { 0x000080f0, 0x00000000 },
-    { 0x000080f4, 0x00000000 },
-    { 0x000080f8, 0x00000000 },
-    { 0x000080fc, 0x00020000 },
-    { 0x00008100, 0x00020000 },
-    { 0x00008104, 0x00000001 },
-    { 0x00008108, 0x00000052 },
-    { 0x0000810c, 0x00000000 },
-    { 0x00008110, 0x00000168 },
-    { 0x00008118, 0x000100aa },
-    { 0x0000811c, 0x00003210 },
-    { 0x00008120, 0x08f04800 },
-    { 0x00008124, 0x00000000 },
-    { 0x00008128, 0x00000000 },
-    { 0x0000812c, 0x00000000 },
-    { 0x00008130, 0x00000000 },
-    { 0x00008134, 0x00000000 },
-    { 0x00008138, 0x00000000 },
-    { 0x0000813c, 0x00000000 },
-    { 0x00008144, 0x00000000 },
-    { 0x00008168, 0x00000000 },
-    { 0x0000816c, 0x00000000 },
-    { 0x00008170, 0x32143320 },
-    { 0x00008174, 0xfaa4fa50 },
-    { 0x00008178, 0x00000100 },
-    { 0x0000817c, 0x00000000 },
-    { 0x000081c4, 0x00000000 },
-    { 0x000081d0, 0x00003210 },
-    { 0x000081ec, 0x00000000 },
-    { 0x000081f0, 0x00000000 },
-    { 0x000081f4, 0x00000000 },
-    { 0x000081f8, 0x00000000 },
-    { 0x000081fc, 0x00000000 },
-    { 0x00008200, 0x00000000 },
-    { 0x00008204, 0x00000000 },
-    { 0x00008208, 0x00000000 },
-    { 0x0000820c, 0x00000000 },
-    { 0x00008210, 0x00000000 },
-    { 0x00008214, 0x00000000 },
-    { 0x00008218, 0x00000000 },
-    { 0x0000821c, 0x00000000 },
-    { 0x00008220, 0x00000000 },
-    { 0x00008224, 0x00000000 },
-    { 0x00008228, 0x00000000 },
-    { 0x0000822c, 0x00000000 },
-    { 0x00008230, 0x00000000 },
-    { 0x00008234, 0x00000000 },
-    { 0x00008238, 0x00000000 },
-    { 0x0000823c, 0x00000000 },
-    { 0x00008240, 0x00100000 },
-    { 0x00008244, 0x0010f400 },
-    { 0x00008248, 0x00000100 },
-    { 0x0000824c, 0x0001e800 },
-    { 0x00008250, 0x00000000 },
-    { 0x00008254, 0x00000000 },
-    { 0x00008258, 0x00000000 },
-    { 0x0000825c, 0x400000ff },
-    { 0x00008260, 0x00080922 },
-    { 0x00008270, 0x00000000 },
-    { 0x00008274, 0x40000000 },
-    { 0x00008278, 0x003e4180 },
-    { 0x0000827c, 0x00000000 },
-    { 0x00008284, 0x0000002c },
-    { 0x00008288, 0x0000002c },
-    { 0x0000828c, 0x00000000 },
-    { 0x00008294, 0x00000000 },
-    { 0x00008298, 0x00000000 },
-    { 0x00008300, 0x00000000 },
-    { 0x00008304, 0x00000000 },
-    { 0x00008308, 0x00000000 },
-    { 0x0000830c, 0x00000000 },
-    { 0x00008310, 0x00000000 },
-    { 0x00008314, 0x00000000 },
-    { 0x00008318, 0x00000000 },
-    { 0x00008328, 0x00000000 },
-    { 0x0000832c, 0x00000007 },
-    { 0x00008330, 0x00000302 },
-    { 0x00008334, 0x00000e00 },
-    { 0x00008338, 0x00000000 },
-    { 0x0000833c, 0x00000000 },
-    { 0x00008340, 0x000107ff },
-    { 0x00009808, 0x00000000 },
-    { 0x0000980c, 0xad848e19 },
-    { 0x00009810, 0x7d14e000 },
-    { 0x00009814, 0x9c0a9f6b },
-    { 0x0000981c, 0x00000000 },
-    { 0x0000982c, 0x0000a000 },
-    { 0x00009830, 0x00000000 },
-    { 0x0000983c, 0x00200400 },
-    { 0x00009840, 0x206a01ae },
-    { 0x0000984c, 0x1284233c },
-    { 0x00009854, 0x00000859 },
-    { 0x00009900, 0x00000000 },
-    { 0x00009904, 0x00000000 },
-    { 0x00009908, 0x00000000 },
-    { 0x0000990c, 0x00000000 },
-    { 0x0000991c, 0x10000fff },
-    { 0x00009920, 0x05100000 },
-    { 0x0000a920, 0x05100000 },
-    { 0x0000b920, 0x05100000 },
-    { 0x00009928, 0x00000001 },
-    { 0x0000992c, 0x00000004 },
-    { 0x00009934, 0x1e1f2022 },
-    { 0x00009938, 0x0a0b0c0d },
-    { 0x0000993c, 0x00000000 },
-    { 0x00009948, 0x9280b212 },
-    { 0x0000994c, 0x00020028 },
-    { 0x0000c95c, 0x004b6a8e },
-    { 0x0000c968, 0x000003ce },
-    { 0x00009970, 0x190fb515 },
-    { 0x00009974, 0x00000000 },
-    { 0x00009978, 0x00000001 },
-    { 0x0000997c, 0x00000000 },
-    { 0x00009980, 0x00000000 },
-    { 0x00009984, 0x00000000 },
-    { 0x00009988, 0x00000000 },
-    { 0x0000998c, 0x00000000 },
-    { 0x00009990, 0x00000000 },
-    { 0x00009994, 0x00000000 },
-    { 0x00009998, 0x00000000 },
-    { 0x0000999c, 0x00000000 },
-    { 0x000099a0, 0x00000000 },
-    { 0x000099a4, 0x00000001 },
-    { 0x000099a8, 0x201fff00 },
-    { 0x000099ac, 0x006f0000 },
-    { 0x000099b0, 0x03051000 },
-    { 0x000099dc, 0x00000000 },
-    { 0x000099e0, 0x00000200 },
-    { 0x000099e4, 0xaaaaaaaa },
-    { 0x000099e8, 0x3c466478 },
-    { 0x000099ec, 0x0cc80caa },
-    { 0x000099fc, 0x00001042 },
-    { 0x00009b00, 0x00000000 },
-    { 0x00009b04, 0x00000001 },
-    { 0x00009b08, 0x00000002 },
-    { 0x00009b0c, 0x00000003 },
-    { 0x00009b10, 0x00000004 },
-    { 0x00009b14, 0x00000005 },
-    { 0x00009b18, 0x00000008 },
-    { 0x00009b1c, 0x00000009 },
-    { 0x00009b20, 0x0000000a },
-    { 0x00009b24, 0x0000000b },
-    { 0x00009b28, 0x0000000c },
-    { 0x00009b2c, 0x0000000d },
-    { 0x00009b30, 0x00000010 },
-    { 0x00009b34, 0x00000011 },
-    { 0x00009b38, 0x00000012 },
-    { 0x00009b3c, 0x00000013 },
-    { 0x00009b40, 0x00000014 },
-    { 0x00009b44, 0x00000015 },
-    { 0x00009b48, 0x00000018 },
-    { 0x00009b4c, 0x00000019 },
-    { 0x00009b50, 0x0000001a },
-    { 0x00009b54, 0x0000001b },
-    { 0x00009b58, 0x0000001c },
-    { 0x00009b5c, 0x0000001d },
-    { 0x00009b60, 0x00000020 },
-    { 0x00009b64, 0x00000021 },
-    { 0x00009b68, 0x00000022 },
-    { 0x00009b6c, 0x00000023 },
-    { 0x00009b70, 0x00000024 },
-    { 0x00009b74, 0x00000025 },
-    { 0x00009b78, 0x00000028 },
-    { 0x00009b7c, 0x00000029 },
-    { 0x00009b80, 0x0000002a },
-    { 0x00009b84, 0x0000002b },
-    { 0x00009b88, 0x0000002c },
-    { 0x00009b8c, 0x0000002d },
-    { 0x00009b90, 0x00000030 },
-    { 0x00009b94, 0x00000031 },
-    { 0x00009b98, 0x00000032 },
-    { 0x00009b9c, 0x00000033 },
-    { 0x00009ba0, 0x00000034 },
-    { 0x00009ba4, 0x00000035 },
-    { 0x00009ba8, 0x00000035 },
-    { 0x00009bac, 0x00000035 },
-    { 0x00009bb0, 0x00000035 },
-    { 0x00009bb4, 0x00000035 },
-    { 0x00009bb8, 0x00000035 },
-    { 0x00009bbc, 0x00000035 },
-    { 0x00009bc0, 0x00000035 },
-    { 0x00009bc4, 0x00000035 },
-    { 0x00009bc8, 0x00000035 },
-    { 0x00009bcc, 0x00000035 },
-    { 0x00009bd0, 0x00000035 },
-    { 0x00009bd4, 0x00000035 },
-    { 0x00009bd8, 0x00000035 },
-    { 0x00009bdc, 0x00000035 },
-    { 0x00009be0, 0x00000035 },
-    { 0x00009be4, 0x00000035 },
-    { 0x00009be8, 0x00000035 },
-    { 0x00009bec, 0x00000035 },
-    { 0x00009bf0, 0x00000035 },
-    { 0x00009bf4, 0x00000035 },
-    { 0x00009bf8, 0x00000010 },
-    { 0x00009bfc, 0x0000001a },
-    { 0x0000a210, 0x40806333 },
-    { 0x0000a214, 0x00106c10 },
-    { 0x0000a218, 0x009c4060 },
-    { 0x0000a220, 0x018830c6 },
-    { 0x0000a224, 0x00000400 },
-    { 0x0000a228, 0x001a0bb5 },
-    { 0x0000a22c, 0x00000000 },
-    { 0x0000a234, 0x20202020 },
-    { 0x0000a238, 0x20202020 },
-    { 0x0000a23c, 0x13c889ae },
-    { 0x0000a240, 0x38490a20 },
-    { 0x0000a244, 0x00007bb6 },
-    { 0x0000a248, 0x0fff3ffc },
-    { 0x0000a24c, 0x00000001 },
-    { 0x0000a250, 0x0000a000 },
-    { 0x0000a254, 0x00000000 },
-    { 0x0000a258, 0x0cc75380 },
-    { 0x0000a25c, 0x0f0f0f01 },
-    { 0x0000a260, 0xdfa91f01 },
-    { 0x0000a268, 0x00000001 },
-    { 0x0000a26c, 0x0ebae9c6 },
-    { 0x0000b26c, 0x0ebae9c6 },
-    { 0x0000c26c, 0x0ebae9c6 },
-    { 0x0000d270, 0x00820820 },
-    { 0x0000a278, 0x1ce739ce },
-    { 0x0000a27c, 0x050701ce },
-    { 0x0000a338, 0x00000000 },
-    { 0x0000a33c, 0x00000000 },
-    { 0x0000a340, 0x00000000 },
-    { 0x0000a344, 0x00000000 },
-    { 0x0000a348, 0x3fffffff },
-    { 0x0000a34c, 0x3fffffff },
-    { 0x0000a350, 0x3fffffff },
-    { 0x0000a354, 0x0003ffff },
-    { 0x0000a358, 0x79a8aa33 },
-    { 0x0000d35c, 0x07ffffef },
-    { 0x0000d360, 0x0fffffe7 },
-    { 0x0000d364, 0x17ffffe5 },
-    { 0x0000d368, 0x1fffffe4 },
-    { 0x0000d36c, 0x37ffffe3 },
-    { 0x0000d370, 0x3fffffe3 },
-    { 0x0000d374, 0x57ffffe3 },
-    { 0x0000d378, 0x5fffffe2 },
-    { 0x0000d37c, 0x7fffffe2 },
-    { 0x0000d380, 0x7f3c7bba },
-    { 0x0000d384, 0xf3307ff0 },
-    { 0x0000a388, 0x0c000000 },
-    { 0x0000a38c, 0x20202020 },
-    { 0x0000a390, 0x20202020 },
-    { 0x0000a394, 0x1ce739ce },
-    { 0x0000a398, 0x000001ce },
-    { 0x0000a39c, 0x00000001 },
-    { 0x0000a3a0, 0x00000000 },
-    { 0x0000a3a4, 0x00000000 },
-    { 0x0000a3a8, 0x00000000 },
-    { 0x0000a3ac, 0x00000000 },
-    { 0x0000a3b0, 0x00000000 },
-    { 0x0000a3b4, 0x00000000 },
-    { 0x0000a3b8, 0x00000000 },
-    { 0x0000a3bc, 0x00000000 },
-    { 0x0000a3c0, 0x00000000 },
-    { 0x0000a3c4, 0x00000000 },
-    { 0x0000a3c8, 0x00000246 },
-    { 0x0000a3cc, 0x20202020 },
-    { 0x0000a3d0, 0x20202020 },
-    { 0x0000a3d4, 0x20202020 },
-    { 0x0000a3dc, 0x1ce739ce },
-    { 0x0000a3e0, 0x000001ce },
-};
-
-static const u32 ar5416Bank0_9100[][2] = {
-    { 0x000098b0, 0x1e5795e5 },
-    { 0x000098e0, 0x02008020 },
-};
-
-static const u32 ar5416BB_RfGain_9100[][3] = {
-    { 0x00009a00, 0x00000000, 0x00000000 },
-    { 0x00009a04, 0x00000040, 0x00000040 },
-    { 0x00009a08, 0x00000080, 0x00000080 },
-    { 0x00009a0c, 0x000001a1, 0x00000141 },
-    { 0x00009a10, 0x000001e1, 0x00000181 },
-    { 0x00009a14, 0x00000021, 0x000001c1 },
-    { 0x00009a18, 0x00000061, 0x00000001 },
-    { 0x00009a1c, 0x00000168, 0x00000041 },
-    { 0x00009a20, 0x000001a8, 0x000001a8 },
-    { 0x00009a24, 0x000001e8, 0x000001e8 },
-    { 0x00009a28, 0x00000028, 0x00000028 },
-    { 0x00009a2c, 0x00000068, 0x00000068 },
-    { 0x00009a30, 0x00000189, 0x000000a8 },
-    { 0x00009a34, 0x000001c9, 0x00000169 },
-    { 0x00009a38, 0x00000009, 0x000001a9 },
-    { 0x00009a3c, 0x00000049, 0x000001e9 },
-    { 0x00009a40, 0x00000089, 0x00000029 },
-    { 0x00009a44, 0x00000170, 0x00000069 },
-    { 0x00009a48, 0x000001b0, 0x00000190 },
-    { 0x00009a4c, 0x000001f0, 0x000001d0 },
-    { 0x00009a50, 0x00000030, 0x00000010 },
-    { 0x00009a54, 0x00000070, 0x00000050 },
-    { 0x00009a58, 0x00000191, 0x00000090 },
-    { 0x00009a5c, 0x000001d1, 0x00000151 },
-    { 0x00009a60, 0x00000011, 0x00000191 },
-    { 0x00009a64, 0x00000051, 0x000001d1 },
-    { 0x00009a68, 0x00000091, 0x00000011 },
-    { 0x00009a6c, 0x000001b8, 0x00000051 },
-    { 0x00009a70, 0x000001f8, 0x00000198 },
-    { 0x00009a74, 0x00000038, 0x000001d8 },
-    { 0x00009a78, 0x00000078, 0x00000018 },
-    { 0x00009a7c, 0x00000199, 0x00000058 },
-    { 0x00009a80, 0x000001d9, 0x00000098 },
-    { 0x00009a84, 0x00000019, 0x00000159 },
-    { 0x00009a88, 0x00000059, 0x00000199 },
-    { 0x00009a8c, 0x00000099, 0x000001d9 },
-    { 0x00009a90, 0x000000d9, 0x00000019 },
-    { 0x00009a94, 0x000000f9, 0x00000059 },
-    { 0x00009a98, 0x000000f9, 0x00000099 },
-    { 0x00009a9c, 0x000000f9, 0x000000d9 },
-    { 0x00009aa0, 0x000000f9, 0x000000f9 },
-    { 0x00009aa4, 0x000000f9, 0x000000f9 },
-    { 0x00009aa8, 0x000000f9, 0x000000f9 },
-    { 0x00009aac, 0x000000f9, 0x000000f9 },
-    { 0x00009ab0, 0x000000f9, 0x000000f9 },
-    { 0x00009ab4, 0x000000f9, 0x000000f9 },
-    { 0x00009ab8, 0x000000f9, 0x000000f9 },
-    { 0x00009abc, 0x000000f9, 0x000000f9 },
-    { 0x00009ac0, 0x000000f9, 0x000000f9 },
-    { 0x00009ac4, 0x000000f9, 0x000000f9 },
-    { 0x00009ac8, 0x000000f9, 0x000000f9 },
-    { 0x00009acc, 0x000000f9, 0x000000f9 },
-    { 0x00009ad0, 0x000000f9, 0x000000f9 },
-    { 0x00009ad4, 0x000000f9, 0x000000f9 },
-    { 0x00009ad8, 0x000000f9, 0x000000f9 },
-    { 0x00009adc, 0x000000f9, 0x000000f9 },
-    { 0x00009ae0, 0x000000f9, 0x000000f9 },
-    { 0x00009ae4, 0x000000f9, 0x000000f9 },
-    { 0x00009ae8, 0x000000f9, 0x000000f9 },
-    { 0x00009aec, 0x000000f9, 0x000000f9 },
-    { 0x00009af0, 0x000000f9, 0x000000f9 },
-    { 0x00009af4, 0x000000f9, 0x000000f9 },
-    { 0x00009af8, 0x000000f9, 0x000000f9 },
-    { 0x00009afc, 0x000000f9, 0x000000f9 },
-};
-
-static const u32 ar5416Bank1_9100[][2] = {
-    { 0x000098b0, 0x02108421},
-    { 0x000098ec, 0x00000008},
-};
-
-static const u32 ar5416Bank2_9100[][2] = {
-    { 0x000098b0, 0x0e73ff17},
-    { 0x000098e0, 0x00000420},
-};
-
-static const u32 ar5416Bank3_9100[][3] = {
-    { 0x000098f0, 0x01400018, 0x01c00018 },
-};
-
-static const u32 ar5416Bank6_9100[][3] = {
-
-    { 0x0000989c, 0x00000000, 0x00000000 },
-    { 0x0000989c, 0x00000000, 0x00000000 },
-    { 0x0000989c, 0x00000000, 0x00000000 },
-    { 0x0000989c, 0x00e00000, 0x00e00000 },
-    { 0x0000989c, 0x005e0000, 0x005e0000 },
-    { 0x0000989c, 0x00120000, 0x00120000 },
-    { 0x0000989c, 0x00620000, 0x00620000 },
-    { 0x0000989c, 0x00020000, 0x00020000 },
-    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
-    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
-    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
-    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
-    { 0x0000989c, 0x005f0000, 0x005f0000 },
-    { 0x0000989c, 0x00870000, 0x00870000 },
-    { 0x0000989c, 0x00f90000, 0x00f90000 },
-    { 0x0000989c, 0x007b0000, 0x007b0000 },
-    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
-    { 0x0000989c, 0x00f50000, 0x00f50000 },
-    { 0x0000989c, 0x00dc0000, 0x00dc0000 },
-    { 0x0000989c, 0x00110000, 0x00110000 },
-    { 0x0000989c, 0x006100a8, 0x006100a8 },
-    { 0x0000989c, 0x004210a2, 0x004210a2 },
-    { 0x0000989c, 0x0014000f, 0x0014000f },
-    { 0x0000989c, 0x00c40002, 0x00c40002 },
-    { 0x0000989c, 0x003000f2, 0x003000f2 },
-    { 0x0000989c, 0x00440016, 0x00440016 },
-    { 0x0000989c, 0x00410040, 0x00410040 },
-    { 0x0000989c, 0x000180d6, 0x000180d6 },
-    { 0x0000989c, 0x0000c0aa, 0x0000c0aa },
-    { 0x0000989c, 0x000000b1, 0x000000b1 },
-    { 0x0000989c, 0x00002000, 0x00002000 },
-    { 0x0000989c, 0x000000d4, 0x000000d4 },
-    { 0x000098d0, 0x0000000f, 0x0010000f },
-};
-
-
-static const u32 ar5416Bank6TPC_9100[][3] = {
-
-    { 0x0000989c, 0x00000000, 0x00000000 },
-    { 0x0000989c, 0x00000000, 0x00000000 },
-    { 0x0000989c, 0x00000000, 0x00000000 },
-    { 0x0000989c, 0x00e00000, 0x00e00000 },
-    { 0x0000989c, 0x005e0000, 0x005e0000 },
-    { 0x0000989c, 0x00120000, 0x00120000 },
-    { 0x0000989c, 0x00620000, 0x00620000 },
-    { 0x0000989c, 0x00020000, 0x00020000 },
-    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
-    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
-    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
-    { 0x0000989c, 0x40ff0000, 0x40ff0000 },
-    { 0x0000989c, 0x005f0000, 0x005f0000 },
-    { 0x0000989c, 0x00870000, 0x00870000 },
-    { 0x0000989c, 0x00f90000, 0x00f90000 },
-    { 0x0000989c, 0x007b0000, 0x007b0000 },
-    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
-    { 0x0000989c, 0x00f50000, 0x00f50000 },
-    { 0x0000989c, 0x00dc0000, 0x00dc0000 },
-    { 0x0000989c, 0x00110000, 0x00110000 },
-    { 0x0000989c, 0x006100a8, 0x006100a8 },
-    { 0x0000989c, 0x00423022, 0x00423022 },
-    { 0x0000989c, 0x2014008f, 0x2014008f },
-    { 0x0000989c, 0x00c40002, 0x00c40002 },
-    { 0x0000989c, 0x003000f2, 0x003000f2 },
-    { 0x0000989c, 0x00440016, 0x00440016 },
-    { 0x0000989c, 0x00410040, 0x00410040 },
-    { 0x0000989c, 0x0001805e, 0x0001805e },
-    { 0x0000989c, 0x0000c0ab, 0x0000c0ab },
-    { 0x0000989c, 0x000000e1, 0x000000e1 },
-    { 0x0000989c, 0x00007080, 0x00007080 },
-    { 0x0000989c, 0x000000d4, 0x000000d4 },
-    { 0x000098d0, 0x0000000f, 0x0010000f },
-};
-
-static const u32 ar5416Bank7_9100[][2] = {
-    { 0x0000989c, 0x00000500 },
-    { 0x0000989c, 0x00000800 },
-    { 0x000098cc, 0x0000000e },
-};
-
-static const u32 ar5416Addac_9100[][2] = {
-    {0x0000989c, 0x00000000 },
-    {0x0000989c, 0x00000000 },
-    {0x0000989c, 0x00000000 },
-    {0x0000989c, 0x00000000 },
-    {0x0000989c, 0x00000000 },
-    {0x0000989c, 0x00000000 },
-    {0x0000989c, 0x00000000 },
-    {0x0000989c, 0x00000010 },
-    {0x0000989c, 0x00000000 },
-    {0x0000989c, 0x00000000 },
-    {0x0000989c, 0x00000000 },
-    {0x0000989c, 0x00000000 },
-    {0x0000989c, 0x00000000 },
-    {0x0000989c, 0x00000000 },
-    {0x0000989c, 0x00000000 },
-    {0x0000989c, 0x00000000 },
-    {0x0000989c, 0x00000000 },
-    {0x0000989c, 0x00000000 },
-    {0x0000989c, 0x00000000 },
-    {0x0000989c, 0x00000000 },
-    {0x0000989c, 0x00000000 },
-    {0x0000989c, 0x000000c0 },
-    {0x0000989c, 0x00000015 },
-    {0x0000989c, 0x00000000 },
-    {0x0000989c, 0x00000000 },
-    {0x0000989c, 0x00000000 },
-    {0x0000989c, 0x00000000 },
-    {0x0000989c, 0x00000000 },
-    {0x0000989c, 0x00000000 },
-    {0x0000989c, 0x00000000 },
-    {0x0000989c, 0x00000000 },
-    {0x000098cc, 0x00000000 },
-};
-
-static const u32 ar5416Modes_9160[][6] = {
-    { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 },
-    { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 },
-    { 0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180 },
-    { 0x000010f0, 0x0000a000, 0x00014000, 0x00016000, 0x0000b000, 0x00014008 },
-    { 0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00, 0x06e006e0 },
-    { 0x0000801c, 0x128d93a7, 0x128d93cf, 0x12e013d7, 0x12e013ab, 0x098813cf },
-    { 0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303 },
-    { 0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200 },
-    { 0x00009824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
-    { 0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001 },
-    { 0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
-    { 0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007 },
-    { 0x00009844, 0x0372161e, 0x0372161e, 0x037216a0, 0x037216a0, 0x037216a0 },
-    { 0x00009848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
-    { 0x0000a848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
-    { 0x0000b848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
-    { 0x00009850, 0x6c48b4e2, 0x6c48b4e2, 0x6c48b0e2, 0x6c48b0e2, 0x6c48b0e2 },
-    { 0x00009858, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e },
-    { 0x0000985c, 0x31395d5e, 0x31395d5e, 0x31395d5e, 0x31395d5e, 0x31395d5e },
-    { 0x00009860, 0x00048d18, 0x00048d18, 0x00048d20, 0x00048d20, 0x00048d18 },
-    { 0x0000c864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00 },
-    { 0x00009868, 0x409a40d0, 0x409a40d0, 0x409a40d0, 0x409a40d0, 0x409a40d0 },
-    { 0x0000986c, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 },
-    { 0x00009914, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898, 0x000007d0 },
-    { 0x00009918, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b, 0x00000016 },
-    { 0x00009924, 0xd00a8a07, 0xd00a8a07, 0xd00a8a0d, 0xd00a8a0d, 0xd00a8a0d },
-    { 0x00009944, 0xffb81020, 0xffb81020, 0xffb81020, 0xffb81020, 0xffb81020 },
-    { 0x00009960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40 },
-    { 0x0000a960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40 },
-    { 0x0000b960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40 },
-    { 0x00009964, 0x00001120, 0x00001120, 0x00001120, 0x00001120, 0x00001120 },
-    { 0x0000c968, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce, 0x000003ce },
-    { 0x0000c9bc, 0x001a0600, 0x001a0600, 0x001a0c00, 0x001a0c00, 0x001a0c00 },
-    { 0x000099c0, 0x038919be, 0x038919be, 0x038919be, 0x038919be, 0x038919be },
-    { 0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77 },
-    { 0x000099c8, 0x60f65329, 0x60f65329, 0x60f65329, 0x60f65329, 0x60f65329 },
-    { 0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8 },
-    { 0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, 0x00046384 },
-    { 0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
-    { 0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
-    { 0x0000a204, 0x00000880, 0x00000880, 0x00000880, 0x00000880, 0x00000880 },
-    { 0x0000a208, 0xd6be4788, 0xd6be4788, 0xd03e4788, 0xd03e4788, 0xd03e4788 },
-    { 0x0000a20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120 },
-    { 0x0000b20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120 },
-    { 0x0000c20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120 },
-    { 0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a },
-    { 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000 },
-    { 0x0000a274, 0x0a1a9caa, 0x0a1a9caa, 0x0a1a7caa, 0x0a1a7caa, 0x0a1a7caa },
-    { 0x0000a300, 0x18010000, 0x18010000, 0x18010000, 0x18010000, 0x18010000 },
-    { 0x0000a304, 0x30032602, 0x30032602, 0x2e032402, 0x2e032402, 0x2e032402 },
-    { 0x0000a308, 0x48073e06, 0x48073e06, 0x4a0a3c06, 0x4a0a3c06, 0x4a0a3c06 },
-    { 0x0000a30c, 0x560b4c0a, 0x560b4c0a, 0x621a540b, 0x621a540b, 0x621a540b },
-    { 0x0000a310, 0x641a600f, 0x641a600f, 0x764f6c1b, 0x764f6c1b, 0x764f6c1b },
-    { 0x0000a314, 0x7a4f6e1b, 0x7a4f6e1b, 0x845b7a5a, 0x845b7a5a, 0x845b7a5a },
-    { 0x0000a318, 0x8c5b7e5a, 0x8c5b7e5a, 0x950f8ccf, 0x950f8ccf, 0x950f8ccf },
-    { 0x0000a31c, 0x9d0f96cf, 0x9d0f96cf, 0xa5cf9b4f, 0xa5cf9b4f, 0xa5cf9b4f },
-    { 0x0000a320, 0xb51fa69f, 0xb51fa69f, 0xbddfaf1f, 0xbddfaf1f, 0xbddfaf1f },
-    { 0x0000a324, 0xcb3fbd07, 0xcb3fbcbf, 0xd1ffc93f, 0xd1ffc93f, 0xd1ffc93f },
-    { 0x0000a328, 0x0000d7bf, 0x0000d7bf, 0x00000000, 0x00000000, 0x00000000 },
-    { 0x0000a32c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
-    { 0x0000a330, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
-    { 0x0000a334, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
-};
+#ifndef INITVALS_9002_10_H
+#define INITVALS_9002_10_H
 
-static const u32 ar5416Common_9160[][2] = {
-    { 0x0000000c, 0x00000000 },
-    { 0x00000030, 0x00020015 },
-    { 0x00000034, 0x00000005 },
-    { 0x00000040, 0x00000000 },
-    { 0x00000044, 0x00000008 },
-    { 0x00000048, 0x00000008 },
-    { 0x0000004c, 0x00000010 },
-    { 0x00000050, 0x00000000 },
-    { 0x00000054, 0x0000001f },
-    { 0x00000800, 0x00000000 },
-    { 0x00000804, 0x00000000 },
-    { 0x00000808, 0x00000000 },
-    { 0x0000080c, 0x00000000 },
-    { 0x00000810, 0x00000000 },
-    { 0x00000814, 0x00000000 },
-    { 0x00000818, 0x00000000 },
-    { 0x0000081c, 0x00000000 },
-    { 0x00000820, 0x00000000 },
-    { 0x00000824, 0x00000000 },
-    { 0x00001040, 0x002ffc0f },
-    { 0x00001044, 0x002ffc0f },
-    { 0x00001048, 0x002ffc0f },
-    { 0x0000104c, 0x002ffc0f },
-    { 0x00001050, 0x002ffc0f },
-    { 0x00001054, 0x002ffc0f },
-    { 0x00001058, 0x002ffc0f },
-    { 0x0000105c, 0x002ffc0f },
-    { 0x00001060, 0x002ffc0f },
-    { 0x00001064, 0x002ffc0f },
-    { 0x00001230, 0x00000000 },
-    { 0x00001270, 0x00000000 },
-    { 0x00001038, 0x00000000 },
-    { 0x00001078, 0x00000000 },
-    { 0x000010b8, 0x00000000 },
-    { 0x000010f8, 0x00000000 },
-    { 0x00001138, 0x00000000 },
-    { 0x00001178, 0x00000000 },
-    { 0x000011b8, 0x00000000 },
-    { 0x000011f8, 0x00000000 },
-    { 0x00001238, 0x00000000 },
-    { 0x00001278, 0x00000000 },
-    { 0x000012b8, 0x00000000 },
-    { 0x000012f8, 0x00000000 },
-    { 0x00001338, 0x00000000 },
-    { 0x00001378, 0x00000000 },
-    { 0x000013b8, 0x00000000 },
-    { 0x000013f8, 0x00000000 },
-    { 0x00001438, 0x00000000 },
-    { 0x00001478, 0x00000000 },
-    { 0x000014b8, 0x00000000 },
-    { 0x000014f8, 0x00000000 },
-    { 0x00001538, 0x00000000 },
-    { 0x00001578, 0x00000000 },
-    { 0x000015b8, 0x00000000 },
-    { 0x000015f8, 0x00000000 },
-    { 0x00001638, 0x00000000 },
-    { 0x00001678, 0x00000000 },
-    { 0x000016b8, 0x00000000 },
-    { 0x000016f8, 0x00000000 },
-    { 0x00001738, 0x00000000 },
-    { 0x00001778, 0x00000000 },
-    { 0x000017b8, 0x00000000 },
-    { 0x000017f8, 0x00000000 },
-    { 0x0000103c, 0x00000000 },
-    { 0x0000107c, 0x00000000 },
-    { 0x000010bc, 0x00000000 },
-    { 0x000010fc, 0x00000000 },
-    { 0x0000113c, 0x00000000 },
-    { 0x0000117c, 0x00000000 },
-    { 0x000011bc, 0x00000000 },
-    { 0x000011fc, 0x00000000 },
-    { 0x0000123c, 0x00000000 },
-    { 0x0000127c, 0x00000000 },
-    { 0x000012bc, 0x00000000 },
-    { 0x000012fc, 0x00000000 },
-    { 0x0000133c, 0x00000000 },
-    { 0x0000137c, 0x00000000 },
-    { 0x000013bc, 0x00000000 },
-    { 0x000013fc, 0x00000000 },
-    { 0x0000143c, 0x00000000 },
-    { 0x0000147c, 0x00000000 },
-    { 0x00004030, 0x00000002 },
-    { 0x0000403c, 0x00000002 },
-    { 0x00007010, 0x00000020 },
-    { 0x00007038, 0x000004c2 },
-    { 0x00008004, 0x00000000 },
-    { 0x00008008, 0x00000000 },
-    { 0x0000800c, 0x00000000 },
-    { 0x00008018, 0x00000700 },
-    { 0x00008020, 0x00000000 },
-    { 0x00008038, 0x00000000 },
-    { 0x0000803c, 0x00000000 },
-    { 0x00008048, 0x40000000 },
-    { 0x00008054, 0x00000000 },
-    { 0x00008058, 0x00000000 },
-    { 0x0000805c, 0x000fc78f },
-    { 0x00008060, 0x0000000f },
-    { 0x00008064, 0x00000000 },
-    { 0x000080c0, 0x2a82301a },
-    { 0x000080c4, 0x05dc01e0 },
-    { 0x000080c8, 0x1f402710 },
-    { 0x000080cc, 0x01f40000 },
-    { 0x000080d0, 0x00001e00 },
-    { 0x000080d4, 0x00000000 },
-    { 0x000080d8, 0x00400000 },
-    { 0x000080e0, 0xffffffff },
-    { 0x000080e4, 0x0000ffff },
-    { 0x000080e8, 0x003f3f3f },
-    { 0x000080ec, 0x00000000 },
-    { 0x000080f0, 0x00000000 },
-    { 0x000080f4, 0x00000000 },
-    { 0x000080f8, 0x00000000 },
-    { 0x000080fc, 0x00020000 },
-    { 0x00008100, 0x00020000 },
-    { 0x00008104, 0x00000001 },
-    { 0x00008108, 0x00000052 },
-    { 0x0000810c, 0x00000000 },
-    { 0x00008110, 0x00000168 },
-    { 0x00008118, 0x000100aa },
-    { 0x0000811c, 0x00003210 },
-    { 0x00008120, 0x08f04800 },
-    { 0x00008124, 0x00000000 },
-    { 0x00008128, 0x00000000 },
-    { 0x0000812c, 0x00000000 },
-    { 0x00008130, 0x00000000 },
-    { 0x00008134, 0x00000000 },
-    { 0x00008138, 0x00000000 },
-    { 0x0000813c, 0x00000000 },
-    { 0x00008144, 0xffffffff },
-    { 0x00008168, 0x00000000 },
-    { 0x0000816c, 0x00000000 },
-    { 0x00008170, 0x32143320 },
-    { 0x00008174, 0xfaa4fa50 },
-    { 0x00008178, 0x00000100 },
-    { 0x0000817c, 0x00000000 },
-    { 0x000081c4, 0x00000000 },
-    { 0x000081d0, 0x00003210 },
-    { 0x000081ec, 0x00000000 },
-    { 0x000081f0, 0x00000000 },
-    { 0x000081f4, 0x00000000 },
-    { 0x000081f8, 0x00000000 },
-    { 0x000081fc, 0x00000000 },
-    { 0x00008200, 0x00000000 },
-    { 0x00008204, 0x00000000 },
-    { 0x00008208, 0x00000000 },
-    { 0x0000820c, 0x00000000 },
-    { 0x00008210, 0x00000000 },
-    { 0x00008214, 0x00000000 },
-    { 0x00008218, 0x00000000 },
-    { 0x0000821c, 0x00000000 },
-    { 0x00008220, 0x00000000 },
-    { 0x00008224, 0x00000000 },
-    { 0x00008228, 0x00000000 },
-    { 0x0000822c, 0x00000000 },
-    { 0x00008230, 0x00000000 },
-    { 0x00008234, 0x00000000 },
-    { 0x00008238, 0x00000000 },
-    { 0x0000823c, 0x00000000 },
-    { 0x00008240, 0x00100000 },
-    { 0x00008244, 0x0010f400 },
-    { 0x00008248, 0x00000100 },
-    { 0x0000824c, 0x0001e800 },
-    { 0x00008250, 0x00000000 },
-    { 0x00008254, 0x00000000 },
-    { 0x00008258, 0x00000000 },
-    { 0x0000825c, 0x400000ff },
-    { 0x00008260, 0x00080922 },
-    { 0x00008270, 0x00000000 },
-    { 0x00008274, 0x40000000 },
-    { 0x00008278, 0x003e4180 },
-    { 0x0000827c, 0x00000000 },
-    { 0x00008284, 0x0000002c },
-    { 0x00008288, 0x0000002c },
-    { 0x0000828c, 0x00000000 },
-    { 0x00008294, 0x00000000 },
-    { 0x00008298, 0x00000000 },
-    { 0x00008300, 0x00000000 },
-    { 0x00008304, 0x00000000 },
-    { 0x00008308, 0x00000000 },
-    { 0x0000830c, 0x00000000 },
-    { 0x00008310, 0x00000000 },
-    { 0x00008314, 0x00000000 },
-    { 0x00008318, 0x00000000 },
-    { 0x00008328, 0x00000000 },
-    { 0x0000832c, 0x00000007 },
-    { 0x00008330, 0x00000302 },
-    { 0x00008334, 0x00000e00 },
-    { 0x00008338, 0x00ff0000 },
-    { 0x0000833c, 0x00000000 },
-    { 0x00008340, 0x000107ff },
-    { 0x00009808, 0x00000000 },
-    { 0x0000980c, 0xad848e19 },
-    { 0x00009810, 0x7d14e000 },
-    { 0x00009814, 0x9c0a9f6b },
-    { 0x0000981c, 0x00000000 },
-    { 0x0000982c, 0x0000a000 },
-    { 0x00009830, 0x00000000 },
-    { 0x0000983c, 0x00200400 },
-    { 0x00009840, 0x206a01ae },
-    { 0x0000984c, 0x1284233c },
-    { 0x00009854, 0x00000859 },
-    { 0x00009900, 0x00000000 },
-    { 0x00009904, 0x00000000 },
-    { 0x00009908, 0x00000000 },
-    { 0x0000990c, 0x00000000 },
-    { 0x0000991c, 0x10000fff },
-    { 0x00009920, 0x05100000 },
-    { 0x0000a920, 0x05100000 },
-    { 0x0000b920, 0x05100000 },
-    { 0x00009928, 0x00000001 },
-    { 0x0000992c, 0x00000004 },
-    { 0x00009934, 0x1e1f2022 },
-    { 0x00009938, 0x0a0b0c0d },
-    { 0x0000993c, 0x00000000 },
-    { 0x00009948, 0x9280b212 },
-    { 0x0000994c, 0x00020028 },
-    { 0x00009954, 0x5f3ca3de },
-    { 0x00009958, 0x2108ecff },
-    { 0x00009940, 0x00750604 },
-    { 0x0000c95c, 0x004b6a8e },
-    { 0x00009970, 0x190fb515 },
-    { 0x00009974, 0x00000000 },
-    { 0x00009978, 0x00000001 },
-    { 0x0000997c, 0x00000000 },
-    { 0x00009980, 0x00000000 },
-    { 0x00009984, 0x00000000 },
-    { 0x00009988, 0x00000000 },
-    { 0x0000998c, 0x00000000 },
-    { 0x00009990, 0x00000000 },
-    { 0x00009994, 0x00000000 },
-    { 0x00009998, 0x00000000 },
-    { 0x0000999c, 0x00000000 },
-    { 0x000099a0, 0x00000000 },
-    { 0x000099a4, 0x00000001 },
-    { 0x000099a8, 0x201fff00 },
-    { 0x000099ac, 0x006f0000 },
-    { 0x000099b0, 0x03051000 },
-    { 0x000099dc, 0x00000000 },
-    { 0x000099e0, 0x00000200 },
-    { 0x000099e4, 0xaaaaaaaa },
-    { 0x000099e8, 0x3c466478 },
-    { 0x000099ec, 0x0cc80caa },
-    { 0x000099fc, 0x00001042 },
-    { 0x00009b00, 0x00000000 },
-    { 0x00009b04, 0x00000001 },
-    { 0x00009b08, 0x00000002 },
-    { 0x00009b0c, 0x00000003 },
-    { 0x00009b10, 0x00000004 },
-    { 0x00009b14, 0x00000005 },
-    { 0x00009b18, 0x00000008 },
-    { 0x00009b1c, 0x00000009 },
-    { 0x00009b20, 0x0000000a },
-    { 0x00009b24, 0x0000000b },
-    { 0x00009b28, 0x0000000c },
-    { 0x00009b2c, 0x0000000d },
-    { 0x00009b30, 0x00000010 },
-    { 0x00009b34, 0x00000011 },
-    { 0x00009b38, 0x00000012 },
-    { 0x00009b3c, 0x00000013 },
-    { 0x00009b40, 0x00000014 },
-    { 0x00009b44, 0x00000015 },
-    { 0x00009b48, 0x00000018 },
-    { 0x00009b4c, 0x00000019 },
-    { 0x00009b50, 0x0000001a },
-    { 0x00009b54, 0x0000001b },
-    { 0x00009b58, 0x0000001c },
-    { 0x00009b5c, 0x0000001d },
-    { 0x00009b60, 0x00000020 },
-    { 0x00009b64, 0x00000021 },
-    { 0x00009b68, 0x00000022 },
-    { 0x00009b6c, 0x00000023 },
-    { 0x00009b70, 0x00000024 },
-    { 0x00009b74, 0x00000025 },
-    { 0x00009b78, 0x00000028 },
-    { 0x00009b7c, 0x00000029 },
-    { 0x00009b80, 0x0000002a },
-    { 0x00009b84, 0x0000002b },
-    { 0x00009b88, 0x0000002c },
-    { 0x00009b8c, 0x0000002d },
-    { 0x00009b90, 0x00000030 },
-    { 0x00009b94, 0x00000031 },
-    { 0x00009b98, 0x00000032 },
-    { 0x00009b9c, 0x00000033 },
-    { 0x00009ba0, 0x00000034 },
-    { 0x00009ba4, 0x00000035 },
-    { 0x00009ba8, 0x00000035 },
-    { 0x00009bac, 0x00000035 },
-    { 0x00009bb0, 0x00000035 },
-    { 0x00009bb4, 0x00000035 },
-    { 0x00009bb8, 0x00000035 },
-    { 0x00009bbc, 0x00000035 },
-    { 0x00009bc0, 0x00000035 },
-    { 0x00009bc4, 0x00000035 },
-    { 0x00009bc8, 0x00000035 },
-    { 0x00009bcc, 0x00000035 },
-    { 0x00009bd0, 0x00000035 },
-    { 0x00009bd4, 0x00000035 },
-    { 0x00009bd8, 0x00000035 },
-    { 0x00009bdc, 0x00000035 },
-    { 0x00009be0, 0x00000035 },
-    { 0x00009be4, 0x00000035 },
-    { 0x00009be8, 0x00000035 },
-    { 0x00009bec, 0x00000035 },
-    { 0x00009bf0, 0x00000035 },
-    { 0x00009bf4, 0x00000035 },
-    { 0x00009bf8, 0x00000010 },
-    { 0x00009bfc, 0x0000001a },
-    { 0x0000a210, 0x40806333 },
-    { 0x0000a214, 0x00106c10 },
-    { 0x0000a218, 0x009c4060 },
-    { 0x0000a220, 0x018830c6 },
-    { 0x0000a224, 0x00000400 },
-    { 0x0000a228, 0x001a0bb5 },
-    { 0x0000a22c, 0x00000000 },
-    { 0x0000a234, 0x20202020 },
-    { 0x0000a238, 0x20202020 },
-    { 0x0000a23c, 0x13c889af },
-    { 0x0000a240, 0x38490a20 },
-    { 0x0000a244, 0x00007bb6 },
-    { 0x0000a248, 0x0fff3ffc },
-    { 0x0000a24c, 0x00000001 },
-    { 0x0000a250, 0x0000e000 },
-    { 0x0000a254, 0x00000000 },
-    { 0x0000a258, 0x0cc75380 },
-    { 0x0000a25c, 0x0f0f0f01 },
-    { 0x0000a260, 0xdfa91f01 },
-    { 0x0000a268, 0x00000001 },
-    { 0x0000a26c, 0x0ebae9c6 },
-    { 0x0000b26c, 0x0ebae9c6 },
-    { 0x0000c26c, 0x0ebae9c6 },
-    { 0x0000d270, 0x00820820 },
-    { 0x0000a278, 0x1ce739ce },
-    { 0x0000a27c, 0x050701ce },
-    { 0x0000a338, 0x00000000 },
-    { 0x0000a33c, 0x00000000 },
-    { 0x0000a340, 0x00000000 },
-    { 0x0000a344, 0x00000000 },
-    { 0x0000a348, 0x3fffffff },
-    { 0x0000a34c, 0x3fffffff },
-    { 0x0000a350, 0x3fffffff },
-    { 0x0000a354, 0x0003ffff },
-    { 0x0000a358, 0x79bfaa03 },
-    { 0x0000d35c, 0x07ffffef },
-    { 0x0000d360, 0x0fffffe7 },
-    { 0x0000d364, 0x17ffffe5 },
-    { 0x0000d368, 0x1fffffe4 },
-    { 0x0000d36c, 0x37ffffe3 },
-    { 0x0000d370, 0x3fffffe3 },
-    { 0x0000d374, 0x57ffffe3 },
-    { 0x0000d378, 0x5fffffe2 },
-    { 0x0000d37c, 0x7fffffe2 },
-    { 0x0000d380, 0x7f3c7bba },
-    { 0x0000d384, 0xf3307ff0 },
-    { 0x0000a388, 0x0c000000 },
-    { 0x0000a38c, 0x20202020 },
-    { 0x0000a390, 0x20202020 },
-    { 0x0000a394, 0x1ce739ce },
-    { 0x0000a398, 0x000001ce },
-    { 0x0000a39c, 0x00000001 },
-    { 0x0000a3a0, 0x00000000 },
-    { 0x0000a3a4, 0x00000000 },
-    { 0x0000a3a8, 0x00000000 },
-    { 0x0000a3ac, 0x00000000 },
-    { 0x0000a3b0, 0x00000000 },
-    { 0x0000a3b4, 0x00000000 },
-    { 0x0000a3b8, 0x00000000 },
-    { 0x0000a3bc, 0x00000000 },
-    { 0x0000a3c0, 0x00000000 },
-    { 0x0000a3c4, 0x00000000 },
-    { 0x0000a3c8, 0x00000246 },
-    { 0x0000a3cc, 0x20202020 },
-    { 0x0000a3d0, 0x20202020 },
-    { 0x0000a3d4, 0x20202020 },
-    { 0x0000a3dc, 0x1ce739ce },
-    { 0x0000a3e0, 0x000001ce },
-};
-
-static const u32 ar5416Bank0_9160[][2] = {
-    { 0x000098b0, 0x1e5795e5 },
-    { 0x000098e0, 0x02008020 },
-};
-
-static const u32 ar5416BB_RfGain_9160[][3] = {
-    { 0x00009a00, 0x00000000, 0x00000000 },
-    { 0x00009a04, 0x00000040, 0x00000040 },
-    { 0x00009a08, 0x00000080, 0x00000080 },
-    { 0x00009a0c, 0x000001a1, 0x00000141 },
-    { 0x00009a10, 0x000001e1, 0x00000181 },
-    { 0x00009a14, 0x00000021, 0x000001c1 },
-    { 0x00009a18, 0x00000061, 0x00000001 },
-    { 0x00009a1c, 0x00000168, 0x00000041 },
-    { 0x00009a20, 0x000001a8, 0x000001a8 },
-    { 0x00009a24, 0x000001e8, 0x000001e8 },
-    { 0x00009a28, 0x00000028, 0x00000028 },
-    { 0x00009a2c, 0x00000068, 0x00000068 },
-    { 0x00009a30, 0x00000189, 0x000000a8 },
-    { 0x00009a34, 0x000001c9, 0x00000169 },
-    { 0x00009a38, 0x00000009, 0x000001a9 },
-    { 0x00009a3c, 0x00000049, 0x000001e9 },
-    { 0x00009a40, 0x00000089, 0x00000029 },
-    { 0x00009a44, 0x00000170, 0x00000069 },
-    { 0x00009a48, 0x000001b0, 0x00000190 },
-    { 0x00009a4c, 0x000001f0, 0x000001d0 },
-    { 0x00009a50, 0x00000030, 0x00000010 },
-    { 0x00009a54, 0x00000070, 0x00000050 },
-    { 0x00009a58, 0x00000191, 0x00000090 },
-    { 0x00009a5c, 0x000001d1, 0x00000151 },
-    { 0x00009a60, 0x00000011, 0x00000191 },
-    { 0x00009a64, 0x00000051, 0x000001d1 },
-    { 0x00009a68, 0x00000091, 0x00000011 },
-    { 0x00009a6c, 0x000001b8, 0x00000051 },
-    { 0x00009a70, 0x000001f8, 0x00000198 },
-    { 0x00009a74, 0x00000038, 0x000001d8 },
-    { 0x00009a78, 0x00000078, 0x00000018 },
-    { 0x00009a7c, 0x00000199, 0x00000058 },
-    { 0x00009a80, 0x000001d9, 0x00000098 },
-    { 0x00009a84, 0x00000019, 0x00000159 },
-    { 0x00009a88, 0x00000059, 0x00000199 },
-    { 0x00009a8c, 0x00000099, 0x000001d9 },
-    { 0x00009a90, 0x000000d9, 0x00000019 },
-    { 0x00009a94, 0x000000f9, 0x00000059 },
-    { 0x00009a98, 0x000000f9, 0x00000099 },
-    { 0x00009a9c, 0x000000f9, 0x000000d9 },
-    { 0x00009aa0, 0x000000f9, 0x000000f9 },
-    { 0x00009aa4, 0x000000f9, 0x000000f9 },
-    { 0x00009aa8, 0x000000f9, 0x000000f9 },
-    { 0x00009aac, 0x000000f9, 0x000000f9 },
-    { 0x00009ab0, 0x000000f9, 0x000000f9 },
-    { 0x00009ab4, 0x000000f9, 0x000000f9 },
-    { 0x00009ab8, 0x000000f9, 0x000000f9 },
-    { 0x00009abc, 0x000000f9, 0x000000f9 },
-    { 0x00009ac0, 0x000000f9, 0x000000f9 },
-    { 0x00009ac4, 0x000000f9, 0x000000f9 },
-    { 0x00009ac8, 0x000000f9, 0x000000f9 },
-    { 0x00009acc, 0x000000f9, 0x000000f9 },
-    { 0x00009ad0, 0x000000f9, 0x000000f9 },
-    { 0x00009ad4, 0x000000f9, 0x000000f9 },
-    { 0x00009ad8, 0x000000f9, 0x000000f9 },
-    { 0x00009adc, 0x000000f9, 0x000000f9 },
-    { 0x00009ae0, 0x000000f9, 0x000000f9 },
-    { 0x00009ae4, 0x000000f9, 0x000000f9 },
-    { 0x00009ae8, 0x000000f9, 0x000000f9 },
-    { 0x00009aec, 0x000000f9, 0x000000f9 },
-    { 0x00009af0, 0x000000f9, 0x000000f9 },
-    { 0x00009af4, 0x000000f9, 0x000000f9 },
-    { 0x00009af8, 0x000000f9, 0x000000f9 },
-    { 0x00009afc, 0x000000f9, 0x000000f9 },
-};
-
-static const u32 ar5416Bank1_9160[][2] = {
-    { 0x000098b0, 0x02108421 },
-    { 0x000098ec, 0x00000008 },
-};
-
-static const u32 ar5416Bank2_9160[][2] = {
-    { 0x000098b0, 0x0e73ff17 },
-    { 0x000098e0, 0x00000420 },
-};
-
-static const u32 ar5416Bank3_9160[][3] = {
-    { 0x000098f0, 0x01400018, 0x01c00018 },
-};
-
-static const u32 ar5416Bank6_9160[][3] = {
-    { 0x0000989c, 0x00000000, 0x00000000 },
-    { 0x0000989c, 0x00000000, 0x00000000 },
-    { 0x0000989c, 0x00000000, 0x00000000 },
-    { 0x0000989c, 0x00e00000, 0x00e00000 },
-    { 0x0000989c, 0x005e0000, 0x005e0000 },
-    { 0x0000989c, 0x00120000, 0x00120000 },
-    { 0x0000989c, 0x00620000, 0x00620000 },
-    { 0x0000989c, 0x00020000, 0x00020000 },
-    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
-    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
-    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
-    { 0x0000989c, 0x40ff0000, 0x40ff0000 },
-    { 0x0000989c, 0x005f0000, 0x005f0000 },
-    { 0x0000989c, 0x00870000, 0x00870000 },
-    { 0x0000989c, 0x00f90000, 0x00f90000 },
-    { 0x0000989c, 0x007b0000, 0x007b0000 },
-    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
-    { 0x0000989c, 0x00f50000, 0x00f50000 },
-    { 0x0000989c, 0x00dc0000, 0x00dc0000 },
-    { 0x0000989c, 0x00110000, 0x00110000 },
-    { 0x0000989c, 0x006100a8, 0x006100a8 },
-    { 0x0000989c, 0x004210a2, 0x004210a2 },
-    { 0x0000989c, 0x0014008f, 0x0014008f },
-    { 0x0000989c, 0x00c40003, 0x00c40003 },
-    { 0x0000989c, 0x003000f2, 0x003000f2 },
-    { 0x0000989c, 0x00440016, 0x00440016 },
-    { 0x0000989c, 0x00410040, 0x00410040 },
-    { 0x0000989c, 0x0001805e, 0x0001805e },
-    { 0x0000989c, 0x0000c0ab, 0x0000c0ab },
-    { 0x0000989c, 0x000000f1, 0x000000f1 },
-    { 0x0000989c, 0x00002081, 0x00002081 },
-    { 0x0000989c, 0x000000d4, 0x000000d4 },
-    { 0x000098d0, 0x0000000f, 0x0010000f },
-};
-
-static const u32 ar5416Bank6TPC_9160[][3] = {
-    { 0x0000989c, 0x00000000, 0x00000000 },
-    { 0x0000989c, 0x00000000, 0x00000000 },
-    { 0x0000989c, 0x00000000, 0x00000000 },
-    { 0x0000989c, 0x00e00000, 0x00e00000 },
-    { 0x0000989c, 0x005e0000, 0x005e0000 },
-    { 0x0000989c, 0x00120000, 0x00120000 },
-    { 0x0000989c, 0x00620000, 0x00620000 },
-    { 0x0000989c, 0x00020000, 0x00020000 },
-    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
-    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
-    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
-    { 0x0000989c, 0x40ff0000, 0x40ff0000 },
-    { 0x0000989c, 0x005f0000, 0x005f0000 },
-    { 0x0000989c, 0x00870000, 0x00870000 },
-    { 0x0000989c, 0x00f90000, 0x00f90000 },
-    { 0x0000989c, 0x007b0000, 0x007b0000 },
-    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
-    { 0x0000989c, 0x00f50000, 0x00f50000 },
-    { 0x0000989c, 0x00dc0000, 0x00dc0000 },
-    { 0x0000989c, 0x00110000, 0x00110000 },
-    { 0x0000989c, 0x006100a8, 0x006100a8 },
-    { 0x0000989c, 0x00423022, 0x00423022 },
-    { 0x0000989c, 0x2014008f, 0x2014008f },
-    { 0x0000989c, 0x00c40002, 0x00c40002 },
-    { 0x0000989c, 0x003000f2, 0x003000f2 },
-    { 0x0000989c, 0x00440016, 0x00440016 },
-    { 0x0000989c, 0x00410040, 0x00410040 },
-    { 0x0000989c, 0x0001805e, 0x0001805e },
-    { 0x0000989c, 0x0000c0ab, 0x0000c0ab },
-    { 0x0000989c, 0x000000e1, 0x000000e1 },
-    { 0x0000989c, 0x00007080, 0x00007080 },
-    { 0x0000989c, 0x000000d4, 0x000000d4 },
-    { 0x000098d0, 0x0000000f, 0x0010000f },
-};
-
-static const u32 ar5416Bank7_9160[][2] = {
-    { 0x0000989c, 0x00000500 },
-    { 0x0000989c, 0x00000800 },
-    { 0x000098cc, 0x0000000e },
-};
-
-static u32 ar5416Addac_9160[][2] = {
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x000000c0 },
-    {0x0000989c,  0x00000018 },
-    {0x0000989c,  0x00000004 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x000000c0 },
-    {0x0000989c,  0x00000019 },
-    {0x0000989c,  0x00000004 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000004 },
-    {0x0000989c,  0x00000003 },
-    {0x0000989c,  0x00000008 },
-    {0x0000989c,  0x00000000 },
-    {0x000098cc,  0x00000000 },
-};
-
-static u32 ar5416Addac_91601_1[][2] = {
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x000000c0 },
-    {0x0000989c,  0x00000018 },
-    {0x0000989c,  0x00000004 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x000000c0 },
-    {0x0000989c,  0x00000019 },
-    {0x0000989c,  0x00000004 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x000098cc,  0x00000000 },
-};
-
-/* XXX 9280 1 */
 static const u32 ar9280Modes_9280[][6] = {
     { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 },
     { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 },
@@ -6112,7 +4139,8 @@ static const u_int32_t ar9287Common_9287_1_1[][2] = {
 
 /*
  * For Japanese regulatory requirements, 2484 MHz requires the following three
- * registers be programmed differently from the channel between 2412 and 2472 MHz.
+ * registers be programmed differently from the channel between 2412 and
+ * 2472 MHz.
  */
 static const u_int32_t ar9287Common_normal_cck_fir_coeff_92871_1[][2] = {
     { 0x0000a1f4, 0x00fffeff },
@@ -7198,3 +5226,5 @@ static const u_int32_t ar9271Modes_high_power_tx_gain_9271[][6] = {
     { 0x0000a3dc, 0x06318c63, 0x06318c63, 0x06318c63, 0x06318c63, 0x06318c63 },
     { 0x0000a3e0, 0x00000063, 0x00000063, 0x00000063, 0x00000063, 0x00000063 },
 };
+
+#endif /* INITVALS_9002_10_H */
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index f695437..9ea4595 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -21,7 +21,9 @@
 #include "hw.h"
 #include "hw-ops.h"
 #include "rc.h"
-#include "initvals.h"
+#include "ar5008_initvals.h"
+#include "ar9001_initvals.h"
+#include "ar9002_initvals.h"
 
 #define ATH9K_CLOCK_RATE_CCK		22
 #define ATH9K_CLOCK_RATE_5GHZ_OFDM	40
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 103+ messages in thread

* [PATCH v3 32/97] ath9k_hw: add initvals for the AR9003 hardware family
  2010-04-15 21:38 [PATCH v3 00/97] ath9k: add AR9003 support Luis R. Rodriguez
                   ` (30 preceding siblings ...)
  2010-04-15 21:38 ` [PATCH v3 31/97] ath9k_hw: split initvals.h by hardware family Luis R. Rodriguez
@ 2010-04-15 21:38 ` Luis R. Rodriguez
  2010-04-15 21:38 ` [PATCH v3 33/97] ath9k_hw: add helpers for processing the AR9003 INI Luis R. Rodriguez
                   ` (64 subsequent siblings)
  96 siblings, 0 replies; 103+ messages in thread
From: Luis R. Rodriguez @ 2010-04-15 21:38 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Luis R. Rodriguez

The AR9003 hardware family now initializes hardware by block
components and into stages: pre, core and init.

Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/ar9003_initvals.h | 1793 ++++++++++++++++++++++
 drivers/net/wireless/ath/ath9k/hw.c              |   73 +
 drivers/net/wireless/ath/ath9k/hw.h              |   13 +
 3 files changed, 1879 insertions(+), 0 deletions(-)
 create mode 100644 drivers/net/wireless/ath/ath9k/ar9003_initvals.h

diff --git a/drivers/net/wireless/ath/ath9k/ar9003_initvals.h b/drivers/net/wireless/ath/ath9k/ar9003_initvals.h
new file mode 100644
index 0000000..e0391b1
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/ar9003_initvals.h
@@ -0,0 +1,1793 @@
+/*
+ * Copyright (c) 2010 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef INITVALS_9003_H
+#define INITVALS_9003_H
+
+/* AR9003 2.0 */
+
+static const u32 ar9300_2p0_radio_postamble[][5] = {
+	/* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
+	{0x0001609c, 0x0dd08f29, 0x0dd08f29, 0x0b283f31, 0x0b283f31},
+	{0x000160ac, 0xa4653c00, 0xa4653c00, 0x24652800, 0x24652800},
+	{0x000160b0, 0x03284f3e, 0x03284f3e, 0x05d08f20, 0x05d08f20},
+	{0x0001610c, 0x08000000, 0x00000000, 0x00000000, 0x00000000},
+	{0x0001650c, 0x08000000, 0x00000000, 0x00000000, 0x00000000},
+	{0x0001690c, 0x08000000, 0x00000000, 0x00000000, 0x00000000},
+};
+
+static const u32 ar9300Modes_lowest_ob_db_tx_gain_table_2p0[][5] = {
+	/* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
+	{0x0000a410, 0x000050da, 0x000050da, 0x000050da, 0x000050da},
+	{0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+	{0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002},
+	{0x0000a508, 0x0a000020, 0x0a000020, 0x08000004, 0x08000004},
+	{0x0000a50c, 0x10000023, 0x10000023, 0x0b000200, 0x0b000200},
+	{0x0000a510, 0x16000220, 0x16000220, 0x0f000202, 0x0f000202},
+	{0x0000a514, 0x1c000223, 0x1c000223, 0x12000400, 0x12000400},
+	{0x0000a518, 0x21020220, 0x21020220, 0x16000402, 0x16000402},
+	{0x0000a51c, 0x27020223, 0x27020223, 0x19000404, 0x19000404},
+	{0x0000a520, 0x2b022220, 0x2b022220, 0x1c000603, 0x1c000603},
+	{0x0000a524, 0x2f022222, 0x2f022222, 0x21000a02, 0x21000a02},
+	{0x0000a528, 0x34022225, 0x34022225, 0x25000a04, 0x25000a04},
+	{0x0000a52c, 0x3a02222a, 0x3a02222a, 0x28000a20, 0x28000a20},
+	{0x0000a530, 0x3e02222c, 0x3e02222c, 0x2c000e20, 0x2c000e20},
+	{0x0000a534, 0x4202242a, 0x4202242a, 0x30000e22, 0x30000e22},
+	{0x0000a538, 0x4702244a, 0x4702244a, 0x34000e24, 0x34000e24},
+	{0x0000a53c, 0x4b02244c, 0x4b02244c, 0x38001640, 0x38001640},
+	{0x0000a540, 0x4e02246c, 0x4e02246c, 0x3c001660, 0x3c001660},
+	{0x0000a544, 0x5302266c, 0x5302266c, 0x3f001861, 0x3f001861},
+	{0x0000a548, 0x5702286c, 0x5702286c, 0x43001a81, 0x43001a81},
+	{0x0000a54c, 0x5c04286b, 0x5c04286b, 0x47001a83, 0x47001a83},
+	{0x0000a550, 0x61042a6c, 0x61042a6c, 0x4a001c84, 0x4a001c84},
+	{0x0000a554, 0x66062a6c, 0x66062a6c, 0x4e001ce3, 0x4e001ce3},
+	{0x0000a558, 0x6b062e6c, 0x6b062e6c, 0x52001ce5, 0x52001ce5},
+	{0x0000a55c, 0x7006308c, 0x7006308c, 0x56001ce9, 0x56001ce9},
+	{0x0000a560, 0x730a308a, 0x730a308a, 0x5a001ceb, 0x5a001ceb},
+	{0x0000a564, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
+	{0x0000a568, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
+	{0x0000a56c, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
+	{0x0000a570, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
+	{0x0000a574, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
+	{0x0000a578, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
+	{0x0000a57c, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
+	{0x0000a580, 0x00800000, 0x00800000, 0x00800000, 0x00800000},
+	{0x0000a584, 0x06800003, 0x06800003, 0x04800002, 0x04800002},
+	{0x0000a588, 0x0a800020, 0x0a800020, 0x08800004, 0x08800004},
+	{0x0000a58c, 0x10800023, 0x10800023, 0x0b800200, 0x0b800200},
+	{0x0000a590, 0x16800220, 0x16800220, 0x0f800202, 0x0f800202},
+	{0x0000a594, 0x1c800223, 0x1c800223, 0x12800400, 0x12800400},
+	{0x0000a598, 0x21820220, 0x21820220, 0x16800402, 0x16800402},
+	{0x0000a59c, 0x27820223, 0x27820223, 0x19800404, 0x19800404},
+	{0x0000a5a0, 0x2b822220, 0x2b822220, 0x1c800603, 0x1c800603},
+	{0x0000a5a4, 0x2f822222, 0x2f822222, 0x21800a02, 0x21800a02},
+	{0x0000a5a8, 0x34822225, 0x34822225, 0x25800a04, 0x25800a04},
+	{0x0000a5ac, 0x3a82222a, 0x3a82222a, 0x28800a20, 0x28800a20},
+	{0x0000a5b0, 0x3e82222c, 0x3e82222c, 0x2c800e20, 0x2c800e20},
+	{0x0000a5b4, 0x4282242a, 0x4282242a, 0x30800e22, 0x30800e22},
+	{0x0000a5b8, 0x4782244a, 0x4782244a, 0x34800e24, 0x34800e24},
+	{0x0000a5bc, 0x4b82244c, 0x4b82244c, 0x38801640, 0x38801640},
+	{0x0000a5c0, 0x4e82246c, 0x4e82246c, 0x3c801660, 0x3c801660},
+	{0x0000a5c4, 0x5382266c, 0x5382266c, 0x3f801861, 0x3f801861},
+	{0x0000a5c8, 0x5782286c, 0x5782286c, 0x43801a81, 0x43801a81},
+	{0x0000a5cc, 0x5c84286b, 0x5c84286b, 0x47801a83, 0x47801a83},
+	{0x0000a5d0, 0x61842a6c, 0x61842a6c, 0x4a801c84, 0x4a801c84},
+	{0x0000a5d4, 0x66862a6c, 0x66862a6c, 0x4e801ce3, 0x4e801ce3},
+	{0x0000a5d8, 0x6b862e6c, 0x6b862e6c, 0x52801ce5, 0x52801ce5},
+	{0x0000a5dc, 0x7086308c, 0x7086308c, 0x56801ce9, 0x56801ce9},
+	{0x0000a5e0, 0x738a308a, 0x738a308a, 0x5a801ceb, 0x5a801ceb},
+	{0x0000a5e4, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
+	{0x0000a5e8, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
+	{0x0000a5ec, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
+	{0x0000a5f0, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
+	{0x0000a5f4, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
+	{0x0000a5f8, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
+	{0x0000a5fc, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
+	{0x00016044, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
+	{0x00016048, 0x60001a61, 0x60001a61, 0x60001a61, 0x60001a61},
+	{0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
+	{0x00016444, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
+	{0x00016448, 0x60001a61, 0x60001a61, 0x60001a61, 0x60001a61},
+	{0x00016468, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
+	{0x00016844, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
+	{0x00016848, 0x60001a61, 0x60001a61, 0x60001a61, 0x60001a61},
+	{0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
+};
+
+static const u32 ar9300Modes_fast_clock_2p0[][3] = {
+	/* Addr      5G_HT20     5G_HT40   */
+	{0x00001030, 0x00000268, 0x000004d0},
+	{0x00001070, 0x0000018c, 0x00000318},
+	{0x000010b0, 0x00000fd0, 0x00001fa0},
+	{0x00008014, 0x044c044c, 0x08980898},
+	{0x0000801c, 0x148ec02b, 0x148ec057},
+	{0x00008318, 0x000044c0, 0x00008980},
+	{0x00009e00, 0x03721821, 0x03721821},
+	{0x0000a230, 0x0000000b, 0x00000016},
+	{0x0000a254, 0x00000898, 0x00001130},
+};
+
+static const u32 ar9300_2p0_radio_core[][2] = {
+	/* Addr      allmodes  */
+	{0x00016000, 0x36db6db6},
+	{0x00016004, 0x6db6db40},
+	{0x00016008, 0x73f00000},
+	{0x0001600c, 0x00000000},
+	{0x00016040, 0x7f80fff8},
+	{0x0001604c, 0x76d005b5},
+	{0x00016050, 0x556cf031},
+	{0x00016054, 0x43449440},
+	{0x00016058, 0x0c51c92c},
+	{0x0001605c, 0x3db7fffc},
+	{0x00016060, 0xfffffffc},
+	{0x00016064, 0x000f0278},
+	{0x0001606c, 0x6db60000},
+	{0x00016080, 0x00000000},
+	{0x00016084, 0x0e48048c},
+	{0x00016088, 0x54214514},
+	{0x0001608c, 0x119f481e},
+	{0x00016090, 0x24926490},
+	{0x00016098, 0xd2888888},
+	{0x000160a0, 0x0a108ffe},
+	{0x000160a4, 0x812fc370},
+	{0x000160a8, 0x423c8000},
+	{0x000160b4, 0x92480080},
+	{0x000160c0, 0x00adb6d0},
+	{0x000160c4, 0x6db6db60},
+	{0x000160c8, 0x6db6db6c},
+	{0x000160cc, 0x01e6c000},
+	{0x00016100, 0x3fffbe01},
+	{0x00016104, 0xfff80000},
+	{0x00016108, 0x00080010},
+	{0x00016140, 0x10804008},
+	{0x00016144, 0x02084080},
+	{0x00016148, 0x00000000},
+	{0x00016280, 0x058a0001},
+	{0x00016284, 0x3d840208},
+	{0x00016288, 0x01a20408},
+	{0x0001628c, 0x00038c07},
+	{0x00016290, 0x40000004},
+	{0x00016294, 0x458aa14f},
+	{0x00016380, 0x00000000},
+	{0x00016384, 0x00000000},
+	{0x00016388, 0x00800700},
+	{0x0001638c, 0x00800700},
+	{0x00016390, 0x00800700},
+	{0x00016394, 0x00000000},
+	{0x00016398, 0x00000000},
+	{0x0001639c, 0x00000000},
+	{0x000163a0, 0x00000001},
+	{0x000163a4, 0x00000001},
+	{0x000163a8, 0x00000000},
+	{0x000163ac, 0x00000000},
+	{0x000163b0, 0x00000000},
+	{0x000163b4, 0x00000000},
+	{0x000163b8, 0x00000000},
+	{0x000163bc, 0x00000000},
+	{0x000163c0, 0x000000a0},
+	{0x000163c4, 0x000c0000},
+	{0x000163c8, 0x14021402},
+	{0x000163cc, 0x00001402},
+	{0x000163d0, 0x00000000},
+	{0x000163d4, 0x00000000},
+	{0x00016400, 0x36db6db6},
+	{0x00016404, 0x6db6db40},
+	{0x00016408, 0x73f00000},
+	{0x0001640c, 0x00000000},
+	{0x00016440, 0x7f80fff8},
+	{0x0001644c, 0x76d005b5},
+	{0x00016450, 0x556cf031},
+	{0x00016454, 0x43449440},
+	{0x00016458, 0x0c51c92c},
+	{0x0001645c, 0x3db7fffc},
+	{0x00016460, 0xfffffffc},
+	{0x00016464, 0x000f0278},
+	{0x0001646c, 0x6db60000},
+	{0x00016500, 0x3fffbe01},
+	{0x00016504, 0xfff80000},
+	{0x00016508, 0x00080010},
+	{0x00016540, 0x10804008},
+	{0x00016544, 0x02084080},
+	{0x00016548, 0x00000000},
+	{0x00016780, 0x00000000},
+	{0x00016784, 0x00000000},
+	{0x00016788, 0x00800700},
+	{0x0001678c, 0x00800700},
+	{0x00016790, 0x00800700},
+	{0x00016794, 0x00000000},
+	{0x00016798, 0x00000000},
+	{0x0001679c, 0x00000000},
+	{0x000167a0, 0x00000001},
+	{0x000167a4, 0x00000001},
+	{0x000167a8, 0x00000000},
+	{0x000167ac, 0x00000000},
+	{0x000167b0, 0x00000000},
+	{0x000167b4, 0x00000000},
+	{0x000167b8, 0x00000000},
+	{0x000167bc, 0x00000000},
+	{0x000167c0, 0x000000a0},
+	{0x000167c4, 0x000c0000},
+	{0x000167c8, 0x14021402},
+	{0x000167cc, 0x00001402},
+	{0x000167d0, 0x00000000},
+	{0x000167d4, 0x00000000},
+	{0x00016800, 0x36db6db6},
+	{0x00016804, 0x6db6db40},
+	{0x00016808, 0x73f00000},
+	{0x0001680c, 0x00000000},
+	{0x00016840, 0x7f80fff8},
+	{0x0001684c, 0x76d005b5},
+	{0x00016850, 0x556cf031},
+	{0x00016854, 0x43449440},
+	{0x00016858, 0x0c51c92c},
+	{0x0001685c, 0x3db7fffc},
+	{0x00016860, 0xfffffffc},
+	{0x00016864, 0x000f0278},
+	{0x0001686c, 0x6db60000},
+	{0x00016900, 0x3fffbe01},
+	{0x00016904, 0xfff80000},
+	{0x00016908, 0x00080010},
+	{0x00016940, 0x10804008},
+	{0x00016944, 0x02084080},
+	{0x00016948, 0x00000000},
+	{0x00016b80, 0x00000000},
+	{0x00016b84, 0x00000000},
+	{0x00016b88, 0x00800700},
+	{0x00016b8c, 0x00800700},
+	{0x00016b90, 0x00800700},
+	{0x00016b94, 0x00000000},
+	{0x00016b98, 0x00000000},
+	{0x00016b9c, 0x00000000},
+	{0x00016ba0, 0x00000001},
+	{0x00016ba4, 0x00000001},
+	{0x00016ba8, 0x00000000},
+	{0x00016bac, 0x00000000},
+	{0x00016bb0, 0x00000000},
+	{0x00016bb4, 0x00000000},
+	{0x00016bb8, 0x00000000},
+	{0x00016bbc, 0x00000000},
+	{0x00016bc0, 0x000000a0},
+	{0x00016bc4, 0x000c0000},
+	{0x00016bc8, 0x14021402},
+	{0x00016bcc, 0x00001402},
+	{0x00016bd0, 0x00000000},
+	{0x00016bd4, 0x00000000},
+};
+
+static const u32 ar9300Common_rx_gain_table_merlin_2p0[][2] = {
+	/* Addr      allmodes  */
+	{0x0000a000, 0x02000101},
+	{0x0000a004, 0x02000102},
+	{0x0000a008, 0x02000103},
+	{0x0000a00c, 0x02000104},
+	{0x0000a010, 0x02000200},
+	{0x0000a014, 0x02000201},
+	{0x0000a018, 0x02000202},
+	{0x0000a01c, 0x02000203},
+	{0x0000a020, 0x02000204},
+	{0x0000a024, 0x02000205},
+	{0x0000a028, 0x02000208},
+	{0x0000a02c, 0x02000302},
+	{0x0000a030, 0x02000303},
+	{0x0000a034, 0x02000304},
+	{0x0000a038, 0x02000400},
+	{0x0000a03c, 0x02010300},
+	{0x0000a040, 0x02010301},
+	{0x0000a044, 0x02010302},
+	{0x0000a048, 0x02000500},
+	{0x0000a04c, 0x02010400},
+	{0x0000a050, 0x02020300},
+	{0x0000a054, 0x02020301},
+	{0x0000a058, 0x02020302},
+	{0x0000a05c, 0x02020303},
+	{0x0000a060, 0x02020400},
+	{0x0000a064, 0x02030300},
+	{0x0000a068, 0x02030301},
+	{0x0000a06c, 0x02030302},
+	{0x0000a070, 0x02030303},
+	{0x0000a074, 0x02030400},
+	{0x0000a078, 0x02040300},
+	{0x0000a07c, 0x02040301},
+	{0x0000a080, 0x02040302},
+	{0x0000a084, 0x02040303},
+	{0x0000a088, 0x02030500},
+	{0x0000a08c, 0x02040400},
+	{0x0000a090, 0x02050203},
+	{0x0000a094, 0x02050204},
+	{0x0000a098, 0x02050205},
+	{0x0000a09c, 0x02040500},
+	{0x0000a0a0, 0x02050301},
+	{0x0000a0a4, 0x02050302},
+	{0x0000a0a8, 0x02050303},
+	{0x0000a0ac, 0x02050400},
+	{0x0000a0b0, 0x02050401},
+	{0x0000a0b4, 0x02050402},
+	{0x0000a0b8, 0x02050403},
+	{0x0000a0bc, 0x02050500},
+	{0x0000a0c0, 0x02050501},
+	{0x0000a0c4, 0x02050502},
+	{0x0000a0c8, 0x02050503},
+	{0x0000a0cc, 0x02050504},
+	{0x0000a0d0, 0x02050600},
+	{0x0000a0d4, 0x02050601},
+	{0x0000a0d8, 0x02050602},
+	{0x0000a0dc, 0x02050603},
+	{0x0000a0e0, 0x02050604},
+	{0x0000a0e4, 0x02050700},
+	{0x0000a0e8, 0x02050701},
+	{0x0000a0ec, 0x02050702},
+	{0x0000a0f0, 0x02050703},
+	{0x0000a0f4, 0x02050704},
+	{0x0000a0f8, 0x02050705},
+	{0x0000a0fc, 0x02050708},
+	{0x0000a100, 0x02050709},
+	{0x0000a104, 0x0205070a},
+	{0x0000a108, 0x0205070b},
+	{0x0000a10c, 0x0205070c},
+	{0x0000a110, 0x0205070d},
+	{0x0000a114, 0x02050710},
+	{0x0000a118, 0x02050711},
+	{0x0000a11c, 0x02050712},
+	{0x0000a120, 0x02050713},
+	{0x0000a124, 0x02050714},
+	{0x0000a128, 0x02050715},
+	{0x0000a12c, 0x02050730},
+	{0x0000a130, 0x02050731},
+	{0x0000a134, 0x02050732},
+	{0x0000a138, 0x02050733},
+	{0x0000a13c, 0x02050734},
+	{0x0000a140, 0x02050735},
+	{0x0000a144, 0x02050750},
+	{0x0000a148, 0x02050751},
+	{0x0000a14c, 0x02050752},
+	{0x0000a150, 0x02050753},
+	{0x0000a154, 0x02050754},
+	{0x0000a158, 0x02050755},
+	{0x0000a15c, 0x02050770},
+	{0x0000a160, 0x02050771},
+	{0x0000a164, 0x02050772},
+	{0x0000a168, 0x02050773},
+	{0x0000a16c, 0x02050774},
+	{0x0000a170, 0x02050775},
+	{0x0000a174, 0x00000776},
+	{0x0000a178, 0x00000776},
+	{0x0000a17c, 0x00000776},
+	{0x0000a180, 0x00000776},
+	{0x0000a184, 0x00000776},
+	{0x0000a188, 0x00000776},
+	{0x0000a18c, 0x00000776},
+	{0x0000a190, 0x00000776},
+	{0x0000a194, 0x00000776},
+	{0x0000a198, 0x00000776},
+	{0x0000a19c, 0x00000776},
+	{0x0000a1a0, 0x00000776},
+	{0x0000a1a4, 0x00000776},
+	{0x0000a1a8, 0x00000776},
+	{0x0000a1ac, 0x00000776},
+	{0x0000a1b0, 0x00000776},
+	{0x0000a1b4, 0x00000776},
+	{0x0000a1b8, 0x00000776},
+	{0x0000a1bc, 0x00000776},
+	{0x0000a1c0, 0x00000776},
+	{0x0000a1c4, 0x00000776},
+	{0x0000a1c8, 0x00000776},
+	{0x0000a1cc, 0x00000776},
+	{0x0000a1d0, 0x00000776},
+	{0x0000a1d4, 0x00000776},
+	{0x0000a1d8, 0x00000776},
+	{0x0000a1dc, 0x00000776},
+	{0x0000a1e0, 0x00000776},
+	{0x0000a1e4, 0x00000776},
+	{0x0000a1e8, 0x00000776},
+	{0x0000a1ec, 0x00000776},
+	{0x0000a1f0, 0x00000776},
+	{0x0000a1f4, 0x00000776},
+	{0x0000a1f8, 0x00000776},
+	{0x0000a1fc, 0x00000776},
+	{0x0000b000, 0x02000101},
+	{0x0000b004, 0x02000102},
+	{0x0000b008, 0x02000103},
+	{0x0000b00c, 0x02000104},
+	{0x0000b010, 0x02000200},
+	{0x0000b014, 0x02000201},
+	{0x0000b018, 0x02000202},
+	{0x0000b01c, 0x02000203},
+	{0x0000b020, 0x02000204},
+	{0x0000b024, 0x02000205},
+	{0x0000b028, 0x02000208},
+	{0x0000b02c, 0x02000302},
+	{0x0000b030, 0x02000303},
+	{0x0000b034, 0x02000304},
+	{0x0000b038, 0x02000400},
+	{0x0000b03c, 0x02010300},
+	{0x0000b040, 0x02010301},
+	{0x0000b044, 0x02010302},
+	{0x0000b048, 0x02000500},
+	{0x0000b04c, 0x02010400},
+	{0x0000b050, 0x02020300},
+	{0x0000b054, 0x02020301},
+	{0x0000b058, 0x02020302},
+	{0x0000b05c, 0x02020303},
+	{0x0000b060, 0x02020400},
+	{0x0000b064, 0x02030300},
+	{0x0000b068, 0x02030301},
+	{0x0000b06c, 0x02030302},
+	{0x0000b070, 0x02030303},
+	{0x0000b074, 0x02030400},
+	{0x0000b078, 0x02040300},
+	{0x0000b07c, 0x02040301},
+	{0x0000b080, 0x02040302},
+	{0x0000b084, 0x02040303},
+	{0x0000b088, 0x02030500},
+	{0x0000b08c, 0x02040400},
+	{0x0000b090, 0x02050203},
+	{0x0000b094, 0x02050204},
+	{0x0000b098, 0x02050205},
+	{0x0000b09c, 0x02040500},
+	{0x0000b0a0, 0x02050301},
+	{0x0000b0a4, 0x02050302},
+	{0x0000b0a8, 0x02050303},
+	{0x0000b0ac, 0x02050400},
+	{0x0000b0b0, 0x02050401},
+	{0x0000b0b4, 0x02050402},
+	{0x0000b0b8, 0x02050403},
+	{0x0000b0bc, 0x02050500},
+	{0x0000b0c0, 0x02050501},
+	{0x0000b0c4, 0x02050502},
+	{0x0000b0c8, 0x02050503},
+	{0x0000b0cc, 0x02050504},
+	{0x0000b0d0, 0x02050600},
+	{0x0000b0d4, 0x02050601},
+	{0x0000b0d8, 0x02050602},
+	{0x0000b0dc, 0x02050603},
+	{0x0000b0e0, 0x02050604},
+	{0x0000b0e4, 0x02050700},
+	{0x0000b0e8, 0x02050701},
+	{0x0000b0ec, 0x02050702},
+	{0x0000b0f0, 0x02050703},
+	{0x0000b0f4, 0x02050704},
+	{0x0000b0f8, 0x02050705},
+	{0x0000b0fc, 0x02050708},
+	{0x0000b100, 0x02050709},
+	{0x0000b104, 0x0205070a},
+	{0x0000b108, 0x0205070b},
+	{0x0000b10c, 0x0205070c},
+	{0x0000b110, 0x0205070d},
+	{0x0000b114, 0x02050710},
+	{0x0000b118, 0x02050711},
+	{0x0000b11c, 0x02050712},
+	{0x0000b120, 0x02050713},
+	{0x0000b124, 0x02050714},
+	{0x0000b128, 0x02050715},
+	{0x0000b12c, 0x02050730},
+	{0x0000b130, 0x02050731},
+	{0x0000b134, 0x02050732},
+	{0x0000b138, 0x02050733},
+	{0x0000b13c, 0x02050734},
+	{0x0000b140, 0x02050735},
+	{0x0000b144, 0x02050750},
+	{0x0000b148, 0x02050751},
+	{0x0000b14c, 0x02050752},
+	{0x0000b150, 0x02050753},
+	{0x0000b154, 0x02050754},
+	{0x0000b158, 0x02050755},
+	{0x0000b15c, 0x02050770},
+	{0x0000b160, 0x02050771},
+	{0x0000b164, 0x02050772},
+	{0x0000b168, 0x02050773},
+	{0x0000b16c, 0x02050774},
+	{0x0000b170, 0x02050775},
+	{0x0000b174, 0x00000776},
+	{0x0000b178, 0x00000776},
+	{0x0000b17c, 0x00000776},
+	{0x0000b180, 0x00000776},
+	{0x0000b184, 0x00000776},
+	{0x0000b188, 0x00000776},
+	{0x0000b18c, 0x00000776},
+	{0x0000b190, 0x00000776},
+	{0x0000b194, 0x00000776},
+	{0x0000b198, 0x00000776},
+	{0x0000b19c, 0x00000776},
+	{0x0000b1a0, 0x00000776},
+	{0x0000b1a4, 0x00000776},
+	{0x0000b1a8, 0x00000776},
+	{0x0000b1ac, 0x00000776},
+	{0x0000b1b0, 0x00000776},
+	{0x0000b1b4, 0x00000776},
+	{0x0000b1b8, 0x00000776},
+	{0x0000b1bc, 0x00000776},
+	{0x0000b1c0, 0x00000776},
+	{0x0000b1c4, 0x00000776},
+	{0x0000b1c8, 0x00000776},
+	{0x0000b1cc, 0x00000776},
+	{0x0000b1d0, 0x00000776},
+	{0x0000b1d4, 0x00000776},
+	{0x0000b1d8, 0x00000776},
+	{0x0000b1dc, 0x00000776},
+	{0x0000b1e0, 0x00000776},
+	{0x0000b1e4, 0x00000776},
+	{0x0000b1e8, 0x00000776},
+	{0x0000b1ec, 0x00000776},
+	{0x0000b1f0, 0x00000776},
+	{0x0000b1f4, 0x00000776},
+	{0x0000b1f8, 0x00000776},
+	{0x0000b1fc, 0x00000776},
+};
+
+static const u32 ar9300_2p0_mac_postamble[][5] = {
+	/* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
+	{0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160},
+	{0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c},
+	{0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38},
+	{0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00},
+	{0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b},
+	{0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810},
+	{0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a},
+	{0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440},
+};
+
+static const u32 ar9300_2p0_soc_postamble[][5] = {
+	/* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
+	{0x00007010, 0x00000023, 0x00000023, 0x00000022, 0x00000022},
+};
+
+static const u32 ar9200_merlin_2p0_radio_core[][2] = {
+	/* Addr      common    */
+	{0x00007800, 0x00040000},
+	{0x00007804, 0xdb005012},
+	{0x00007808, 0x04924914},
+	{0x0000780c, 0x21084210},
+	{0x00007810, 0x6d801300},
+	{0x00007814, 0x0019beff},
+	{0x00007818, 0x07e41000},
+	{0x0000781c, 0x00392000},
+	{0x00007820, 0x92592480},
+	{0x00007824, 0x00040000},
+	{0x00007828, 0xdb005012},
+	{0x0000782c, 0x04924914},
+	{0x00007830, 0x21084210},
+	{0x00007834, 0x6d801300},
+	{0x00007838, 0x0019beff},
+	{0x0000783c, 0x07e40000},
+	{0x00007840, 0x00392000},
+	{0x00007844, 0x92592480},
+	{0x00007848, 0x00100000},
+	{0x0000784c, 0x773f0567},
+	{0x00007850, 0x54214514},
+	{0x00007854, 0x12035828},
+	{0x00007858, 0x92592692},
+	{0x0000785c, 0x00000000},
+	{0x00007860, 0x56400000},
+	{0x00007864, 0x0a8e370e},
+	{0x00007868, 0xc0102850},
+	{0x0000786c, 0x812d4000},
+	{0x00007870, 0x807ec400},
+	{0x00007874, 0x001b6db0},
+	{0x00007878, 0x00376b63},
+	{0x0000787c, 0x06db6db6},
+	{0x00007880, 0x006d8000},
+	{0x00007884, 0xffeffffe},
+	{0x00007888, 0xffeffffe},
+	{0x0000788c, 0x00010000},
+	{0x00007890, 0x02060aeb},
+	{0x00007894, 0x5a108000},
+};
+
+static const u32 ar9300_2p0_baseband_postamble[][5] = {
+	/* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
+	{0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8005, 0xd00a8005},
+	{0x00009820, 0x206a022e, 0x206a022e, 0x206a012e, 0x206a012e},
+	{0x00009824, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0},
+	{0x00009828, 0x06903081, 0x06903081, 0x06903881, 0x06903881},
+	{0x0000982c, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4},
+	{0x00009830, 0x0000059c, 0x0000059c, 0x0000059c, 0x0000059c},
+	{0x00009c00, 0x00000044, 0x000000c4, 0x000000c4, 0x00000044},
+	{0x00009e00, 0x0372161e, 0x0372161e, 0x037216a0, 0x037216a0},
+	{0x00009e04, 0x00802020, 0x00802020, 0x00802020, 0x00802020},
+	{0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000e2, 0x6c4000e2},
+	{0x00009e10, 0x7ec88d2e, 0x7ec88d2e, 0x7ec84d2e, 0x7ec84d2e},
+	{0x00009e14, 0x31395d5e, 0x3139605e, 0x3139605e, 0x31395d5e},
+	{0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+	{0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c},
+	{0x00009e20, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce},
+	{0x00009e2c, 0x0000001c, 0x0000001c, 0x00000021, 0x00000021},
+	{0x00009e44, 0x02321e27, 0x02321e27, 0x02282324, 0x02282324},
+	{0x00009e48, 0x5030201a, 0x5030201a, 0x50302010, 0x50302010},
+	{0x00009fc8, 0x0003f000, 0x0003f000, 0x0001a000, 0x0001a000},
+	{0x0000a204, 0x000037c0, 0x000037c4, 0x000037c4, 0x000037c0},
+	{0x0000a208, 0x00000104, 0x00000104, 0x00000004, 0x00000004},
+	{0x0000a230, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b},
+	{0x0000a238, 0xffb81018, 0xffb81018, 0xffb81018, 0xffb81018},
+	{0x0000a250, 0x00000000, 0x00000000, 0x00000210, 0x00000108},
+	{0x0000a254, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898},
+	{0x0000a258, 0x02020002, 0x02020002, 0x02020002, 0x02020002},
+	{0x0000a25c, 0x01000e0e, 0x01000e0e, 0x01000e0e, 0x01000e0e},
+	{0x0000a260, 0x0a021501, 0x0a021501, 0x3a021501, 0x3a021501},
+	{0x0000a264, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e},
+	{0x0000a280, 0x00000007, 0x00000007, 0x0000000b, 0x0000000b},
+	{0x0000a284, 0x00000000, 0x00000000, 0x00000150, 0x00000150},
+	{0x0000a288, 0x00000110, 0x00000110, 0x00000110, 0x00000110},
+	{0x0000a28c, 0x00022222, 0x00022222, 0x00022222, 0x00022222},
+	{0x0000a2c4, 0x00158d18, 0x00158d18, 0x00158d18, 0x00158d18},
+	{0x0000a2d0, 0x00071981, 0x00071981, 0x00071981, 0x00071982},
+	{0x0000a2d8, 0xf999a83a, 0xf999a83a, 0xf999a83a, 0xf999a83a},
+	{0x0000a358, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+	{0x0000a830, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c},
+	{0x0000ae04, 0x00800000, 0x00800000, 0x00800000, 0x00800000},
+	{0x0000ae18, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+	{0x0000ae1c, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c},
+	{0x0000ae20, 0x000001b5, 0x000001b5, 0x000001ce, 0x000001ce},
+	{0x0000b284, 0x00000000, 0x00000000, 0x00000150, 0x00000150},
+	{0x0000b830, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c},
+	{0x0000be04, 0x00800000, 0x00800000, 0x00800000, 0x00800000},
+	{0x0000be18, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+	{0x0000be1c, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c},
+	{0x0000be20, 0x000001b5, 0x000001b5, 0x000001ce, 0x000001ce},
+	{0x0000c284, 0x00000000, 0x00000000, 0x00000150, 0x00000150},
+};
+
+static const u32 ar9300_2p0_baseband_core[][2] = {
+	/* Addr      allmodes  */
+	{0x00009800, 0xafe68e30},
+	{0x00009804, 0xfd14e000},
+	{0x00009808, 0x9c0a9f6b},
+	{0x0000980c, 0x04900000},
+	{0x00009814, 0x9280c00a},
+	{0x00009818, 0x00000000},
+	{0x0000981c, 0x00020028},
+	{0x00009834, 0x5f3ca3de},
+	{0x00009838, 0x0108ecff},
+	{0x0000983c, 0x14750600},
+	{0x00009880, 0x201fff00},
+	{0x00009884, 0x00001042},
+	{0x000098a4, 0x00200400},
+	{0x000098b0, 0x52440bbe},
+	{0x000098d0, 0x004b6a8e},
+	{0x000098d4, 0x00000820},
+	{0x000098dc, 0x00000000},
+	{0x000098f0, 0x00000000},
+	{0x000098f4, 0x00000000},
+	{0x00009c04, 0xff55ff55},
+	{0x00009c08, 0x0320ff55},
+	{0x00009c0c, 0x00000000},
+	{0x00009c10, 0x00000000},
+	{0x00009c14, 0x00046384},
+	{0x00009c18, 0x05b6b440},
+	{0x00009c1c, 0x00b6b440},
+	{0x00009d00, 0xc080a333},
+	{0x00009d04, 0x40206c10},
+	{0x00009d08, 0x009c4060},
+	{0x00009d0c, 0x9883800a},
+	{0x00009d10, 0x01834061},
+	{0x00009d14, 0x00c0040b},
+	{0x00009d18, 0x00000000},
+	{0x00009e08, 0x0038233c},
+	{0x00009e24, 0x990bb515},
+	{0x00009e28, 0x0c6f0000},
+	{0x00009e30, 0x06336f77},
+	{0x00009e34, 0x6af6532f},
+	{0x00009e38, 0x0cc80c00},
+	{0x00009e3c, 0xcf946222},
+	{0x00009e40, 0x0d261820},
+	{0x00009e4c, 0x00001004},
+	{0x00009e50, 0x00ff03f1},
+	{0x00009e54, 0x00000000},
+	{0x00009fc0, 0x803e4788},
+	{0x00009fc4, 0x0001efb5},
+	{0x00009fcc, 0x40000014},
+	{0x00009fd0, 0x01193b93},
+	{0x0000a20c, 0x00000000},
+	{0x0000a220, 0x00000000},
+	{0x0000a224, 0x00000000},
+	{0x0000a228, 0x10002310},
+	{0x0000a22c, 0x01036a1e},
+	{0x0000a234, 0x10000fff},
+	{0x0000a23c, 0x00000000},
+	{0x0000a244, 0x0c000000},
+	{0x0000a2a0, 0x00000001},
+	{0x0000a2c0, 0x00000001},
+	{0x0000a2c8, 0x00000000},
+	{0x0000a2cc, 0x18c43433},
+	{0x0000a2d4, 0x00000000},
+	{0x0000a2dc, 0x00000000},
+	{0x0000a2e0, 0x00000000},
+	{0x0000a2e4, 0x00000000},
+	{0x0000a2e8, 0x00000000},
+	{0x0000a2ec, 0x00000000},
+	{0x0000a2f0, 0x00000000},
+	{0x0000a2f4, 0x00000000},
+	{0x0000a2f8, 0x00000000},
+	{0x0000a344, 0x00000000},
+	{0x0000a34c, 0x00000000},
+	{0x0000a350, 0x0000a000},
+	{0x0000a364, 0x00000000},
+	{0x0000a370, 0x00000000},
+	{0x0000a390, 0x00000001},
+	{0x0000a394, 0x00000444},
+	{0x0000a398, 0x001f0e0f},
+	{0x0000a39c, 0x0075393f},
+	{0x0000a3a0, 0xb79f6427},
+	{0x0000a3a4, 0x00000000},
+	{0x0000a3a8, 0xaaaaaaaa},
+	{0x0000a3ac, 0x3c466478},
+	{0x0000a3c0, 0x20202020},
+	{0x0000a3c4, 0x22222220},
+	{0x0000a3c8, 0x20200020},
+	{0x0000a3cc, 0x20202020},
+	{0x0000a3d0, 0x20202020},
+	{0x0000a3d4, 0x20202020},
+	{0x0000a3d8, 0x20202020},
+	{0x0000a3dc, 0x20202020},
+	{0x0000a3e0, 0x20202020},
+	{0x0000a3e4, 0x20202020},
+	{0x0000a3e8, 0x20202020},
+	{0x0000a3ec, 0x20202020},
+	{0x0000a3f0, 0x00000000},
+	{0x0000a3f4, 0x00000246},
+	{0x0000a3f8, 0x0cdbd380},
+	{0x0000a3fc, 0x000f0f01},
+	{0x0000a400, 0x8fa91f01},
+	{0x0000a404, 0x00000000},
+	{0x0000a408, 0x0e79e5c6},
+	{0x0000a40c, 0x00820820},
+	{0x0000a414, 0x1ce739ce},
+	{0x0000a418, 0x7d001dce},
+	{0x0000a41c, 0x1ce739ce},
+	{0x0000a420, 0x000001ce},
+	{0x0000a424, 0x1ce739ce},
+	{0x0000a428, 0x000001ce},
+	{0x0000a42c, 0x1ce739ce},
+	{0x0000a430, 0x1ce739ce},
+	{0x0000a434, 0x00000000},
+	{0x0000a438, 0x00001801},
+	{0x0000a43c, 0x00000000},
+	{0x0000a440, 0x00000000},
+	{0x0000a444, 0x00000000},
+	{0x0000a448, 0x07000080},
+	{0x0000a44c, 0x00000001},
+	{0x0000a450, 0x00010000},
+	{0x0000a458, 0x00000000},
+	{0x0000a600, 0x00000000},
+	{0x0000a604, 0x00000000},
+	{0x0000a608, 0x00000000},
+	{0x0000a60c, 0x00000000},
+	{0x0000a610, 0x00000000},
+	{0x0000a614, 0x00000000},
+	{0x0000a618, 0x00000000},
+	{0x0000a61c, 0x00000000},
+	{0x0000a620, 0x00000000},
+	{0x0000a624, 0x00000000},
+	{0x0000a628, 0x00000000},
+	{0x0000a62c, 0x00000000},
+	{0x0000a630, 0x00000000},
+	{0x0000a634, 0x00000000},
+	{0x0000a638, 0x00000000},
+	{0x0000a63c, 0x00000000},
+	{0x0000a640, 0x00000000},
+	{0x0000a644, 0x3ffd9d74},
+	{0x0000a648, 0x0048060a},
+	{0x0000a64c, 0x00000637},
+	{0x0000a670, 0x03020100},
+	{0x0000a674, 0x09080504},
+	{0x0000a678, 0x0d0c0b0a},
+	{0x0000a67c, 0x13121110},
+	{0x0000a680, 0x31301514},
+	{0x0000a684, 0x35343332},
+	{0x0000a688, 0x00000036},
+	{0x0000a690, 0x00000838},
+	{0x0000a7c0, 0x00000000},
+	{0x0000a7c4, 0xfffffffc},
+	{0x0000a7c8, 0x00000000},
+	{0x0000a7cc, 0x00000000},
+	{0x0000a7d0, 0x00000000},
+	{0x0000a7d4, 0x00000004},
+	{0x0000a7dc, 0x00000001},
+	{0x0000a8d0, 0x004b6a8e},
+	{0x0000a8d4, 0x00000820},
+	{0x0000a8dc, 0x00000000},
+	{0x0000a8f0, 0x00000000},
+	{0x0000a8f4, 0x00000000},
+	{0x0000b2d0, 0x00000080},
+	{0x0000b2d4, 0x00000000},
+	{0x0000b2dc, 0x00000000},
+	{0x0000b2e0, 0x00000000},
+	{0x0000b2e4, 0x00000000},
+	{0x0000b2e8, 0x00000000},
+	{0x0000b2ec, 0x00000000},
+	{0x0000b2f0, 0x00000000},
+	{0x0000b2f4, 0x00000000},
+	{0x0000b2f8, 0x00000000},
+	{0x0000b408, 0x0e79e5c0},
+	{0x0000b40c, 0x00820820},
+	{0x0000b420, 0x00000000},
+	{0x0000b8d0, 0x004b6a8e},
+	{0x0000b8d4, 0x00000820},
+	{0x0000b8dc, 0x00000000},
+	{0x0000b8f0, 0x00000000},
+	{0x0000b8f4, 0x00000000},
+	{0x0000c2d0, 0x00000080},
+	{0x0000c2d4, 0x00000000},
+	{0x0000c2dc, 0x00000000},
+	{0x0000c2e0, 0x00000000},
+	{0x0000c2e4, 0x00000000},
+	{0x0000c2e8, 0x00000000},
+	{0x0000c2ec, 0x00000000},
+	{0x0000c2f0, 0x00000000},
+	{0x0000c2f4, 0x00000000},
+	{0x0000c2f8, 0x00000000},
+	{0x0000c408, 0x0e79e5c0},
+	{0x0000c40c, 0x00820820},
+	{0x0000c420, 0x00000000},
+};
+
+static const u32 ar9300Modes_high_power_tx_gain_table_2p0[][5] = {
+	/* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
+	{0x0000a410, 0x000050d9, 0x000050d9, 0x000050da, 0x000050da},
+	{0x0000a500, 0x00020220, 0x00020220, 0x00000000, 0x00000000},
+	{0x0000a504, 0x06020223, 0x06020223, 0x04000002, 0x04000002},
+	{0x0000a508, 0x0b022220, 0x0b022220, 0x08000004, 0x08000004},
+	{0x0000a50c, 0x10022223, 0x10022223, 0x0b000200, 0x0b000200},
+	{0x0000a510, 0x17022620, 0x17022620, 0x0f000202, 0x0f000202},
+	{0x0000a514, 0x1b022622, 0x1b022622, 0x11000400, 0x11000400},
+	{0x0000a518, 0x1f022822, 0x1f022822, 0x15000402, 0x15000402},
+	{0x0000a51c, 0x24022842, 0x24022842, 0x19000404, 0x19000404},
+	{0x0000a520, 0x28042840, 0x28042840, 0x1b000603, 0x1b000603},
+	{0x0000a524, 0x2c042842, 0x2c042842, 0x1f000a02, 0x1f000a02},
+	{0x0000a528, 0x30042844, 0x30042844, 0x23000a04, 0x23000a04},
+	{0x0000a52c, 0x34042846, 0x34042846, 0x26000a20, 0x26000a20},
+	{0x0000a530, 0x39042869, 0x39042869, 0x2a000e20, 0x2a000e20},
+	{0x0000a534, 0x3d062869, 0x3d062869, 0x2e000e22, 0x2e000e22},
+	{0x0000a538, 0x44062c69, 0x44062c69, 0x31000e24, 0x31000e24},
+	{0x0000a53c, 0x48063069, 0x48063069, 0x34001640, 0x34001640},
+	{0x0000a540, 0x4c0a3065, 0x4c0a3065, 0x38001660, 0x38001660},
+	{0x0000a544, 0x500a3069, 0x500a3069, 0x3b001861, 0x3b001861},
+	{0x0000a548, 0x530a3469, 0x530a3469, 0x3e001a81, 0x3e001a81},
+	{0x0000a54c, 0x590a7464, 0x590a7464, 0x42001a83, 0x42001a83},
+	{0x0000a550, 0x5e0a7865, 0x5e0a7865, 0x44001c84, 0x44001c84},
+	{0x0000a554, 0x630a7e66, 0x630a7e66, 0x48001ce3, 0x48001ce3},
+	{0x0000a558, 0x680a7e89, 0x680a7e89, 0x4c001ce5, 0x4c001ce5},
+	{0x0000a55c, 0x6e0a7e8c, 0x6e0a7e8c, 0x50001ce9, 0x50001ce9},
+	{0x0000a560, 0x730e7e8c, 0x730e7e8c, 0x54001ceb, 0x54001ceb},
+	{0x0000a564, 0x730e7e8c, 0x730e7e8c, 0x56001eec, 0x56001eec},
+	{0x0000a568, 0x730e7e8c, 0x730e7e8c, 0x56001eec, 0x56001eec},
+	{0x0000a56c, 0x730e7e8c, 0x730e7e8c, 0x56001eec, 0x56001eec},
+	{0x0000a570, 0x730e7e8c, 0x730e7e8c, 0x56001eec, 0x56001eec},
+	{0x0000a574, 0x730e7e8c, 0x730e7e8c, 0x56001eec, 0x56001eec},
+	{0x0000a578, 0x730e7e8c, 0x730e7e8c, 0x56001eec, 0x56001eec},
+	{0x0000a57c, 0x730e7e8c, 0x730e7e8c, 0x56001eec, 0x56001eec},
+	{0x0000a580, 0x00820220, 0x00820220, 0x00800000, 0x00800000},
+	{0x0000a584, 0x06820223, 0x06820223, 0x04800002, 0x04800002},
+	{0x0000a588, 0x0b822220, 0x0b822220, 0x08800004, 0x08800004},
+	{0x0000a58c, 0x10822223, 0x10822223, 0x0b800200, 0x0b800200},
+	{0x0000a590, 0x17822620, 0x17822620, 0x0f800202, 0x0f800202},
+	{0x0000a594, 0x1b822622, 0x1b822622, 0x11800400, 0x11800400},
+	{0x0000a598, 0x1f822822, 0x1f822822, 0x15800402, 0x15800402},
+	{0x0000a59c, 0x24822842, 0x24822842, 0x19800404, 0x19800404},
+	{0x0000a5a0, 0x28842840, 0x28842840, 0x1b800603, 0x1b800603},
+	{0x0000a5a4, 0x2c842842, 0x2c842842, 0x1f800a02, 0x1f800a02},
+	{0x0000a5a8, 0x30842844, 0x30842844, 0x23800a04, 0x23800a04},
+	{0x0000a5ac, 0x34842846, 0x34842846, 0x26800a20, 0x26800a20},
+	{0x0000a5b0, 0x39842869, 0x39842869, 0x2a800e20, 0x2a800e20},
+	{0x0000a5b4, 0x3d862869, 0x3d862869, 0x2e800e22, 0x2e800e22},
+	{0x0000a5b8, 0x44862c69, 0x44862c69, 0x31800e24, 0x31800e24},
+	{0x0000a5bc, 0x48863069, 0x48863069, 0x34801640, 0x34801640},
+	{0x0000a5c0, 0x4c8a3065, 0x4c8a3065, 0x38801660, 0x38801660},
+	{0x0000a5c4, 0x508a3069, 0x508a3069, 0x3b801861, 0x3b801861},
+	{0x0000a5c8, 0x538a3469, 0x538a3469, 0x3e801a81, 0x3e801a81},
+	{0x0000a5cc, 0x598a7464, 0x598a7464, 0x42801a83, 0x42801a83},
+	{0x0000a5d0, 0x5e8a7865, 0x5e8a7865, 0x44801c84, 0x44801c84},
+	{0x0000a5d4, 0x638a7e66, 0x638a7e66, 0x48801ce3, 0x48801ce3},
+	{0x0000a5d8, 0x688a7e89, 0x688a7e89, 0x4c801ce5, 0x4c801ce5},
+	{0x0000a5dc, 0x6e8a7e8c, 0x6e8a7e8c, 0x50801ce9, 0x50801ce9},
+	{0x0000a5e0, 0x738e7e8c, 0x738e7e8c, 0x54801ceb, 0x54801ceb},
+	{0x0000a5e4, 0x738e7e8c, 0x738e7e8c, 0x56801eec, 0x56801eec},
+	{0x0000a5e8, 0x738e7e8c, 0x738e7e8c, 0x56801eec, 0x56801eec},
+	{0x0000a5ec, 0x738e7e8c, 0x738e7e8c, 0x56801eec, 0x56801eec},
+	{0x0000a5f0, 0x738e7e8c, 0x738e7e8c, 0x56801eec, 0x56801eec},
+	{0x0000a5f4, 0x738e7e8c, 0x738e7e8c, 0x56801eec, 0x56801eec},
+	{0x0000a5f8, 0x738e7e8c, 0x738e7e8c, 0x56801eec, 0x56801eec},
+	{0x0000a5fc, 0x738e7e8c, 0x738e7e8c, 0x56801eec, 0x56801eec},
+	{0x00016044, 0x056db2e6, 0x056db2e6, 0x056db2e6, 0x056db2e6},
+	{0x00016048, 0xad241a61, 0xad241a61, 0xad241a61, 0xad241a61},
+	{0x00016068, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c},
+	{0x00016444, 0x056db2e6, 0x056db2e6, 0x056db2e6, 0x056db2e6},
+	{0x00016448, 0xad241a61, 0xad241a61, 0xad241a61, 0xad241a61},
+	{0x00016468, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c},
+	{0x00016844, 0x056db2e6, 0x056db2e6, 0x056db2e6, 0x056db2e6},
+	{0x00016848, 0xad241a61, 0xad241a61, 0xad241a61, 0xad241a61},
+	{0x00016868, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c},
+};
+
+static const u32 ar9300Modes_high_ob_db_tx_gain_table_2p0[][5] = {
+	/* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
+	{0x0000a410, 0x000050d9, 0x000050d9, 0x000050da, 0x000050da},
+	{0x0000a500, 0x00020220, 0x00020220, 0x00000000, 0x00000000},
+	{0x0000a504, 0x06020223, 0x06020223, 0x04000002, 0x04000002},
+	{0x0000a508, 0x0b022220, 0x0b022220, 0x08000004, 0x08000004},
+	{0x0000a50c, 0x10022223, 0x10022223, 0x0b000200, 0x0b000200},
+	{0x0000a510, 0x17022620, 0x17022620, 0x0f000202, 0x0f000202},
+	{0x0000a514, 0x1b022622, 0x1b022622, 0x11000400, 0x11000400},
+	{0x0000a518, 0x1f022822, 0x1f022822, 0x15000402, 0x15000402},
+	{0x0000a51c, 0x24022842, 0x24022842, 0x19000404, 0x19000404},
+	{0x0000a520, 0x28042840, 0x28042840, 0x1b000603, 0x1b000603},
+	{0x0000a524, 0x2c042842, 0x2c042842, 0x1f000a02, 0x1f000a02},
+	{0x0000a528, 0x30042844, 0x30042844, 0x23000a04, 0x23000a04},
+	{0x0000a52c, 0x34042846, 0x34042846, 0x26000a20, 0x26000a20},
+	{0x0000a530, 0x39042869, 0x39042869, 0x2a000e20, 0x2a000e20},
+	{0x0000a534, 0x3d062869, 0x3d062869, 0x2e000e22, 0x2e000e22},
+	{0x0000a538, 0x44062c69, 0x44062c69, 0x31000e24, 0x31000e24},
+	{0x0000a53c, 0x48063069, 0x48063069, 0x34001640, 0x34001640},
+	{0x0000a540, 0x4c0a3065, 0x4c0a3065, 0x38001660, 0x38001660},
+	{0x0000a544, 0x500a3069, 0x500a3069, 0x3b001861, 0x3b001861},
+	{0x0000a548, 0x530a3469, 0x530a3469, 0x3e001a81, 0x3e001a81},
+	{0x0000a54c, 0x590a7464, 0x590a7464, 0x42001a83, 0x42001a83},
+	{0x0000a550, 0x5e0a7865, 0x5e0a7865, 0x44001c84, 0x44001c84},
+	{0x0000a554, 0x630a7e66, 0x630a7e66, 0x48001ce3, 0x48001ce3},
+	{0x0000a558, 0x680a7e89, 0x680a7e89, 0x4c001ce5, 0x4c001ce5},
+	{0x0000a55c, 0x6e0a7e8c, 0x6e0a7e8c, 0x50001ce9, 0x50001ce9},
+	{0x0000a560, 0x730e7e8c, 0x730e7e8c, 0x54001ceb, 0x54001ceb},
+	{0x0000a564, 0x730e7e8c, 0x730e7e8c, 0x56001eec, 0x56001eec},
+	{0x0000a568, 0x730e7e8c, 0x730e7e8c, 0x56001eec, 0x56001eec},
+	{0x0000a56c, 0x730e7e8c, 0x730e7e8c, 0x56001eec, 0x56001eec},
+	{0x0000a570, 0x730e7e8c, 0x730e7e8c, 0x56001eec, 0x56001eec},
+	{0x0000a574, 0x730e7e8c, 0x730e7e8c, 0x56001eec, 0x56001eec},
+	{0x0000a578, 0x730e7e8c, 0x730e7e8c, 0x56001eec, 0x56001eec},
+	{0x0000a57c, 0x730e7e8c, 0x730e7e8c, 0x56001eec, 0x56001eec},
+	{0x0000a580, 0x00820220, 0x00820220, 0x00800000, 0x00800000},
+	{0x0000a584, 0x06820223, 0x06820223, 0x04800002, 0x04800002},
+	{0x0000a588, 0x0b822220, 0x0b822220, 0x08800004, 0x08800004},
+	{0x0000a58c, 0x10822223, 0x10822223, 0x0b800200, 0x0b800200},
+	{0x0000a590, 0x17822620, 0x17822620, 0x0f800202, 0x0f800202},
+	{0x0000a594, 0x1b822622, 0x1b822622, 0x11800400, 0x11800400},
+	{0x0000a598, 0x1f822822, 0x1f822822, 0x15800402, 0x15800402},
+	{0x0000a59c, 0x24822842, 0x24822842, 0x19800404, 0x19800404},
+	{0x0000a5a0, 0x28842840, 0x28842840, 0x1b800603, 0x1b800603},
+	{0x0000a5a4, 0x2c842842, 0x2c842842, 0x1f800a02, 0x1f800a02},
+	{0x0000a5a8, 0x30842844, 0x30842844, 0x23800a04, 0x23800a04},
+	{0x0000a5ac, 0x34842846, 0x34842846, 0x26800a20, 0x26800a20},
+	{0x0000a5b0, 0x39842869, 0x39842869, 0x2a800e20, 0x2a800e20},
+	{0x0000a5b4, 0x3d862869, 0x3d862869, 0x2e800e22, 0x2e800e22},
+	{0x0000a5b8, 0x44862c69, 0x44862c69, 0x31800e24, 0x31800e24},
+	{0x0000a5bc, 0x48863069, 0x48863069, 0x34801640, 0x34801640},
+	{0x0000a5c0, 0x4c8a3065, 0x4c8a3065, 0x38801660, 0x38801660},
+	{0x0000a5c4, 0x508a3069, 0x508a3069, 0x3b801861, 0x3b801861},
+	{0x0000a5c8, 0x538a3469, 0x538a3469, 0x3e801a81, 0x3e801a81},
+	{0x0000a5cc, 0x598a7464, 0x598a7464, 0x42801a83, 0x42801a83},
+	{0x0000a5d0, 0x5e8a7865, 0x5e8a7865, 0x44801c84, 0x44801c84},
+	{0x0000a5d4, 0x638a7e66, 0x638a7e66, 0x48801ce3, 0x48801ce3},
+	{0x0000a5d8, 0x688a7e89, 0x688a7e89, 0x4c801ce5, 0x4c801ce5},
+	{0x0000a5dc, 0x6e8a7e8c, 0x6e8a7e8c, 0x50801ce9, 0x50801ce9},
+	{0x0000a5e0, 0x738e7e8c, 0x738e7e8c, 0x54801ceb, 0x54801ceb},
+	{0x0000a5e4, 0x738e7e8c, 0x738e7e8c, 0x56801eec, 0x56801eec},
+	{0x0000a5e8, 0x738e7e8c, 0x738e7e8c, 0x56801eec, 0x56801eec},
+	{0x0000a5ec, 0x738e7e8c, 0x738e7e8c, 0x56801eec, 0x56801eec},
+	{0x0000a5f0, 0x738e7e8c, 0x738e7e8c, 0x56801eec, 0x56801eec},
+	{0x0000a5f4, 0x738e7e8c, 0x738e7e8c, 0x56801eec, 0x56801eec},
+	{0x0000a5f8, 0x738e7e8c, 0x738e7e8c, 0x56801eec, 0x56801eec},
+	{0x0000a5fc, 0x738e7e8c, 0x738e7e8c, 0x56801eec, 0x56801eec},
+	{0x00016044, 0x056db2e4, 0x056db2e4, 0x056db2e4, 0x056db2e4},
+	{0x00016048, 0x8c001a61, 0x8c001a61, 0x8c001a61, 0x8c001a61},
+	{0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
+	{0x00016444, 0x056db2e4, 0x056db2e4, 0x056db2e4, 0x056db2e4},
+	{0x00016448, 0x8c001a61, 0x8c001a61, 0x8c001a61, 0x8c001a61},
+	{0x00016468, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
+	{0x00016844, 0x056db2e4, 0x056db2e4, 0x056db2e4, 0x056db2e4},
+	{0x00016848, 0x8c001a61, 0x8c001a61, 0x8c001a61, 0x8c001a61},
+	{0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
+};
+
+static const u32 ar9300Common_rx_gain_table_2p0[][2] = {
+	/* Addr      allmodes  */
+	{0x0000a000, 0x00010000},
+	{0x0000a004, 0x00030002},
+	{0x0000a008, 0x00050004},
+	{0x0000a00c, 0x00810080},
+	{0x0000a010, 0x01800082},
+	{0x0000a014, 0x01820181},
+	{0x0000a018, 0x01840183},
+	{0x0000a01c, 0x01880185},
+	{0x0000a020, 0x018a0189},
+	{0x0000a024, 0x02850284},
+	{0x0000a028, 0x02890288},
+	{0x0000a02c, 0x028b028a},
+	{0x0000a030, 0x028d028c},
+	{0x0000a034, 0x02910290},
+	{0x0000a038, 0x02930292},
+	{0x0000a03c, 0x03910390},
+	{0x0000a040, 0x03930392},
+	{0x0000a044, 0x03950394},
+	{0x0000a048, 0x00000396},
+	{0x0000a04c, 0x00000000},
+	{0x0000a050, 0x00000000},
+	{0x0000a054, 0x00000000},
+	{0x0000a058, 0x00000000},
+	{0x0000a05c, 0x00000000},
+	{0x0000a060, 0x00000000},
+	{0x0000a064, 0x00000000},
+	{0x0000a068, 0x00000000},
+	{0x0000a06c, 0x00000000},
+	{0x0000a070, 0x00000000},
+	{0x0000a074, 0x00000000},
+	{0x0000a078, 0x00000000},
+	{0x0000a07c, 0x00000000},
+	{0x0000a080, 0x28282828},
+	{0x0000a084, 0x21212128},
+	{0x0000a088, 0x21212121},
+	{0x0000a08c, 0x1c1c1c21},
+	{0x0000a090, 0x1c1c1c1c},
+	{0x0000a094, 0x17171c1c},
+	{0x0000a098, 0x02020212},
+	{0x0000a09c, 0x02020202},
+	{0x0000a0a0, 0x00000000},
+	{0x0000a0a4, 0x00000000},
+	{0x0000a0a8, 0x00000000},
+	{0x0000a0ac, 0x00000000},
+	{0x0000a0b0, 0x00000000},
+	{0x0000a0b4, 0x00000000},
+	{0x0000a0b8, 0x00000000},
+	{0x0000a0bc, 0x00000000},
+	{0x0000a0c0, 0x001f0000},
+	{0x0000a0c4, 0x011f0100},
+	{0x0000a0c8, 0x011d011e},
+	{0x0000a0cc, 0x011b011c},
+	{0x0000a0d0, 0x02030204},
+	{0x0000a0d4, 0x02010202},
+	{0x0000a0d8, 0x021f0200},
+	{0x0000a0dc, 0x021d021e},
+	{0x0000a0e0, 0x03010302},
+	{0x0000a0e4, 0x031f0300},
+	{0x0000a0e8, 0x0402031e},
+	{0x0000a0ec, 0x04000401},
+	{0x0000a0f0, 0x041e041f},
+	{0x0000a0f4, 0x05010502},
+	{0x0000a0f8, 0x051f0500},
+	{0x0000a0fc, 0x0602051e},
+	{0x0000a100, 0x06000601},
+	{0x0000a104, 0x061e061f},
+	{0x0000a108, 0x0703061d},
+	{0x0000a10c, 0x07010702},
+	{0x0000a110, 0x00000700},
+	{0x0000a114, 0x00000000},
+	{0x0000a118, 0x00000000},
+	{0x0000a11c, 0x00000000},
+	{0x0000a120, 0x00000000},
+	{0x0000a124, 0x00000000},
+	{0x0000a128, 0x00000000},
+	{0x0000a12c, 0x00000000},
+	{0x0000a130, 0x00000000},
+	{0x0000a134, 0x00000000},
+	{0x0000a138, 0x00000000},
+	{0x0000a13c, 0x00000000},
+	{0x0000a140, 0x001f0000},
+	{0x0000a144, 0x011f0100},
+	{0x0000a148, 0x011d011e},
+	{0x0000a14c, 0x011b011c},
+	{0x0000a150, 0x02030204},
+	{0x0000a154, 0x02010202},
+	{0x0000a158, 0x021f0200},
+	{0x0000a15c, 0x021d021e},
+	{0x0000a160, 0x03010302},
+	{0x0000a164, 0x031f0300},
+	{0x0000a168, 0x0402031e},
+	{0x0000a16c, 0x04000401},
+	{0x0000a170, 0x041e041f},
+	{0x0000a174, 0x05010502},
+	{0x0000a178, 0x051f0500},
+	{0x0000a17c, 0x0602051e},
+	{0x0000a180, 0x06000601},
+	{0x0000a184, 0x061e061f},
+	{0x0000a188, 0x0703061d},
+	{0x0000a18c, 0x07010702},
+	{0x0000a190, 0x00000700},
+	{0x0000a194, 0x00000000},
+	{0x0000a198, 0x00000000},
+	{0x0000a19c, 0x00000000},
+	{0x0000a1a0, 0x00000000},
+	{0x0000a1a4, 0x00000000},
+	{0x0000a1a8, 0x00000000},
+	{0x0000a1ac, 0x00000000},
+	{0x0000a1b0, 0x00000000},
+	{0x0000a1b4, 0x00000000},
+	{0x0000a1b8, 0x00000000},
+	{0x0000a1bc, 0x00000000},
+	{0x0000a1c0, 0x00000000},
+	{0x0000a1c4, 0x00000000},
+	{0x0000a1c8, 0x00000000},
+	{0x0000a1cc, 0x00000000},
+	{0x0000a1d0, 0x00000000},
+	{0x0000a1d4, 0x00000000},
+	{0x0000a1d8, 0x00000000},
+	{0x0000a1dc, 0x00000000},
+	{0x0000a1e0, 0x00000000},
+	{0x0000a1e4, 0x00000000},
+	{0x0000a1e8, 0x00000000},
+	{0x0000a1ec, 0x00000000},
+	{0x0000a1f0, 0x00000396},
+	{0x0000a1f4, 0x00000396},
+	{0x0000a1f8, 0x00000396},
+	{0x0000a1fc, 0x00000196},
+	{0x0000b000, 0x00010000},
+	{0x0000b004, 0x00030002},
+	{0x0000b008, 0x00050004},
+	{0x0000b00c, 0x00810080},
+	{0x0000b010, 0x00830082},
+	{0x0000b014, 0x01810180},
+	{0x0000b018, 0x01830182},
+	{0x0000b01c, 0x01850184},
+	{0x0000b020, 0x02810280},
+	{0x0000b024, 0x02830282},
+	{0x0000b028, 0x02850284},
+	{0x0000b02c, 0x02890288},
+	{0x0000b030, 0x028b028a},
+	{0x0000b034, 0x0388028c},
+	{0x0000b038, 0x038a0389},
+	{0x0000b03c, 0x038c038b},
+	{0x0000b040, 0x0390038d},
+	{0x0000b044, 0x03920391},
+	{0x0000b048, 0x03940393},
+	{0x0000b04c, 0x03960395},
+	{0x0000b050, 0x00000000},
+	{0x0000b054, 0x00000000},
+	{0x0000b058, 0x00000000},
+	{0x0000b05c, 0x00000000},
+	{0x0000b060, 0x00000000},
+	{0x0000b064, 0x00000000},
+	{0x0000b068, 0x00000000},
+	{0x0000b06c, 0x00000000},
+	{0x0000b070, 0x00000000},
+	{0x0000b074, 0x00000000},
+	{0x0000b078, 0x00000000},
+	{0x0000b07c, 0x00000000},
+	{0x0000b080, 0x32323232},
+	{0x0000b084, 0x2f2f3232},
+	{0x0000b088, 0x23282a2d},
+	{0x0000b08c, 0x1c1e2123},
+	{0x0000b090, 0x14171919},
+	{0x0000b094, 0x0e0e1214},
+	{0x0000b098, 0x03050707},
+	{0x0000b09c, 0x00030303},
+	{0x0000b0a0, 0x00000000},
+	{0x0000b0a4, 0x00000000},
+	{0x0000b0a8, 0x00000000},
+	{0x0000b0ac, 0x00000000},
+	{0x0000b0b0, 0x00000000},
+	{0x0000b0b4, 0x00000000},
+	{0x0000b0b8, 0x00000000},
+	{0x0000b0bc, 0x00000000},
+	{0x0000b0c0, 0x003f0020},
+	{0x0000b0c4, 0x00400041},
+	{0x0000b0c8, 0x0140005f},
+	{0x0000b0cc, 0x0160015f},
+	{0x0000b0d0, 0x017e017f},
+	{0x0000b0d4, 0x02410242},
+	{0x0000b0d8, 0x025f0240},
+	{0x0000b0dc, 0x027f0260},
+	{0x0000b0e0, 0x0341027e},
+	{0x0000b0e4, 0x035f0340},
+	{0x0000b0e8, 0x037f0360},
+	{0x0000b0ec, 0x04400441},
+	{0x0000b0f0, 0x0460045f},
+	{0x0000b0f4, 0x0541047f},
+	{0x0000b0f8, 0x055f0540},
+	{0x0000b0fc, 0x057f0560},
+	{0x0000b100, 0x06400641},
+	{0x0000b104, 0x0660065f},
+	{0x0000b108, 0x067e067f},
+	{0x0000b10c, 0x07410742},
+	{0x0000b110, 0x075f0740},
+	{0x0000b114, 0x077f0760},
+	{0x0000b118, 0x07800781},
+	{0x0000b11c, 0x07a0079f},
+	{0x0000b120, 0x07c107bf},
+	{0x0000b124, 0x000007c0},
+	{0x0000b128, 0x00000000},
+	{0x0000b12c, 0x00000000},
+	{0x0000b130, 0x00000000},
+	{0x0000b134, 0x00000000},
+	{0x0000b138, 0x00000000},
+	{0x0000b13c, 0x00000000},
+	{0x0000b140, 0x003f0020},
+	{0x0000b144, 0x00400041},
+	{0x0000b148, 0x0140005f},
+	{0x0000b14c, 0x0160015f},
+	{0x0000b150, 0x017e017f},
+	{0x0000b154, 0x02410242},
+	{0x0000b158, 0x025f0240},
+	{0x0000b15c, 0x027f0260},
+	{0x0000b160, 0x0341027e},
+	{0x0000b164, 0x035f0340},
+	{0x0000b168, 0x037f0360},
+	{0x0000b16c, 0x04400441},
+	{0x0000b170, 0x0460045f},
+	{0x0000b174, 0x0541047f},
+	{0x0000b178, 0x055f0540},
+	{0x0000b17c, 0x057f0560},
+	{0x0000b180, 0x06400641},
+	{0x0000b184, 0x0660065f},
+	{0x0000b188, 0x067e067f},
+	{0x0000b18c, 0x07410742},
+	{0x0000b190, 0x075f0740},
+	{0x0000b194, 0x077f0760},
+	{0x0000b198, 0x07800781},
+	{0x0000b19c, 0x07a0079f},
+	{0x0000b1a0, 0x07c107bf},
+	{0x0000b1a4, 0x000007c0},
+	{0x0000b1a8, 0x00000000},
+	{0x0000b1ac, 0x00000000},
+	{0x0000b1b0, 0x00000000},
+	{0x0000b1b4, 0x00000000},
+	{0x0000b1b8, 0x00000000},
+	{0x0000b1bc, 0x00000000},
+	{0x0000b1c0, 0x00000000},
+	{0x0000b1c4, 0x00000000},
+	{0x0000b1c8, 0x00000000},
+	{0x0000b1cc, 0x00000000},
+	{0x0000b1d0, 0x00000000},
+	{0x0000b1d4, 0x00000000},
+	{0x0000b1d8, 0x00000000},
+	{0x0000b1dc, 0x00000000},
+	{0x0000b1e0, 0x00000000},
+	{0x0000b1e4, 0x00000000},
+	{0x0000b1e8, 0x00000000},
+	{0x0000b1ec, 0x00000000},
+	{0x0000b1f0, 0x00000396},
+	{0x0000b1f4, 0x00000396},
+	{0x0000b1f8, 0x00000396},
+	{0x0000b1fc, 0x00000196},
+};
+
+static const u32 ar9300Modes_low_ob_db_tx_gain_table_2p0[][5] = {
+	/* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
+	{0x0000a410, 0x000050da, 0x000050da, 0x000050da, 0x000050da},
+	{0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+	{0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002},
+	{0x0000a508, 0x0a000020, 0x0a000020, 0x08000004, 0x08000004},
+	{0x0000a50c, 0x10000023, 0x10000023, 0x0b000200, 0x0b000200},
+	{0x0000a510, 0x16000220, 0x16000220, 0x0f000202, 0x0f000202},
+	{0x0000a514, 0x1c000223, 0x1c000223, 0x12000400, 0x12000400},
+	{0x0000a518, 0x21020220, 0x21020220, 0x16000402, 0x16000402},
+	{0x0000a51c, 0x27020223, 0x27020223, 0x19000404, 0x19000404},
+	{0x0000a520, 0x2b022220, 0x2b022220, 0x1c000603, 0x1c000603},
+	{0x0000a524, 0x2f022222, 0x2f022222, 0x21000a02, 0x21000a02},
+	{0x0000a528, 0x34022225, 0x34022225, 0x25000a04, 0x25000a04},
+	{0x0000a52c, 0x3a02222a, 0x3a02222a, 0x28000a20, 0x28000a20},
+	{0x0000a530, 0x3e02222c, 0x3e02222c, 0x2c000e20, 0x2c000e20},
+	{0x0000a534, 0x4202242a, 0x4202242a, 0x30000e22, 0x30000e22},
+	{0x0000a538, 0x4702244a, 0x4702244a, 0x34000e24, 0x34000e24},
+	{0x0000a53c, 0x4b02244c, 0x4b02244c, 0x38001640, 0x38001640},
+	{0x0000a540, 0x4e02246c, 0x4e02246c, 0x3c001660, 0x3c001660},
+	{0x0000a544, 0x5302266c, 0x5302266c, 0x3f001861, 0x3f001861},
+	{0x0000a548, 0x5702286c, 0x5702286c, 0x43001a81, 0x43001a81},
+	{0x0000a54c, 0x5c04286b, 0x5c04286b, 0x47001a83, 0x47001a83},
+	{0x0000a550, 0x61042a6c, 0x61042a6c, 0x4a001c84, 0x4a001c84},
+	{0x0000a554, 0x66062a6c, 0x66062a6c, 0x4e001ce3, 0x4e001ce3},
+	{0x0000a558, 0x6b062e6c, 0x6b062e6c, 0x52001ce5, 0x52001ce5},
+	{0x0000a55c, 0x7006308c, 0x7006308c, 0x56001ce9, 0x56001ce9},
+	{0x0000a560, 0x730a308a, 0x730a308a, 0x5a001ceb, 0x5a001ceb},
+	{0x0000a564, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
+	{0x0000a568, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
+	{0x0000a56c, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
+	{0x0000a570, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
+	{0x0000a574, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
+	{0x0000a578, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
+	{0x0000a57c, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
+	{0x0000a580, 0x00800000, 0x00800000, 0x00800000, 0x00800000},
+	{0x0000a584, 0x06800003, 0x06800003, 0x04800002, 0x04800002},
+	{0x0000a588, 0x0a800020, 0x0a800020, 0x08800004, 0x08800004},
+	{0x0000a58c, 0x10800023, 0x10800023, 0x0b800200, 0x0b800200},
+	{0x0000a590, 0x16800220, 0x16800220, 0x0f800202, 0x0f800202},
+	{0x0000a594, 0x1c800223, 0x1c800223, 0x12800400, 0x12800400},
+	{0x0000a598, 0x21820220, 0x21820220, 0x16800402, 0x16800402},
+	{0x0000a59c, 0x27820223, 0x27820223, 0x19800404, 0x19800404},
+	{0x0000a5a0, 0x2b822220, 0x2b822220, 0x1c800603, 0x1c800603},
+	{0x0000a5a4, 0x2f822222, 0x2f822222, 0x21800a02, 0x21800a02},
+	{0x0000a5a8, 0x34822225, 0x34822225, 0x25800a04, 0x25800a04},
+	{0x0000a5ac, 0x3a82222a, 0x3a82222a, 0x28800a20, 0x28800a20},
+	{0x0000a5b0, 0x3e82222c, 0x3e82222c, 0x2c800e20, 0x2c800e20},
+	{0x0000a5b4, 0x4282242a, 0x4282242a, 0x30800e22, 0x30800e22},
+	{0x0000a5b8, 0x4782244a, 0x4782244a, 0x34800e24, 0x34800e24},
+	{0x0000a5bc, 0x4b82244c, 0x4b82244c, 0x38801640, 0x38801640},
+	{0x0000a5c0, 0x4e82246c, 0x4e82246c, 0x3c801660, 0x3c801660},
+	{0x0000a5c4, 0x5382266c, 0x5382266c, 0x3f801861, 0x3f801861},
+	{0x0000a5c8, 0x5782286c, 0x5782286c, 0x43801a81, 0x43801a81},
+	{0x0000a5cc, 0x5c84286b, 0x5c84286b, 0x47801a83, 0x47801a83},
+	{0x0000a5d0, 0x61842a6c, 0x61842a6c, 0x4a801c84, 0x4a801c84},
+	{0x0000a5d4, 0x66862a6c, 0x66862a6c, 0x4e801ce3, 0x4e801ce3},
+	{0x0000a5d8, 0x6b862e6c, 0x6b862e6c, 0x52801ce5, 0x52801ce5},
+	{0x0000a5dc, 0x7086308c, 0x7086308c, 0x56801ce9, 0x56801ce9},
+	{0x0000a5e0, 0x738a308a, 0x738a308a, 0x5a801ceb, 0x5a801ceb},
+	{0x0000a5e4, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
+	{0x0000a5e8, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
+	{0x0000a5ec, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
+	{0x0000a5f0, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
+	{0x0000a5f4, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
+	{0x0000a5f8, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
+	{0x0000a5fc, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
+	{0x00016044, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
+	{0x00016048, 0x64001a61, 0x64001a61, 0x64001a61, 0x64001a61},
+	{0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
+	{0x00016444, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
+	{0x00016448, 0x64001a61, 0x64001a61, 0x64001a61, 0x64001a61},
+	{0x00016468, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
+	{0x00016844, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
+	{0x00016848, 0x64001a61, 0x64001a61, 0x64001a61, 0x64001a61},
+	{0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
+};
+
+static const u32 ar9300_2p0_mac_core[][2] = {
+	/* Addr      allmodes  */
+	{0x00000008, 0x00000000},
+	{0x00000030, 0x00020085},
+	{0x00000034, 0x00000005},
+	{0x00000040, 0x00000000},
+	{0x00000044, 0x00000000},
+	{0x00000048, 0x00000008},
+	{0x0000004c, 0x00000010},
+	{0x00000050, 0x00000000},
+	{0x00001040, 0x002ffc0f},
+	{0x00001044, 0x002ffc0f},
+	{0x00001048, 0x002ffc0f},
+	{0x0000104c, 0x002ffc0f},
+	{0x00001050, 0x002ffc0f},
+	{0x00001054, 0x002ffc0f},
+	{0x00001058, 0x002ffc0f},
+	{0x0000105c, 0x002ffc0f},
+	{0x00001060, 0x002ffc0f},
+	{0x00001064, 0x002ffc0f},
+	{0x000010f0, 0x00000100},
+	{0x00001270, 0x00000000},
+	{0x000012b0, 0x00000000},
+	{0x000012f0, 0x00000000},
+	{0x0000143c, 0x00000000},
+	{0x0000147c, 0x00000000},
+	{0x00008000, 0x00000000},
+	{0x00008004, 0x00000000},
+	{0x00008008, 0x00000000},
+	{0x0000800c, 0x00000000},
+	{0x00008018, 0x00000000},
+	{0x00008020, 0x00000000},
+	{0x00008038, 0x00000000},
+	{0x0000803c, 0x00000000},
+	{0x00008040, 0x00000000},
+	{0x00008044, 0x00000000},
+	{0x00008048, 0x00000000},
+	{0x0000804c, 0xffffffff},
+	{0x00008054, 0x00000000},
+	{0x00008058, 0x00000000},
+	{0x0000805c, 0x000fc78f},
+	{0x00008060, 0x0000000f},
+	{0x00008064, 0x00000000},
+	{0x00008070, 0x00000310},
+	{0x00008074, 0x00000020},
+	{0x00008078, 0x00000000},
+	{0x0000809c, 0x0000000f},
+	{0x000080a0, 0x00000000},
+	{0x000080a4, 0x02ff0000},
+	{0x000080a8, 0x0e070605},
+	{0x000080ac, 0x0000000d},
+	{0x000080b0, 0x00000000},
+	{0x000080b4, 0x00000000},
+	{0x000080b8, 0x00000000},
+	{0x000080bc, 0x00000000},
+	{0x000080c0, 0x2a800000},
+	{0x000080c4, 0x06900168},
+	{0x000080c8, 0x13881c20},
+	{0x000080cc, 0x01f40000},
+	{0x000080d0, 0x00252500},
+	{0x000080d4, 0x00a00000},
+	{0x000080d8, 0x00400000},
+	{0x000080dc, 0x00000000},
+	{0x000080e0, 0xffffffff},
+	{0x000080e4, 0x0000ffff},
+	{0x000080e8, 0x3f3f3f3f},
+	{0x000080ec, 0x00000000},
+	{0x000080f0, 0x00000000},
+	{0x000080f4, 0x00000000},
+	{0x000080fc, 0x00020000},
+	{0x00008100, 0x00000000},
+	{0x00008108, 0x00000052},
+	{0x0000810c, 0x00000000},
+	{0x00008110, 0x00000000},
+	{0x00008114, 0x000007ff},
+	{0x00008118, 0x000000aa},
+	{0x0000811c, 0x00003210},
+	{0x00008124, 0x00000000},
+	{0x00008128, 0x00000000},
+	{0x0000812c, 0x00000000},
+	{0x00008130, 0x00000000},
+	{0x00008134, 0x00000000},
+	{0x00008138, 0x00000000},
+	{0x0000813c, 0x0000ffff},
+	{0x00008144, 0xffffffff},
+	{0x00008168, 0x00000000},
+	{0x0000816c, 0x00000000},
+	{0x00008170, 0x18486200},
+	{0x00008174, 0x33332210},
+	{0x00008178, 0x00000000},
+	{0x0000817c, 0x00020000},
+	{0x000081c0, 0x00000000},
+	{0x000081c4, 0x33332210},
+	{0x000081c8, 0x00000000},
+	{0x000081cc, 0x00000000},
+	{0x000081d4, 0x00000000},
+	{0x000081ec, 0x00000000},
+	{0x000081f0, 0x00000000},
+	{0x000081f4, 0x00000000},
+	{0x000081f8, 0x00000000},
+	{0x000081fc, 0x00000000},
+	{0x00008240, 0x00100000},
+	{0x00008244, 0x0010f424},
+	{0x00008248, 0x00000800},
+	{0x0000824c, 0x0001e848},
+	{0x00008250, 0x00000000},
+	{0x00008254, 0x00000000},
+	{0x00008258, 0x00000000},
+	{0x0000825c, 0x40000000},
+	{0x00008260, 0x00080922},
+	{0x00008264, 0x98a00010},
+	{0x00008268, 0xffffffff},
+	{0x0000826c, 0x0000ffff},
+	{0x00008270, 0x00000000},
+	{0x00008274, 0x40000000},
+	{0x00008278, 0x003e4180},
+	{0x0000827c, 0x00000004},
+	{0x00008284, 0x0000002c},
+	{0x00008288, 0x0000002c},
+	{0x0000828c, 0x000000ff},
+	{0x00008294, 0x00000000},
+	{0x00008298, 0x00000000},
+	{0x0000829c, 0x00000000},
+	{0x00008300, 0x00000140},
+	{0x00008314, 0x00000000},
+	{0x0000831c, 0x0000010d},
+	{0x00008328, 0x00000000},
+	{0x0000832c, 0x00000007},
+	{0x00008330, 0x00000302},
+	{0x00008334, 0x00000700},
+	{0x00008338, 0x00ff0000},
+	{0x0000833c, 0x02400000},
+	{0x00008340, 0x000107ff},
+	{0x00008344, 0xaa48105b},
+	{0x00008348, 0x008f0000},
+	{0x0000835c, 0x00000000},
+	{0x00008360, 0xffffffff},
+	{0x00008364, 0xffffffff},
+	{0x00008368, 0x00000000},
+	{0x00008370, 0x00000000},
+	{0x00008374, 0x000000ff},
+	{0x00008378, 0x00000000},
+	{0x0000837c, 0x00000000},
+	{0x00008380, 0xffffffff},
+	{0x00008384, 0xffffffff},
+	{0x00008390, 0xffffffff},
+	{0x00008394, 0xffffffff},
+	{0x00008398, 0x00000000},
+	{0x0000839c, 0x00000000},
+	{0x000083a0, 0x00000000},
+	{0x000083a4, 0x0000fa14},
+	{0x000083a8, 0x000f0c00},
+	{0x000083ac, 0x33332210},
+	{0x000083b0, 0x33332210},
+	{0x000083b4, 0x33332210},
+	{0x000083b8, 0x33332210},
+	{0x000083bc, 0x00000000},
+	{0x000083c0, 0x00000000},
+	{0x000083c4, 0x00000000},
+	{0x000083c8, 0x00000000},
+	{0x000083cc, 0x00000200},
+	{0x000083d0, 0x000301ff},
+};
+
+static const u32 ar9300Common_wo_xlna_rx_gain_table_2p0[][2] = {
+	/* Addr      allmodes  */
+	{0x0000a000, 0x00010000},
+	{0x0000a004, 0x00030002},
+	{0x0000a008, 0x00050004},
+	{0x0000a00c, 0x00810080},
+	{0x0000a010, 0x01800082},
+	{0x0000a014, 0x01820181},
+	{0x0000a018, 0x01840183},
+	{0x0000a01c, 0x01880185},
+	{0x0000a020, 0x018a0189},
+	{0x0000a024, 0x02850284},
+	{0x0000a028, 0x02890288},
+	{0x0000a02c, 0x03850384},
+	{0x0000a030, 0x03890388},
+	{0x0000a034, 0x038b038a},
+	{0x0000a038, 0x038d038c},
+	{0x0000a03c, 0x03910390},
+	{0x0000a040, 0x03930392},
+	{0x0000a044, 0x03950394},
+	{0x0000a048, 0x00000396},
+	{0x0000a04c, 0x00000000},
+	{0x0000a050, 0x00000000},
+	{0x0000a054, 0x00000000},
+	{0x0000a058, 0x00000000},
+	{0x0000a05c, 0x00000000},
+	{0x0000a060, 0x00000000},
+	{0x0000a064, 0x00000000},
+	{0x0000a068, 0x00000000},
+	{0x0000a06c, 0x00000000},
+	{0x0000a070, 0x00000000},
+	{0x0000a074, 0x00000000},
+	{0x0000a078, 0x00000000},
+	{0x0000a07c, 0x00000000},
+	{0x0000a080, 0x28282828},
+	{0x0000a084, 0x28282828},
+	{0x0000a088, 0x28282828},
+	{0x0000a08c, 0x28282828},
+	{0x0000a090, 0x28282828},
+	{0x0000a094, 0x21212128},
+	{0x0000a098, 0x171c1c1c},
+	{0x0000a09c, 0x02020212},
+	{0x0000a0a0, 0x00000202},
+	{0x0000a0a4, 0x00000000},
+	{0x0000a0a8, 0x00000000},
+	{0x0000a0ac, 0x00000000},
+	{0x0000a0b0, 0x00000000},
+	{0x0000a0b4, 0x00000000},
+	{0x0000a0b8, 0x00000000},
+	{0x0000a0bc, 0x00000000},
+	{0x0000a0c0, 0x001f0000},
+	{0x0000a0c4, 0x011f0100},
+	{0x0000a0c8, 0x011d011e},
+	{0x0000a0cc, 0x011b011c},
+	{0x0000a0d0, 0x02030204},
+	{0x0000a0d4, 0x02010202},
+	{0x0000a0d8, 0x021f0200},
+	{0x0000a0dc, 0x021d021e},
+	{0x0000a0e0, 0x03010302},
+	{0x0000a0e4, 0x031f0300},
+	{0x0000a0e8, 0x0402031e},
+	{0x0000a0ec, 0x04000401},
+	{0x0000a0f0, 0x041e041f},
+	{0x0000a0f4, 0x05010502},
+	{0x0000a0f8, 0x051f0500},
+	{0x0000a0fc, 0x0602051e},
+	{0x0000a100, 0x06000601},
+	{0x0000a104, 0x061e061f},
+	{0x0000a108, 0x0703061d},
+	{0x0000a10c, 0x07010702},
+	{0x0000a110, 0x00000700},
+	{0x0000a114, 0x00000000},
+	{0x0000a118, 0x00000000},
+	{0x0000a11c, 0x00000000},
+	{0x0000a120, 0x00000000},
+	{0x0000a124, 0x00000000},
+	{0x0000a128, 0x00000000},
+	{0x0000a12c, 0x00000000},
+	{0x0000a130, 0x00000000},
+	{0x0000a134, 0x00000000},
+	{0x0000a138, 0x00000000},
+	{0x0000a13c, 0x00000000},
+	{0x0000a140, 0x001f0000},
+	{0x0000a144, 0x011f0100},
+	{0x0000a148, 0x011d011e},
+	{0x0000a14c, 0x011b011c},
+	{0x0000a150, 0x02030204},
+	{0x0000a154, 0x02010202},
+	{0x0000a158, 0x021f0200},
+	{0x0000a15c, 0x021d021e},
+	{0x0000a160, 0x03010302},
+	{0x0000a164, 0x031f0300},
+	{0x0000a168, 0x0402031e},
+	{0x0000a16c, 0x04000401},
+	{0x0000a170, 0x041e041f},
+	{0x0000a174, 0x05010502},
+	{0x0000a178, 0x051f0500},
+	{0x0000a17c, 0x0602051e},
+	{0x0000a180, 0x06000601},
+	{0x0000a184, 0x061e061f},
+	{0x0000a188, 0x0703061d},
+	{0x0000a18c, 0x07010702},
+	{0x0000a190, 0x00000700},
+	{0x0000a194, 0x00000000},
+	{0x0000a198, 0x00000000},
+	{0x0000a19c, 0x00000000},
+	{0x0000a1a0, 0x00000000},
+	{0x0000a1a4, 0x00000000},
+	{0x0000a1a8, 0x00000000},
+	{0x0000a1ac, 0x00000000},
+	{0x0000a1b0, 0x00000000},
+	{0x0000a1b4, 0x00000000},
+	{0x0000a1b8, 0x00000000},
+	{0x0000a1bc, 0x00000000},
+	{0x0000a1c0, 0x00000000},
+	{0x0000a1c4, 0x00000000},
+	{0x0000a1c8, 0x00000000},
+	{0x0000a1cc, 0x00000000},
+	{0x0000a1d0, 0x00000000},
+	{0x0000a1d4, 0x00000000},
+	{0x0000a1d8, 0x00000000},
+	{0x0000a1dc, 0x00000000},
+	{0x0000a1e0, 0x00000000},
+	{0x0000a1e4, 0x00000000},
+	{0x0000a1e8, 0x00000000},
+	{0x0000a1ec, 0x00000000},
+	{0x0000a1f0, 0x00000396},
+	{0x0000a1f4, 0x00000396},
+	{0x0000a1f8, 0x00000396},
+	{0x0000a1fc, 0x00000296},
+	{0x0000b000, 0x00010000},
+	{0x0000b004, 0x00030002},
+	{0x0000b008, 0x00050004},
+	{0x0000b00c, 0x00810080},
+	{0x0000b010, 0x00830082},
+	{0x0000b014, 0x01810180},
+	{0x0000b018, 0x01830182},
+	{0x0000b01c, 0x01850184},
+	{0x0000b020, 0x02810280},
+	{0x0000b024, 0x02830282},
+	{0x0000b028, 0x02850284},
+	{0x0000b02c, 0x02890288},
+	{0x0000b030, 0x028b028a},
+	{0x0000b034, 0x0388028c},
+	{0x0000b038, 0x038a0389},
+	{0x0000b03c, 0x038c038b},
+	{0x0000b040, 0x0390038d},
+	{0x0000b044, 0x03920391},
+	{0x0000b048, 0x03940393},
+	{0x0000b04c, 0x03960395},
+	{0x0000b050, 0x00000000},
+	{0x0000b054, 0x00000000},
+	{0x0000b058, 0x00000000},
+	{0x0000b05c, 0x00000000},
+	{0x0000b060, 0x00000000},
+	{0x0000b064, 0x00000000},
+	{0x0000b068, 0x00000000},
+	{0x0000b06c, 0x00000000},
+	{0x0000b070, 0x00000000},
+	{0x0000b074, 0x00000000},
+	{0x0000b078, 0x00000000},
+	{0x0000b07c, 0x00000000},
+	{0x0000b080, 0x32323232},
+	{0x0000b084, 0x2f2f3232},
+	{0x0000b088, 0x23282a2d},
+	{0x0000b08c, 0x1c1e2123},
+	{0x0000b090, 0x14171919},
+	{0x0000b094, 0x0e0e1214},
+	{0x0000b098, 0x03050707},
+	{0x0000b09c, 0x00030303},
+	{0x0000b0a0, 0x00000000},
+	{0x0000b0a4, 0x00000000},
+	{0x0000b0a8, 0x00000000},
+	{0x0000b0ac, 0x00000000},
+	{0x0000b0b0, 0x00000000},
+	{0x0000b0b4, 0x00000000},
+	{0x0000b0b8, 0x00000000},
+	{0x0000b0bc, 0x00000000},
+	{0x0000b0c0, 0x003f0020},
+	{0x0000b0c4, 0x00400041},
+	{0x0000b0c8, 0x0140005f},
+	{0x0000b0cc, 0x0160015f},
+	{0x0000b0d0, 0x017e017f},
+	{0x0000b0d4, 0x02410242},
+	{0x0000b0d8, 0x025f0240},
+	{0x0000b0dc, 0x027f0260},
+	{0x0000b0e0, 0x0341027e},
+	{0x0000b0e4, 0x035f0340},
+	{0x0000b0e8, 0x037f0360},
+	{0x0000b0ec, 0x04400441},
+	{0x0000b0f0, 0x0460045f},
+	{0x0000b0f4, 0x0541047f},
+	{0x0000b0f8, 0x055f0540},
+	{0x0000b0fc, 0x057f0560},
+	{0x0000b100, 0x06400641},
+	{0x0000b104, 0x0660065f},
+	{0x0000b108, 0x067e067f},
+	{0x0000b10c, 0x07410742},
+	{0x0000b110, 0x075f0740},
+	{0x0000b114, 0x077f0760},
+	{0x0000b118, 0x07800781},
+	{0x0000b11c, 0x07a0079f},
+	{0x0000b120, 0x07c107bf},
+	{0x0000b124, 0x000007c0},
+	{0x0000b128, 0x00000000},
+	{0x0000b12c, 0x00000000},
+	{0x0000b130, 0x00000000},
+	{0x0000b134, 0x00000000},
+	{0x0000b138, 0x00000000},
+	{0x0000b13c, 0x00000000},
+	{0x0000b140, 0x003f0020},
+	{0x0000b144, 0x00400041},
+	{0x0000b148, 0x0140005f},
+	{0x0000b14c, 0x0160015f},
+	{0x0000b150, 0x017e017f},
+	{0x0000b154, 0x02410242},
+	{0x0000b158, 0x025f0240},
+	{0x0000b15c, 0x027f0260},
+	{0x0000b160, 0x0341027e},
+	{0x0000b164, 0x035f0340},
+	{0x0000b168, 0x037f0360},
+	{0x0000b16c, 0x04400441},
+	{0x0000b170, 0x0460045f},
+	{0x0000b174, 0x0541047f},
+	{0x0000b178, 0x055f0540},
+	{0x0000b17c, 0x057f0560},
+	{0x0000b180, 0x06400641},
+	{0x0000b184, 0x0660065f},
+	{0x0000b188, 0x067e067f},
+	{0x0000b18c, 0x07410742},
+	{0x0000b190, 0x075f0740},
+	{0x0000b194, 0x077f0760},
+	{0x0000b198, 0x07800781},
+	{0x0000b19c, 0x07a0079f},
+	{0x0000b1a0, 0x07c107bf},
+	{0x0000b1a4, 0x000007c0},
+	{0x0000b1a8, 0x00000000},
+	{0x0000b1ac, 0x00000000},
+	{0x0000b1b0, 0x00000000},
+	{0x0000b1b4, 0x00000000},
+	{0x0000b1b8, 0x00000000},
+	{0x0000b1bc, 0x00000000},
+	{0x0000b1c0, 0x00000000},
+	{0x0000b1c4, 0x00000000},
+	{0x0000b1c8, 0x00000000},
+	{0x0000b1cc, 0x00000000},
+	{0x0000b1d0, 0x00000000},
+	{0x0000b1d4, 0x00000000},
+	{0x0000b1d8, 0x00000000},
+	{0x0000b1dc, 0x00000000},
+	{0x0000b1e0, 0x00000000},
+	{0x0000b1e4, 0x00000000},
+	{0x0000b1e8, 0x00000000},
+	{0x0000b1ec, 0x00000000},
+	{0x0000b1f0, 0x00000396},
+	{0x0000b1f4, 0x00000396},
+	{0x0000b1f8, 0x00000396},
+	{0x0000b1fc, 0x00000196},
+};
+
+static const u32 ar9300_2p0_soc_preamble[][2] = {
+	/* Addr      allmodes  */
+	{0x000040a4, 0x00a0c1c9},
+	{0x00007008, 0x00000000},
+	{0x00007020, 0x00000000},
+	{0x00007034, 0x00000002},
+	{0x00007038, 0x000004c2},
+};
+
+/*
+ * PCIE-PHY programming array, to be used prior to entering
+ * full sleep (holding RTC in reset, PLL is ON in L1 mode)
+ */
+static const u32 ar9300PciePhy_pll_on_clkreq_disable_L1_2p0[][2] = {
+	{0x00004040, 0x08212e5e},
+	{0x00004040, 0x0008003b},
+	{0x00004044, 0x00000000},
+};
+
+/*
+ * PCIE-PHY programming array, to be used when not in
+ * full sleep (holding RTC in reset)
+ */
+static const u32 ar9300PciePhy_clkreq_enable_L1_2p0[][2] = {
+	{0x00004040, 0x08253e5e},
+	{0x00004040, 0x0008003b},
+	{0x00004044, 0x00000000},
+};
+
+/*
+ * PCIE-PHY programming array, to be used prior to entering
+ * full sleep (holding RTC in reset)
+ */
+static const u32 ar9300PciePhy_clkreq_disable_L1_2p0[][2] = {
+	{0x00004040, 0x08213e5e},
+	{0x00004040, 0x0008003b},
+	{0x00004044, 0x00000000},
+};
+
+#endif /* INITVALS_9003_H */
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 9ea4595..a285e17 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -24,6 +24,7 @@
 #include "ar5008_initvals.h"
 #include "ar9001_initvals.h"
 #include "ar9002_initvals.h"
+#include "ar9003_initvals.h"
 
 #define ATH9K_CLOCK_RATE_CCK		22
 #define ATH9K_CLOCK_RATE_5GHZ_OFDM	40
@@ -814,6 +815,77 @@ static void ar9002_hw_init_mode_regs(struct ath_hw *ah)
 	}
 }
 
+/* AR9003 2.0 - new INI format (pre, core, post arrays per subsystem) */
+static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
+{
+	/* mac */
+	INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0);
+	INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE],
+		       ar9300_2p0_mac_core,
+		       ARRAY_SIZE(ar9300_2p0_mac_core), 2);
+	INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST],
+		       ar9300_2p0_mac_postamble,
+		       ARRAY_SIZE(ar9300_2p0_mac_postamble), 5);
+
+	/* bb */
+	INIT_INI_ARRAY(&ah->iniBB[ATH_INI_PRE], NULL, 0, 0);
+	INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE],
+		       ar9300_2p0_baseband_core,
+		       ARRAY_SIZE(ar9300_2p0_baseband_core), 2);
+	INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST],
+		       ar9300_2p0_baseband_postamble,
+		       ARRAY_SIZE(ar9300_2p0_baseband_postamble), 5);
+
+	/* radio */
+	INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_PRE], NULL, 0, 0);
+	INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE],
+		       ar9300_2p0_radio_core,
+		       ARRAY_SIZE(ar9300_2p0_radio_core), 2);
+	INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST],
+		       ar9300_2p0_radio_postamble,
+		       ARRAY_SIZE(ar9300_2p0_radio_postamble), 5);
+
+	/* soc */
+	INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE],
+		       ar9300_2p0_soc_preamble,
+		       ARRAY_SIZE(ar9300_2p0_soc_preamble), 2);
+	INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_CORE], NULL, 0, 0);
+	INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST],
+		       ar9300_2p0_soc_postamble,
+		       ARRAY_SIZE(ar9300_2p0_soc_postamble), 5);
+
+	/* rx/tx gain */
+	INIT_INI_ARRAY(&ah->iniModesRxGain,
+		       ar9300Common_rx_gain_table_2p0,
+		       ARRAY_SIZE(ar9300Common_rx_gain_table_2p0), 2);
+	INIT_INI_ARRAY(&ah->iniModesTxGain,
+		       ar9300Modes_lowest_ob_db_tx_gain_table_2p0,
+		       ARRAY_SIZE(ar9300Modes_lowest_ob_db_tx_gain_table_2p0),
+		       5);
+
+	/* Load PCIE SERDES settings from INI */
+
+	/* Awake Setting */
+
+	INIT_INI_ARRAY(&ah->iniPcieSerdes,
+		       ar9300PciePhy_pll_on_clkreq_disable_L1_2p0,
+		       ARRAY_SIZE(ar9300PciePhy_pll_on_clkreq_disable_L1_2p0),
+		       2);
+
+	/* Sleep Setting */
+
+	INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower,
+		       ar9300PciePhy_clkreq_enable_L1_2p0,
+		       ARRAY_SIZE(ar9300PciePhy_clkreq_enable_L1_2p0),
+		       2);
+
+	/* Fast clock modal settings */
+	INIT_INI_ARRAY(&ah->iniModesAdditional,
+		       ar9300Modes_fast_clock_2p0,
+		       ARRAY_SIZE(ar9300Modes_fast_clock_2p0),
+		       3);
+}
+
 static void ath9k_hw_init_mode_gain_regs(struct ath_hw *ah)
 {
 	if (AR_SREV_9287_11_OR_LATER(ah))
@@ -3582,6 +3654,7 @@ static void ar9003_hw_attach_ops(struct ath_hw *ah)
 {
 	struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
 
+	priv_ops->init_mode_regs = ar9003_hw_init_mode_regs;
 	priv_ops->macversion_supported = ar9003_hw_macversion_supported;
 
 	ar9003_hw_attach_phy_ops(ah);
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index d713ff2..c3928be 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -139,6 +139,13 @@
 #define ATH9K_HW_RX_HP_QDEPTH	16
 #define ATH9K_HW_RX_LP_QDEPTH	128
 
+enum ath_ini_subsys {
+	ATH_INI_PRE = 0,
+	ATH_INI_CORE,
+	ATH_INI_POST,
+	ATH_INI_NUM_SPLIT,
+};
+
 enum wireless_mode {
 	ATH9K_MODE_11A = 0,
 	ATH9K_MODE_11G,
@@ -668,6 +675,7 @@ struct ath_hw {
 	struct ar5416IniArray iniBank7;
 	struct ar5416IniArray iniAddac;
 	struct ar5416IniArray iniPcieSerdes;
+	struct ar5416IniArray iniPcieSerdesLowPower;
 	struct ar5416IniArray iniModesAdditional;
 	struct ar5416IniArray iniModesRxGain;
 	struct ar5416IniArray iniModesTxGain;
@@ -680,6 +688,11 @@ struct ath_hw {
 	struct ar5416IniArray iniModes_high_power_tx_gain_9271;
 	struct ar5416IniArray iniModes_normal_power_tx_gain_9271;
 
+	struct ar5416IniArray iniMac[ATH_INI_NUM_SPLIT];
+	struct ar5416IniArray iniBB[ATH_INI_NUM_SPLIT];
+	struct ar5416IniArray iniRadio[ATH_INI_NUM_SPLIT];
+	struct ar5416IniArray iniSOC[ATH_INI_NUM_SPLIT];
+
 	u32 intr_gen_timer_trigger;
 	u32 intr_gen_timer_thresh;
 	struct ath_gen_timer_table hw_gen_timers;
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 103+ messages in thread

* [PATCH v3 33/97] ath9k_hw: add helpers for processing the AR9003 INI
  2010-04-15 21:38 [PATCH v3 00/97] ath9k: add AR9003 support Luis R. Rodriguez
                   ` (31 preceding siblings ...)
  2010-04-15 21:38 ` [PATCH v3 32/97] ath9k_hw: add initvals for the AR9003 " Luis R. Rodriguez
@ 2010-04-15 21:38 ` Luis R. Rodriguez
  2010-04-15 21:38 ` [PATCH v3 34/97] ath9k_hw: Split off ANI control to the PHY ops Luis R. Rodriguez
                   ` (63 subsequent siblings)
  96 siblings, 0 replies; 103+ messages in thread
From: Luis R. Rodriguez @ 2010-04-15 21:38 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Luis R. Rodriguez, Felix Fietkau

Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
 drivers/net/wireless/ath/ath9k/ar9003_phy.c |  186 ++++++++++++++++++++++++++-
 drivers/net/wireless/ath/ath9k/ar9003_phy.h |    2 +
 drivers/net/wireless/ath/ath9k/reg.h        |   13 ++
 3 files changed, 198 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
index 3e3472e..acbf122 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
@@ -186,7 +186,40 @@ static u32 ar9003_hw_compute_pll_control(struct ath_hw *ah,
 static void ar9003_hw_set_channel_regs(struct ath_hw *ah,
 				       struct ath9k_channel *chan)
 {
-	/* TODO */
+	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,
@@ -195,11 +228,158 @@ static void ar9003_hw_init_bb(struct ath_hw *ah,
 	/* TODO */
 }
 
+void ar9003_hw_set_chain_masks(struct ath_hw *ah, u8 rx, u8 tx)
+{
+	switch (rx) {
+	case 0x5:
+		REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP,
+			    AR_PHY_SWAP_ALT_CHAIN);
+	case 0x3:
+	case 0x1:
+	case 0x2:
+	case 0x7:
+		REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx);
+		REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx);
+		break;
+	default:
+		break;
+	}
+
+	REG_WRITE(ah, AR_SELFGEN_MASK, tx);
+	if (tx == 0x5) {
+		REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP,
+			    AR_PHY_SWAP_ALT_CHAIN);
+	}
+}
+
+/*
+ * Override INI values with chip specific configuration.
+ */
+static void ar9003_hw_override_ini(struct ath_hw *ah)
+{
+	u32 val;
+
+	/*
+	 * Set the RX_ABORT and RX_DIS and clear it only after
+	 * RXE is set for MAC. This prevents frames with
+	 * corrupted descriptor status.
+	 */
+	REG_SET_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
+
+	/*
+	 * For AR9280 and above, there is a new feature that allows
+	 * Multicast search based on both MAC Address and Key ID. By default,
+	 * this feature is enabled. But since the driver is not using this
+	 * feature, we switch it off; otherwise multicast search based on
+	 * MAC addr only will fail.
+	 */
+	val = REG_READ(ah, AR_PCU_MISC_MODE2) & (~AR_ADHOC_MCAST_KEYID_ENABLE);
+	REG_WRITE(ah, AR_PCU_MISC_MODE2,
+		  val | AR_AGG_WEP_ENABLE_FIX | AR_AGG_WEP_ENABLE);
+}
+
+static void ar9003_hw_prog_ini(struct ath_hw *ah,
+			       struct ar5416IniArray *iniArr,
+			       int column)
+{
+	unsigned int i, regWrites = 0;
+
+	/* New INI format: Array may be undefined (pre, core, post arrays) */
+	if (!iniArr->ia_array)
+		return;
+
+	/*
+	 * New INI format: Pre, core, and post arrays for a given subsystem
+	 * may be modal (> 2 columns) or non-modal (2 columns). Determine if
+	 * the array is non-modal and force the column to 1.
+	 */
+	if (column >= iniArr->ia_columns)
+		column = 1;
+
+	for (i = 0; i < iniArr->ia_rows; i++) {
+		u32 reg = INI_RA(iniArr, i, 0);
+		u32 val = INI_RA(iniArr, i, column);
+
+		REG_WRITE(ah, reg, val);
+
+		/*
+		 * Determine if this is a shift register value, and insert the
+		 * configured delay if so.
+		 */
+		if (reg >= 0x16000 && reg < 0x17000
+		    && ah->config.analog_shiftreg)
+			udelay(100);
+
+		DO_DELAY(regWrites);
+	}
+}
+
 static int ar9003_hw_process_ini(struct ath_hw *ah,
 				 struct ath9k_channel *chan)
 {
-	/* TODO */
-	return -1;
+	struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
+	unsigned int regWrites = 0, i;
+	struct ieee80211_channel *channel = chan->chan;
+	u32 modesIndex, freqIndex;
+
+	switch (chan->chanmode) {
+	case CHANNEL_A:
+	case CHANNEL_A_HT20:
+		modesIndex = 1;
+		freqIndex = 1;
+		break;
+	case CHANNEL_A_HT40PLUS:
+	case CHANNEL_A_HT40MINUS:
+		modesIndex = 2;
+		freqIndex = 1;
+		break;
+	case CHANNEL_G:
+	case CHANNEL_G_HT20:
+	case CHANNEL_B:
+		modesIndex = 4;
+		freqIndex = 2;
+		break;
+	case CHANNEL_G_HT40PLUS:
+	case CHANNEL_G_HT40MINUS:
+		modesIndex = 3;
+		freqIndex = 2;
+		break;
+
+	default:
+		return -EINVAL;
+	}
+
+	for (i = 0; i < ATH_INI_NUM_SPLIT; i++) {
+		ar9003_hw_prog_ini(ah, &ah->iniSOC[i], modesIndex);
+		ar9003_hw_prog_ini(ah, &ah->iniMac[i], modesIndex);
+		ar9003_hw_prog_ini(ah, &ah->iniBB[i], modesIndex);
+		ar9003_hw_prog_ini(ah, &ah->iniRadio[i], modesIndex);
+	}
+
+	REG_WRITE_ARRAY(&ah->iniModesRxGain, 1, regWrites);
+	REG_WRITE_ARRAY(&ah->iniModesTxGain, modesIndex, regWrites);
+
+	/*
+	 * For 5GHz channels requiring Fast Clock, apply
+	 * different modal values.
+	 */
+	if (IS_CHAN_A_5MHZ_SPACED(chan))
+		REG_WRITE_ARRAY(&ah->iniModesAdditional,
+				modesIndex, regWrites);
+
+	ar9003_hw_override_ini(ah);
+	ar9003_hw_set_channel_regs(ah, chan);
+	ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask);
+
+	/* Set TX power */
+	ah->eep_ops->set_txpower(ah, chan,
+				 ath9k_regd_get_ctl(regulatory, chan),
+				 channel->max_antenna_gain * 2,
+				 channel->max_power * 2,
+				 min((u32) MAX_RATE_POWER,
+				 (u32) regulatory->power_limit));
+
+	return 0;
 }
 
 static void ar9003_hw_set_rfmode(struct ath_hw *ah,
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.h b/drivers/net/wireless/ath/ath9k/ar9003_phy.h
index 2e51e57..70e647b 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.h
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.h
@@ -801,4 +801,6 @@
 
 #define AR_PHY_BB_WD_STATUS_CLR         0x00000008
 
+void ar9003_hw_set_chain_masks(struct ath_hw *ah, u8 rx, u8 tx);
+
 #endif  /* AR9003_PHY_H */
diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h
index 9d63286..96b2cfe 100644
--- a/drivers/net/wireless/ath/ath9k/reg.h
+++ b/drivers/net/wireless/ath/ath9k/reg.h
@@ -1756,4 +1756,17 @@ enum {
 #define AR9271_CORE_CLOCK	117   /* clock to 117Mhz */
 #define AR9271_TARGET_BAUD_RATE	19200 /* 115200 */
 
+#define AR_AGG_WEP_ENABLE_FIX		0x00000008  /* This allows the use of AR_AGG_WEP_ENABLE */
+#define AR_ADHOC_MCAST_KEYID_ENABLE     0x00000040  /* This bit enables the Multicast search
+						     * based on both MAC Address and Key ID.
+						     * If bit is 0, then Multicast search is
+						     * based on MAC address only.
+						     * For Merlin and above only.
+						     */
+#define AR_AGG_WEP_ENABLE               0x00020000  /* This field enables AGG_WEP feature,
+						     * when it is enable, AGG_WEP would takes
+						     * charge of the encryption interface of
+						     * pcu_txsm.
+						     */
+
 #endif
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 103+ messages in thread

* [PATCH v3 34/97] ath9k_hw: Split off ANI control to the PHY ops
  2010-04-15 21:38 [PATCH v3 00/97] ath9k: add AR9003 support Luis R. Rodriguez
                   ` (32 preceding siblings ...)
  2010-04-15 21:38 ` [PATCH v3 33/97] ath9k_hw: add helpers for processing the AR9003 INI Luis R. Rodriguez
@ 2010-04-15 21:38 ` Luis R. Rodriguez
  2010-04-15 21:38 ` [PATCH v3 35/97] ath9k_hw: add all the AR9003 PHY callbacks Luis R. Rodriguez
                   ` (62 subsequent siblings)
  96 siblings, 0 replies; 103+ messages in thread
From: Luis R. Rodriguez @ 2010-04-15 21:38 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Felix Fietkau

From: Felix Fietkau <nbd@openwrt.org>

Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
 drivers/net/wireless/ath/ath9k/ani.c        |  186 +--------------------------
 drivers/net/wireless/ath/ath9k/ar5008_phy.c |  184 ++++++++++++++++++++++++++
 drivers/net/wireless/ath/ath9k/ar9003_phy.c |    8 +
 drivers/net/wireless/ath/ath9k/hw-ops.h     |    6 +
 drivers/net/wireless/ath/ath9k/hw.h         |    2 +
 5 files changed, 201 insertions(+), 185 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c
index 031802c..5a2d867 100644
--- a/drivers/net/wireless/ath/ath9k/ani.c
+++ b/drivers/net/wireless/ath/ath9k/ani.c
@@ -15,7 +15,7 @@
  */
 
 #include "hw.h"
-#include "ar9002_phy.h"
+#include "hw-ops.h"
 
 static int ath9k_hw_get_ani_channel_idx(struct ath_hw *ah,
 					struct ath9k_channel *chan)
@@ -38,190 +38,6 @@ static int ath9k_hw_get_ani_channel_idx(struct ath_hw *ah,
 	return 0;
 }
 
-static bool ath9k_hw_ani_control(struct ath_hw *ah,
-				 enum ath9k_ani_cmd cmd, int param)
-{
-	struct ar5416AniState *aniState = ah->curani;
-	struct ath_common *common = ath9k_hw_common(ah);
-
-	switch (cmd & ah->ani_function) {
-	case ATH9K_ANI_NOISE_IMMUNITY_LEVEL:{
-		u32 level = param;
-
-		if (level >= ARRAY_SIZE(ah->totalSizeDesired)) {
-			ath_print(common, ATH_DBG_ANI,
-				  "level out of range (%u > %u)\n",
-				  level,
-				  (unsigned)ARRAY_SIZE(ah->totalSizeDesired));
-			return false;
-		}
-
-		REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ,
-			      AR_PHY_DESIRED_SZ_TOT_DES,
-			      ah->totalSizeDesired[level]);
-		REG_RMW_FIELD(ah, AR_PHY_AGC_CTL1,
-			      AR_PHY_AGC_CTL1_COARSE_LOW,
-			      ah->coarse_low[level]);
-		REG_RMW_FIELD(ah, AR_PHY_AGC_CTL1,
-			      AR_PHY_AGC_CTL1_COARSE_HIGH,
-			      ah->coarse_high[level]);
-		REG_RMW_FIELD(ah, AR_PHY_FIND_SIG,
-			      AR_PHY_FIND_SIG_FIRPWR,
-			      ah->firpwr[level]);
-
-		if (level > aniState->noiseImmunityLevel)
-			ah->stats.ast_ani_niup++;
-		else if (level < aniState->noiseImmunityLevel)
-			ah->stats.ast_ani_nidown++;
-		aniState->noiseImmunityLevel = level;
-		break;
-	}
-	case ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION:{
-		const int m1ThreshLow[] = { 127, 50 };
-		const int m2ThreshLow[] = { 127, 40 };
-		const int m1Thresh[] = { 127, 0x4d };
-		const int m2Thresh[] = { 127, 0x40 };
-		const int m2CountThr[] = { 31, 16 };
-		const int m2CountThrLow[] = { 63, 48 };
-		u32 on = param ? 1 : 0;
-
-		REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
-			      AR_PHY_SFCORR_LOW_M1_THRESH_LOW,
-			      m1ThreshLow[on]);
-		REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
-			      AR_PHY_SFCORR_LOW_M2_THRESH_LOW,
-			      m2ThreshLow[on]);
-		REG_RMW_FIELD(ah, AR_PHY_SFCORR,
-			      AR_PHY_SFCORR_M1_THRESH,
-			      m1Thresh[on]);
-		REG_RMW_FIELD(ah, AR_PHY_SFCORR,
-			      AR_PHY_SFCORR_M2_THRESH,
-			      m2Thresh[on]);
-		REG_RMW_FIELD(ah, AR_PHY_SFCORR,
-			      AR_PHY_SFCORR_M2COUNT_THR,
-			      m2CountThr[on]);
-		REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
-			      AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW,
-			      m2CountThrLow[on]);
-
-		REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
-			      AR_PHY_SFCORR_EXT_M1_THRESH_LOW,
-			      m1ThreshLow[on]);
-		REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
-			      AR_PHY_SFCORR_EXT_M2_THRESH_LOW,
-			      m2ThreshLow[on]);
-		REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
-			      AR_PHY_SFCORR_EXT_M1_THRESH,
-			      m1Thresh[on]);
-		REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
-			      AR_PHY_SFCORR_EXT_M2_THRESH,
-			      m2Thresh[on]);
-
-		if (on)
-			REG_SET_BIT(ah, AR_PHY_SFCORR_LOW,
-				    AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW);
-		else
-			REG_CLR_BIT(ah, AR_PHY_SFCORR_LOW,
-				    AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW);
-
-		if (!on != aniState->ofdmWeakSigDetectOff) {
-			if (on)
-				ah->stats.ast_ani_ofdmon++;
-			else
-				ah->stats.ast_ani_ofdmoff++;
-			aniState->ofdmWeakSigDetectOff = !on;
-		}
-		break;
-	}
-	case ATH9K_ANI_CCK_WEAK_SIGNAL_THR:{
-		const int weakSigThrCck[] = { 8, 6 };
-		u32 high = param ? 1 : 0;
-
-		REG_RMW_FIELD(ah, AR_PHY_CCK_DETECT,
-			      AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK,
-			      weakSigThrCck[high]);
-		if (high != aniState->cckWeakSigThreshold) {
-			if (high)
-				ah->stats.ast_ani_cckhigh++;
-			else
-				ah->stats.ast_ani_ccklow++;
-			aniState->cckWeakSigThreshold = high;
-		}
-		break;
-	}
-	case ATH9K_ANI_FIRSTEP_LEVEL:{
-		const int firstep[] = { 0, 4, 8 };
-		u32 level = param;
-
-		if (level >= ARRAY_SIZE(firstep)) {
-			ath_print(common, ATH_DBG_ANI,
-				  "level out of range (%u > %u)\n",
-				  level,
-				  (unsigned) ARRAY_SIZE(firstep));
-			return false;
-		}
-		REG_RMW_FIELD(ah, AR_PHY_FIND_SIG,
-			      AR_PHY_FIND_SIG_FIRSTEP,
-			      firstep[level]);
-		if (level > aniState->firstepLevel)
-			ah->stats.ast_ani_stepup++;
-		else if (level < aniState->firstepLevel)
-			ah->stats.ast_ani_stepdown++;
-		aniState->firstepLevel = level;
-		break;
-	}
-	case ATH9K_ANI_SPUR_IMMUNITY_LEVEL:{
-		const int cycpwrThr1[] =
-			{ 2, 4, 6, 8, 10, 12, 14, 16 };
-		u32 level = param;
-
-		if (level >= ARRAY_SIZE(cycpwrThr1)) {
-			ath_print(common, ATH_DBG_ANI,
-				  "level out of range (%u > %u)\n",
-				  level,
-				  (unsigned) ARRAY_SIZE(cycpwrThr1));
-			return false;
-		}
-		REG_RMW_FIELD(ah, AR_PHY_TIMING5,
-			      AR_PHY_TIMING5_CYCPWR_THR1,
-			      cycpwrThr1[level]);
-		if (level > aniState->spurImmunityLevel)
-			ah->stats.ast_ani_spurup++;
-		else if (level < aniState->spurImmunityLevel)
-			ah->stats.ast_ani_spurdown++;
-		aniState->spurImmunityLevel = level;
-		break;
-	}
-	case ATH9K_ANI_PRESENT:
-		break;
-	default:
-		ath_print(common, ATH_DBG_ANI,
-			  "invalid cmd %u\n", cmd);
-		return false;
-	}
-
-	ath_print(common, ATH_DBG_ANI, "ANI parameters:\n");
-	ath_print(common, ATH_DBG_ANI,
-		  "noiseImmunityLevel=%d, spurImmunityLevel=%d, "
-		  "ofdmWeakSigDetectOff=%d\n",
-		  aniState->noiseImmunityLevel,
-		  aniState->spurImmunityLevel,
-		  !aniState->ofdmWeakSigDetectOff);
-	ath_print(common, ATH_DBG_ANI,
-		  "cckWeakSigThreshold=%d, "
-		  "firstepLevel=%d, listenTime=%d\n",
-		  aniState->cckWeakSigThreshold,
-		  aniState->firstepLevel,
-		  aniState->listenTime);
-	ath_print(common, ATH_DBG_ANI,
-		"cycleCount=%d, ofdmPhyErrCount=%d, cckPhyErrCount=%d\n\n",
-		aniState->cycleCount,
-		aniState->ofdmPhyErrCount,
-		aniState->cckPhyErrCount);
-
-	return true;
-}
-
 static void ath9k_hw_update_mibstats(struct ath_hw *ah,
 				     struct ath9k_mib_stats *stats)
 {
diff --git a/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
index 9685f4c..dddca59 100644
--- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
@@ -1015,6 +1015,189 @@ static u32 ar5008_hw_compute_pll_control(struct ath_hw *ah,
 	return pll;
 }
 
+static bool ar5008_hw_ani_control(struct ath_hw *ah,
+				  enum ath9k_ani_cmd cmd, int param)
+{
+	struct ar5416AniState *aniState = ah->curani;
+	struct ath_common *common = ath9k_hw_common(ah);
+
+	switch (cmd & ah->ani_function) {
+	case ATH9K_ANI_NOISE_IMMUNITY_LEVEL:{
+		u32 level = param;
+
+		if (level >= ARRAY_SIZE(ah->totalSizeDesired)) {
+			ath_print(common, ATH_DBG_ANI,
+				  "level out of range (%u > %u)\n",
+				  level,
+				  (unsigned)ARRAY_SIZE(ah->totalSizeDesired));
+			return false;
+		}
+
+		REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ,
+			      AR_PHY_DESIRED_SZ_TOT_DES,
+			      ah->totalSizeDesired[level]);
+		REG_RMW_FIELD(ah, AR_PHY_AGC_CTL1,
+			      AR_PHY_AGC_CTL1_COARSE_LOW,
+			      ah->coarse_low[level]);
+		REG_RMW_FIELD(ah, AR_PHY_AGC_CTL1,
+			      AR_PHY_AGC_CTL1_COARSE_HIGH,
+			      ah->coarse_high[level]);
+		REG_RMW_FIELD(ah, AR_PHY_FIND_SIG,
+			      AR_PHY_FIND_SIG_FIRPWR,
+			      ah->firpwr[level]);
+
+		if (level > aniState->noiseImmunityLevel)
+			ah->stats.ast_ani_niup++;
+		else if (level < aniState->noiseImmunityLevel)
+			ah->stats.ast_ani_nidown++;
+		aniState->noiseImmunityLevel = level;
+		break;
+	}
+	case ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION:{
+		const int m1ThreshLow[] = { 127, 50 };
+		const int m2ThreshLow[] = { 127, 40 };
+		const int m1Thresh[] = { 127, 0x4d };
+		const int m2Thresh[] = { 127, 0x40 };
+		const int m2CountThr[] = { 31, 16 };
+		const int m2CountThrLow[] = { 63, 48 };
+		u32 on = param ? 1 : 0;
+
+		REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
+			      AR_PHY_SFCORR_LOW_M1_THRESH_LOW,
+			      m1ThreshLow[on]);
+		REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
+			      AR_PHY_SFCORR_LOW_M2_THRESH_LOW,
+			      m2ThreshLow[on]);
+		REG_RMW_FIELD(ah, AR_PHY_SFCORR,
+			      AR_PHY_SFCORR_M1_THRESH,
+			      m1Thresh[on]);
+		REG_RMW_FIELD(ah, AR_PHY_SFCORR,
+			      AR_PHY_SFCORR_M2_THRESH,
+			      m2Thresh[on]);
+		REG_RMW_FIELD(ah, AR_PHY_SFCORR,
+			      AR_PHY_SFCORR_M2COUNT_THR,
+			      m2CountThr[on]);
+		REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
+			      AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW,
+			      m2CountThrLow[on]);
+
+		REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
+			      AR_PHY_SFCORR_EXT_M1_THRESH_LOW,
+			      m1ThreshLow[on]);
+		REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
+			      AR_PHY_SFCORR_EXT_M2_THRESH_LOW,
+			      m2ThreshLow[on]);
+		REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
+			      AR_PHY_SFCORR_EXT_M1_THRESH,
+			      m1Thresh[on]);
+		REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
+			      AR_PHY_SFCORR_EXT_M2_THRESH,
+			      m2Thresh[on]);
+
+		if (on)
+			REG_SET_BIT(ah, AR_PHY_SFCORR_LOW,
+				    AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW);
+		else
+			REG_CLR_BIT(ah, AR_PHY_SFCORR_LOW,
+				    AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW);
+
+		if (!on != aniState->ofdmWeakSigDetectOff) {
+			if (on)
+				ah->stats.ast_ani_ofdmon++;
+			else
+				ah->stats.ast_ani_ofdmoff++;
+			aniState->ofdmWeakSigDetectOff = !on;
+		}
+		break;
+	}
+	case ATH9K_ANI_CCK_WEAK_SIGNAL_THR:{
+		const int weakSigThrCck[] = { 8, 6 };
+		u32 high = param ? 1 : 0;
+
+		REG_RMW_FIELD(ah, AR_PHY_CCK_DETECT,
+			      AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK,
+			      weakSigThrCck[high]);
+		if (high != aniState->cckWeakSigThreshold) {
+			if (high)
+				ah->stats.ast_ani_cckhigh++;
+			else
+				ah->stats.ast_ani_ccklow++;
+			aniState->cckWeakSigThreshold = high;
+		}
+		break;
+	}
+	case ATH9K_ANI_FIRSTEP_LEVEL:{
+		const int firstep[] = { 0, 4, 8 };
+		u32 level = param;
+
+		if (level >= ARRAY_SIZE(firstep)) {
+			ath_print(common, ATH_DBG_ANI,
+				  "level out of range (%u > %u)\n",
+				  level,
+				  (unsigned) ARRAY_SIZE(firstep));
+			return false;
+		}
+		REG_RMW_FIELD(ah, AR_PHY_FIND_SIG,
+			      AR_PHY_FIND_SIG_FIRSTEP,
+			      firstep[level]);
+		if (level > aniState->firstepLevel)
+			ah->stats.ast_ani_stepup++;
+		else if (level < aniState->firstepLevel)
+			ah->stats.ast_ani_stepdown++;
+		aniState->firstepLevel = level;
+		break;
+	}
+	case ATH9K_ANI_SPUR_IMMUNITY_LEVEL:{
+		const int cycpwrThr1[] = { 2, 4, 6, 8, 10, 12, 14, 16 };
+		u32 level = param;
+
+		if (level >= ARRAY_SIZE(cycpwrThr1)) {
+			ath_print(common, ATH_DBG_ANI,
+				  "level out of range (%u > %u)\n",
+				  level,
+				  (unsigned) ARRAY_SIZE(cycpwrThr1));
+			return false;
+		}
+		REG_RMW_FIELD(ah, AR_PHY_TIMING5,
+			      AR_PHY_TIMING5_CYCPWR_THR1,
+			      cycpwrThr1[level]);
+		if (level > aniState->spurImmunityLevel)
+			ah->stats.ast_ani_spurup++;
+		else if (level < aniState->spurImmunityLevel)
+			ah->stats.ast_ani_spurdown++;
+		aniState->spurImmunityLevel = level;
+		break;
+	}
+	case ATH9K_ANI_PRESENT:
+		break;
+	default:
+		ath_print(common, ATH_DBG_ANI,
+			  "invalid cmd %u\n", cmd);
+		return false;
+	}
+
+	ath_print(common, ATH_DBG_ANI, "ANI parameters:\n");
+	ath_print(common, ATH_DBG_ANI,
+		  "noiseImmunityLevel=%d, spurImmunityLevel=%d, "
+		  "ofdmWeakSigDetectOff=%d\n",
+		  aniState->noiseImmunityLevel,
+		  aniState->spurImmunityLevel,
+		  !aniState->ofdmWeakSigDetectOff);
+	ath_print(common, ATH_DBG_ANI,
+		  "cckWeakSigThreshold=%d, "
+		  "firstepLevel=%d, listenTime=%d\n",
+		  aniState->cckWeakSigThreshold,
+		  aniState->firstepLevel,
+		  aniState->listenTime);
+	ath_print(common, ATH_DBG_ANI,
+		"cycleCount=%d, ofdmPhyErrCount=%d, cckPhyErrCount=%d\n\n",
+		aniState->cycleCount,
+		aniState->ofdmPhyErrCount,
+		aniState->cckPhyErrCount);
+
+	return true;
+}
+
 void ar5008_hw_attach_phy_ops(struct ath_hw *ah)
 {
 	struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
@@ -1036,6 +1219,7 @@ void ar5008_hw_attach_phy_ops(struct ath_hw *ah)
 	priv_ops->enable_rfkill = ar5008_hw_enable_rfkill;
 	priv_ops->restore_chainmask = ar5008_restore_chainmask;
 	priv_ops->set_diversity = ar5008_set_diversity;
+	priv_ops->ani_control = ar5008_hw_ani_control;
 
 	if (AR_SREV_9100(ah))
 		priv_ops->compute_pll_control = ar9100_hw_compute_pll_control;
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
index acbf122..356e03d 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
@@ -420,6 +420,13 @@ static void ar9003_hw_set_diversity(struct ath_hw *ah, bool value)
 	/* TODO */
 }
 
+static bool ar9003_hw_ani_control(struct ath_hw *ah,
+				  enum ath9k_ani_cmd cmd, int param)
+{
+	/* TODO */
+	return false;
+}
+
 void ar9003_hw_attach_phy_ops(struct ath_hw *ah)
 {
 	struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
@@ -437,4 +444,5 @@ void ar9003_hw_attach_phy_ops(struct ath_hw *ah)
 	priv_ops->rfbus_done = ar9003_hw_rfbus_done;
 	priv_ops->enable_rfkill = ar9003_hw_enable_rfkill;
 	priv_ops->set_diversity = ar9003_hw_set_diversity;
+	priv_ops->ani_control = ar9003_hw_ani_control;
 }
diff --git a/drivers/net/wireless/ath/ath9k/hw-ops.h b/drivers/net/wireless/ath/ath9k/hw-ops.h
index 19259fb..08a51a2 100644
--- a/drivers/net/wireless/ath/ath9k/hw-ops.h
+++ b/drivers/net/wireless/ath/ath9k/hw-ops.h
@@ -146,4 +146,10 @@ static inline void ath9k_hw_set_diversity(struct ath_hw *ah, bool value)
 	return ath9k_hw_private_ops(ah)->set_diversity(ah, value);
 }
 
+static inline bool ath9k_hw_ani_control(struct ath_hw *ah,
+					enum ath9k_ani_cmd cmd, int param)
+{
+	return ath9k_hw_private_ops(ah)->ani_control(ah, cmd, param);
+}
+
 #endif /* ATH9K_HW_OPS_H */
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index c3928be..b0cfc77 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -508,6 +508,8 @@ struct ath_hw_private_ops {
 	void (*set_diversity)(struct ath_hw *ah, bool value);
 	u32 (*compute_pll_control)(struct ath_hw *ah,
 				   struct ath9k_channel *chan);
+	bool (*ani_control)(struct ath_hw *ah, enum ath9k_ani_cmd cmd,
+			    int param);
 };
 
 /**
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 103+ messages in thread

* [PATCH v3 35/97] ath9k_hw: add all the AR9003 PHY callbacks
  2010-04-15 21:38 [PATCH v3 00/97] ath9k: add AR9003 support Luis R. Rodriguez
                   ` (33 preceding siblings ...)
  2010-04-15 21:38 ` [PATCH v3 34/97] ath9k_hw: Split off ANI control to the PHY ops Luis R. Rodriguez
@ 2010-04-15 21:38 ` Luis R. Rodriguez
  2010-04-15 21:38 ` [PATCH v3 36/97] ath9k_hw: Define tx control struct for AR9003 Luis R. Rodriguez
                   ` (61 subsequent siblings)
  96 siblings, 0 replies; 103+ messages in thread
From: Luis R. Rodriguez @ 2010-04-15 21:38 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Luis R. Rodriguez

Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/ar9003_phy.c |  300 ++++++++++++++++++++++++++-
 1 files changed, 289 insertions(+), 11 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
index 356e03d..c938b85 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
@@ -225,7 +225,30 @@ static void ar9003_hw_set_channel_regs(struct ath_hw *ah,
 static void ar9003_hw_init_bb(struct ath_hw *ah,
 			      struct ath9k_channel *chan)
 {
-	/* TODO */
+	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)
@@ -385,46 +408,301 @@ static int ar9003_hw_process_ini(struct ath_hw *ah,
 static void ar9003_hw_set_rfmode(struct ath_hw *ah,
 				 struct ath9k_channel *chan)
 {
-	/* TODO */
+	u32 rfMode = 0;
+
+	if (chan == NULL)
+		return;
+
+	rfMode |= (IS_CHAN_B(chan) || IS_CHAN_G(chan))
+		? AR_PHY_MODE_DYNAMIC : AR_PHY_MODE_OFDM;
+
+	if (IS_CHAN_A_5MHZ_SPACED(chan))
+		rfMode |= (AR_PHY_MODE_DYNAMIC | AR_PHY_MODE_DYN_CCK_DISABLE);
+
+	REG_WRITE(ah, AR_PHY_MODE, rfMode);
 }
 
 static void ar9003_hw_mark_phy_inactive(struct ath_hw *ah)
 {
-	/* TODO */
+	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)
 {
-	/* TODO */
+	u32 coef_scaled, ds_coef_exp, ds_coef_man;
+	u32 clockMhzScaled = 0x64000000;
+	struct chan_centers centers;
+
+	/*
+	 * half and quarter rate can divide the scaled clock by 2 or 4
+	 * scale for selected channel bandwidth
+	 */
+	if (IS_CHAN_HALF_RATE(chan))
+		clockMhzScaled = clockMhzScaled >> 1;
+	else if (IS_CHAN_QUARTER_RATE(chan))
+		clockMhzScaled = clockMhzScaled >> 2;
+
+	/*
+	 * ALGO -> coef = 1e8/fcarrier*fclock/40;
+	 * scaled coef to provide precision for this floating calculation
+	 */
+	ath9k_hw_get_channel_centers(ah, chan, &centers);
+	coef_scaled = clockMhzScaled / centers.synth_center;
+
+	ath9k_hw_get_delta_slope_vals(ah, coef_scaled, &ds_coef_man,
+				      &ds_coef_exp);
+
+	REG_RMW_FIELD(ah, AR_PHY_TIMING3,
+		      AR_PHY_TIMING3_DSC_MAN, ds_coef_man);
+	REG_RMW_FIELD(ah, AR_PHY_TIMING3,
+		      AR_PHY_TIMING3_DSC_EXP, ds_coef_exp);
+
+	/*
+	 * For Short GI,
+	 * scaled coeff is 9/10 that of normal coeff
+	 */
+	coef_scaled = (9 * coef_scaled) / 10;
+
+	ath9k_hw_get_delta_slope_vals(ah, coef_scaled, &ds_coef_man,
+				      &ds_coef_exp);
+
+	/* for short gi */
+	REG_RMW_FIELD(ah, AR_PHY_SGI_DELTA,
+		      AR_PHY_SGI_DSC_MAN, ds_coef_man);
+	REG_RMW_FIELD(ah, AR_PHY_SGI_DELTA,
+		      AR_PHY_SGI_DSC_EXP, ds_coef_exp);
 }
 
 static bool ar9003_hw_rfbus_req(struct ath_hw *ah)
 {
-	/* TODO */
-	return false;
+	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)
 {
-	/* TODO */
+	u32 synthDelay = REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY;
+	if (IS_CHAN_B(ah->curchan))
+		synthDelay = (4 * synthDelay) / 22;
+	else
+		synthDelay /= 10;
+
+	udelay(synthDelay + BASE_ACTIVATE_DELAY);
+
+	REG_WRITE(ah, AR_PHY_RFBUS_REQ, 0);
 }
 
+/*
+ * Set the interrupt and GPIO values so the ISR can disable RF
+ * on a switch signal.  Assumes GPIO port and interrupt polarity
+ * are set prior to call.
+ */
 static void ar9003_hw_enable_rfkill(struct ath_hw *ah)
 {
-	/* TODO */
+	/* Connect rfsilent_bb_l to baseband */
+	REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL,
+		    AR_GPIO_INPUT_EN_VAL_RFSILENT_BB);
+	/* Set input mux for rfsilent_bb_l to GPIO #0 */
+	REG_CLR_BIT(ah, AR_GPIO_INPUT_MUX2,
+		    AR_GPIO_INPUT_MUX2_RFSILENT);
+
+	/*
+	 * Configure the desired GPIO port for input and
+	 * enable baseband rf silence.
+	 */
+	ath9k_hw_cfg_gpio_input(ah, ah->rfkill_gpio);
+	REG_SET_BIT(ah, AR_PHY_TEST, RFSILENT_BB);
 }
 
 static void ar9003_hw_set_diversity(struct ath_hw *ah, bool value)
 {
-	/* TODO */
+	u32 v = REG_READ(ah, AR_PHY_CCK_DETECT);
+	if (value)
+		v |= AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV;
+	else
+		v &= ~AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV;
+	REG_WRITE(ah, AR_PHY_CCK_DETECT, v);
 }
 
 static bool ar9003_hw_ani_control(struct ath_hw *ah,
 				  enum ath9k_ani_cmd cmd, int param)
 {
-	/* TODO */
-	return false;
+	struct ar5416AniState *aniState = ah->curani;
+	struct ath_common *common = ath9k_hw_common(ah);
+
+	switch (cmd & ah->ani_function) {
+	case ATH9K_ANI_NOISE_IMMUNITY_LEVEL:{
+		u32 level = param;
+
+		if (level >= ARRAY_SIZE(ah->totalSizeDesired)) {
+			ath_print(common, ATH_DBG_ANI,
+				  "level out of range (%u > %u)\n",
+				  level,
+				  (unsigned)ARRAY_SIZE(ah->totalSizeDesired));
+			return false;
+		}
+
+		REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ,
+			      AR_PHY_DESIRED_SZ_TOT_DES,
+			      ah->totalSizeDesired[level]);
+		REG_RMW_FIELD(ah, AR_PHY_AGC,
+			      AR_PHY_AGC_COARSE_LOW,
+			      ah->coarse_low[level]);
+		REG_RMW_FIELD(ah, AR_PHY_AGC,
+			      AR_PHY_AGC_COARSE_HIGH,
+			      ah->coarse_high[level]);
+		REG_RMW_FIELD(ah, AR_PHY_FIND_SIG,
+			      AR_PHY_FIND_SIG_FIRPWR, ah->firpwr[level]);
+
+		if (level > aniState->noiseImmunityLevel)
+			ah->stats.ast_ani_niup++;
+		else if (level < aniState->noiseImmunityLevel)
+			ah->stats.ast_ani_nidown++;
+		aniState->noiseImmunityLevel = level;
+		break;
+	}
+	case ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION:{
+		const int m1ThreshLow[] = { 127, 50 };
+		const int m2ThreshLow[] = { 127, 40 };
+		const int m1Thresh[] = { 127, 0x4d };
+		const int m2Thresh[] = { 127, 0x40 };
+		const int m2CountThr[] = { 31, 16 };
+		const int m2CountThrLow[] = { 63, 48 };
+		u32 on = param ? 1 : 0;
+
+		REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
+			      AR_PHY_SFCORR_LOW_M1_THRESH_LOW,
+			      m1ThreshLow[on]);
+		REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
+			      AR_PHY_SFCORR_LOW_M2_THRESH_LOW,
+			      m2ThreshLow[on]);
+		REG_RMW_FIELD(ah, AR_PHY_SFCORR,
+			      AR_PHY_SFCORR_M1_THRESH, m1Thresh[on]);
+		REG_RMW_FIELD(ah, AR_PHY_SFCORR,
+			      AR_PHY_SFCORR_M2_THRESH, m2Thresh[on]);
+		REG_RMW_FIELD(ah, AR_PHY_SFCORR,
+			      AR_PHY_SFCORR_M2COUNT_THR, m2CountThr[on]);
+		REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
+			      AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW,
+			      m2CountThrLow[on]);
+
+		REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
+			      AR_PHY_SFCORR_EXT_M1_THRESH_LOW, m1ThreshLow[on]);
+		REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
+			      AR_PHY_SFCORR_EXT_M2_THRESH_LOW, m2ThreshLow[on]);
+		REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
+			      AR_PHY_SFCORR_EXT_M1_THRESH, m1Thresh[on]);
+		REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
+			      AR_PHY_SFCORR_EXT_M2_THRESH, m2Thresh[on]);
+
+		if (on)
+			REG_SET_BIT(ah, AR_PHY_SFCORR_LOW,
+				    AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW);
+		else
+			REG_CLR_BIT(ah, AR_PHY_SFCORR_LOW,
+				    AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW);
+
+		if (!on != aniState->ofdmWeakSigDetectOff) {
+			if (on)
+				ah->stats.ast_ani_ofdmon++;
+			else
+				ah->stats.ast_ani_ofdmoff++;
+			aniState->ofdmWeakSigDetectOff = !on;
+		}
+		break;
+	}
+	case ATH9K_ANI_CCK_WEAK_SIGNAL_THR:{
+		const int weakSigThrCck[] = { 8, 6 };
+		u32 high = param ? 1 : 0;
+
+		REG_RMW_FIELD(ah, AR_PHY_CCK_DETECT,
+			      AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK,
+			      weakSigThrCck[high]);
+		if (high != aniState->cckWeakSigThreshold) {
+			if (high)
+				ah->stats.ast_ani_cckhigh++;
+			else
+				ah->stats.ast_ani_ccklow++;
+			aniState->cckWeakSigThreshold = high;
+		}
+		break;
+	}
+	case ATH9K_ANI_FIRSTEP_LEVEL:{
+		const int firstep[] = { 0, 4, 8 };
+		u32 level = param;
+
+		if (level >= ARRAY_SIZE(firstep)) {
+			ath_print(common, ATH_DBG_ANI,
+				  "level out of range (%u > %u)\n",
+				  level,
+				  (unsigned) ARRAY_SIZE(firstep));
+			return false;
+		}
+		REG_RMW_FIELD(ah, AR_PHY_FIND_SIG,
+			      AR_PHY_FIND_SIG_FIRSTEP,
+			      firstep[level]);
+		if (level > aniState->firstepLevel)
+			ah->stats.ast_ani_stepup++;
+		else if (level < aniState->firstepLevel)
+			ah->stats.ast_ani_stepdown++;
+		aniState->firstepLevel = level;
+		break;
+	}
+	case ATH9K_ANI_SPUR_IMMUNITY_LEVEL:{
+		const int cycpwrThr1[] = { 2, 4, 6, 8, 10, 12, 14, 16 };
+		u32 level = param;
+
+		if (level >= ARRAY_SIZE(cycpwrThr1)) {
+			ath_print(common, ATH_DBG_ANI,
+				  "level out of range (%u > %u)\n",
+				  level,
+				  (unsigned) ARRAY_SIZE(cycpwrThr1));
+			return false;
+		}
+		REG_RMW_FIELD(ah, AR_PHY_TIMING5,
+			      AR_PHY_TIMING5_CYCPWR_THR1,
+			      cycpwrThr1[level]);
+		if (level > aniState->spurImmunityLevel)
+			ah->stats.ast_ani_spurup++;
+		else if (level < aniState->spurImmunityLevel)
+			ah->stats.ast_ani_spurdown++;
+		aniState->spurImmunityLevel = level;
+		break;
+	}
+	case ATH9K_ANI_PRESENT:
+		break;
+	default:
+		ath_print(common, ATH_DBG_ANI,
+			  "invalid cmd %u\n", cmd);
+		return false;
+	}
+
+	ath_print(common, ATH_DBG_ANI, "ANI parameters:\n");
+	ath_print(common, ATH_DBG_ANI,
+		  "noiseImmunityLevel=%d, spurImmunityLevel=%d, "
+		  "ofdmWeakSigDetectOff=%d\n",
+		  aniState->noiseImmunityLevel,
+		  aniState->spurImmunityLevel,
+		  !aniState->ofdmWeakSigDetectOff);
+	ath_print(common, ATH_DBG_ANI,
+		  "cckWeakSigThreshold=%d, "
+		  "firstepLevel=%d, listenTime=%d\n",
+		  aniState->cckWeakSigThreshold,
+		  aniState->firstepLevel,
+		  aniState->listenTime);
+	ath_print(common, ATH_DBG_ANI,
+		"cycleCount=%d, ofdmPhyErrCount=%d, cckPhyErrCount=%d\n\n",
+		aniState->cycleCount,
+		aniState->ofdmPhyErrCount,
+		aniState->cckPhyErrCount);
+
+	return true;
 }
 
 void ar9003_hw_attach_phy_ops(struct ath_hw *ah)
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 103+ messages in thread

* [PATCH v3 36/97] ath9k_hw: Define tx control struct for AR9003
  2010-04-15 21:38 [PATCH v3 00/97] ath9k: add AR9003 support Luis R. Rodriguez
                   ` (34 preceding siblings ...)
  2010-04-15 21:38 ` [PATCH v3 35/97] ath9k_hw: add all the AR9003 PHY callbacks Luis R. Rodriguez
@ 2010-04-15 21:38 ` Luis R. Rodriguez
  2010-04-15 21:38 ` [PATCH v3 37/97] ath9k_hw: Move code which populates ds_data to ath9k_hw Luis R. Rodriguez
                   ` (60 subsequent siblings)
  96 siblings, 0 replies; 103+ messages in thread
From: Luis R. Rodriguez @ 2010-04-15 21:38 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Vasanthakumar Thiagarajan

From: Vasanthakumar Thiagarajan <vasanth@atheros.com>

Store appropriate desc length which will be used by the
ath9k module while duplicating tx desc.

Signed-off-by: Vasanthakumar Thiagarajan <vasanth@atheros.com>
---
 drivers/net/wireless/ath/ath9k/ar9003_mac.h |   28 +++++++++++++++++++++++++++
 drivers/net/wireless/ath/ath9k/hw.c         |    3 ++
 drivers/net/wireless/ath/ath9k/hw.h         |    1 +
 3 files changed, 32 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.h b/drivers/net/wireless/ath/ath9k/ar9003_mac.h
index b22f78c..7374439 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_mac.h
+++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.h
@@ -37,6 +37,34 @@ struct ar9003_rxs {
 	u32 status11;
 } __packed;
 
+/* Transmit Control Descriptor */
+struct ar9003_txc {
+	u32 info;   /* descriptor information */
+	u32 link;   /* link pointer */
+	u32 data0;  /* data pointer to 1st buffer */
+	u32 ctl3;   /* DMA control 3  */
+	u32 data1;  /* data pointer to 2nd buffer */
+	u32 ctl5;   /* DMA control 5  */
+	u32 data2;  /* data pointer to 3rd buffer */
+	u32 ctl7;   /* DMA control 7  */
+	u32 data3;  /* data pointer to 4th buffer */
+	u32 ctl9;   /* DMA control 9  */
+	u32 ctl10;  /* DMA control 10 */
+	u32 ctl11;  /* DMA control 11 */
+	u32 ctl12;  /* DMA control 12 */
+	u32 ctl13;  /* DMA control 13 */
+	u32 ctl14;  /* DMA control 14 */
+	u32 ctl15;  /* DMA control 15 */
+	u32 ctl16;  /* DMA control 16 */
+	u32 ctl17;  /* DMA control 17 */
+	u32 ctl18;  /* DMA control 18 */
+	u32 ctl19;  /* DMA control 19 */
+	u32 ctl20;  /* DMA control 20 */
+	u32 ctl21;  /* DMA control 21 */
+	u32 ctl22;  /* DMA control 22 */
+	u32 pad[9]; /* pad to cache line (128 bytes/32 dwords) */
+} __packed;
+
 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,
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index a285e17..aa80d43 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -2962,6 +2962,9 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
 		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);
+	} else {
+		pCap->tx_desc_len = sizeof(struct ath_desc);
 	}
 
 	return 0;
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index b0cfc77..ce9d12b 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -206,6 +206,7 @@ struct ath9k_hw_capabilities {
 	u8 rx_hp_qdepth;
 	u8 rx_lp_qdepth;
 	u8 rx_status_len;
+	u8 tx_desc_len;
 };
 
 struct ath9k_ops_config {
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 103+ messages in thread

* [PATCH v3 37/97] ath9k_hw: Move code which populates ds_data to ath9k_hw
  2010-04-15 21:38 [PATCH v3 00/97] ath9k: add AR9003 support Luis R. Rodriguez
                   ` (35 preceding siblings ...)
  2010-04-15 21:38 ` [PATCH v3 36/97] ath9k_hw: Define tx control struct for AR9003 Luis R. Rodriguez
@ 2010-04-15 21:38 ` Luis R. Rodriguez
  2010-04-15 21:38 ` [PATCH v3 38/97] ath9k_hw: Add abstraction to set/get link pointer Luis R. Rodriguez
                   ` (59 subsequent siblings)
  96 siblings, 0 replies; 103+ messages in thread
From: Luis R. Rodriguez @ 2010-04-15 21:38 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Vasanthakumar Thiagarajan

From: Vasanthakumar Thiagarajan <vasanth@atheros.com>

Signed-off-by: Vasanthakumar Thiagarajan <vasanth@atheros.com>
---
 drivers/net/wireless/ath/ath9k/beacon.c |    4 +---
 drivers/net/wireless/ath/ath9k/mac.c    |    5 ++++-
 drivers/net/wireless/ath/ath9k/mac.h    |    3 ++-
 drivers/net/wireless/ath/ath9k/xmit.c   |    4 ++--
 4 files changed, 9 insertions(+), 7 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c
index 22375a7..268b598 100644
--- a/drivers/net/wireless/ath/ath9k/beacon.c
+++ b/drivers/net/wireless/ath/ath9k/beacon.c
@@ -93,8 +93,6 @@ static void ath_beacon_setup(struct ath_softc *sc, struct ath_vif *avp,
 		antenna = ((sc->beacon.ast_be_xmit / sc->nbcnvifs) & 1 ? 2 : 1);
 	}
 
-	ds->ds_data = bf->bf_buf_addr;
-
 	sband = &sc->sbands[common->hw->conf.channel->band];
 	rate = sband->bitrates[rateidx].hw_value;
 	if (sc->sc_flags & SC_OP_PREAMBLE_SHORT)
@@ -109,7 +107,7 @@ static void ath_beacon_setup(struct ath_softc *sc, struct ath_vif *avp,
 
 	/* NB: beacon's BufLen must be a multiple of 4 bytes */
 	ath9k_hw_filltxdesc(ah, ds, roundup(skb->len, 4),
-			    true, true, ds);
+			    true, true, ds, bf->bf_buf_addr);
 
 	memset(series, 0, sizeof(struct ath9k_11n_rate_series) * 4);
 	series[0].Tries = 1;
diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c
index ae9d54c..0c9c378 100644
--- a/drivers/net/wireless/ath/ath9k/mac.c
+++ b/drivers/net/wireless/ath/ath9k/mac.c
@@ -220,10 +220,13 @@ EXPORT_SYMBOL(ath9k_hw_stoptxdma);
 
 void ath9k_hw_filltxdesc(struct ath_hw *ah, struct ath_desc *ds,
 			 u32 segLen, bool firstSeg,
-			 bool lastSeg, const struct ath_desc *ds0)
+			 bool lastSeg, const struct ath_desc *ds0,
+			 dma_addr_t buf_addr)
 {
 	struct ar5416_desc *ads = AR5416DESC(ds);
 
+	ads->ds_data = buf_addr;
+
 	if (firstSeg) {
 		ads->ds_ctl1 |= segLen | (lastSeg ? 0 : AR_TxMore);
 	} else if (lastSeg) {
diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h
index 126a403..f2f4ad2 100644
--- a/drivers/net/wireless/ath/ath9k/mac.h
+++ b/drivers/net/wireless/ath/ath9k/mac.h
@@ -693,7 +693,8 @@ bool ath9k_hw_updatetxtriglevel(struct ath_hw *ah, bool bIncTrigLevel);
 bool ath9k_hw_stoptxdma(struct ath_hw *ah, u32 q);
 void ath9k_hw_filltxdesc(struct ath_hw *ah, struct ath_desc *ds,
 			 u32 segLen, bool firstSeg,
-			 bool lastSeg, const struct ath_desc *ds0);
+			 bool lastSeg, const struct ath_desc *ds0,
+			 dma_addr_t buf_addr);
 void ath9k_hw_cleartxdesc(struct ath_hw *ah, struct ath_desc *ds);
 int ath9k_hw_txprocdesc(struct ath_hw *ah, struct ath_desc *ds,
 			struct ath_tx_status *ts);
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 02df4cb..7219e29 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -1660,7 +1660,6 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf,
 
 	ds = bf->bf_desc;
 	ds->ds_link = 0;
-	ds->ds_data = bf->bf_buf_addr;
 
 	ath9k_hw_set11n_txdesc(ah, ds, bf->bf_frmlen, frm_type, MAX_RATE_POWER,
 			       bf->bf_keyix, bf->bf_keytype, bf->bf_flags);
@@ -1669,7 +1668,8 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf,
 			    skb->len,	/* segment length */
 			    true,	/* first segment */
 			    true,	/* last segment */
-			    ds);	/* first descriptor */
+			    ds,		/* first descriptor */
+			    bf->bf_buf_addr);
 
 	spin_lock_bh(&txctl->txq->axq_lock);
 
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 103+ messages in thread

* [PATCH v3 38/97] ath9k_hw: Add abstraction to set/get link pointer
  2010-04-15 21:38 [PATCH v3 00/97] ath9k: add AR9003 support Luis R. Rodriguez
                   ` (36 preceding siblings ...)
  2010-04-15 21:38 ` [PATCH v3 37/97] ath9k_hw: Move code which populates ds_data to ath9k_hw Luis R. Rodriguez
@ 2010-04-15 21:38 ` Luis R. Rodriguez
  2010-04-15 21:38 ` [PATCH v3 39/97] ath9k: Use abstraction to get " Luis R. Rodriguez
                   ` (58 subsequent siblings)
  96 siblings, 0 replies; 103+ messages in thread
From: Luis R. Rodriguez @ 2010-04-15 21:38 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Vasanthakumar Thiagarajan

From: Vasanthakumar Thiagarajan <vasanth@atheros.com>

Signed-off-by: Vasanthakumar Thiagarajan <vasanth@atheros.com>
---
 drivers/net/wireless/ath/ath9k/ar9003_mac.c |   12 ++++++++++++
 drivers/net/wireless/ath/ath9k/hw-ops.h     |   11 +++++++++++
 drivers/net/wireless/ath/ath9k/hw.h         |    2 ++
 drivers/net/wireless/ath/ath9k/mac.c        |   13 +++++++++++++
 drivers/net/wireless/ath/ath9k/xmit.c       |    7 ++++---
 5 files changed, 42 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.c b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
index 2089006..f28adb2 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
@@ -20,11 +20,23 @@ static void ar9003_hw_rx_enable(struct ath_hw *hw)
 	REG_WRITE(hw, AR_CR, 0);
 }
 
+static void ar9003_hw_set_desc_link(void *ds, u32 ds_link)
+{
+	((struct ar9003_txc *) ds)->link = ds_link;
+}
+
+static void ar9003_hw_get_desc_link(void *ds, u32 **ds_link)
+{
+	*ds_link = &((struct ar9003_txc *) ds)->link;
+}
+
 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;
 }
 
 void ath9k_hw_set_rx_bufsize(struct ath_hw *ah, u16 buf_size)
diff --git a/drivers/net/wireless/ath/ath9k/hw-ops.h b/drivers/net/wireless/ath/ath9k/hw-ops.h
index 08a51a2..a770107 100644
--- a/drivers/net/wireless/ath/ath9k/hw-ops.h
+++ b/drivers/net/wireless/ath/ath9k/hw-ops.h
@@ -33,6 +33,17 @@ 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);
+}
 /* Private hardware call ops */
 
 /* PHY ops */
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index ce9d12b..c02f46e 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -526,6 +526,8 @@ struct ath_hw_ops {
 				     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);
 };
 
 struct ath_hw {
diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c
index 0c9c378..a8dab23 100644
--- a/drivers/net/wireless/ath/ath9k/mac.c
+++ b/drivers/net/wireless/ath/ath9k/mac.c
@@ -21,12 +21,25 @@ 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;
+}
+
 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;
 }
+
 static void ath9k_hw_set_txq_interrupts(struct ath_hw *ah,
 					struct ath9k_tx_queue_info *qi)
 {
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 7219e29..4f12de9 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -665,7 +665,7 @@ static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc,
 		bpad = PADBYTES(al_delta) + (ndelim << 2);
 
 		bf->bf_next = NULL;
-		bf->bf_desc->ds_link = 0;
+		ath9k_hw_set_desc_link(sc->sc_ah, bf->bf_desc, 0);
 
 		/* link buffers of this frame to the aggregate */
 		ath_tx_addto_baw(sc, tid, bf);
@@ -673,7 +673,8 @@ static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc,
 		list_move_tail(&bf->list, bf_q);
 		if (bf_prev) {
 			bf_prev->bf_next = bf;
-			bf_prev->bf_desc->ds_link = bf->bf_daddr;
+			ath9k_hw_set_desc_link(sc->sc_ah, bf_prev->bf_desc,
+					       bf->bf_daddr);
 		}
 		bf_prev = bf;
 
@@ -1659,7 +1660,7 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf,
 	list_add_tail(&bf->list, &bf_head);
 
 	ds = bf->bf_desc;
-	ds->ds_link = 0;
+	ath9k_hw_set_desc_link(ah, ds, 0);
 
 	ath9k_hw_set11n_txdesc(ah, ds, bf->bf_frmlen, frm_type, MAX_RATE_POWER,
 			       bf->bf_keyix, bf->bf_keytype, bf->bf_flags);
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 103+ messages in thread

* [PATCH v3 39/97] ath9k: Use abstraction to get link pointer
  2010-04-15 21:38 [PATCH v3 00/97] ath9k: add AR9003 support Luis R. Rodriguez
                   ` (37 preceding siblings ...)
  2010-04-15 21:38 ` [PATCH v3 38/97] ath9k_hw: Add abstraction to set/get link pointer Luis R. Rodriguez
@ 2010-04-15 21:38 ` Luis R. Rodriguez
  2010-04-15 21:38 ` [PATCH v3 40/97] ath9k: Use memcpy in ath_clone_txbuf() Luis R. Rodriguez
                   ` (57 subsequent siblings)
  96 siblings, 0 replies; 103+ messages in thread
From: Luis R. Rodriguez @ 2010-04-15 21:38 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Vasanthakumar Thiagarajan

From: Vasanthakumar Thiagarajan <vasanth@atheros.com>

Signed-off-by: Vasanthakumar Thiagarajan <vasanth@atheros.com>
---
 drivers/net/wireless/ath/ath9k/xmit.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 4f12de9..16f7a3d 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -1242,7 +1242,7 @@ static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq,
 			  txq->axq_qnum, txq->axq_link,
 			  ito64(bf->bf_daddr), bf->bf_desc);
 	}
-	txq->axq_link = &(bf->bf_lastbf->bf_desc->ds_link);
+	ath9k_hw_get_desc_link(ah, bf->bf_lastbf->bf_desc, &txq->axq_link);
 	ath9k_hw_txstart(ah, txq->axq_qnum);
 }
 
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 103+ messages in thread

* [PATCH v3 40/97] ath9k: Use memcpy in ath_clone_txbuf()
  2010-04-15 21:38 [PATCH v3 00/97] ath9k: add AR9003 support Luis R. Rodriguez
                   ` (38 preceding siblings ...)
  2010-04-15 21:38 ` [PATCH v3 39/97] ath9k: Use abstraction to get " Luis R. Rodriguez
@ 2010-04-15 21:38 ` Luis R. Rodriguez
  2010-04-15 21:38 ` [PATCH v3 41/97] ath9k: Remove ATH9K_TX_SW_ABORTED and introduce a bool for this purpose Luis R. Rodriguez
                   ` (56 subsequent siblings)
  96 siblings, 0 replies; 103+ messages in thread
From: Luis R. Rodriguez @ 2010-04-15 21:38 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Vasanthakumar Thiagarajan

From: Vasanthakumar Thiagarajan <vasanth@atheros.com>

Signed-off-by: Vasanthakumar Thiagarajan <vasanth@atheros.com>
---
 drivers/net/wireless/ath/ath9k/xmit.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 16f7a3d..4bc52f4 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -279,7 +279,7 @@ static struct ath_buf* ath_clone_txbuf(struct ath_softc *sc, struct ath_buf *bf)
 	tbf->aphy = bf->aphy;
 	tbf->bf_mpdu = bf->bf_mpdu;
 	tbf->bf_buf_addr = bf->bf_buf_addr;
-	*(tbf->bf_desc) = *(bf->bf_desc);
+	memcpy(tbf->bf_desc, bf->bf_desc, sc->sc_ah->caps.tx_desc_len);
 	tbf->bf_state = bf->bf_state;
 	tbf->bf_dmacontext = bf->bf_dmacontext;
 
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 103+ messages in thread

* [PATCH v3 41/97] ath9k: Remove ATH9K_TX_SW_ABORTED and introduce a bool for this purpose
  2010-04-15 21:38 [PATCH v3 00/97] ath9k: add AR9003 support Luis R. Rodriguez
                   ` (39 preceding siblings ...)
  2010-04-15 21:38 ` [PATCH v3 40/97] ath9k: Use memcpy in ath_clone_txbuf() Luis R. Rodriguez
@ 2010-04-15 21:38 ` Luis R. Rodriguez
  2010-04-15 21:38 ` [PATCH v3 42/97] ath9k: Make bf_desc of ath_buf opaque Luis R. Rodriguez
                   ` (55 subsequent siblings)
  96 siblings, 0 replies; 103+ messages in thread
From: Luis R. Rodriguez @ 2010-04-15 21:38 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Vasanthakumar Thiagarajan, Felix Fietkau

From: Vasanthakumar Thiagarajan <vasanth@atheros.com>

Signed-off-by: Vasanthakumar Thiagarajan <vasanth@atheros.com>
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
 drivers/net/wireless/ath/ath9k/common.h |    1 +
 drivers/net/wireless/ath/ath9k/mac.h    |    1 -
 drivers/net/wireless/ath/ath9k/xmit.c   |    9 ++++-----
 3 files changed, 5 insertions(+), 6 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/common.h b/drivers/net/wireless/ath/ath9k/common.h
index 1a87283..5fd7fe1 100644
--- a/drivers/net/wireless/ath/ath9k/common.h
+++ b/drivers/net/wireless/ath/ath9k/common.h
@@ -82,6 +82,7 @@ struct ath_buf {
 	dma_addr_t bf_buf_addr;		/* physical addr of data buffer */
 	bool bf_stale;
 	bool bf_isnullfunc;
+	bool bf_tx_aborted;
 	u16 bf_flags;
 	struct ath_buf_state bf_state;
 	dma_addr_t bf_dmacontext;
diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h
index f2f4ad2..99f81eb 100644
--- a/drivers/net/wireless/ath/ath9k/mac.h
+++ b/drivers/net/wireless/ath/ath9k/mac.h
@@ -86,7 +86,6 @@
 #define ATH9K_TX_DESC_CFG_ERR      0x04
 #define ATH9K_TX_DATA_UNDERRUN     0x08
 #define ATH9K_TX_DELIM_UNDERRUN    0x10
-#define ATH9K_TX_SW_ABORTED        0x40
 #define ATH9K_TX_SW_FILTERED       0x80
 
 /* 64 bytes */
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 4bc52f4..6ab2099 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -359,7 +359,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
 			acked_cnt++;
 		} else {
 			if (!(tid->state & AGGR_CLEANUP) &&
-			    ts->ts_flags != ATH9K_TX_SW_ABORTED) {
+			    !bf_last->bf_tx_aborted) {
 				if (bf->bf_retries < ATH_MAX_SW_RETRIES) {
 					ath_tx_set_retry(sc, txq, bf);
 					txpending = 1;
@@ -1036,9 +1036,6 @@ void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx)
 	struct ath_tx_status ts;
 
 	memset(&ts, 0, sizeof(ts));
-	if (!retry_tx)
-		ts.ts_flags = ATH9K_TX_SW_ABORTED;
-
 	INIT_LIST_HEAD(&bf_head);
 
 	for (;;) {
@@ -1063,6 +1060,8 @@ void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx)
 		}
 
 		lastbf = bf->bf_lastbf;
+		if (!retry_tx)
+			lastbf->bf_tx_aborted = true;
 
 		/* remove ath_buf's of the same mpdu from txq */
 		list_cut_position(&bf_head, &txq->axq_q, &lastbf->list);
@@ -1897,7 +1896,7 @@ static int ath_tx_num_badfrms(struct ath_softc *sc, struct ath_buf *bf,
 	int nbad = 0;
 	int isaggr = 0;
 
-	if (ts->ts_flags == ATH9K_TX_SW_ABORTED)
+	if (bf->bf_tx_aborted)
 		return 0;
 
 	isaggr = bf_isaggr(bf);
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 103+ messages in thread

* [PATCH v3 42/97] ath9k: Make bf_desc of ath_buf opaque
  2010-04-15 21:38 [PATCH v3 00/97] ath9k: add AR9003 support Luis R. Rodriguez
                   ` (40 preceding siblings ...)
  2010-04-15 21:38 ` [PATCH v3 41/97] ath9k: Remove ATH9K_TX_SW_ABORTED and introduce a bool for this purpose Luis R. Rodriguez
@ 2010-04-15 21:38 ` Luis R. Rodriguez
  2010-04-16 22:00   ` Pavel Roskin
  2010-04-15 21:38 ` [PATCH v3 43/97] ath9k: Add Rx EDMA support Luis R. Rodriguez
                   ` (54 subsequent siblings)
  96 siblings, 1 reply; 103+ messages in thread
From: Luis R. Rodriguez @ 2010-04-15 21:38 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Vasanthakumar Thiagarajan

From: Vasanthakumar Thiagarajan <vasanth@atheros.com>

Signed-off-by: Vasanthakumar Thiagarajan <vasanth@atheros.com>
---
 drivers/net/wireless/ath/ath9k/common.h |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/common.h b/drivers/net/wireless/ath/ath9k/common.h
index 5fd7fe1..e08f7e5 100644
--- a/drivers/net/wireless/ath/ath9k/common.h
+++ b/drivers/net/wireless/ath/ath9k/common.h
@@ -77,7 +77,7 @@ struct ath_buf {
 					   an aggregate) */
 	struct ath_buf *bf_next;	/* next subframe in the aggregate */
 	struct sk_buff *bf_mpdu;	/* enclosing frame structure */
-	struct ath_desc *bf_desc;	/* virtual addr of desc */
+	void *bf_desc;			/* virtual addr of desc */
 	dma_addr_t bf_daddr;		/* physical addr of desc */
 	dma_addr_t bf_buf_addr;		/* physical addr of data buffer */
 	bool bf_stale;
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 103+ messages in thread

* [PATCH v3 43/97] ath9k: Add Rx EDMA support
  2010-04-15 21:38 [PATCH v3 00/97] ath9k: add AR9003 support Luis R. Rodriguez
                   ` (41 preceding siblings ...)
  2010-04-15 21:38 ` [PATCH v3 42/97] ath9k: Make bf_desc of ath_buf opaque Luis R. Rodriguez
@ 2010-04-15 21:38 ` Luis R. Rodriguez
  2010-04-15 21:38 ` [PATCH v3 44/97] ath9k_hw: Split out the function for reading the noise floor Luis R. Rodriguez
                   ` (53 subsequent siblings)
  96 siblings, 0 replies; 103+ messages in thread
From: Luis R. Rodriguez @ 2010-04-15 21:38 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Felix Fietkau, Vasanthakumar Thiagarajan

From: Felix Fietkau <nbd@openwrt.org>

Signed-off-by: Felix Fietkau <nbd@openwrt.org>
Signed-off-by: Vasanthakumar Thiagarajan <vasanth@atheros.com>
---
 drivers/net/wireless/ath/ath9k/ar9003_mac.c |    3 +
 drivers/net/wireless/ath/ath9k/ath9k.h      |   10 +-
 drivers/net/wireless/ath/ath9k/hw.h         |    2 +
 drivers/net/wireless/ath/ath9k/main.c       |   40 ++-
 drivers/net/wireless/ath/ath9k/recv.c       |  517 +++++++++++++++++++++------
 5 files changed, 459 insertions(+), 113 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.c b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
index f28adb2..b229597 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
@@ -72,6 +72,9 @@ int ath9k_hw_process_rxdesc_edma(struct ath_hw *ah, struct ath_rx_status *rxs,
 	if ((rxsp->ds_info & (AR_TxRxDesc | AR_CtrlStat)) != 0)
 		return -EINPROGRESS;
 
+	if (!rxs)
+		return 0;
+
 	rxs->rs_status = 0;
 	rxs->rs_flags =  0;
 
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index bdcd257..a11d830 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -223,6 +223,12 @@ struct ath_tx {
 	struct ath_descdma txdma;
 };
 
+struct ath_rx_edma {
+	struct sk_buff_head rx_fifo;
+	struct sk_buff_head rx_buffers;
+	u32 rx_fifo_hwsize;
+};
+
 struct ath_rx {
 	u8 defant;
 	u8 rxotherant;
@@ -232,6 +238,8 @@ struct ath_rx {
 	spinlock_t rxbuflock;
 	struct list_head rxbuf;
 	struct ath_descdma rxdma;
+	struct ath_buf *rx_bufptr;
+	struct ath_rx_edma rx_edma[ATH9K_RX_QUEUE_MAX];
 };
 
 int ath_startrecv(struct ath_softc *sc);
@@ -240,7 +248,7 @@ void ath_flushrecv(struct ath_softc *sc);
 u32 ath_calcrxfilter(struct ath_softc *sc);
 int ath_rx_init(struct ath_softc *sc, int nbufs);
 void ath_rx_cleanup(struct ath_softc *sc);
-int ath_rx_tasklet(struct ath_softc *sc, int flush);
+int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp);
 struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype);
 void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq);
 int ath_tx_setup(struct ath_softc *sc, int haltype);
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index c02f46e..1eceda2 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -246,6 +246,8 @@ struct ath9k_ops_config {
 enum ath9k_int {
 	ATH9K_INT_RX = 0x00000001,
 	ATH9K_INT_RXDESC = 0x00000002,
+	ATH9K_INT_RXHP = 0x00000001,
+	ATH9K_INT_RXLP = 0x00000002,
 	ATH9K_INT_RXNOFRM = 0x00000008,
 	ATH9K_INT_RXEOL = 0x00000010,
 	ATH9K_INT_RXORN = 0x00000020,
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 494456c..92f6fdc 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -401,6 +401,7 @@ void ath9k_tasklet(unsigned long data)
 	struct ath_common *common = ath9k_hw_common(ah);
 
 	u32 status = sc->intrstatus;
+	u32 rxmask;
 
 	ath9k_ps_wakeup(sc);
 
@@ -410,9 +411,21 @@ void ath9k_tasklet(unsigned long data)
 		return;
 	}
 
-	if (status & (ATH9K_INT_RX | ATH9K_INT_RXEOL | ATH9K_INT_RXORN)) {
+	if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
+		rxmask = (ATH9K_INT_RXHP | ATH9K_INT_RXLP | ATH9K_INT_RXEOL |
+			  ATH9K_INT_RXORN);
+	else
+		rxmask = (ATH9K_INT_RX | ATH9K_INT_RXEOL | ATH9K_INT_RXORN);
+
+	if (status & rxmask) {
 		spin_lock_bh(&sc->rx.rxflushlock);
-		ath_rx_tasklet(sc, 0);
+
+		/* Check for high priority Rx first */
+		if ((ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) &&
+		    (status & ATH9K_INT_RXHP))
+			ath_rx_tasklet(sc, 0, true);
+
+		ath_rx_tasklet(sc, 0, false);
 		spin_unlock_bh(&sc->rx.rxflushlock);
 	}
 
@@ -445,6 +458,8 @@ irqreturn_t ath_isr(int irq, void *dev)
 		ATH9K_INT_RXORN |		\
 		ATH9K_INT_RXEOL |		\
 		ATH9K_INT_RX |			\
+		ATH9K_INT_RXLP |		\
+		ATH9K_INT_RXHP |		\
 		ATH9K_INT_TX |			\
 		ATH9K_INT_BMISS |		\
 		ATH9K_INT_CST |			\
@@ -496,7 +511,8 @@ irqreturn_t ath_isr(int irq, void *dev)
 	 * If a FATAL or RXORN interrupt is received, we have to reset the
 	 * chip immediately.
 	 */
-	if (status & (ATH9K_INT_FATAL | ATH9K_INT_RXORN))
+	if ((status & ATH9K_INT_FATAL) || ((status & ATH9K_INT_RXORN) &&
+	    !(ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)))
 		goto chip_reset;
 
 	if (status & ATH9K_INT_SWBA)
@@ -505,6 +521,13 @@ irqreturn_t ath_isr(int irq, void *dev)
 	if (status & ATH9K_INT_TXURN)
 		ath9k_hw_updatetxtriglevel(ah, true);
 
+	if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
+		if (status & ATH9K_INT_RXEOL) {
+			ah->imask &= ~(ATH9K_INT_RXEOL | ATH9K_INT_RXORN);
+			ath9k_hw_set_interrupts(ah, ah->imask);
+		}
+	}
+
 	if (status & ATH9K_INT_MIB) {
 		/*
 		 * Disable interrupts until we service the MIB
@@ -1162,9 +1185,14 @@ static int ath9k_start(struct ieee80211_hw *hw)
 	}
 
 	/* Setup our intr mask. */
-	ah->imask = ATH9K_INT_RX | ATH9K_INT_TX
-		| ATH9K_INT_RXEOL | ATH9K_INT_RXORN
-		| ATH9K_INT_FATAL | ATH9K_INT_GLOBAL;
+	ah->imask = ATH9K_INT_TX | ATH9K_INT_RXEOL |
+		    ATH9K_INT_RXORN | ATH9K_INT_FATAL |
+		    ATH9K_INT_GLOBAL;
+
+	if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
+		ah->imask |= ATH9K_INT_RXHP | ATH9K_INT_RXLP;
+	else
+		ah->imask |= ATH9K_INT_RX;
 
 	if (ah->caps.hw_caps & ATH9K_HW_CAP_GTT)
 		ah->imask |= ATH9K_INT_GTT;
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index 94560e2..ffb599c 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -16,6 +16,8 @@
 
 #include "ath9k.h"
 
+#define SKB_CB_ATHBUF(__skb)	(*((struct ath_buf **)__skb->cb))
+
 static struct ieee80211_hw * ath_get_virt_hw(struct ath_softc *sc,
 					     struct ieee80211_hdr *hdr)
 {
@@ -115,56 +117,246 @@ static void ath_opmode_init(struct ath_softc *sc)
 	ath9k_hw_setmcastfilter(ah, mfilt[0], mfilt[1]);
 }
 
-int ath_rx_init(struct ath_softc *sc, int nbufs)
+static bool ath_rx_edma_buf_link(struct ath_softc *sc,
+				 enum ath9k_rx_qtype qtype)
 {
-	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
+	struct ath_hw *ah = sc->sc_ah;
+	struct ath_rx_edma *rx_edma;
 	struct sk_buff *skb;
 	struct ath_buf *bf;
-	int error = 0;
 
-	spin_lock_init(&sc->rx.rxflushlock);
-	sc->sc_flags &= ~SC_OP_RXFLUSH;
-	spin_lock_init(&sc->rx.rxbuflock);
+	rx_edma = &sc->rx.rx_edma[qtype];
+	if (skb_queue_len(&rx_edma->rx_fifo) >= rx_edma->rx_fifo_hwsize)
+		return false;
 
-	common->rx_bufsize = roundup(IEEE80211_MAX_MPDU_LEN,
-				     min(common->cachelsz, (u16)64));
+	bf = list_first_entry(&sc->rx.rxbuf, struct ath_buf, list);
+	list_del_init(&bf->list);
 
-	ath_print(common, ATH_DBG_CONFIG, "cachelsz %u rxbufsize %u\n",
-		  common->cachelsz, common->rx_bufsize);
+	skb = bf->bf_mpdu;
+
+	ATH_RXBUF_RESET(bf);
+	memset(skb->data, 0, ah->caps.rx_status_len);
+	dma_sync_single_for_device(sc->dev, bf->bf_buf_addr,
+				ah->caps.rx_status_len, DMA_TO_DEVICE);
 
-	/* Initialize rx descriptors */
+	SKB_CB_ATHBUF(skb) = bf;
+	ath9k_hw_addrxbuf_edma(ah, bf->bf_buf_addr, qtype);
+	skb_queue_tail(&rx_edma->rx_fifo, skb);
 
-	error = ath_descdma_setup(sc, &sc->rx.rxdma, &sc->rx.rxbuf,
-				  "rx", nbufs, 1);
-	if (error != 0) {
-		ath_print(common, ATH_DBG_FATAL,
-			  "failed to allocate rx descriptors: %d\n", error);
-		goto err;
+	return true;
+}
+
+static void ath_rx_addbuffer_edma(struct ath_softc *sc,
+				  enum ath9k_rx_qtype qtype, int size)
+{
+	struct ath_rx_edma *rx_edma;
+	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
+	u32 nbuf = 0;
+
+	rx_edma = &sc->rx.rx_edma[qtype];
+	if (list_empty(&sc->rx.rxbuf)) {
+		ath_print(common, ATH_DBG_QUEUE, "No free rx buf available\n");
+		return;
 	}
 
+	while (!list_empty(&sc->rx.rxbuf)) {
+		nbuf++;
+
+		if (!ath_rx_edma_buf_link(sc, qtype))
+			break;
+
+		if (nbuf >= size)
+			break;
+	}
+}
+
+static void ath_rx_remove_buffer(struct ath_softc *sc,
+				 enum ath9k_rx_qtype qtype)
+{
+	struct ath_buf *bf;
+	struct ath_rx_edma *rx_edma;
+	struct sk_buff *skb;
+
+	rx_edma = &sc->rx.rx_edma[qtype];
+
+	while ((skb = skb_dequeue(&rx_edma->rx_fifo)) != NULL) {
+		bf = SKB_CB_ATHBUF(skb);
+		BUG_ON(!bf);
+		list_add_tail(&bf->list, &sc->rx.rxbuf);
+	}
+}
+
+static void ath_rx_edma_cleanup(struct ath_softc *sc)
+{
+	struct ath_buf *bf;
+
+	ath_rx_remove_buffer(sc, ATH9K_RX_QUEUE_LP);
+	ath_rx_remove_buffer(sc, ATH9K_RX_QUEUE_HP);
+
 	list_for_each_entry(bf, &sc->rx.rxbuf, list) {
+		if (bf->bf_mpdu)
+			dev_kfree_skb_any(bf->bf_mpdu);
+	}
+
+	INIT_LIST_HEAD(&sc->rx.rxbuf);
+
+	kfree(sc->rx.rx_bufptr);
+	sc->rx.rx_bufptr = NULL;
+}
+
+static void ath_rx_edma_init_queue(struct ath_rx_edma *rx_edma, int size)
+{
+	skb_queue_head_init(&rx_edma->rx_fifo);
+	skb_queue_head_init(&rx_edma->rx_buffers);
+	rx_edma->rx_fifo_hwsize = size;
+}
+
+static int ath_rx_edma_init(struct ath_softc *sc, int nbufs)
+{
+	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
+	struct ath_hw *ah = sc->sc_ah;
+	struct sk_buff *skb;
+	struct ath_buf *bf;
+	int error = 0, i;
+	u32 size;
+
+
+	common->rx_bufsize = roundup(IEEE80211_MAX_MPDU_LEN +
+				     ah->caps.rx_status_len,
+				     min(common->cachelsz, (u16)64));
+
+	ath9k_hw_set_rx_bufsize(ah, common->rx_bufsize -
+				    ah->caps.rx_status_len);
+
+	ath_rx_edma_init_queue(&sc->rx.rx_edma[ATH9K_RX_QUEUE_LP],
+			       ah->caps.rx_lp_qdepth);
+	ath_rx_edma_init_queue(&sc->rx.rx_edma[ATH9K_RX_QUEUE_HP],
+			       ah->caps.rx_hp_qdepth);
+
+	size = sizeof(struct ath_buf) * nbufs;
+	bf = kzalloc(size, GFP_KERNEL);
+	if (!bf)
+		return -ENOMEM;
+
+	INIT_LIST_HEAD(&sc->rx.rxbuf);
+	sc->rx.rx_bufptr = bf;
+
+	for (i = 0; i < nbufs; i++, bf++) {
 		skb = ath_rxbuf_alloc(common, common->rx_bufsize, GFP_KERNEL);
-		if (skb == NULL) {
+		if (!skb) {
 			error = -ENOMEM;
-			goto err;
+			goto rx_init_fail;
 		}
 
+		memset(skb->data, 0, common->rx_bufsize);
 		bf->bf_mpdu = skb;
+
 		bf->bf_buf_addr = dma_map_single(sc->dev, skb->data,
 						 common->rx_bufsize,
-						 DMA_FROM_DEVICE);
+						 DMA_BIDIRECTIONAL);
 		if (unlikely(dma_mapping_error(sc->dev,
-					       bf->bf_buf_addr))) {
-			dev_kfree_skb_any(skb);
-			bf->bf_mpdu = NULL;
+						bf->bf_buf_addr))) {
+				dev_kfree_skb_any(skb);
+				bf->bf_mpdu = NULL;
+				ath_print(common, ATH_DBG_FATAL,
+					"dma_mapping_error() on RX init\n");
+				error = -ENOMEM;
+				goto rx_init_fail;
+		}
+
+		list_add_tail(&bf->list, &sc->rx.rxbuf);
+	}
+
+	return 0;
+
+rx_init_fail:
+	ath_rx_edma_cleanup(sc);
+	return error;
+}
+
+static void ath_edma_start_recv(struct ath_softc *sc)
+{
+	spin_lock_bh(&sc->rx.rxbuflock);
+
+	ath9k_hw_rxena(sc->sc_ah);
+
+	ath_rx_addbuffer_edma(sc, ATH9K_RX_QUEUE_HP,
+			      sc->rx.rx_edma[ATH9K_RX_QUEUE_HP].rx_fifo_hwsize);
+
+	ath_rx_addbuffer_edma(sc, ATH9K_RX_QUEUE_LP,
+			      sc->rx.rx_edma[ATH9K_RX_QUEUE_LP].rx_fifo_hwsize);
+
+	spin_unlock_bh(&sc->rx.rxbuflock);
+
+	ath_opmode_init(sc);
+
+	ath9k_hw_startpcureceive(sc->sc_ah);
+}
+
+static void ath_edma_stop_recv(struct ath_softc *sc)
+{
+	spin_lock_bh(&sc->rx.rxbuflock);
+	ath_rx_remove_buffer(sc, ATH9K_RX_QUEUE_HP);
+	ath_rx_remove_buffer(sc, ATH9K_RX_QUEUE_LP);
+	spin_unlock_bh(&sc->rx.rxbuflock);
+}
+
+int ath_rx_init(struct ath_softc *sc, int nbufs)
+{
+	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
+	struct sk_buff *skb;
+	struct ath_buf *bf;
+	int error = 0;
+
+	spin_lock_init(&sc->rx.rxflushlock);
+	sc->sc_flags &= ~SC_OP_RXFLUSH;
+	spin_lock_init(&sc->rx.rxbuflock);
+
+	if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
+		return ath_rx_edma_init(sc, nbufs);
+	} else {
+		common->rx_bufsize = roundup(IEEE80211_MAX_MPDU_LEN,
+				min(common->cachelsz, (u16)64));
+
+		ath_print(common, ATH_DBG_CONFIG, "cachelsz %u rxbufsize %u\n",
+				common->cachelsz, common->rx_bufsize);
+
+		/* Initialize rx descriptors */
+
+		error = ath_descdma_setup(sc, &sc->rx.rxdma, &sc->rx.rxbuf,
+				"rx", nbufs, 1);
+		if (error != 0) {
 			ath_print(common, ATH_DBG_FATAL,
-				  "dma_mapping_error() on RX init\n");
-			error = -ENOMEM;
+				  "failed to allocate rx descriptors: %d\n",
+				  error);
 			goto err;
 		}
-		bf->bf_dmacontext = bf->bf_buf_addr;
+
+		list_for_each_entry(bf, &sc->rx.rxbuf, list) {
+			skb = ath_rxbuf_alloc(common, common->rx_bufsize,
+					      GFP_KERNEL);
+			if (skb == NULL) {
+				error = -ENOMEM;
+				goto err;
+			}
+
+			bf->bf_mpdu = skb;
+			bf->bf_buf_addr = dma_map_single(sc->dev, skb->data,
+					common->rx_bufsize,
+					DMA_FROM_DEVICE);
+			if (unlikely(dma_mapping_error(sc->dev,
+							bf->bf_buf_addr))) {
+				dev_kfree_skb_any(skb);
+				bf->bf_mpdu = NULL;
+				ath_print(common, ATH_DBG_FATAL,
+					  "dma_mapping_error() on RX init\n");
+				error = -ENOMEM;
+				goto err;
+			}
+			bf->bf_dmacontext = bf->bf_buf_addr;
+		}
+		sc->rx.rxlink = NULL;
 	}
-	sc->rx.rxlink = NULL;
 
 err:
 	if (error)
@@ -180,17 +372,23 @@ void ath_rx_cleanup(struct ath_softc *sc)
 	struct sk_buff *skb;
 	struct ath_buf *bf;
 
-	list_for_each_entry(bf, &sc->rx.rxbuf, list) {
-		skb = bf->bf_mpdu;
-		if (skb) {
-			dma_unmap_single(sc->dev, bf->bf_buf_addr,
-					 common->rx_bufsize, DMA_FROM_DEVICE);
-			dev_kfree_skb(skb);
+	if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
+		ath_rx_edma_cleanup(sc);
+		return;
+	} else {
+		list_for_each_entry(bf, &sc->rx.rxbuf, list) {
+			skb = bf->bf_mpdu;
+			if (skb) {
+				dma_unmap_single(sc->dev, bf->bf_buf_addr,
+						common->rx_bufsize,
+						DMA_FROM_DEVICE);
+				dev_kfree_skb(skb);
+			}
 		}
-	}
 
-	if (sc->rx.rxdma.dd_desc_len != 0)
-		ath_descdma_cleanup(sc, &sc->rx.rxdma, &sc->rx.rxbuf);
+		if (sc->rx.rxdma.dd_desc_len != 0)
+			ath_descdma_cleanup(sc, &sc->rx.rxdma, &sc->rx.rxbuf);
+	}
 }
 
 /*
@@ -273,6 +471,11 @@ int ath_startrecv(struct ath_softc *sc)
 	struct ath_hw *ah = sc->sc_ah;
 	struct ath_buf *bf, *tbf;
 
+	if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
+		ath_edma_start_recv(sc);
+		return 0;
+	}
+
 	spin_lock_bh(&sc->rx.rxbuflock);
 	if (list_empty(&sc->rx.rxbuf))
 		goto start_recv;
@@ -306,7 +509,11 @@ bool ath_stoprecv(struct ath_softc *sc)
 	ath9k_hw_stoppcurecv(ah);
 	ath9k_hw_setrxfilter(ah, 0);
 	stopped = ath9k_hw_stopdmarecv(ah);
-	sc->rx.rxlink = NULL;
+
+	if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
+		ath_edma_stop_recv(sc);
+	else
+		sc->rx.rxlink = NULL;
 
 	return stopped;
 }
@@ -315,7 +522,9 @@ void ath_flushrecv(struct ath_softc *sc)
 {
 	spin_lock_bh(&sc->rx.rxflushlock);
 	sc->sc_flags |= SC_OP_RXFLUSH;
-	ath_rx_tasklet(sc, 1);
+	if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
+		ath_rx_tasklet(sc, 1, true);
+	ath_rx_tasklet(sc, 1, false);
 	sc->sc_flags &= ~SC_OP_RXFLUSH;
 	spin_unlock_bh(&sc->rx.rxflushlock);
 }
@@ -469,14 +678,147 @@ static void ath_rx_send_to_mac80211(struct ieee80211_hw *hw,
 		ieee80211_rx(hw, skb);
 }
 
-int ath_rx_tasklet(struct ath_softc *sc, int flush)
+static bool ath_edma_get_buffers(struct ath_softc *sc,
+				 enum ath9k_rx_qtype qtype)
 {
-#define PA2DESC(_sc, _pa)                                               \
-	((struct ath_desc *)((caddr_t)(_sc)->rx.rxdma.dd_desc +		\
-			     ((_pa) - (_sc)->rx.rxdma.dd_desc_paddr)))
+	struct ath_rx_edma *rx_edma = &sc->rx.rx_edma[qtype];
+	struct ath_hw *ah = sc->sc_ah;
+	struct ath_common *common = ath9k_hw_common(ah);
+	struct sk_buff *skb;
+	struct ath_buf *bf;
+	int ret;
+
+	skb = skb_peek(&rx_edma->rx_fifo);
+	if (!skb)
+		return false;
+
+	bf = SKB_CB_ATHBUF(skb);
+	BUG_ON(!bf);
+
+	dma_sync_single_for_device(sc->dev, bf->bf_buf_addr,
+				common->rx_bufsize, DMA_FROM_DEVICE);
+
+	ret = ath9k_hw_process_rxdesc_edma(ah, NULL, skb->data);
+	if (ret == -EINPROGRESS)
+		return false;
+
+	__skb_unlink(skb, &rx_edma->rx_fifo);
+	if (ret == -EINVAL) {
+		/* corrupt descriptor, skip this one and the following one */
+		list_add_tail(&bf->list, &sc->rx.rxbuf);
+		ath_rx_edma_buf_link(sc, qtype);
+		skb = skb_peek(&rx_edma->rx_fifo);
+		if (!skb)
+			return true;
+
+		bf = SKB_CB_ATHBUF(skb);
+		BUG_ON(!bf);
+
+		__skb_unlink(skb, &rx_edma->rx_fifo);
+		list_add_tail(&bf->list, &sc->rx.rxbuf);
+		ath_rx_edma_buf_link(sc, qtype);
+	}
+	skb_queue_tail(&rx_edma->rx_buffers, skb);
+
+	return true;
+}
 
+static struct ath_buf *ath_edma_get_next_rx_buf(struct ath_softc *sc,
+						struct ath_rx_status *rs,
+						enum ath9k_rx_qtype qtype)
+{
+	struct ath_rx_edma *rx_edma = &sc->rx.rx_edma[qtype];
+	struct sk_buff *skb;
 	struct ath_buf *bf;
+
+	while (ath_edma_get_buffers(sc, qtype));
+	skb = __skb_dequeue(&rx_edma->rx_buffers);
+	if (!skb)
+		return NULL;
+
+	bf = SKB_CB_ATHBUF(skb);
+	ath9k_hw_process_rxdesc_edma(sc->sc_ah, rs, skb->data);
+	return bf;
+}
+
+static struct ath_buf *ath_get_next_rx_buf(struct ath_softc *sc,
+					   struct ath_rx_status *rs)
+{
+	struct ath_hw *ah = sc->sc_ah;
+	struct ath_common *common = ath9k_hw_common(ah);
 	struct ath_desc *ds;
+	struct ath_buf *bf;
+	int ret;
+
+	if (list_empty(&sc->rx.rxbuf)) {
+		sc->rx.rxlink = NULL;
+		return NULL;
+	}
+
+	bf = list_first_entry(&sc->rx.rxbuf, struct ath_buf, list);
+	ds = bf->bf_desc;
+
+	/*
+	 * Must provide the virtual address of the current
+	 * descriptor, the physical address, and the virtual
+	 * address of the next descriptor in the h/w chain.
+	 * This allows the HAL to look ahead to see if the
+	 * hardware is done with a descriptor by checking the
+	 * done bit in the following descriptor and the address
+	 * of the current descriptor the DMA engine is working
+	 * on.  All this is necessary because of our use of
+	 * a self-linked list to avoid rx overruns.
+	 */
+	ret = ath9k_hw_rxprocdesc(ah, ds, rs, 0);
+	if (ret == -EINPROGRESS) {
+		struct ath_rx_status trs;
+		struct ath_buf *tbf;
+		struct ath_desc *tds;
+
+		memset(&trs, 0, sizeof(trs));
+		if (list_is_last(&bf->list, &sc->rx.rxbuf)) {
+			sc->rx.rxlink = NULL;
+			return NULL;
+		}
+
+		tbf = list_entry(bf->list.next, struct ath_buf, list);
+
+		/*
+		 * On some hardware the descriptor status words could
+		 * get corrupted, including the done bit. Because of
+		 * this, check if the next descriptor's done bit is
+		 * set or not.
+		 *
+		 * If the next descriptor's done bit is set, the current
+		 * descriptor has been corrupted. Force s/w to discard
+		 * this descriptor and continue...
+		 */
+
+		tds = tbf->bf_desc;
+		ret = ath9k_hw_rxprocdesc(ah, tds, &trs, 0);
+		if (ret == -EINPROGRESS)
+			return NULL;
+	}
+
+	if (!bf->bf_mpdu)
+		return bf;
+
+	/*
+	 * Synchronize the DMA transfer with CPU before
+	 * 1. accessing the frame
+	 * 2. requeueing the same buffer to h/w
+	 */
+	dma_sync_single_for_device(sc->dev, bf->bf_buf_addr,
+			common->rx_bufsize,
+			DMA_FROM_DEVICE);
+
+	return bf;
+}
+
+
+int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
+{
+	struct ath_buf *bf;
 	struct sk_buff *skb = NULL, *requeue_skb;
 	struct ieee80211_rx_status *rxs;
 	struct ath_hw *ah = sc->sc_ah;
@@ -491,7 +833,16 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
 	int retval;
 	bool decrypt_error = false;
 	struct ath_rx_status rs;
+	enum ath9k_rx_qtype qtype;
+	bool edma = !!(ah->caps.hw_caps & ATH9K_HW_CAP_EDMA);
+	int dma_type;
 
+	if (edma)
+		dma_type = DMA_FROM_DEVICE;
+	else
+		dma_type = DMA_BIDIRECTIONAL;
+
+	qtype = hp ? ATH9K_RX_QUEUE_HP : ATH9K_RX_QUEUE_LP;
 	spin_lock_bh(&sc->rx.rxbuflock);
 
 	do {
@@ -499,71 +850,19 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
 		if ((sc->sc_flags & SC_OP_RXFLUSH) && (flush == 0))
 			break;
 
-		if (list_empty(&sc->rx.rxbuf)) {
-			sc->rx.rxlink = NULL;
-			break;
-		}
-
-		bf = list_first_entry(&sc->rx.rxbuf, struct ath_buf, list);
-		ds = bf->bf_desc;
-
-		/*
-		 * Must provide the virtual address of the current
-		 * descriptor, the physical address, and the virtual
-		 * address of the next descriptor in the h/w chain.
-		 * This allows the HAL to look ahead to see if the
-		 * hardware is done with a descriptor by checking the
-		 * done bit in the following descriptor and the address
-		 * of the current descriptor the DMA engine is working
-		 * on.  All this is necessary because of our use of
-		 * a self-linked list to avoid rx overruns.
-		 */
 		memset(&rs, 0, sizeof(rs));
-		retval = ath9k_hw_rxprocdesc(ah, ds, &rs, 0);
-		if (retval == -EINPROGRESS) {
-			struct ath_rx_status trs;
-			struct ath_buf *tbf;
-			struct ath_desc *tds;
-
-			memset(&trs, 0, sizeof(trs));
-			if (list_is_last(&bf->list, &sc->rx.rxbuf)) {
-				sc->rx.rxlink = NULL;
-				break;
-			}
+		if (edma)
+			bf = ath_edma_get_next_rx_buf(sc, &rs, qtype);
+		else
+			bf = ath_get_next_rx_buf(sc, &rs);
 
-			tbf = list_entry(bf->list.next, struct ath_buf, list);
-
-			/*
-			 * On some hardware the descriptor status words could
-			 * get corrupted, including the done bit. Because of
-			 * this, check if the next descriptor's done bit is
-			 * set or not.
-			 *
-			 * If the next descriptor's done bit is set, the current
-			 * descriptor has been corrupted. Force s/w to discard
-			 * this descriptor and continue...
-			 */
-
-			tds = tbf->bf_desc;
-			retval = ath9k_hw_rxprocdesc(ah, tds, &trs, 0);
-			if (retval == -EINPROGRESS) {
-				break;
-			}
-		}
+		if (!bf)
+			break;
 
 		skb = bf->bf_mpdu;
 		if (!skb)
 			continue;
 
-		/*
-		 * Synchronize the DMA transfer with CPU before
-		 * 1. accessing the frame
-		 * 2. requeueing the same buffer to h/w
-		 */
-		dma_sync_single_for_cpu(sc->dev, bf->bf_buf_addr,
-				common->rx_bufsize,
-				DMA_FROM_DEVICE);
-
 		hdr = (struct ieee80211_hdr *) skb->data;
 		rxs =  IEEE80211_SKB_RXCB(skb);
 
@@ -597,9 +896,11 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
 		/* Unmap the frame */
 		dma_unmap_single(sc->dev, bf->bf_buf_addr,
 				 common->rx_bufsize,
-				 DMA_FROM_DEVICE);
+				 dma_type);
 
-		skb_put(skb, rs.rs_datalen);
+		skb_put(skb, rs.rs_datalen + ah->caps.rx_status_len);
+		if (ah->caps.rx_status_len)
+			skb_pull(skb, ah->caps.rx_status_len);
 
 		ath9k_cmn_rx_skb_postprocess(common, skb, &rs,
 					     rxs, decrypt_error);
@@ -608,7 +909,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
 		bf->bf_mpdu = requeue_skb;
 		bf->bf_buf_addr = dma_map_single(sc->dev, requeue_skb->data,
 						 common->rx_bufsize,
-						 DMA_FROM_DEVICE);
+						 dma_type);
 		if (unlikely(dma_mapping_error(sc->dev,
 			  bf->bf_buf_addr))) {
 			dev_kfree_skb_any(requeue_skb);
@@ -639,12 +940,16 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
 		ath_rx_send_to_mac80211(hw, sc, skb, rxs);
 
 requeue:
-		list_move_tail(&bf->list, &sc->rx.rxbuf);
-		ath_rx_buf_link(sc, bf);
+		if (edma) {
+			list_add_tail(&bf->list, &sc->rx.rxbuf);
+			ath_rx_edma_buf_link(sc, qtype);
+		} else {
+			list_move_tail(&bf->list, &sc->rx.rxbuf);
+			ath_rx_buf_link(sc, bf);
+		}
 	} while (1);
 
 	spin_unlock_bh(&sc->rx.rxbuflock);
 
 	return 0;
-#undef PA2DESC
 }
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 103+ messages in thread

* [PATCH v3 44/97] ath9k_hw: Split out the function for reading the noise floor
  2010-04-15 21:38 [PATCH v3 00/97] ath9k: add AR9003 support Luis R. Rodriguez
                   ` (42 preceding siblings ...)
  2010-04-15 21:38 ` [PATCH v3 43/97] ath9k: Add Rx EDMA support Luis R. Rodriguez
@ 2010-04-15 21:38 ` Luis R. Rodriguez
  2010-04-15 21:38 ` [PATCH v3 45/97] ath9k_hw: the eep_map is used only for AR9280 PCI card ini fixup Luis R. Rodriguez
                   ` (52 subsequent siblings)
  96 siblings, 0 replies; 103+ messages in thread
From: Luis R. Rodriguez @ 2010-04-15 21:38 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Felix Fietkau, Luis R. Rodriguez

From: Felix Fietkau <nbd@openwrt.org>

Signed-off-by: Felix Fietkau <nbd@openwrt.org>
Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/ar5008_phy.c |   50 ++++++++++++
 drivers/net/wireless/ath/ath9k/ar9002_phy.c |   53 +++++++++++++
 drivers/net/wireless/ath/ath9k/ar9003_phy.c |  110 +++++++++++++++++++++++++++
 drivers/net/wireless/ath/ath9k/calib.c      |   90 +---------------------
 drivers/net/wireless/ath/ath9k/hw-ops.h     |    6 ++
 drivers/net/wireless/ath/ath9k/hw.c         |    3 +
 drivers/net/wireless/ath/ath9k/hw.h         |   12 +++
 7 files changed, 235 insertions(+), 89 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
index dddca59..bd3792c 100644
--- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
@@ -1198,6 +1198,55 @@ static bool ar5008_hw_ani_control(struct ath_hw *ah,
 	return true;
 }
 
+static void ar5008_hw_do_getnf(struct ath_hw *ah,
+			      int16_t nfarray[NUM_NF_READINGS])
+{
+	struct ath_common *common = ath9k_hw_common(ah);
+	int16_t nf;
+
+	nf = MS(REG_READ(ah, AR_PHY_CCA), AR_PHY_MINCCA_PWR);
+	if (nf & 0x100)
+		nf = 0 - ((nf ^ 0x1ff) + 1);
+	ath_print(common, ATH_DBG_CALIBRATE,
+		  "NF calibrated [ctl] [chain 0] is %d\n", nf);
+	nfarray[0] = nf;
+
+	nf = MS(REG_READ(ah, AR_PHY_CH1_CCA), AR_PHY_CH1_MINCCA_PWR);
+	if (nf & 0x100)
+		nf = 0 - ((nf ^ 0x1ff) + 1);
+	ath_print(common, ATH_DBG_CALIBRATE,
+		  "NF calibrated [ctl] [chain 1] is %d\n", nf);
+	nfarray[1] = nf;
+
+	nf = MS(REG_READ(ah, AR_PHY_CH2_CCA), AR_PHY_CH2_MINCCA_PWR);
+	if (nf & 0x100)
+		nf = 0 - ((nf ^ 0x1ff) + 1);
+	ath_print(common, ATH_DBG_CALIBRATE,
+		  "NF calibrated [ctl] [chain 2] is %d\n", nf);
+	nfarray[2] = nf;
+
+	nf = MS(REG_READ(ah, AR_PHY_EXT_CCA), AR_PHY_EXT_MINCCA_PWR);
+	if (nf & 0x100)
+		nf = 0 - ((nf ^ 0x1ff) + 1);
+	ath_print(common, ATH_DBG_CALIBRATE,
+		  "NF calibrated [ext] [chain 0] is %d\n", nf);
+	nfarray[3] = nf;
+
+	nf = MS(REG_READ(ah, AR_PHY_CH1_EXT_CCA), AR_PHY_CH1_EXT_MINCCA_PWR);
+	if (nf & 0x100)
+		nf = 0 - ((nf ^ 0x1ff) + 1);
+	ath_print(common, ATH_DBG_CALIBRATE,
+		  "NF calibrated [ext] [chain 1] is %d\n", nf);
+	nfarray[4] = nf;
+
+	nf = MS(REG_READ(ah, AR_PHY_CH2_EXT_CCA), AR_PHY_CH2_EXT_MINCCA_PWR);
+	if (nf & 0x100)
+		nf = 0 - ((nf ^ 0x1ff) + 1);
+	ath_print(common, ATH_DBG_CALIBRATE,
+		  "NF calibrated [ext] [chain 2] is %d\n", nf);
+	nfarray[5] = nf;
+}
+
 void ar5008_hw_attach_phy_ops(struct ath_hw *ah)
 {
 	struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
@@ -1220,6 +1269,7 @@ void ar5008_hw_attach_phy_ops(struct ath_hw *ah)
 	priv_ops->restore_chainmask = ar5008_restore_chainmask;
 	priv_ops->set_diversity = ar5008_set_diversity;
 	priv_ops->ani_control = ar5008_hw_ani_control;
+	priv_ops->do_getnf = ar5008_hw_do_getnf;
 
 	if (AR_SREV_9100(ah))
 		priv_ops->compute_pll_control = ar9100_hw_compute_pll_control;
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_phy.c b/drivers/net/wireless/ath/ath9k/ar9002_phy.c
index 1f8ac0a..a0a2f58 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9002_phy.c
@@ -467,6 +467,58 @@ static u32 ar9002_hw_compute_pll_control(struct ath_hw *ah,
 	return pll;
 }
 
+static void ar9002_hw_do_getnf(struct ath_hw *ah,
+			      int16_t nfarray[NUM_NF_READINGS])
+{
+	struct ath_common *common = ath9k_hw_common(ah);
+	int16_t nf;
+
+	nf = MS(REG_READ(ah, AR_PHY_CCA), AR9280_PHY_MINCCA_PWR);
+
+	if (nf & 0x100)
+		nf = 0 - ((nf ^ 0x1ff) + 1);
+	ath_print(common, ATH_DBG_CALIBRATE,
+		  "NF calibrated [ctl] [chain 0] is %d\n", nf);
+
+	if (AR_SREV_9271(ah) && (nf >= -114))
+		nf = -116;
+
+	nfarray[0] = nf;
+
+	if (!AR_SREV_9285(ah) && !AR_SREV_9271(ah)) {
+		nf = MS(REG_READ(ah, AR_PHY_CH1_CCA),
+				AR9280_PHY_CH1_MINCCA_PWR);
+
+		if (nf & 0x100)
+			nf = 0 - ((nf ^ 0x1ff) + 1);
+		ath_print(common, ATH_DBG_CALIBRATE,
+			  "NF calibrated [ctl] [chain 1] is %d\n", nf);
+		nfarray[1] = nf;
+	}
+
+	nf = MS(REG_READ(ah, AR_PHY_EXT_CCA), AR9280_PHY_EXT_MINCCA_PWR);
+	if (nf & 0x100)
+		nf = 0 - ((nf ^ 0x1ff) + 1);
+	ath_print(common, ATH_DBG_CALIBRATE,
+		  "NF calibrated [ext] [chain 0] is %d\n", nf);
+
+	if (AR_SREV_9271(ah) && (nf >= -114))
+		nf = -116;
+
+	nfarray[3] = nf;
+
+	if (!AR_SREV_9285(ah) && !AR_SREV_9271(ah)) {
+		nf = MS(REG_READ(ah, AR_PHY_CH1_EXT_CCA),
+				AR9280_PHY_CH1_EXT_MINCCA_PWR);
+
+		if (nf & 0x100)
+			nf = 0 - ((nf ^ 0x1ff) + 1);
+		ath_print(common, ATH_DBG_CALIBRATE,
+			  "NF calibrated [ext] [chain 1] is %d\n", nf);
+		nfarray[4] = nf;
+	}
+}
+
 void ar9002_hw_attach_phy_ops(struct ath_hw *ah)
 {
 	struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
@@ -478,4 +530,5 @@ void ar9002_hw_attach_phy_ops(struct ath_hw *ah)
 	priv_ops->spur_mitigate_freq = ar9002_hw_spur_mitigate;
 	priv_ops->olc_init = ar9002_olc_init;
 	priv_ops->compute_pll_control = ar9002_hw_compute_pll_control;
+	priv_ops->do_getnf = ar9002_hw_do_getnf;
 }
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
index c938b85..67b3b65 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
@@ -705,6 +705,115 @@ static bool ar9003_hw_ani_control(struct ath_hw *ah,
 	return true;
 }
 
+static void ar9003_hw_nf_sanitize_2g(struct ath_hw *ah, s16 *nf)
+{
+	struct ath_common *common = ath9k_hw_common(ah);
+
+	if (*nf > ah->nf_2g_max) {
+		ath_print(common, ATH_DBG_CALIBRATE,
+			  "2 GHz NF (%d) > MAX (%d), "
+			  "correcting to MAX",
+			  *nf, ah->nf_2g_max);
+		*nf = ah->nf_2g_max;
+	} else if (*nf < ah->nf_2g_min) {
+		ath_print(common, ATH_DBG_CALIBRATE,
+			  "2 GHz NF (%d) < MIN (%d), "
+			  "correcting to MIN",
+			  *nf, ah->nf_2g_min);
+		*nf = ah->nf_2g_min;
+	}
+}
+
+static void ar9003_hw_nf_sanitize_5g(struct ath_hw *ah, s16 *nf)
+{
+	struct ath_common *common = ath9k_hw_common(ah);
+
+	if (*nf > ah->nf_5g_max) {
+		ath_print(common, ATH_DBG_CALIBRATE,
+			  "5 GHz NF (%d) > MAX (%d), "
+			  "correcting to MAX",
+			  *nf, ah->nf_5g_max);
+		*nf = ah->nf_5g_max;
+	} else if (*nf < ah->nf_5g_min) {
+		ath_print(common, ATH_DBG_CALIBRATE,
+			  "5 GHz NF (%d) < MIN (%d), "
+			  "correcting to MIN",
+			  *nf, ah->nf_5g_min);
+		*nf = ah->nf_5g_min;
+	}
+}
+
+static void ar9003_hw_nf_sanitize(struct ath_hw *ah, s16 *nf)
+{
+	if (IS_CHAN_2GHZ(ah->curchan))
+		ar9003_hw_nf_sanitize_2g(ah, nf);
+	else
+		ar9003_hw_nf_sanitize_5g(ah, nf);
+}
+
+static void ar9003_hw_do_getnf(struct ath_hw *ah,
+			      int16_t nfarray[NUM_NF_READINGS])
+{
+	struct ath_common *common = ath9k_hw_common(ah);
+	int16_t nf;
+
+	nf = MS(REG_READ(ah, AR_PHY_CCA_0), AR_PHY_MINCCA_PWR);
+	if (nf & 0x100)
+		nf = 0 - ((nf ^ 0x1ff) + 1);
+	ar9003_hw_nf_sanitize(ah, &nf);
+	ath_print(common, ATH_DBG_CALIBRATE,
+		  "NF calibrated [ctl] [chain 0] is %d\n", nf);
+	nfarray[0] = nf;
+
+	nf = MS(REG_READ(ah, AR_PHY_CCA_1), AR_PHY_CH1_MINCCA_PWR);
+	if (nf & 0x100)
+		nf = 0 - ((nf ^ 0x1ff) + 1);
+	ar9003_hw_nf_sanitize(ah, &nf);
+	ath_print(common, ATH_DBG_CALIBRATE,
+		  "NF calibrated [ctl] [chain 1] is %d\n", nf);
+	nfarray[1] = nf;
+
+	nf = MS(REG_READ(ah, AR_PHY_CCA_2), AR_PHY_CH2_MINCCA_PWR);
+	if (nf & 0x100)
+		nf = 0 - ((nf ^ 0x1ff) + 1);
+	ar9003_hw_nf_sanitize(ah, &nf);
+	ath_print(common, ATH_DBG_CALIBRATE,
+		  "NF calibrated [ctl] [chain 2] is %d\n", nf);
+	nfarray[2] = nf;
+
+	nf = MS(REG_READ(ah, AR_PHY_EXT_CCA), AR_PHY_EXT_MINCCA_PWR);
+	if (nf & 0x100)
+		nf = 0 - ((nf ^ 0x1ff) + 1);
+	ar9003_hw_nf_sanitize(ah, &nf);
+	ath_print(common, ATH_DBG_CALIBRATE,
+		  "NF calibrated [ext] [chain 0] is %d\n", nf);
+	nfarray[3] = nf;
+
+	nf = MS(REG_READ(ah, AR_PHY_EXT_CCA_1), AR_PHY_CH1_EXT_MINCCA_PWR);
+	if (nf & 0x100)
+		nf = 0 - ((nf ^ 0x1ff) + 1);
+	ar9003_hw_nf_sanitize(ah, &nf);
+	ath_print(common, ATH_DBG_CALIBRATE,
+		  "NF calibrated [ext] [chain 1] is %d\n", nf);
+	nfarray[4] = nf;
+
+	nf = MS(REG_READ(ah, AR_PHY_EXT_CCA_2), AR_PHY_CH2_EXT_MINCCA_PWR);
+	if (nf & 0x100)
+		nf = 0 - ((nf ^ 0x1ff) + 1);
+	ar9003_hw_nf_sanitize(ah, &nf);
+	ath_print(common, ATH_DBG_CALIBRATE,
+		  "NF calibrated [ext] [chain 2] is %d\n", nf);
+	nfarray[5] = nf;
+}
+
+void ar9003_hw_set_nf_limits(struct ath_hw *ah)
+{
+	ah->nf_2g_max = AR_PHY_CCA_MAX_GOOD_VAL_9300_2GHZ;
+	ah->nf_2g_min = AR_PHY_CCA_MIN_GOOD_VAL_9300_2GHZ;
+	ah->nf_5g_max = AR_PHY_CCA_MAX_GOOD_VAL_9300_5GHZ;
+	ah->nf_5g_min = AR_PHY_CCA_MIN_GOOD_VAL_9300_5GHZ;
+}
+
 void ar9003_hw_attach_phy_ops(struct ath_hw *ah)
 {
 	struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
@@ -723,4 +832,5 @@ void ar9003_hw_attach_phy_ops(struct ath_hw *ah)
 	priv_ops->enable_rfkill = ar9003_hw_enable_rfkill;
 	priv_ops->set_diversity = ar9003_hw_set_diversity;
 	priv_ops->ani_control = ar9003_hw_ani_control;
+	priv_ops->do_getnf = ar9003_hw_do_getnf;
 }
diff --git a/drivers/net/wireless/ath/ath9k/calib.c b/drivers/net/wireless/ath/ath9k/calib.c
index eba85ad..eed2c76 100644
--- a/drivers/net/wireless/ath/ath9k/calib.c
+++ b/drivers/net/wireless/ath/ath9k/calib.c
@@ -15,6 +15,7 @@
  */
 
 #include "hw.h"
+#include "hw-ops.h"
 #include "ar9002_phy.h"
 
 /* We can tune this as we go by monitoring really low values */
@@ -88,95 +89,6 @@ static void ath9k_hw_update_nfcal_hist_buffer(struct ath9k_nfcal_hist *h,
 	return;
 }
 
-static void ath9k_hw_do_getnf(struct ath_hw *ah,
-			      int16_t nfarray[NUM_NF_READINGS])
-{
-	struct ath_common *common = ath9k_hw_common(ah);
-	int16_t nf;
-
-	if (AR_SREV_9280_10_OR_LATER(ah))
-		nf = MS(REG_READ(ah, AR_PHY_CCA), AR9280_PHY_MINCCA_PWR);
-	else
-		nf = MS(REG_READ(ah, AR_PHY_CCA), AR_PHY_MINCCA_PWR);
-
-	if (nf & 0x100)
-		nf = 0 - ((nf ^ 0x1ff) + 1);
-	ath_print(common, ATH_DBG_CALIBRATE,
-		  "NF calibrated [ctl] [chain 0] is %d\n", nf);
-
-	if (AR_SREV_9271(ah) && (nf >= -114))
-		nf = -116;
-
-	nfarray[0] = nf;
-
-	if (!AR_SREV_9285(ah) && !AR_SREV_9271(ah)) {
-		if (AR_SREV_9280_10_OR_LATER(ah))
-			nf = MS(REG_READ(ah, AR_PHY_CH1_CCA),
-					AR9280_PHY_CH1_MINCCA_PWR);
-		else
-			nf = MS(REG_READ(ah, AR_PHY_CH1_CCA),
-					AR_PHY_CH1_MINCCA_PWR);
-
-		if (nf & 0x100)
-			nf = 0 - ((nf ^ 0x1ff) + 1);
-		ath_print(common, ATH_DBG_CALIBRATE,
-			  "NF calibrated [ctl] [chain 1] is %d\n", nf);
-		nfarray[1] = nf;
-
-		if (!AR_SREV_9280(ah) && !AR_SREV_9287(ah)) {
-			nf = MS(REG_READ(ah, AR_PHY_CH2_CCA),
-					AR_PHY_CH2_MINCCA_PWR);
-			if (nf & 0x100)
-				nf = 0 - ((nf ^ 0x1ff) + 1);
-			ath_print(common, ATH_DBG_CALIBRATE,
-				  "NF calibrated [ctl] [chain 2] is %d\n", nf);
-			nfarray[2] = nf;
-		}
-	}
-
-	if (AR_SREV_9280_10_OR_LATER(ah))
-		nf = MS(REG_READ(ah, AR_PHY_EXT_CCA),
-			AR9280_PHY_EXT_MINCCA_PWR);
-	else
-		nf = MS(REG_READ(ah, AR_PHY_EXT_CCA),
-			AR_PHY_EXT_MINCCA_PWR);
-
-	if (nf & 0x100)
-		nf = 0 - ((nf ^ 0x1ff) + 1);
-	ath_print(common, ATH_DBG_CALIBRATE,
-		  "NF calibrated [ext] [chain 0] is %d\n", nf);
-
-	if (AR_SREV_9271(ah) && (nf >= -114))
-		nf = -116;
-
-	nfarray[3] = nf;
-
-	if (!AR_SREV_9285(ah) && !AR_SREV_9271(ah)) {
-		if (AR_SREV_9280_10_OR_LATER(ah))
-			nf = MS(REG_READ(ah, AR_PHY_CH1_EXT_CCA),
-					AR9280_PHY_CH1_EXT_MINCCA_PWR);
-		else
-			nf = MS(REG_READ(ah, AR_PHY_CH1_EXT_CCA),
-					AR_PHY_CH1_EXT_MINCCA_PWR);
-
-		if (nf & 0x100)
-			nf = 0 - ((nf ^ 0x1ff) + 1);
-		ath_print(common, ATH_DBG_CALIBRATE,
-			  "NF calibrated [ext] [chain 1] is %d\n", nf);
-		nfarray[4] = nf;
-
-		if (!AR_SREV_9280(ah) && !AR_SREV_9287(ah)) {
-			nf = MS(REG_READ(ah, AR_PHY_CH2_EXT_CCA),
-					AR_PHY_CH2_EXT_MINCCA_PWR);
-			if (nf & 0x100)
-				nf = 0 - ((nf ^ 0x1ff) + 1);
-			ath_print(common, ATH_DBG_CALIBRATE,
-				  "NF calibrated [ext] [chain 2] is %d\n", nf);
-			nfarray[5] = nf;
-		}
-	}
-}
-
 static bool getNoiseFloorThresh(struct ath_hw *ah,
 				enum ieee80211_band band,
 				int16_t *nft)
diff --git a/drivers/net/wireless/ath/ath9k/hw-ops.h b/drivers/net/wireless/ath/ath9k/hw-ops.h
index a770107..e2b8ad4 100644
--- a/drivers/net/wireless/ath/ath9k/hw-ops.h
+++ b/drivers/net/wireless/ath/ath9k/hw-ops.h
@@ -163,4 +163,10 @@ static inline bool ath9k_hw_ani_control(struct ath_hw *ah,
 	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])
+{
+	return ath9k_hw_private_ops(ah)->do_getnf(ah, nfarray);
+}
+
 #endif /* ATH9K_HW_OPS_H */
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index aa80d43..2dcfaa9 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -1072,6 +1072,9 @@ static int __ath9k_hw_init(struct ath_hw *ah)
 	else
 		ah->tx_trig_level = (AR_FTRIG_512B >> AR_FTRIG_S);
 
+	if (AR_SREV_9300_20_OR_LATER(ah))
+		ar9003_hw_set_nf_limits(ah);
+
 	ath9k_init_nfcal_hist_buffer(ah);
 
 	common->state = ATH_HW_INITIALIZED;
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 1eceda2..7889ecb 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -513,6 +513,7 @@ struct ath_hw_private_ops {
 				   struct ath9k_channel *chan);
 	bool (*ani_control)(struct ath_hw *ah, enum ath9k_ani_cmd cmd,
 			    int param);
+	void (*do_getnf)(struct ath_hw *ah, int16_t nfarray[NUM_NF_READINGS]);
 };
 
 /**
@@ -553,6 +554,10 @@ struct ath_hw {
 	bool is_pciexpress;
 	bool need_an_top2_fixup;
 	u16 tx_trig_level;
+	s16 nf_2g_max;
+	s16 nf_2g_min;
+	s16 nf_5g_max;
+	s16 nf_5g_min;
 	u16 rfsilent;
 	u32 rfkill_gpio;
 	u32 rfkill_polarity;
@@ -818,6 +823,13 @@ void ath9k_hw_htc_resetinit(struct ath_hw *ah);
 void ath9k_hw_get_delta_slope_vals(struct ath_hw *ah, u32 coef_scaled,
 				   u32 *coef_mantissa, u32 *coef_exponent);
 
+/*
+ * Code specifric to AR9003, we stuff these here to avoid callbacks
+ * for older families
+ */
+void ar9003_hw_set_nf_limits(struct ath_hw *ah);
+
+/* Hardware family op attach helpers */
 void ar5008_hw_attach_phy_ops(struct ath_hw *ah);
 void ar9002_hw_attach_phy_ops(struct ath_hw *ah);
 void ar9003_hw_attach_phy_ops(struct ath_hw *ah);
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 103+ messages in thread

* [PATCH v3 45/97] ath9k_hw: the eep_map is used only for AR9280 PCI card ini fixup
  2010-04-15 21:38 [PATCH v3 00/97] ath9k: add AR9003 support Luis R. Rodriguez
                   ` (43 preceding siblings ...)
  2010-04-15 21:38 ` [PATCH v3 44/97] ath9k_hw: Split out the function for reading the noise floor Luis R. Rodriguez
@ 2010-04-15 21:38 ` Luis R. Rodriguez
  2010-04-15 21:38 ` [PATCH v3 46/97] ath9k_hw: add a helper for Power Amplifier calibration for AR9002 Luis R. Rodriguez
                   ` (51 subsequent siblings)
  96 siblings, 0 replies; 103+ messages in thread
From: Luis R. Rodriguez @ 2010-04-15 21:38 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Senthil Balasubramanian, Felix Fietkau

From: Senthil Balasubramanian <senthilkumar@atheros.com>

We can reorganize the code in such a way that eep_map can be removed,
which makes the code more clearer.

Signed-off-by: Senthil Balasubramanian <senthilkumar@atheros.com>
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
 drivers/net/wireless/ath/ath9k/eeprom.c |    3 ---
 drivers/net/wireless/ath/ath9k/eeprom.h |    7 -------
 drivers/net/wireless/ath/ath9k/hw.c     |    2 +-
 drivers/net/wireless/ath/ath9k/hw.h     |    1 -
 4 files changed, 1 insertions(+), 12 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/eeprom.c b/drivers/net/wireless/ath/ath9k/eeprom.c
index dacaae9..1a48f43 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom.c
@@ -257,13 +257,10 @@ int ath9k_hw_eeprom_init(struct ath_hw *ah)
 	int status;
 
 	if (AR_SREV_9287(ah)) {
-		ah->eep_map = EEP_MAP_AR9287;
 		ah->eep_ops = &eep_AR9287_ops;
 	} else if (AR_SREV_9285(ah) || AR_SREV_9271(ah)) {
-		ah->eep_map = EEP_MAP_4KBITS;
 		ah->eep_ops = &eep_4k_ops;
 	} else {
-		ah->eep_map = EEP_MAP_DEFAULT;
 		ah->eep_ops = &eep_def_ops;
 	}
 
diff --git a/drivers/net/wireless/ath/ath9k/eeprom.h b/drivers/net/wireless/ath/ath9k/eeprom.h
index 2f2993b..e087e2d 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom.h
+++ b/drivers/net/wireless/ath/ath9k/eeprom.h
@@ -656,13 +656,6 @@ struct ath9k_country_entry {
 	u8 iso[3];
 };
 
-enum ath9k_eep_map {
-	EEP_MAP_DEFAULT = 0x0,
-	EEP_MAP_4KBITS,
-	EEP_MAP_AR9287,
-	EEP_MAP_MAX
-};
-
 struct eeprom_ops {
 	int (*check_eeprom)(struct ath_hw *hw);
 	u32 (*get_eeprom)(struct ath_hw *hw, enum eeprom_param param);
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 2dcfaa9..ec48e7b 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -947,7 +947,7 @@ static void ath9k_hw_init_eeprom_fix(struct ath_hw *ah)
 	struct ath_common *common = ath9k_hw_common(ah);
 
 	ah->need_an_top2_fixup = (ah->hw_version.devid == AR9280_DEVID_PCI) &&
-				 (ah->eep_map != EEP_MAP_4KBITS) &&
+				 !AR_SREV_9285(ah) && !AR_SREV_9271(ah) &&
 				 ((pBase->version & 0xff) > 0x0a) &&
 				 (pBase->pwdclkind == 0);
 
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 7889ecb..48fb5ce 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -548,7 +548,6 @@ struct ath_hw {
 		struct ar9287_eeprom map9287;
 	} eeprom;
 	const struct eeprom_ops *eep_ops;
-	enum ath9k_eep_map eep_map;
 
 	bool sw_mgmt_crypto;
 	bool is_pciexpress;
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 103+ messages in thread

* [PATCH v3 46/97] ath9k_hw: add a helper for Power Amplifier calibration for AR9002
  2010-04-15 21:38 [PATCH v3 00/97] ath9k: add AR9003 support Luis R. Rodriguez
                   ` (44 preceding siblings ...)
  2010-04-15 21:38 ` [PATCH v3 45/97] ath9k_hw: the eep_map is used only for AR9280 PCI card ini fixup Luis R. Rodriguez
@ 2010-04-15 21:38 ` Luis R. Rodriguez
  2010-04-15 21:38 ` [PATCH v3 47/97] ath9k_hw: add a helper for the OLC tem compensation " Luis R. Rodriguez
                   ` (50 subsequent siblings)
  96 siblings, 0 replies; 103+ messages in thread
From: Luis R. Rodriguez @ 2010-04-15 21:38 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Luis R. Rodriguez

The code can be simplified and shared between two locations if we bring
this into a helper. During reset we do not account for the skip count.

Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/calib.c |   32 +++++++++++++++++---------------
 1 files changed, 17 insertions(+), 15 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/calib.c b/drivers/net/wireless/ath/ath9k/calib.c
index eed2c76..26bc381 100644
--- a/drivers/net/wireless/ath/ath9k/calib.c
+++ b/drivers/net/wireless/ath/ath9k/calib.c
@@ -949,6 +949,21 @@ static inline void ath9k_hw_9285_pa_cal(struct ath_hw *ah, bool is_reset)
 
 }
 
+static void ar9002_hw_pa_cal(struct ath_hw *ah, bool is_reset)
+{
+	if (AR_SREV_9271(ah)) {
+		if (is_reset || !ah->pacal_info.skipcount)
+			ath9k_hw_9271_pa_cal(ah, is_reset);
+		else
+			ah->pacal_info.skipcount--;
+	} else if (AR_SREV_9285_11_OR_LATER(ah)) {
+		if (is_reset || !ah->pacal_info.skipcount)
+			ath9k_hw_9285_pa_cal(ah, is_reset);
+		else
+			ah->pacal_info.skipcount--;
+	}
+}
+
 bool ath9k_hw_calibrate(struct ath_hw *ah, struct ath9k_channel *chan,
 			u8 rxchainmask, bool longcal)
 {
@@ -973,17 +988,7 @@ bool ath9k_hw_calibrate(struct ath_hw *ah, struct ath9k_channel *chan,
 	/* Do NF cal only at longer intervals */
 	if (longcal) {
 		/* Do periodic PAOffset Cal */
-		if (AR_SREV_9271(ah)) {
-			if (!ah->pacal_info.skipcount)
-				ath9k_hw_9271_pa_cal(ah, false);
-			else
-				ah->pacal_info.skipcount--;
-		} else if (AR_SREV_9285_11_OR_LATER(ah)) {
-			if (!ah->pacal_info.skipcount)
-				ath9k_hw_9285_pa_cal(ah, false);
-			else
-				ah->pacal_info.skipcount--;
-		}
+		ar9002_hw_pa_cal(ah, false);
 
 		if (OLC_FOR_AR9280_20_LATER || OLC_FOR_AR9287_10_LATER)
 			ath9k_olc_temp_compensation(ah);
@@ -1142,10 +1147,7 @@ bool ath9k_hw_init_cal(struct ath_hw *ah, struct ath9k_channel *chan)
 	}
 
 	/* Do PA Calibration */
-	if (AR_SREV_9271(ah))
-		ath9k_hw_9271_pa_cal(ah, true);
-	else if (AR_SREV_9285_11_OR_LATER(ah))
-		ath9k_hw_9285_pa_cal(ah, true);
+	ar9002_hw_pa_cal(ah, true);
 
 	/* Do NF Calibration after DC offset and other calibrations */
 	REG_WRITE(ah, AR_PHY_AGC_CONTROL,
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 103+ messages in thread

* [PATCH v3 47/97] ath9k_hw: add a helper for the OLC tem compensation for AR9002
  2010-04-15 21:38 [PATCH v3 00/97] ath9k: add AR9003 support Luis R. Rodriguez
                   ` (45 preceding siblings ...)
  2010-04-15 21:38 ` [PATCH v3 46/97] ath9k_hw: add a helper for Power Amplifier calibration for AR9002 Luis R. Rodriguez
@ 2010-04-15 21:38 ` Luis R. Rodriguez
  2010-04-15 21:38 ` [PATCH v3 48/97] ath9k_hw: rename PA calib for AR9287 Luis R. Rodriguez
                   ` (49 subsequent siblings)
  96 siblings, 0 replies; 103+ messages in thread
From: Luis R. Rodriguez @ 2010-04-15 21:38 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Luis R. Rodriguez

Open Loop Control temperature compensation changes between our
hardware so use a helper for it.

Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/calib.c |   10 +++++++---
 1 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/calib.c b/drivers/net/wireless/ath/ath9k/calib.c
index 26bc381..156ae34 100644
--- a/drivers/net/wireless/ath/ath9k/calib.c
+++ b/drivers/net/wireless/ath/ath9k/calib.c
@@ -964,6 +964,12 @@ static void ar9002_hw_pa_cal(struct ath_hw *ah, bool is_reset)
 	}
 }
 
+static void ar9002_hw_olc_temp_compensation(struct ath_hw *ah)
+{
+	if (OLC_FOR_AR9280_20_LATER || OLC_FOR_AR9287_10_LATER)
+		ath9k_olc_temp_compensation(ah);
+}
+
 bool ath9k_hw_calibrate(struct ath_hw *ah, struct ath9k_channel *chan,
 			u8 rxchainmask, bool longcal)
 {
@@ -989,9 +995,7 @@ bool ath9k_hw_calibrate(struct ath_hw *ah, struct ath9k_channel *chan,
 	if (longcal) {
 		/* Do periodic PAOffset Cal */
 		ar9002_hw_pa_cal(ah, false);
-
-		if (OLC_FOR_AR9280_20_LATER || OLC_FOR_AR9287_10_LATER)
-			ath9k_olc_temp_compensation(ah);
+		ar9002_hw_olc_temp_compensation(ah);
 
 		/* Get the value from the previous NF cal and update history buffer */
 		ath9k_hw_getnf(ah, chan);
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 103+ messages in thread

* [PATCH v3 48/97] ath9k_hw: rename PA calib for AR9287
  2010-04-15 21:38 [PATCH v3 00/97] ath9k: add AR9003 support Luis R. Rodriguez
                   ` (46 preceding siblings ...)
  2010-04-15 21:38 ` [PATCH v3 47/97] ath9k_hw: add a helper for the OLC tem compensation " Luis R. Rodriguez
@ 2010-04-15 21:38 ` Luis R. Rodriguez
  2010-04-15 21:38 ` [PATCH v3 49/97] ath9k_hw: shift code for AR9280 OLC temp comp Luis R. Rodriguez
                   ` (48 subsequent siblings)
  96 siblings, 0 replies; 103+ messages in thread
From: Luis R. Rodriguez @ 2010-04-15 21:38 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Luis R. Rodriguez

Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/calib.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/calib.c b/drivers/net/wireless/ath/ath9k/calib.c
index 156ae34..e2c427b 100644
--- a/drivers/net/wireless/ath/ath9k/calib.c
+++ b/drivers/net/wireless/ath/ath9k/calib.c
@@ -671,7 +671,7 @@ s16 ath9k_hw_getchan_noise(struct ath_hw *ah, struct ath9k_channel *chan)
 }
 EXPORT_SYMBOL(ath9k_hw_getchan_noise);
 
-static void ath9k_olc_temp_compensation_9287(struct ath_hw *ah)
+static void ar9287_hw_olc_temp_compensation(struct ath_hw *ah)
 {
 	u32 rddata;
 	int32_t delta, currPDADC, slope;
@@ -706,7 +706,7 @@ static void ath9k_olc_temp_compensation(struct ath_hw *ah)
 	int delta, currPDADC, regval;
 
 	if (OLC_FOR_AR9287_10_LATER) {
-		ath9k_olc_temp_compensation_9287(ah);
+		ar9287_hw_olc_temp_compensation(ah);
 	} else {
 		rddata = REG_READ(ah, AR_PHY_TX_PWRCTRL4);
 		currPDADC = MS(rddata, AR_PHY_TX_PWRCTRL_PD_AVG_OUT);
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 103+ messages in thread

* [PATCH v3 49/97] ath9k_hw: shift code for AR9280 OLC temp comp
  2010-04-15 21:38 [PATCH v3 00/97] ath9k: add AR9003 support Luis R. Rodriguez
                   ` (47 preceding siblings ...)
  2010-04-15 21:38 ` [PATCH v3 48/97] ath9k_hw: rename PA calib for AR9287 Luis R. Rodriguez
@ 2010-04-15 21:38 ` Luis R. Rodriguez
  2010-04-15 21:38 ` [PATCH v3 50/97] ath9k_hw: move the AR9280 OLC temp comp to its own helper Luis R. Rodriguez
                   ` (47 subsequent siblings)
  96 siblings, 0 replies; 103+ messages in thread
From: Luis R. Rodriguez @ 2010-04-15 21:38 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Luis R. Rodriguez

We're bailing out on the alternative code path so remove the
else branch.

Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/calib.c |   35 +++++++++++++++----------------
 1 files changed, 17 insertions(+), 18 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/calib.c b/drivers/net/wireless/ath/ath9k/calib.c
index e2c427b..5d61169 100644
--- a/drivers/net/wireless/ath/ath9k/calib.c
+++ b/drivers/net/wireless/ath/ath9k/calib.c
@@ -711,25 +711,24 @@ static void ath9k_olc_temp_compensation(struct ath_hw *ah)
 		rddata = REG_READ(ah, AR_PHY_TX_PWRCTRL4);
 		currPDADC = MS(rddata, AR_PHY_TX_PWRCTRL_PD_AVG_OUT);
 
-		if (ah->initPDADC == 0 || currPDADC == 0) {
+		if (ah->initPDADC == 0 || currPDADC == 0)
 			return;
-		} else {
-			if (ah->eep_ops->get_eeprom(ah, EEP_DAC_HPWR_5G))
-				delta = (currPDADC - ah->initPDADC + 4) / 8;
-			else
-				delta = (currPDADC - ah->initPDADC + 5) / 10;
-
-			if (delta != ah->PDADCdelta) {
-				ah->PDADCdelta = delta;
-				for (i = 1; i < AR9280_TX_GAIN_TABLE_SIZE; i++) {
-					regval = ah->originalGain[i] - delta;
-					if (regval < 0)
-						regval = 0;
-
-					REG_RMW_FIELD(ah,
-						      AR_PHY_TX_GAIN_TBL1 + i * 4,
-						      AR_PHY_TX_GAIN, regval);
-				}
+
+		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);
 			}
 		}
 	}
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 103+ messages in thread

* [PATCH v3 50/97] ath9k_hw: move the AR9280 OLC temp comp to its own helper
  2010-04-15 21:38 [PATCH v3 00/97] ath9k: add AR9003 support Luis R. Rodriguez
                   ` (48 preceding siblings ...)
  2010-04-15 21:38 ` [PATCH v3 49/97] ath9k_hw: shift code for AR9280 OLC temp comp Luis R. Rodriguez
@ 2010-04-15 21:38 ` Luis R. Rodriguez
  2010-04-15 21:38 ` [PATCH v3 51/97] ath9k_hw: simplify OLC temp compensation for AR9002 Luis R. Rodriguez
                   ` (46 subsequent siblings)
  96 siblings, 0 replies; 103+ messages in thread
From: Luis R. Rodriguez @ 2010-04-15 21:38 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Luis R. Rodriguez

Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/calib.c |   52 +++++++++++++++++--------------
 1 files changed, 28 insertions(+), 24 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/calib.c b/drivers/net/wireless/ath/ath9k/calib.c
index 5d61169..dae200c 100644
--- a/drivers/net/wireless/ath/ath9k/calib.c
+++ b/drivers/net/wireless/ath/ath9k/calib.c
@@ -700,40 +700,44 @@ static void ar9287_hw_olc_temp_compensation(struct ath_hw *ah)
 	}
 }
 
-static void ath9k_olc_temp_compensation(struct ath_hw *ah)
+static void ar9280_hw_olc_temp_compensation(struct ath_hw *ah)
 {
 	u32 rddata, i;
 	int delta, currPDADC, regval;
 
-	if (OLC_FOR_AR9287_10_LATER) {
-		ar9287_hw_olc_temp_compensation(ah);
-	} else {
-		rddata = REG_READ(ah, AR_PHY_TX_PWRCTRL4);
-		currPDADC = MS(rddata, AR_PHY_TX_PWRCTRL_PD_AVG_OUT);
+	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->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);
-			}
+	if (ah->eep_ops->get_eeprom(ah, EEP_DAC_HPWR_5G))
+		delta = (currPDADC - ah->initPDADC + 4) / 8;
+	else
+		delta = (currPDADC - ah->initPDADC + 5) / 10;
+
+	if (delta != ah->PDADCdelta) {
+		ah->PDADCdelta = delta;
+		for (i = 1; i < AR9280_TX_GAIN_TABLE_SIZE; i++) {
+			regval = ah->originalGain[i] - delta;
+			if (regval < 0)
+				regval = 0;
+
+			REG_RMW_FIELD(ah,
+				      AR_PHY_TX_GAIN_TBL1 + i * 4,
+				      AR_PHY_TX_GAIN, regval);
 		}
 	}
 }
 
+static void ath9k_olc_temp_compensation(struct ath_hw *ah)
+{
+	if (OLC_FOR_AR9287_10_LATER)
+		ar9287_hw_olc_temp_compensation(ah);
+	else
+		ar9280_hw_olc_temp_compensation(ah);
+}
+
 static void ath9k_hw_9271_pa_cal(struct ath_hw *ah, bool is_reset)
 {
 	u32 regVal;
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 103+ messages in thread

* [PATCH v3 51/97] ath9k_hw: simplify OLC temp compensation for AR9002
  2010-04-15 21:38 [PATCH v3 00/97] ath9k: add AR9003 support Luis R. Rodriguez
                   ` (49 preceding siblings ...)
  2010-04-15 21:38 ` [PATCH v3 50/97] ath9k_hw: move the AR9280 OLC temp comp to its own helper Luis R. Rodriguez
@ 2010-04-15 21:38 ` Luis R. Rodriguez
  2010-04-15 21:38 ` [PATCH v3 52/97] ath9k_hw: rename the PA calib routines to match their families Luis R. Rodriguez
                   ` (45 subsequent siblings)
  96 siblings, 0 replies; 103+ messages in thread
From: Luis R. Rodriguez @ 2010-04-15 21:38 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Luis R. Rodriguez

We can do the family revision check on the top level caller.

Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/calib.c |   14 ++++----------
 1 files changed, 4 insertions(+), 10 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/calib.c b/drivers/net/wireless/ath/ath9k/calib.c
index dae200c..b44b305 100644
--- a/drivers/net/wireless/ath/ath9k/calib.c
+++ b/drivers/net/wireless/ath/ath9k/calib.c
@@ -730,14 +730,6 @@ static void ar9280_hw_olc_temp_compensation(struct ath_hw *ah)
 	}
 }
 
-static void ath9k_olc_temp_compensation(struct ath_hw *ah)
-{
-	if (OLC_FOR_AR9287_10_LATER)
-		ar9287_hw_olc_temp_compensation(ah);
-	else
-		ar9280_hw_olc_temp_compensation(ah);
-}
-
 static void ath9k_hw_9271_pa_cal(struct ath_hw *ah, bool is_reset)
 {
 	u32 regVal;
@@ -969,8 +961,10 @@ static void ar9002_hw_pa_cal(struct ath_hw *ah, bool is_reset)
 
 static void ar9002_hw_olc_temp_compensation(struct ath_hw *ah)
 {
-	if (OLC_FOR_AR9280_20_LATER || OLC_FOR_AR9287_10_LATER)
-		ath9k_olc_temp_compensation(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);
 }
 
 bool ath9k_hw_calibrate(struct ath_hw *ah, struct ath9k_channel *chan,
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 103+ messages in thread

* [PATCH v3 52/97] ath9k_hw: rename the PA calib routines to match their families
  2010-04-15 21:38 [PATCH v3 00/97] ath9k: add AR9003 support Luis R. Rodriguez
                   ` (50 preceding siblings ...)
  2010-04-15 21:38 ` [PATCH v3 51/97] ath9k_hw: simplify OLC temp compensation for AR9002 Luis R. Rodriguez
@ 2010-04-15 21:38 ` Luis R. Rodriguez
  2010-04-15 21:38 ` [PATCH v3 53/97] ath9k_hw: rename getNoiseFloorThresh() to ath9k_hw_loadnf() Luis R. Rodriguez
                   ` (44 subsequent siblings)
  96 siblings, 0 replies; 103+ messages in thread
From: Luis R. Rodriguez @ 2010-04-15 21:38 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Luis R. Rodriguez

Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/calib.c |    8 ++++----
 1 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/calib.c b/drivers/net/wireless/ath/ath9k/calib.c
index b44b305..4018074 100644
--- a/drivers/net/wireless/ath/ath9k/calib.c
+++ b/drivers/net/wireless/ath/ath9k/calib.c
@@ -730,7 +730,7 @@ static void ar9280_hw_olc_temp_compensation(struct ath_hw *ah)
 	}
 }
 
-static void ath9k_hw_9271_pa_cal(struct ath_hw *ah, bool is_reset)
+static void ar9271_hw_pa_cal(struct ath_hw *ah, bool is_reset)
 {
 	u32 regVal;
 	unsigned int i;
@@ -831,7 +831,7 @@ static void ath9k_hw_9271_pa_cal(struct ath_hw *ah, bool is_reset)
 		REG_WRITE(ah, regList[i][0], regList[i][1]);
 }
 
-static inline void ath9k_hw_9285_pa_cal(struct ath_hw *ah, bool is_reset)
+static inline void ar9285_hw_pa_cal(struct ath_hw *ah, bool is_reset)
 {
 	struct ath_common *common = ath9k_hw_common(ah);
 	u32 regVal;
@@ -948,12 +948,12 @@ static void ar9002_hw_pa_cal(struct ath_hw *ah, bool is_reset)
 {
 	if (AR_SREV_9271(ah)) {
 		if (is_reset || !ah->pacal_info.skipcount)
-			ath9k_hw_9271_pa_cal(ah, is_reset);
+			ar9271_hw_pa_cal(ah, is_reset);
 		else
 			ah->pacal_info.skipcount--;
 	} else if (AR_SREV_9285_11_OR_LATER(ah)) {
 		if (is_reset || !ah->pacal_info.skipcount)
-			ath9k_hw_9285_pa_cal(ah, is_reset);
+			ar9285_hw_pa_cal(ah, is_reset);
 		else
 			ah->pacal_info.skipcount--;
 	}
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 103+ messages in thread

* [PATCH v3 53/97] ath9k_hw: rename getNoiseFloorThresh() to ath9k_hw_loadnf()
  2010-04-15 21:38 [PATCH v3 00/97] ath9k: add AR9003 support Luis R. Rodriguez
                   ` (51 preceding siblings ...)
  2010-04-15 21:38 ` [PATCH v3 52/97] ath9k_hw: rename the PA calib routines to match their families Luis R. Rodriguez
@ 2010-04-15 21:38 ` Luis R. Rodriguez
  2010-04-15 21:38 ` [PATCH v3 54/97] ath9k_hw: move the cal AR9100 calibration settings Luis R. Rodriguez
                   ` (43 subsequent siblings)
  96 siblings, 0 replies; 103+ messages in thread
From: Luis R. Rodriguez @ 2010-04-15 21:38 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Luis R. Rodriguez

Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/calib.c |    8 ++++----
 1 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/calib.c b/drivers/net/wireless/ath/ath9k/calib.c
index 4018074..aa724c2 100644
--- a/drivers/net/wireless/ath/ath9k/calib.c
+++ b/drivers/net/wireless/ath/ath9k/calib.c
@@ -89,9 +89,9 @@ static void ath9k_hw_update_nfcal_hist_buffer(struct ath9k_nfcal_hist *h,
 	return;
 }
 
-static bool getNoiseFloorThresh(struct ath_hw *ah,
-				enum ieee80211_band band,
-				int16_t *nft)
+static bool ath9k_hw_get_nf_thresh(struct ath_hw *ah,
+				   enum ieee80211_band band,
+				   int16_t *nft)
 {
 	switch (band) {
 	case IEEE80211_BAND_5GHZ:
@@ -612,7 +612,7 @@ int16_t ath9k_hw_getnf(struct ath_hw *ah,
 	} else {
 		ath9k_hw_do_getnf(ah, nfarray);
 		nf = nfarray[0];
-		if (getNoiseFloorThresh(ah, c->band, &nfThresh)
+		if (ath9k_hw_get_nf_thresh(ah, c->band, &nfThresh)
 		    && nf > nfThresh) {
 			ath_print(common, ATH_DBG_CALIBRATE,
 				  "noise floor failed detected; "
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 103+ messages in thread

* [PATCH v3 54/97] ath9k_hw: move the cal AR9100 calibration settings
  2010-04-15 21:38 [PATCH v3 00/97] ath9k: add AR9003 support Luis R. Rodriguez
                   ` (52 preceding siblings ...)
  2010-04-15 21:38 ` [PATCH v3 53/97] ath9k_hw: rename getNoiseFloorThresh() to ath9k_hw_loadnf() Luis R. Rodriguez
@ 2010-04-15 21:38 ` Luis R. Rodriguez
  2010-04-15 21:39 ` [PATCH v3 55/97] ath9k_hw: split calib code by hardware families Luis R. Rodriguez
                   ` (42 subsequent siblings)
  96 siblings, 0 replies; 103+ messages in thread
From: Luis R. Rodriguez @ 2010-04-15 21:38 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Luis R. Rodriguez

The calibration settings should go into the respective
hardware family AR9002 calibration settings callback,
ar9002_hw_init_cal_settings().

Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/hw.c |   14 +++++++-------
 1 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index ec48e7b..51f1e84 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -603,6 +603,12 @@ static bool ar9003_hw_macversion_supported(u32 macversion)
 
 static void ar9002_hw_init_cal_settings(struct ath_hw *ah)
 {
+	if (AR_SREV_9100(ah)) {
+		ah->iq_caldata.calData = &iq_cal_multi_sample;
+		ah->supp_cals = IQ_MISMATCH_CAL;
+		return;
+	}
+
 	if (AR_SREV_9160_10_OR_LATER(ah)) {
 		if (AR_SREV_9280_10_OR_LATER(ah)) {
 			ah->iq_caldata.calData = &iq_cal_single_sample;
@@ -1016,13 +1022,7 @@ static int __ath9k_hw_init(struct ath_hw *ah)
 		return -EOPNOTSUPP;
 	}
 
-	if (AR_SREV_9100(ah)) {
-		ah->iq_caldata.calData = &iq_cal_multi_sample;
-		ah->supp_cals = IQ_MISMATCH_CAL;
-		ah->is_pciexpress = false;
-	}
-
-	if (AR_SREV_9271(ah))
+	if (AR_SREV_9271(ah) || AR_SREV_9100(ah))
 		ah->is_pciexpress = false;
 
 	ah->hw_version.phyRev = REG_READ(ah, AR_PHY_CHIP_ID);
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 103+ messages in thread

* [PATCH v3 55/97] ath9k_hw: split calib code by hardware families
  2010-04-15 21:38 [PATCH v3 00/97] ath9k: add AR9003 support Luis R. Rodriguez
                   ` (53 preceding siblings ...)
  2010-04-15 21:38 ` [PATCH v3 54/97] ath9k_hw: move the cal AR9100 calibration settings Luis R. Rodriguez
@ 2010-04-15 21:39 ` Luis R. Rodriguez
  2010-04-15 21:39 ` [PATCH v3 56/97] ath9k_hw: add the AR9003 ar9003_hw_init_cal callback Luis R. Rodriguez
                   ` (41 subsequent siblings)
  96 siblings, 0 replies; 103+ messages in thread
From: Luis R. Rodriguez @ 2010-04-15 21:39 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Luis R. Rodriguez

Calibration code touches phy registers and since these
change the calibration code needs to be abstracted.

Noise floor calibration is the only thing remaining but
since the remaining calls only touch the AR_PHY_AGC_CONTROL
register we'll just define that register conditionally, that
will be done separately. The goal is to remove the dependency
of ar9002_phy.h on calib.c

This also adds stubs to be filled for AR9003 calibration code.

Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/Makefile       |    4 +-
 drivers/net/wireless/ath/ath9k/ar9002_calib.c |  993 +++++++++++++++++++++++++
 drivers/net/wireless/ath/ath9k/ar9003_calib.c |   66 ++
 drivers/net/wireless/ath/ath9k/calib.c        |  928 +-----------------------
 drivers/net/wireless/ath/ath9k/calib.h        |   15 +-
 drivers/net/wireless/ath/ath9k/hw-ops.h       |   28 +-
 drivers/net/wireless/ath/ath9k/hw.c           |   34 +-
 drivers/net/wireless/ath/ath9k/hw.h           |   21 +-
 8 files changed, 1118 insertions(+), 971 deletions(-)
 create mode 100644 drivers/net/wireless/ath/ath9k/ar9002_calib.c
 create mode 100644 drivers/net/wireless/ath/ath9k/ar9003_calib.c

diff --git a/drivers/net/wireless/ath/ath9k/Makefile b/drivers/net/wireless/ath/ath9k/Makefile
index 96af3d9..d2417ed 100644
--- a/drivers/net/wireless/ath/ath9k/Makefile
+++ b/drivers/net/wireless/ath/ath9k/Makefile
@@ -17,11 +17,13 @@ ath9k_hw-y:=	hw.o \
 		ar9003_phy.o \
 		ar9002_phy.o \
 		ar5008_phy.o \
+		ar9002_calib.o \
+		ar9003_calib.o \
+		calib.o \
 		eeprom.o \
 		eeprom_def.o \
 		eeprom_4k.o \
 		eeprom_9287.o \
-		calib.o \
 		ani.o \
 		btcoex.o \
 		mac.o \
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_calib.c b/drivers/net/wireless/ath/ath9k/ar9002_calib.c
new file mode 100644
index 0000000..cd234aa
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/ar9002_calib.c
@@ -0,0 +1,993 @@
+/*
+ * Copyright (c) 2008-2010 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "hw.h"
+#include "hw-ops.h"
+#include "ar9002_phy.h"
+
+#define AR9285_CLCAL_REDO_THRESH    1
+
+static void ar9002_hw_setup_calibration(struct ath_hw *ah,
+					struct ath9k_cal_list *currCal)
+{
+	struct ath_common *common = ath9k_hw_common(ah);
+
+	REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(0),
+		      AR_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX,
+		      currCal->calData->calCountMax);
+
+	switch (currCal->calData->calType) {
+	case IQ_MISMATCH_CAL:
+		REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_IQ);
+		ath_print(common, ATH_DBG_CALIBRATE,
+			  "starting IQ Mismatch Calibration\n");
+		break;
+	case ADC_GAIN_CAL:
+		REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_GAIN);
+		ath_print(common, ATH_DBG_CALIBRATE,
+			  "starting ADC Gain Calibration\n");
+		break;
+	case ADC_DC_CAL:
+		REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_DC_PER);
+		ath_print(common, ATH_DBG_CALIBRATE,
+			  "starting ADC DC Calibration\n");
+		break;
+	case ADC_DC_INIT_CAL:
+		REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_DC_INIT);
+		ath_print(common, ATH_DBG_CALIBRATE,
+			  "starting Init ADC DC Calibration\n");
+		break;
+	}
+
+	REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4(0),
+		    AR_PHY_TIMING_CTRL4_DO_CAL);
+}
+
+static bool ar9002_hw_per_calibration(struct ath_hw *ah,
+				      struct ath9k_channel *ichan,
+				      u8 rxchainmask,
+				      struct ath9k_cal_list *currCal)
+{
+	bool iscaldone = false;
+
+	if (currCal->calState == CAL_RUNNING) {
+		if (!(REG_READ(ah, AR_PHY_TIMING_CTRL4(0)) &
+		      AR_PHY_TIMING_CTRL4_DO_CAL)) {
+
+			currCal->calData->calCollect(ah);
+			ah->cal_samples++;
+
+			if (ah->cal_samples >=
+			    currCal->calData->calNumSamples) {
+				int i, numChains = 0;
+				for (i = 0; i < AR5416_MAX_CHAINS; i++) {
+					if (rxchainmask & (1 << i))
+						numChains++;
+				}
+
+				currCal->calData->calPostProc(ah, numChains);
+				ichan->CalValid |= currCal->calData->calType;
+				currCal->calState = CAL_DONE;
+				iscaldone = true;
+			} else {
+				ar9002_hw_setup_calibration(ah, currCal);
+			}
+		}
+	} else if (!(ichan->CalValid & currCal->calData->calType)) {
+		ath9k_hw_reset_calibration(ah, currCal);
+	}
+
+	return iscaldone;
+}
+
+/* Assumes you are talking about the currently configured channel */
+static bool ar9002_hw_iscal_supported(struct ath_hw *ah,
+				      enum ath9k_cal_types calType)
+{
+	struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;
+
+	switch (calType & ah->supp_cals) {
+	case IQ_MISMATCH_CAL: /* Both 2 GHz and 5 GHz support OFDM */
+		return true;
+	case ADC_GAIN_CAL:
+	case ADC_DC_CAL:
+		if (!(conf->channel->band == IEEE80211_BAND_2GHZ &&
+		      conf_is_ht20(conf)))
+			return true;
+		break;
+	}
+	return false;
+}
+
+static void ar9002_hw_iqcal_collect(struct ath_hw *ah)
+{
+	int i;
+
+	for (i = 0; i < AR5416_MAX_CHAINS; i++) {
+		ah->totalPowerMeasI[i] +=
+			REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
+		ah->totalPowerMeasQ[i] +=
+			REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
+		ah->totalIqCorrMeas[i] +=
+			(int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
+		ath_print(ath9k_hw_common(ah), ATH_DBG_CALIBRATE,
+			  "%d: Chn %d pmi=0x%08x;pmq=0x%08x;iqcm=0x%08x;\n",
+			  ah->cal_samples, i, ah->totalPowerMeasI[i],
+			  ah->totalPowerMeasQ[i],
+			  ah->totalIqCorrMeas[i]);
+	}
+}
+
+static void ar9002_hw_adc_gaincal_collect(struct ath_hw *ah)
+{
+	int i;
+
+	for (i = 0; i < AR5416_MAX_CHAINS; i++) {
+		ah->totalAdcIOddPhase[i] +=
+			REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
+		ah->totalAdcIEvenPhase[i] +=
+			REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
+		ah->totalAdcQOddPhase[i] +=
+			REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
+		ah->totalAdcQEvenPhase[i] +=
+			REG_READ(ah, AR_PHY_CAL_MEAS_3(i));
+
+		ath_print(ath9k_hw_common(ah), ATH_DBG_CALIBRATE,
+			  "%d: Chn %d oddi=0x%08x; eveni=0x%08x; "
+			  "oddq=0x%08x; evenq=0x%08x;\n",
+			  ah->cal_samples, i,
+			  ah->totalAdcIOddPhase[i],
+			  ah->totalAdcIEvenPhase[i],
+			  ah->totalAdcQOddPhase[i],
+			  ah->totalAdcQEvenPhase[i]);
+	}
+}
+
+static void ar9002_hw_adc_dccal_collect(struct ath_hw *ah)
+{
+	int i;
+
+	for (i = 0; i < AR5416_MAX_CHAINS; i++) {
+		ah->totalAdcDcOffsetIOddPhase[i] +=
+			(int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
+		ah->totalAdcDcOffsetIEvenPhase[i] +=
+			(int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
+		ah->totalAdcDcOffsetQOddPhase[i] +=
+			(int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
+		ah->totalAdcDcOffsetQEvenPhase[i] +=
+			(int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_3(i));
+
+		ath_print(ath9k_hw_common(ah), ATH_DBG_CALIBRATE,
+			  "%d: Chn %d oddi=0x%08x; eveni=0x%08x; "
+			  "oddq=0x%08x; evenq=0x%08x;\n",
+			  ah->cal_samples, i,
+			  ah->totalAdcDcOffsetIOddPhase[i],
+			  ah->totalAdcDcOffsetIEvenPhase[i],
+			  ah->totalAdcDcOffsetQOddPhase[i],
+			  ah->totalAdcDcOffsetQEvenPhase[i]);
+	}
+}
+
+static void ar9002_hw_iqcalibrate(struct ath_hw *ah, u8 numChains)
+{
+	struct ath_common *common = ath9k_hw_common(ah);
+	u32 powerMeasQ, powerMeasI, iqCorrMeas;
+	u32 qCoffDenom, iCoffDenom;
+	int32_t qCoff, iCoff;
+	int iqCorrNeg, i;
+
+	for (i = 0; i < numChains; i++) {
+		powerMeasI = ah->totalPowerMeasI[i];
+		powerMeasQ = ah->totalPowerMeasQ[i];
+		iqCorrMeas = ah->totalIqCorrMeas[i];
+
+		ath_print(common, ATH_DBG_CALIBRATE,
+			  "Starting IQ Cal and Correction for Chain %d\n",
+			  i);
+
+		ath_print(common, ATH_DBG_CALIBRATE,
+			  "Orignal: Chn %diq_corr_meas = 0x%08x\n",
+			  i, ah->totalIqCorrMeas[i]);
+
+		iqCorrNeg = 0;
+
+		if (iqCorrMeas > 0x80000000) {
+			iqCorrMeas = (0xffffffff - iqCorrMeas) + 1;
+			iqCorrNeg = 1;
+		}
+
+		ath_print(common, ATH_DBG_CALIBRATE,
+			  "Chn %d pwr_meas_i = 0x%08x\n", i, powerMeasI);
+		ath_print(common, ATH_DBG_CALIBRATE,
+			  "Chn %d pwr_meas_q = 0x%08x\n", i, powerMeasQ);
+		ath_print(common, ATH_DBG_CALIBRATE, "iqCorrNeg is 0x%08x\n",
+			  iqCorrNeg);
+
+		iCoffDenom = (powerMeasI / 2 + powerMeasQ / 2) / 128;
+		qCoffDenom = powerMeasQ / 64;
+
+		if ((powerMeasQ != 0) && (iCoffDenom != 0) &&
+		    (qCoffDenom != 0)) {
+			iCoff = iqCorrMeas / iCoffDenom;
+			qCoff = powerMeasI / qCoffDenom - 64;
+			ath_print(common, ATH_DBG_CALIBRATE,
+				  "Chn %d iCoff = 0x%08x\n", i, iCoff);
+			ath_print(common, ATH_DBG_CALIBRATE,
+				  "Chn %d qCoff = 0x%08x\n", i, qCoff);
+
+			iCoff = iCoff & 0x3f;
+			ath_print(common, ATH_DBG_CALIBRATE,
+				  "New: Chn %d iCoff = 0x%08x\n", i, iCoff);
+			if (iqCorrNeg == 0x0)
+				iCoff = 0x40 - iCoff;
+
+			if (qCoff > 15)
+				qCoff = 15;
+			else if (qCoff <= -16)
+				qCoff = 16;
+
+			ath_print(common, ATH_DBG_CALIBRATE,
+				  "Chn %d : iCoff = 0x%x  qCoff = 0x%x\n",
+				  i, iCoff, qCoff);
+
+			REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(i),
+				      AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF,
+				      iCoff);
+			REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(i),
+				      AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF,
+				      qCoff);
+			ath_print(common, ATH_DBG_CALIBRATE,
+				  "IQ Cal and Correction done for Chain %d\n",
+				  i);
+		}
+	}
+
+	REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4(0),
+		    AR_PHY_TIMING_CTRL4_IQCORR_ENABLE);
+}
+
+static void ar9002_hw_adc_gaincal_calibrate(struct ath_hw *ah, u8 numChains)
+{
+	struct ath_common *common = ath9k_hw_common(ah);
+	u32 iOddMeasOffset, iEvenMeasOffset, qOddMeasOffset, qEvenMeasOffset;
+	u32 qGainMismatch, iGainMismatch, val, i;
+
+	for (i = 0; i < numChains; i++) {
+		iOddMeasOffset = ah->totalAdcIOddPhase[i];
+		iEvenMeasOffset = ah->totalAdcIEvenPhase[i];
+		qOddMeasOffset = ah->totalAdcQOddPhase[i];
+		qEvenMeasOffset = ah->totalAdcQEvenPhase[i];
+
+		ath_print(common, ATH_DBG_CALIBRATE,
+			  "Starting ADC Gain Cal for Chain %d\n", i);
+
+		ath_print(common, ATH_DBG_CALIBRATE,
+			  "Chn %d pwr_meas_odd_i = 0x%08x\n", i,
+			  iOddMeasOffset);
+		ath_print(common, ATH_DBG_CALIBRATE,
+			  "Chn %d pwr_meas_even_i = 0x%08x\n", i,
+			  iEvenMeasOffset);
+		ath_print(common, ATH_DBG_CALIBRATE,
+			  "Chn %d pwr_meas_odd_q = 0x%08x\n", i,
+			  qOddMeasOffset);
+		ath_print(common, ATH_DBG_CALIBRATE,
+			  "Chn %d pwr_meas_even_q = 0x%08x\n", i,
+			  qEvenMeasOffset);
+
+		if (iOddMeasOffset != 0 && qEvenMeasOffset != 0) {
+			iGainMismatch =
+				((iEvenMeasOffset * 32) /
+				 iOddMeasOffset) & 0x3f;
+			qGainMismatch =
+				((qOddMeasOffset * 32) /
+				 qEvenMeasOffset) & 0x3f;
+
+			ath_print(common, ATH_DBG_CALIBRATE,
+				  "Chn %d gain_mismatch_i = 0x%08x\n", i,
+				  iGainMismatch);
+			ath_print(common, ATH_DBG_CALIBRATE,
+				  "Chn %d gain_mismatch_q = 0x%08x\n", i,
+				  qGainMismatch);
+
+			val = REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i));
+			val &= 0xfffff000;
+			val |= (qGainMismatch) | (iGainMismatch << 6);
+			REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i), val);
+
+			ath_print(common, ATH_DBG_CALIBRATE,
+				  "ADC Gain Cal done for Chain %d\n", i);
+		}
+	}
+
+	REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0),
+		  REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0)) |
+		  AR_PHY_NEW_ADC_GAIN_CORR_ENABLE);
+}
+
+static void ar9002_hw_adc_dccal_calibrate(struct ath_hw *ah, u8 numChains)
+{
+	struct ath_common *common = ath9k_hw_common(ah);
+	u32 iOddMeasOffset, iEvenMeasOffset, val, i;
+	int32_t qOddMeasOffset, qEvenMeasOffset, qDcMismatch, iDcMismatch;
+	const struct ath9k_percal_data *calData =
+		ah->cal_list_curr->calData;
+	u32 numSamples =
+		(1 << (calData->calCountMax + 5)) * calData->calNumSamples;
+
+	for (i = 0; i < numChains; i++) {
+		iOddMeasOffset = ah->totalAdcDcOffsetIOddPhase[i];
+		iEvenMeasOffset = ah->totalAdcDcOffsetIEvenPhase[i];
+		qOddMeasOffset = ah->totalAdcDcOffsetQOddPhase[i];
+		qEvenMeasOffset = ah->totalAdcDcOffsetQEvenPhase[i];
+
+		ath_print(common, ATH_DBG_CALIBRATE,
+			   "Starting ADC DC Offset Cal for Chain %d\n", i);
+
+		ath_print(common, ATH_DBG_CALIBRATE,
+			  "Chn %d pwr_meas_odd_i = %d\n", i,
+			  iOddMeasOffset);
+		ath_print(common, ATH_DBG_CALIBRATE,
+			  "Chn %d pwr_meas_even_i = %d\n", i,
+			  iEvenMeasOffset);
+		ath_print(common, ATH_DBG_CALIBRATE,
+			  "Chn %d pwr_meas_odd_q = %d\n", i,
+			  qOddMeasOffset);
+		ath_print(common, ATH_DBG_CALIBRATE,
+			  "Chn %d pwr_meas_even_q = %d\n", i,
+			  qEvenMeasOffset);
+
+		iDcMismatch = (((iEvenMeasOffset - iOddMeasOffset) * 2) /
+			       numSamples) & 0x1ff;
+		qDcMismatch = (((qOddMeasOffset - qEvenMeasOffset) * 2) /
+			       numSamples) & 0x1ff;
+
+		ath_print(common, ATH_DBG_CALIBRATE,
+			  "Chn %d dc_offset_mismatch_i = 0x%08x\n", i,
+			  iDcMismatch);
+		ath_print(common, ATH_DBG_CALIBRATE,
+			  "Chn %d dc_offset_mismatch_q = 0x%08x\n", i,
+			  qDcMismatch);
+
+		val = REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i));
+		val &= 0xc0000fff;
+		val |= (qDcMismatch << 12) | (iDcMismatch << 21);
+		REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i), val);
+
+		ath_print(common, ATH_DBG_CALIBRATE,
+			  "ADC DC Offset Cal done for Chain %d\n", i);
+	}
+
+	REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0),
+		  REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0)) |
+		  AR_PHY_NEW_ADC_DC_OFFSET_CORR_ENABLE);
+}
+
+static void ar9287_hw_olc_temp_compensation(struct ath_hw *ah)
+{
+	u32 rddata;
+	int32_t delta, currPDADC, slope;
+
+	rddata = REG_READ(ah, AR_PHY_TX_PWRCTRL4);
+	currPDADC = MS(rddata, AR_PHY_TX_PWRCTRL_PD_AVG_OUT);
+
+	if (ah->initPDADC == 0 || currPDADC == 0) {
+		/*
+		 * Zero value indicates that no frames have been transmitted
+		 * yet, can't do temperature compensation until frames are
+		 * transmitted.
+		 */
+		return;
+	} else {
+		slope = ah->eep_ops->get_eeprom(ah, EEP_TEMPSENSE_SLOPE);
+
+		if (slope == 0) { /* to avoid divide by zero case */
+			delta = 0;
+		} else {
+			delta = ((currPDADC - ah->initPDADC)*4) / slope;
+		}
+		REG_RMW_FIELD(ah, AR_PHY_CH0_TX_PWRCTRL11,
+			      AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP, delta);
+		REG_RMW_FIELD(ah, AR_PHY_CH1_TX_PWRCTRL11,
+			      AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP, delta);
+	}
+}
+
+static void ar9280_hw_olc_temp_compensation(struct ath_hw *ah)
+{
+	u32 rddata, i;
+	int delta, currPDADC, regval;
+
+	rddata = REG_READ(ah, AR_PHY_TX_PWRCTRL4);
+	currPDADC = MS(rddata, AR_PHY_TX_PWRCTRL_PD_AVG_OUT);
+
+	if (ah->initPDADC == 0 || currPDADC == 0)
+		return;
+
+	if (ah->eep_ops->get_eeprom(ah, EEP_DAC_HPWR_5G))
+		delta = (currPDADC - ah->initPDADC + 4) / 8;
+	else
+		delta = (currPDADC - ah->initPDADC + 5) / 10;
+
+	if (delta != ah->PDADCdelta) {
+		ah->PDADCdelta = delta;
+		for (i = 1; i < AR9280_TX_GAIN_TABLE_SIZE; i++) {
+			regval = ah->originalGain[i] - delta;
+			if (regval < 0)
+				regval = 0;
+
+			REG_RMW_FIELD(ah,
+				      AR_PHY_TX_GAIN_TBL1 + i * 4,
+				      AR_PHY_TX_GAIN, regval);
+		}
+	}
+}
+
+static void ar9271_hw_pa_cal(struct ath_hw *ah, bool is_reset)
+{
+	u32 regVal;
+	unsigned int i;
+	u32 regList[][2] = {
+		{ 0x786c, 0 },
+		{ 0x7854, 0 },
+		{ 0x7820, 0 },
+		{ 0x7824, 0 },
+		{ 0x7868, 0 },
+		{ 0x783c, 0 },
+		{ 0x7838, 0 } ,
+		{ 0x7828, 0 } ,
+	};
+
+	for (i = 0; i < ARRAY_SIZE(regList); i++)
+		regList[i][1] = REG_READ(ah, regList[i][0]);
+
+	regVal = REG_READ(ah, 0x7834);
+	regVal &= (~(0x1));
+	REG_WRITE(ah, 0x7834, regVal);
+	regVal = REG_READ(ah, 0x9808);
+	regVal |= (0x1 << 27);
+	REG_WRITE(ah, 0x9808, regVal);
+
+	/* 786c,b23,1, pwddac=1 */
+	REG_RMW_FIELD(ah, AR9285_AN_TOP3, AR9285_AN_TOP3_PWDDAC, 1);
+	/* 7854, b5,1, pdrxtxbb=1 */
+	REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDRXTXBB1, 1);
+	/* 7854, b7,1, pdv2i=1 */
+	REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDV2I, 1);
+	/* 7854, b8,1, pddacinterface=1 */
+	REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDDACIF, 1);
+	/* 7824,b12,0, offcal=0 */
+	REG_RMW_FIELD(ah, AR9285_AN_RF2G2, AR9285_AN_RF2G2_OFFCAL, 0);
+	/* 7838, b1,0, pwddb=0 */
+	REG_RMW_FIELD(ah, AR9285_AN_RF2G7, AR9285_AN_RF2G7_PWDDB, 0);
+	/* 7820,b11,0, enpacal=0 */
+	REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_ENPACAL, 0);
+	/* 7820,b25,1, pdpadrv1=0 */
+	REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPADRV1, 0);
+	/* 7820,b24,0, pdpadrv2=0 */
+	REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPADRV2, 0);
+	/* 7820,b23,0, pdpaout=0 */
+	REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPAOUT, 0);
+	/* 783c,b14-16,7, padrvgn2tab_0=7 */
+	REG_RMW_FIELD(ah, AR9285_AN_RF2G8, AR9285_AN_RF2G8_PADRVGN2TAB0, 7);
+	/*
+	 * 7838,b29-31,0, padrvgn1tab_0=0
+	 * does not matter since we turn it off
+	 */
+	REG_RMW_FIELD(ah, AR9285_AN_RF2G7, AR9285_AN_RF2G7_PADRVGN2TAB0, 0);
+
+	REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9271_AN_RF2G3_CCOMP, 0xfff);
+
+	/* Set:
+	 * localmode=1,bmode=1,bmoderxtx=1,synthon=1,
+	 * txon=1,paon=1,oscon=1,synthon_force=1
+	 */
+	REG_WRITE(ah, AR9285_AN_TOP2, 0xca0358a0);
+	udelay(30);
+	REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9271_AN_RF2G6_OFFS, 0);
+
+	/* find off_6_1; */
+	for (i = 6; i > 0; i--) {
+		regVal = REG_READ(ah, 0x7834);
+		regVal |= (1 << (20 + i));
+		REG_WRITE(ah, 0x7834, regVal);
+		udelay(1);
+		/* regVal = REG_READ(ah, 0x7834); */
+		regVal &= (~(0x1 << (20 + i)));
+		regVal |= (MS(REG_READ(ah, 0x7840), AR9285_AN_RXTXBB1_SPARE9)
+			    << (20 + i));
+		REG_WRITE(ah, 0x7834, regVal);
+	}
+
+	regVal = (regVal >> 20) & 0x7f;
+
+	/* Update PA cal info */
+	if ((!is_reset) && (ah->pacal_info.prev_offset == regVal)) {
+		if (ah->pacal_info.max_skipcount < MAX_PACAL_SKIPCOUNT)
+			ah->pacal_info.max_skipcount =
+				2 * ah->pacal_info.max_skipcount;
+		ah->pacal_info.skipcount = ah->pacal_info.max_skipcount;
+	} else {
+		ah->pacal_info.max_skipcount = 1;
+		ah->pacal_info.skipcount = 0;
+		ah->pacal_info.prev_offset = regVal;
+	}
+
+	regVal = REG_READ(ah, 0x7834);
+	regVal |= 0x1;
+	REG_WRITE(ah, 0x7834, regVal);
+	regVal = REG_READ(ah, 0x9808);
+	regVal &= (~(0x1 << 27));
+	REG_WRITE(ah, 0x9808, regVal);
+
+	for (i = 0; i < ARRAY_SIZE(regList); i++)
+		REG_WRITE(ah, regList[i][0], regList[i][1]);
+}
+
+static inline void ar9285_hw_pa_cal(struct ath_hw *ah, bool is_reset)
+{
+	struct ath_common *common = ath9k_hw_common(ah);
+	u32 regVal;
+	int i, offset, offs_6_1, offs_0;
+	u32 ccomp_org, reg_field;
+	u32 regList[][2] = {
+		{ 0x786c, 0 },
+		{ 0x7854, 0 },
+		{ 0x7820, 0 },
+		{ 0x7824, 0 },
+		{ 0x7868, 0 },
+		{ 0x783c, 0 },
+		{ 0x7838, 0 },
+	};
+
+	ath_print(common, ATH_DBG_CALIBRATE, "Running PA Calibration\n");
+
+	/* PA CAL is not needed for high power solution */
+	if (ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE) ==
+	    AR5416_EEP_TXGAIN_HIGH_POWER)
+		return;
+
+	if (AR_SREV_9285_11(ah)) {
+		REG_WRITE(ah, AR9285_AN_TOP4, (AR9285_AN_TOP4_DEFAULT | 0x14));
+		udelay(10);
+	}
+
+	for (i = 0; i < ARRAY_SIZE(regList); i++)
+		regList[i][1] = REG_READ(ah, regList[i][0]);
+
+	regVal = REG_READ(ah, 0x7834);
+	regVal &= (~(0x1));
+	REG_WRITE(ah, 0x7834, regVal);
+	regVal = REG_READ(ah, 0x9808);
+	regVal |= (0x1 << 27);
+	REG_WRITE(ah, 0x9808, regVal);
+
+	REG_RMW_FIELD(ah, AR9285_AN_TOP3, AR9285_AN_TOP3_PWDDAC, 1);
+	REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDRXTXBB1, 1);
+	REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDV2I, 1);
+	REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDDACIF, 1);
+	REG_RMW_FIELD(ah, AR9285_AN_RF2G2, AR9285_AN_RF2G2_OFFCAL, 0);
+	REG_RMW_FIELD(ah, AR9285_AN_RF2G7, AR9285_AN_RF2G7_PWDDB, 0);
+	REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_ENPACAL, 0);
+	REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPADRV1, 0);
+	REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPADRV2, 0);
+	REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPAOUT, 0);
+	REG_RMW_FIELD(ah, AR9285_AN_RF2G8, AR9285_AN_RF2G8_PADRVGN2TAB0, 7);
+	REG_RMW_FIELD(ah, AR9285_AN_RF2G7, AR9285_AN_RF2G7_PADRVGN2TAB0, 0);
+	ccomp_org = MS(REG_READ(ah, AR9285_AN_RF2G6), AR9285_AN_RF2G6_CCOMP);
+	REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9285_AN_RF2G6_CCOMP, 0xf);
+
+	REG_WRITE(ah, AR9285_AN_TOP2, 0xca0358a0);
+	udelay(30);
+	REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9285_AN_RF2G6_OFFS, 0);
+	REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9285_AN_RF2G3_PDVCCOMP, 0);
+
+	for (i = 6; i > 0; i--) {
+		regVal = REG_READ(ah, 0x7834);
+		regVal |= (1 << (19 + i));
+		REG_WRITE(ah, 0x7834, regVal);
+		udelay(1);
+		regVal = REG_READ(ah, 0x7834);
+		regVal &= (~(0x1 << (19 + i)));
+		reg_field = MS(REG_READ(ah, 0x7840), AR9285_AN_RXTXBB1_SPARE9);
+		regVal |= (reg_field << (19 + i));
+		REG_WRITE(ah, 0x7834, regVal);
+	}
+
+	REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9285_AN_RF2G3_PDVCCOMP, 1);
+	udelay(1);
+	reg_field = MS(REG_READ(ah, AR9285_AN_RF2G9), AR9285_AN_RXTXBB1_SPARE9);
+	REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9285_AN_RF2G3_PDVCCOMP, reg_field);
+	offs_6_1 = MS(REG_READ(ah, AR9285_AN_RF2G6), AR9285_AN_RF2G6_OFFS);
+	offs_0   = MS(REG_READ(ah, AR9285_AN_RF2G3), AR9285_AN_RF2G3_PDVCCOMP);
+
+	offset = (offs_6_1<<1) | offs_0;
+	offset = offset - 0;
+	offs_6_1 = offset>>1;
+	offs_0 = offset & 1;
+
+	if ((!is_reset) && (ah->pacal_info.prev_offset == offset)) {
+		if (ah->pacal_info.max_skipcount < MAX_PACAL_SKIPCOUNT)
+			ah->pacal_info.max_skipcount =
+				2 * ah->pacal_info.max_skipcount;
+		ah->pacal_info.skipcount = ah->pacal_info.max_skipcount;
+	} else {
+		ah->pacal_info.max_skipcount = 1;
+		ah->pacal_info.skipcount = 0;
+		ah->pacal_info.prev_offset = offset;
+	}
+
+	REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9285_AN_RF2G6_OFFS, offs_6_1);
+	REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9285_AN_RF2G3_PDVCCOMP, offs_0);
+
+	regVal = REG_READ(ah, 0x7834);
+	regVal |= 0x1;
+	REG_WRITE(ah, 0x7834, regVal);
+	regVal = REG_READ(ah, 0x9808);
+	regVal &= (~(0x1 << 27));
+	REG_WRITE(ah, 0x9808, regVal);
+
+	for (i = 0; i < ARRAY_SIZE(regList); i++)
+		REG_WRITE(ah, regList[i][0], regList[i][1]);
+
+	REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9285_AN_RF2G6_CCOMP, ccomp_org);
+
+	if (AR_SREV_9285_11(ah))
+		REG_WRITE(ah, AR9285_AN_TOP4, AR9285_AN_TOP4_DEFAULT);
+
+}
+
+static void ar9002_hw_pa_cal(struct ath_hw *ah, bool is_reset)
+{
+	if (AR_SREV_9271(ah)) {
+		if (is_reset || !ah->pacal_info.skipcount)
+			ar9271_hw_pa_cal(ah, is_reset);
+		else
+			ah->pacal_info.skipcount--;
+	} else if (AR_SREV_9285_11_OR_LATER(ah)) {
+		if (is_reset || !ah->pacal_info.skipcount)
+			ar9285_hw_pa_cal(ah, is_reset);
+		else
+			ah->pacal_info.skipcount--;
+	}
+}
+
+static void ar9002_hw_olc_temp_compensation(struct ath_hw *ah)
+{
+	if (OLC_FOR_AR9287_10_LATER)
+		ar9287_hw_olc_temp_compensation(ah);
+	else if (OLC_FOR_AR9280_20_LATER)
+		ar9280_hw_olc_temp_compensation(ah);
+}
+
+static bool ar9002_hw_calibrate(struct ath_hw *ah,
+				struct ath9k_channel *chan,
+				u8 rxchainmask,
+				bool longcal)
+{
+	bool iscaldone = true;
+	struct ath9k_cal_list *currCal = ah->cal_list_curr;
+
+	if (currCal &&
+	    (currCal->calState == CAL_RUNNING ||
+	     currCal->calState == CAL_WAITING)) {
+		iscaldone = ar9002_hw_per_calibration(ah, chan,
+						      rxchainmask, currCal);
+		if (iscaldone) {
+			ah->cal_list_curr = currCal = currCal->calNext;
+
+			if (currCal->calState == CAL_WAITING) {
+				iscaldone = false;
+				ath9k_hw_reset_calibration(ah, currCal);
+			}
+		}
+	}
+
+	/* Do NF cal only at longer intervals */
+	if (longcal) {
+		/* Do periodic PAOffset Cal */
+		ar9002_hw_pa_cal(ah, false);
+		ar9002_hw_olc_temp_compensation(ah);
+
+		/*
+		 * Get the value from the previous NF cal and update
+		 * history buffer.
+		 */
+		ath9k_hw_getnf(ah, chan);
+
+		/*
+		 * Load the NF from history buffer of the current channel.
+		 * NF is slow time-variant, so it is OK to use a historical
+		 * value.
+		 */
+		ath9k_hw_loadnf(ah, ah->curchan);
+
+		ath9k_hw_start_nfcal(ah);
+	}
+
+	return iscaldone;
+}
+
+/* Carrier leakage Calibration fix */
+static bool ar9285_hw_cl_cal(struct ath_hw *ah, struct ath9k_channel *chan)
+{
+	struct ath_common *common = ath9k_hw_common(ah);
+
+	REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
+	if (IS_CHAN_HT20(chan)) {
+		REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_PARALLEL_CAL_ENABLE);
+		REG_SET_BIT(ah, AR_PHY_TURBO, AR_PHY_FC_DYN2040_EN);
+		REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
+			    AR_PHY_AGC_CONTROL_FLTR_CAL);
+		REG_CLR_BIT(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_CAL_ENABLE);
+		REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL);
+		if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL,
+				  AR_PHY_AGC_CONTROL_CAL, 0, AH_WAIT_TIMEOUT)) {
+			ath_print(common, ATH_DBG_CALIBRATE, "offset "
+				  "calibration failed to complete in "
+				  "1ms; noisy ??\n");
+			return false;
+		}
+		REG_CLR_BIT(ah, AR_PHY_TURBO, AR_PHY_FC_DYN2040_EN);
+		REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_PARALLEL_CAL_ENABLE);
+		REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
+	}
+	REG_CLR_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC);
+	REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL);
+	REG_SET_BIT(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_CAL_ENABLE);
+	REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL);
+	if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL,
+			  0, AH_WAIT_TIMEOUT)) {
+		ath_print(common, ATH_DBG_CALIBRATE, "offset calibration "
+			  "failed to complete in 1ms; noisy ??\n");
+		return false;
+	}
+
+	REG_SET_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC);
+	REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
+	REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL);
+
+	return true;
+}
+
+static bool ar9285_hw_clc(struct ath_hw *ah, struct ath9k_channel *chan)
+{
+	int i;
+	u_int32_t txgain_max;
+	u_int32_t clc_gain, gain_mask = 0, clc_num = 0;
+	u_int32_t reg_clc_I0, reg_clc_Q0;
+	u_int32_t i0_num = 0;
+	u_int32_t q0_num = 0;
+	u_int32_t total_num = 0;
+	u_int32_t reg_rf2g5_org;
+	bool retv = true;
+
+	if (!(ar9285_hw_cl_cal(ah, chan)))
+		return false;
+
+	txgain_max = MS(REG_READ(ah, AR_PHY_TX_PWRCTRL7),
+			AR_PHY_TX_PWRCTRL_TX_GAIN_TAB_MAX);
+
+	for (i = 0; i < (txgain_max+1); i++) {
+		clc_gain = (REG_READ(ah, (AR_PHY_TX_GAIN_TBL1+(i<<2))) &
+			   AR_PHY_TX_GAIN_CLC) >> AR_PHY_TX_GAIN_CLC_S;
+		if (!(gain_mask & (1 << clc_gain))) {
+			gain_mask |= (1 << clc_gain);
+			clc_num++;
+		}
+	}
+
+	for (i = 0; i < clc_num; i++) {
+		reg_clc_I0 = (REG_READ(ah, (AR_PHY_CLC_TBL1 + (i << 2)))
+			      & AR_PHY_CLC_I0) >> AR_PHY_CLC_I0_S;
+		reg_clc_Q0 = (REG_READ(ah, (AR_PHY_CLC_TBL1 + (i << 2)))
+			      & AR_PHY_CLC_Q0) >> AR_PHY_CLC_Q0_S;
+		if (reg_clc_I0 == 0)
+			i0_num++;
+
+		if (reg_clc_Q0 == 0)
+			q0_num++;
+	}
+	total_num = i0_num + q0_num;
+	if (total_num > AR9285_CLCAL_REDO_THRESH) {
+		reg_rf2g5_org = REG_READ(ah, AR9285_RF2G5);
+		if (AR_SREV_9285E_20(ah)) {
+			REG_WRITE(ah, AR9285_RF2G5,
+				  (reg_rf2g5_org & AR9285_RF2G5_IC50TX) |
+				  AR9285_RF2G5_IC50TX_XE_SET);
+		} else {
+			REG_WRITE(ah, AR9285_RF2G5,
+				  (reg_rf2g5_org & AR9285_RF2G5_IC50TX) |
+				  AR9285_RF2G5_IC50TX_SET);
+		}
+		retv = ar9285_hw_cl_cal(ah, chan);
+		REG_WRITE(ah, AR9285_RF2G5, reg_rf2g5_org);
+	}
+	return retv;
+}
+
+static bool ar9002_hw_init_cal(struct ath_hw *ah, struct ath9k_channel *chan)
+{
+	struct ath_common *common = ath9k_hw_common(ah);
+
+	if (AR_SREV_9271(ah) || AR_SREV_9285_12_OR_LATER(ah)) {
+		if (!ar9285_hw_clc(ah, chan))
+			return false;
+	} else {
+		if (AR_SREV_9280_10_OR_LATER(ah)) {
+			if (!AR_SREV_9287_10_OR_LATER(ah))
+				REG_CLR_BIT(ah, AR_PHY_ADC_CTL,
+					    AR_PHY_ADC_CTL_OFF_PWDADC);
+			REG_SET_BIT(ah, AR_PHY_AGC_CONTROL,
+				    AR_PHY_AGC_CONTROL_FLTR_CAL);
+		}
+
+		/* Calibrate the AGC */
+		REG_WRITE(ah, AR_PHY_AGC_CONTROL,
+			  REG_READ(ah, AR_PHY_AGC_CONTROL) |
+			  AR_PHY_AGC_CONTROL_CAL);
+
+		/* Poll for offset calibration complete */
+		if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL,
+				   AR_PHY_AGC_CONTROL_CAL,
+				   0, AH_WAIT_TIMEOUT)) {
+			ath_print(common, ATH_DBG_CALIBRATE,
+				  "offset calibration failed to "
+				  "complete in 1ms; noisy environment?\n");
+			return false;
+		}
+
+		if (AR_SREV_9280_10_OR_LATER(ah)) {
+			if (!AR_SREV_9287_10_OR_LATER(ah))
+				REG_SET_BIT(ah, AR_PHY_ADC_CTL,
+					    AR_PHY_ADC_CTL_OFF_PWDADC);
+			REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
+				    AR_PHY_AGC_CONTROL_FLTR_CAL);
+		}
+	}
+
+	/* Do PA Calibration */
+	ar9002_hw_pa_cal(ah, true);
+
+	/* Do NF Calibration after DC offset and other calibrations */
+	REG_WRITE(ah, AR_PHY_AGC_CONTROL,
+		  REG_READ(ah, AR_PHY_AGC_CONTROL) | AR_PHY_AGC_CONTROL_NF);
+
+	ah->cal_list = ah->cal_list_last = ah->cal_list_curr = NULL;
+
+	/* Enable IQ, ADC Gain and ADC DC offset CALs */
+	if (AR_SREV_9100(ah) || AR_SREV_9160_10_OR_LATER(ah)) {
+		if (ar9002_hw_iscal_supported(ah, ADC_GAIN_CAL)) {
+			INIT_CAL(&ah->adcgain_caldata);
+			INSERT_CAL(ah, &ah->adcgain_caldata);
+			ath_print(common, ATH_DBG_CALIBRATE,
+				  "enabling ADC Gain Calibration.\n");
+		}
+		if (ar9002_hw_iscal_supported(ah, ADC_DC_CAL)) {
+			INIT_CAL(&ah->adcdc_caldata);
+			INSERT_CAL(ah, &ah->adcdc_caldata);
+			ath_print(common, ATH_DBG_CALIBRATE,
+				  "enabling ADC DC Calibration.\n");
+		}
+		if (ar9002_hw_iscal_supported(ah, IQ_MISMATCH_CAL)) {
+			INIT_CAL(&ah->iq_caldata);
+			INSERT_CAL(ah, &ah->iq_caldata);
+			ath_print(common, ATH_DBG_CALIBRATE,
+				  "enabling IQ Calibration.\n");
+		}
+
+		ah->cal_list_curr = ah->cal_list;
+
+		if (ah->cal_list_curr)
+			ath9k_hw_reset_calibration(ah, ah->cal_list_curr);
+	}
+
+	chan->CalValid = 0;
+
+	return true;
+}
+
+static const struct ath9k_percal_data iq_cal_multi_sample = {
+	IQ_MISMATCH_CAL,
+	MAX_CAL_SAMPLES,
+	PER_MIN_LOG_COUNT,
+	ar9002_hw_iqcal_collect,
+	ar9002_hw_iqcalibrate
+};
+static const struct ath9k_percal_data iq_cal_single_sample = {
+	IQ_MISMATCH_CAL,
+	MIN_CAL_SAMPLES,
+	PER_MAX_LOG_COUNT,
+	ar9002_hw_iqcal_collect,
+	ar9002_hw_iqcalibrate
+};
+static const struct ath9k_percal_data adc_gain_cal_multi_sample = {
+	ADC_GAIN_CAL,
+	MAX_CAL_SAMPLES,
+	PER_MIN_LOG_COUNT,
+	ar9002_hw_adc_gaincal_collect,
+	ar9002_hw_adc_gaincal_calibrate
+};
+static const struct ath9k_percal_data adc_gain_cal_single_sample = {
+	ADC_GAIN_CAL,
+	MIN_CAL_SAMPLES,
+	PER_MAX_LOG_COUNT,
+	ar9002_hw_adc_gaincal_collect,
+	ar9002_hw_adc_gaincal_calibrate
+};
+static const struct ath9k_percal_data adc_dc_cal_multi_sample = {
+	ADC_DC_CAL,
+	MAX_CAL_SAMPLES,
+	PER_MIN_LOG_COUNT,
+	ar9002_hw_adc_dccal_collect,
+	ar9002_hw_adc_dccal_calibrate
+};
+static const struct ath9k_percal_data adc_dc_cal_single_sample = {
+	ADC_DC_CAL,
+	MIN_CAL_SAMPLES,
+	PER_MAX_LOG_COUNT,
+	ar9002_hw_adc_dccal_collect,
+	ar9002_hw_adc_dccal_calibrate
+};
+static const struct ath9k_percal_data adc_init_dc_cal = {
+	ADC_DC_INIT_CAL,
+	MIN_CAL_SAMPLES,
+	INIT_LOG_COUNT,
+	ar9002_hw_adc_dccal_collect,
+	ar9002_hw_adc_dccal_calibrate
+};
+
+static void ar9002_hw_init_cal_settings(struct ath_hw *ah)
+{
+	if (AR_SREV_9100(ah)) {
+		ah->iq_caldata.calData = &iq_cal_multi_sample;
+		ah->supp_cals = IQ_MISMATCH_CAL;
+		return;
+	}
+
+	if (AR_SREV_9160_10_OR_LATER(ah)) {
+		if (AR_SREV_9280_10_OR_LATER(ah)) {
+			ah->iq_caldata.calData = &iq_cal_single_sample;
+			ah->adcgain_caldata.calData =
+				&adc_gain_cal_single_sample;
+			ah->adcdc_caldata.calData =
+				&adc_dc_cal_single_sample;
+			ah->adcdc_calinitdata.calData =
+				&adc_init_dc_cal;
+		} else {
+			ah->iq_caldata.calData = &iq_cal_multi_sample;
+			ah->adcgain_caldata.calData =
+				&adc_gain_cal_multi_sample;
+			ah->adcdc_caldata.calData =
+				&adc_dc_cal_multi_sample;
+			ah->adcdc_calinitdata.calData =
+				&adc_init_dc_cal;
+		}
+		ah->supp_cals = ADC_GAIN_CAL | ADC_DC_CAL | IQ_MISMATCH_CAL;
+	}
+}
+
+void ar9002_hw_attach_calib_ops(struct ath_hw *ah)
+{
+	struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
+	struct ath_hw_ops *ops = ath9k_hw_ops(ah);
+
+	priv_ops->init_cal_settings = ar9002_hw_init_cal_settings;
+	priv_ops->init_cal = ar9002_hw_init_cal;
+	priv_ops->setup_calibration = ar9002_hw_setup_calibration;
+	priv_ops->iscal_supported = ar9002_hw_iscal_supported;
+
+	ops->calibrate = ar9002_hw_calibrate;
+}
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_calib.c b/drivers/net/wireless/ath/ath9k/ar9003_calib.c
new file mode 100644
index 0000000..6a72677
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2010 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "hw.h"
+#include "hw-ops.h"
+#include "ar9003_phy.h"
+
+static void ar9003_hw_setup_calibration(struct ath_hw *ah,
+					struct ath9k_cal_list *currCal)
+{
+	/* TODO */
+}
+
+static bool ar9003_hw_calibrate(struct ath_hw *ah,
+				struct ath9k_channel *chan,
+				u8 rxchainmask,
+				bool longcal)
+{
+	/* TODO */
+	return false;
+}
+
+static bool ar9003_hw_init_cal(struct ath_hw *ah,
+			       struct ath9k_channel *chan)
+{
+	/* TODO */
+	return false;
+}
+
+static void ar9003_hw_init_cal_settings(struct ath_hw *ah)
+{
+	/* TODO */
+}
+
+static bool ar9003_hw_iscal_supported(struct ath_hw *ah,
+				      enum ath9k_cal_types calType)
+{
+	/* TODO */
+	return false;
+}
+
+void ar9003_hw_attach_calib_ops(struct ath_hw *ah)
+{
+	struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
+	struct ath_hw_ops *ops = ath9k_hw_ops(ah);
+
+	priv_ops->init_cal_settings = ar9003_hw_init_cal_settings;
+	priv_ops->init_cal = ar9003_hw_init_cal;
+	priv_ops->setup_calibration = ar9003_hw_setup_calibration;
+	priv_ops->iscal_supported = ar9003_hw_iscal_supported;
+
+	ops->calibrate = ar9003_hw_calibrate;
+}
diff --git a/drivers/net/wireless/ath/ath9k/calib.c b/drivers/net/wireless/ath/ath9k/calib.c
index aa724c2..085e126 100644
--- a/drivers/net/wireless/ath/ath9k/calib.c
+++ b/drivers/net/wireless/ath/ath9k/calib.c
@@ -18,9 +18,10 @@
 #include "hw-ops.h"
 #include "ar9002_phy.h"
 
+/* Common calibration code */
+
 /* We can tune this as we go by monitoring really low values */
 #define ATH9K_NF_TOO_LOW	-60
-#define AR9285_CLCAL_REDO_THRESH    1
 
 /* AR5416 may return very high value (like -31 dBm), in those cases the nf
  * is incorrect and we should use the static NF value. Later we can try to
@@ -108,44 +109,8 @@ static bool ath9k_hw_get_nf_thresh(struct ath_hw *ah,
 	return true;
 }
 
-static void ath9k_hw_setup_calibration(struct ath_hw *ah,
-				       struct ath9k_cal_list *currCal)
-{
-	struct ath_common *common = ath9k_hw_common(ah);
-
-	REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(0),
-		      AR_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX,
-		      currCal->calData->calCountMax);
-
-	switch (currCal->calData->calType) {
-	case IQ_MISMATCH_CAL:
-		REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_IQ);
-		ath_print(common, ATH_DBG_CALIBRATE,
-			  "starting IQ Mismatch Calibration\n");
-		break;
-	case ADC_GAIN_CAL:
-		REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_GAIN);
-		ath_print(common, ATH_DBG_CALIBRATE,
-			  "starting ADC Gain Calibration\n");
-		break;
-	case ADC_DC_CAL:
-		REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_DC_PER);
-		ath_print(common, ATH_DBG_CALIBRATE,
-			  "starting ADC DC Calibration\n");
-		break;
-	case ADC_DC_INIT_CAL:
-		REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_DC_INIT);
-		ath_print(common, ATH_DBG_CALIBRATE,
-			  "starting Init ADC DC Calibration\n");
-		break;
-	}
-
-	REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4(0),
-		    AR_PHY_TIMING_CTRL4_DO_CAL);
-}
-
-static void ath9k_hw_reset_calibration(struct ath_hw *ah,
-				       struct ath9k_cal_list *currCal)
+void ath9k_hw_reset_calibration(struct ath_hw *ah,
+				struct ath9k_cal_list *currCal)
 {
 	int i;
 
@@ -163,324 +128,6 @@ static void ath9k_hw_reset_calibration(struct ath_hw *ah,
 	ah->cal_samples = 0;
 }
 
-static bool ath9k_hw_per_calibration(struct ath_hw *ah,
-				     struct ath9k_channel *ichan,
-				     u8 rxchainmask,
-				     struct ath9k_cal_list *currCal)
-{
-	bool iscaldone = false;
-
-	if (currCal->calState == CAL_RUNNING) {
-		if (!(REG_READ(ah, AR_PHY_TIMING_CTRL4(0)) &
-		      AR_PHY_TIMING_CTRL4_DO_CAL)) {
-
-			currCal->calData->calCollect(ah);
-			ah->cal_samples++;
-
-			if (ah->cal_samples >= currCal->calData->calNumSamples) {
-				int i, numChains = 0;
-				for (i = 0; i < AR5416_MAX_CHAINS; i++) {
-					if (rxchainmask & (1 << i))
-						numChains++;
-				}
-
-				currCal->calData->calPostProc(ah, numChains);
-				ichan->CalValid |= currCal->calData->calType;
-				currCal->calState = CAL_DONE;
-				iscaldone = true;
-			} else {
-				ath9k_hw_setup_calibration(ah, currCal);
-			}
-		}
-	} else if (!(ichan->CalValid & currCal->calData->calType)) {
-		ath9k_hw_reset_calibration(ah, currCal);
-	}
-
-	return iscaldone;
-}
-
-/* Assumes you are talking about the currently configured channel */
-static bool ath9k_hw_iscal_supported(struct ath_hw *ah,
-				     enum ath9k_cal_types calType)
-{
-	struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;
-
-	switch (calType & ah->supp_cals) {
-	case IQ_MISMATCH_CAL: /* Both 2 GHz and 5 GHz support OFDM */
-		return true;
-	case ADC_GAIN_CAL:
-	case ADC_DC_CAL:
-		if (!(conf->channel->band == IEEE80211_BAND_2GHZ &&
-		      conf_is_ht20(conf)))
-			return true;
-		break;
-	}
-	return false;
-}
-
-static void ath9k_hw_iqcal_collect(struct ath_hw *ah)
-{
-	int i;
-
-	for (i = 0; i < AR5416_MAX_CHAINS; i++) {
-		ah->totalPowerMeasI[i] +=
-			REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
-		ah->totalPowerMeasQ[i] +=
-			REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
-		ah->totalIqCorrMeas[i] +=
-			(int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
-		ath_print(ath9k_hw_common(ah), ATH_DBG_CALIBRATE,
-			  "%d: Chn %d pmi=0x%08x;pmq=0x%08x;iqcm=0x%08x;\n",
-			  ah->cal_samples, i, ah->totalPowerMeasI[i],
-			  ah->totalPowerMeasQ[i],
-			  ah->totalIqCorrMeas[i]);
-	}
-}
-
-static void ath9k_hw_adc_gaincal_collect(struct ath_hw *ah)
-{
-	int i;
-
-	for (i = 0; i < AR5416_MAX_CHAINS; i++) {
-		ah->totalAdcIOddPhase[i] +=
-			REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
-		ah->totalAdcIEvenPhase[i] +=
-			REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
-		ah->totalAdcQOddPhase[i] +=
-			REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
-		ah->totalAdcQEvenPhase[i] +=
-			REG_READ(ah, AR_PHY_CAL_MEAS_3(i));
-
-		ath_print(ath9k_hw_common(ah), ATH_DBG_CALIBRATE,
-			  "%d: Chn %d oddi=0x%08x; eveni=0x%08x; "
-			  "oddq=0x%08x; evenq=0x%08x;\n",
-			  ah->cal_samples, i,
-			  ah->totalAdcIOddPhase[i],
-			  ah->totalAdcIEvenPhase[i],
-			  ah->totalAdcQOddPhase[i],
-			  ah->totalAdcQEvenPhase[i]);
-	}
-}
-
-static void ath9k_hw_adc_dccal_collect(struct ath_hw *ah)
-{
-	int i;
-
-	for (i = 0; i < AR5416_MAX_CHAINS; i++) {
-		ah->totalAdcDcOffsetIOddPhase[i] +=
-			(int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
-		ah->totalAdcDcOffsetIEvenPhase[i] +=
-			(int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
-		ah->totalAdcDcOffsetQOddPhase[i] +=
-			(int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
-		ah->totalAdcDcOffsetQEvenPhase[i] +=
-			(int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_3(i));
-
-		ath_print(ath9k_hw_common(ah), ATH_DBG_CALIBRATE,
-			  "%d: Chn %d oddi=0x%08x; eveni=0x%08x; "
-			  "oddq=0x%08x; evenq=0x%08x;\n",
-			  ah->cal_samples, i,
-			  ah->totalAdcDcOffsetIOddPhase[i],
-			  ah->totalAdcDcOffsetIEvenPhase[i],
-			  ah->totalAdcDcOffsetQOddPhase[i],
-			  ah->totalAdcDcOffsetQEvenPhase[i]);
-	}
-}
-
-static void ath9k_hw_iqcalibrate(struct ath_hw *ah, u8 numChains)
-{
-	struct ath_common *common = ath9k_hw_common(ah);
-	u32 powerMeasQ, powerMeasI, iqCorrMeas;
-	u32 qCoffDenom, iCoffDenom;
-	int32_t qCoff, iCoff;
-	int iqCorrNeg, i;
-
-	for (i = 0; i < numChains; i++) {
-		powerMeasI = ah->totalPowerMeasI[i];
-		powerMeasQ = ah->totalPowerMeasQ[i];
-		iqCorrMeas = ah->totalIqCorrMeas[i];
-
-		ath_print(common, ATH_DBG_CALIBRATE,
-			  "Starting IQ Cal and Correction for Chain %d\n",
-			  i);
-
-		ath_print(common, ATH_DBG_CALIBRATE,
-			  "Orignal: Chn %diq_corr_meas = 0x%08x\n",
-			  i, ah->totalIqCorrMeas[i]);
-
-		iqCorrNeg = 0;
-
-		if (iqCorrMeas > 0x80000000) {
-			iqCorrMeas = (0xffffffff - iqCorrMeas) + 1;
-			iqCorrNeg = 1;
-		}
-
-		ath_print(common, ATH_DBG_CALIBRATE,
-			  "Chn %d pwr_meas_i = 0x%08x\n", i, powerMeasI);
-		ath_print(common, ATH_DBG_CALIBRATE,
-			  "Chn %d pwr_meas_q = 0x%08x\n", i, powerMeasQ);
-		ath_print(common, ATH_DBG_CALIBRATE, "iqCorrNeg is 0x%08x\n",
-			  iqCorrNeg);
-
-		iCoffDenom = (powerMeasI / 2 + powerMeasQ / 2) / 128;
-		qCoffDenom = powerMeasQ / 64;
-
-		if ((powerMeasQ != 0) && (iCoffDenom != 0) &&
-		    (qCoffDenom != 0)) {
-			iCoff = iqCorrMeas / iCoffDenom;
-			qCoff = powerMeasI / qCoffDenom - 64;
-			ath_print(common, ATH_DBG_CALIBRATE,
-				  "Chn %d iCoff = 0x%08x\n", i, iCoff);
-			ath_print(common, ATH_DBG_CALIBRATE,
-				  "Chn %d qCoff = 0x%08x\n", i, qCoff);
-
-			iCoff = iCoff & 0x3f;
-			ath_print(common, ATH_DBG_CALIBRATE,
-				  "New: Chn %d iCoff = 0x%08x\n", i, iCoff);
-			if (iqCorrNeg == 0x0)
-				iCoff = 0x40 - iCoff;
-
-			if (qCoff > 15)
-				qCoff = 15;
-			else if (qCoff <= -16)
-				qCoff = 16;
-
-			ath_print(common, ATH_DBG_CALIBRATE,
-				  "Chn %d : iCoff = 0x%x  qCoff = 0x%x\n",
-				  i, iCoff, qCoff);
-
-			REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(i),
-				      AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF,
-				      iCoff);
-			REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(i),
-				      AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF,
-				      qCoff);
-			ath_print(common, ATH_DBG_CALIBRATE,
-				  "IQ Cal and Correction done for Chain %d\n",
-				  i);
-		}
-	}
-
-	REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4(0),
-		    AR_PHY_TIMING_CTRL4_IQCORR_ENABLE);
-}
-
-static void ath9k_hw_adc_gaincal_calibrate(struct ath_hw *ah, u8 numChains)
-{
-	struct ath_common *common = ath9k_hw_common(ah);
-	u32 iOddMeasOffset, iEvenMeasOffset, qOddMeasOffset, qEvenMeasOffset;
-	u32 qGainMismatch, iGainMismatch, val, i;
-
-	for (i = 0; i < numChains; i++) {
-		iOddMeasOffset = ah->totalAdcIOddPhase[i];
-		iEvenMeasOffset = ah->totalAdcIEvenPhase[i];
-		qOddMeasOffset = ah->totalAdcQOddPhase[i];
-		qEvenMeasOffset = ah->totalAdcQEvenPhase[i];
-
-		ath_print(common, ATH_DBG_CALIBRATE,
-			  "Starting ADC Gain Cal for Chain %d\n", i);
-
-		ath_print(common, ATH_DBG_CALIBRATE,
-			  "Chn %d pwr_meas_odd_i = 0x%08x\n", i,
-			  iOddMeasOffset);
-		ath_print(common, ATH_DBG_CALIBRATE,
-			  "Chn %d pwr_meas_even_i = 0x%08x\n", i,
-			  iEvenMeasOffset);
-		ath_print(common, ATH_DBG_CALIBRATE,
-			  "Chn %d pwr_meas_odd_q = 0x%08x\n", i,
-			  qOddMeasOffset);
-		ath_print(common, ATH_DBG_CALIBRATE,
-			  "Chn %d pwr_meas_even_q = 0x%08x\n", i,
-			  qEvenMeasOffset);
-
-		if (iOddMeasOffset != 0 && qEvenMeasOffset != 0) {
-			iGainMismatch =
-				((iEvenMeasOffset * 32) /
-				 iOddMeasOffset) & 0x3f;
-			qGainMismatch =
-				((qOddMeasOffset * 32) /
-				 qEvenMeasOffset) & 0x3f;
-
-			ath_print(common, ATH_DBG_CALIBRATE,
-				  "Chn %d gain_mismatch_i = 0x%08x\n", i,
-				  iGainMismatch);
-			ath_print(common, ATH_DBG_CALIBRATE,
-				  "Chn %d gain_mismatch_q = 0x%08x\n", i,
-				  qGainMismatch);
-
-			val = REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i));
-			val &= 0xfffff000;
-			val |= (qGainMismatch) | (iGainMismatch << 6);
-			REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i), val);
-
-			ath_print(common, ATH_DBG_CALIBRATE,
-				  "ADC Gain Cal done for Chain %d\n", i);
-		}
-	}
-
-	REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0),
-		  REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0)) |
-		  AR_PHY_NEW_ADC_GAIN_CORR_ENABLE);
-}
-
-static void ath9k_hw_adc_dccal_calibrate(struct ath_hw *ah, u8 numChains)
-{
-	struct ath_common *common = ath9k_hw_common(ah);
-	u32 iOddMeasOffset, iEvenMeasOffset, val, i;
-	int32_t qOddMeasOffset, qEvenMeasOffset, qDcMismatch, iDcMismatch;
-	const struct ath9k_percal_data *calData =
-		ah->cal_list_curr->calData;
-	u32 numSamples =
-		(1 << (calData->calCountMax + 5)) * calData->calNumSamples;
-
-	for (i = 0; i < numChains; i++) {
-		iOddMeasOffset = ah->totalAdcDcOffsetIOddPhase[i];
-		iEvenMeasOffset = ah->totalAdcDcOffsetIEvenPhase[i];
-		qOddMeasOffset = ah->totalAdcDcOffsetQOddPhase[i];
-		qEvenMeasOffset = ah->totalAdcDcOffsetQEvenPhase[i];
-
-		ath_print(common, ATH_DBG_CALIBRATE,
-			   "Starting ADC DC Offset Cal for Chain %d\n", i);
-
-		ath_print(common, ATH_DBG_CALIBRATE,
-			  "Chn %d pwr_meas_odd_i = %d\n", i,
-			  iOddMeasOffset);
-		ath_print(common, ATH_DBG_CALIBRATE,
-			  "Chn %d pwr_meas_even_i = %d\n", i,
-			  iEvenMeasOffset);
-		ath_print(common, ATH_DBG_CALIBRATE,
-			  "Chn %d pwr_meas_odd_q = %d\n", i,
-			  qOddMeasOffset);
-		ath_print(common, ATH_DBG_CALIBRATE,
-			  "Chn %d pwr_meas_even_q = %d\n", i,
-			  qEvenMeasOffset);
-
-		iDcMismatch = (((iEvenMeasOffset - iOddMeasOffset) * 2) /
-			       numSamples) & 0x1ff;
-		qDcMismatch = (((qOddMeasOffset - qEvenMeasOffset) * 2) /
-			       numSamples) & 0x1ff;
-
-		ath_print(common, ATH_DBG_CALIBRATE,
-			  "Chn %d dc_offset_mismatch_i = 0x%08x\n", i,
-			  iDcMismatch);
-		ath_print(common, ATH_DBG_CALIBRATE,
-			  "Chn %d dc_offset_mismatch_q = 0x%08x\n", i,
-			  qDcMismatch);
-
-		val = REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i));
-		val &= 0xc0000fff;
-		val |= (qDcMismatch << 12) | (iDcMismatch << 21);
-		REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i), val);
-
-		ath_print(common, ATH_DBG_CALIBRATE,
-			  "ADC DC Offset Cal done for Chain %d\n", i);
-	}
-
-	REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0),
-		  REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0)) |
-		  AR_PHY_NEW_ADC_DC_OFFSET_CORR_ENABLE);
-}
-
 /* This is done for the currently configured channel */
 bool ath9k_hw_reset_calvalid(struct ath_hw *ah)
 {
@@ -670,570 +317,3 @@ s16 ath9k_hw_getchan_noise(struct ath_hw *ah, struct ath9k_channel *chan)
 	return nf;
 }
 EXPORT_SYMBOL(ath9k_hw_getchan_noise);
-
-static void ar9287_hw_olc_temp_compensation(struct ath_hw *ah)
-{
-	u32 rddata;
-	int32_t delta, currPDADC, slope;
-
-	rddata = REG_READ(ah, AR_PHY_TX_PWRCTRL4);
-	currPDADC = MS(rddata, AR_PHY_TX_PWRCTRL_PD_AVG_OUT);
-
-	if (ah->initPDADC == 0 || currPDADC == 0) {
-		/*
-		 * Zero value indicates that no frames have been transmitted yet,
-		 * can't do temperature compensation until frames are transmitted.
-		 */
-		return;
-	} else {
-		slope = ah->eep_ops->get_eeprom(ah, EEP_TEMPSENSE_SLOPE);
-
-		if (slope == 0) { /* to avoid divide by zero case */
-			delta = 0;
-		} else {
-			delta = ((currPDADC - ah->initPDADC)*4) / slope;
-		}
-		REG_RMW_FIELD(ah, AR_PHY_CH0_TX_PWRCTRL11,
-			      AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP, delta);
-		REG_RMW_FIELD(ah, AR_PHY_CH1_TX_PWRCTRL11,
-			      AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP, delta);
-	}
-}
-
-static void ar9280_hw_olc_temp_compensation(struct ath_hw *ah)
-{
-	u32 rddata, i;
-	int delta, currPDADC, regval;
-
-	rddata = REG_READ(ah, AR_PHY_TX_PWRCTRL4);
-	currPDADC = MS(rddata, AR_PHY_TX_PWRCTRL_PD_AVG_OUT);
-
-	if (ah->initPDADC == 0 || currPDADC == 0)
-		return;
-
-	if (ah->eep_ops->get_eeprom(ah, EEP_DAC_HPWR_5G))
-		delta = (currPDADC - ah->initPDADC + 4) / 8;
-	else
-		delta = (currPDADC - ah->initPDADC + 5) / 10;
-
-	if (delta != ah->PDADCdelta) {
-		ah->PDADCdelta = delta;
-		for (i = 1; i < AR9280_TX_GAIN_TABLE_SIZE; i++) {
-			regval = ah->originalGain[i] - delta;
-			if (regval < 0)
-				regval = 0;
-
-			REG_RMW_FIELD(ah,
-				      AR_PHY_TX_GAIN_TBL1 + i * 4,
-				      AR_PHY_TX_GAIN, regval);
-		}
-	}
-}
-
-static void ar9271_hw_pa_cal(struct ath_hw *ah, bool is_reset)
-{
-	u32 regVal;
-	unsigned int i;
-	u32 regList [][2] = {
-		{ 0x786c, 0 },
-		{ 0x7854, 0 },
-		{ 0x7820, 0 },
-		{ 0x7824, 0 },
-		{ 0x7868, 0 },
-		{ 0x783c, 0 },
-		{ 0x7838, 0 } ,
-		{ 0x7828, 0 } ,
-	};
-
-	for (i = 0; i < ARRAY_SIZE(regList); i++)
-		regList[i][1] = REG_READ(ah, regList[i][0]);
-
-	regVal = REG_READ(ah, 0x7834);
-	regVal &= (~(0x1));
-	REG_WRITE(ah, 0x7834, regVal);
-	regVal = REG_READ(ah, 0x9808);
-	regVal |= (0x1 << 27);
-	REG_WRITE(ah, 0x9808, regVal);
-
-	/* 786c,b23,1, pwddac=1 */
-	REG_RMW_FIELD(ah, AR9285_AN_TOP3, AR9285_AN_TOP3_PWDDAC, 1);
-	/* 7854, b5,1, pdrxtxbb=1 */
-	REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDRXTXBB1, 1);
-	/* 7854, b7,1, pdv2i=1 */
-	REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDV2I, 1);
-	/* 7854, b8,1, pddacinterface=1 */
-	REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDDACIF, 1);
-	/* 7824,b12,0, offcal=0 */
-	REG_RMW_FIELD(ah, AR9285_AN_RF2G2, AR9285_AN_RF2G2_OFFCAL, 0);
-	/* 7838, b1,0, pwddb=0 */
-	REG_RMW_FIELD(ah, AR9285_AN_RF2G7, AR9285_AN_RF2G7_PWDDB, 0);
-	/* 7820,b11,0, enpacal=0 */
-	REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_ENPACAL, 0);
-	/* 7820,b25,1, pdpadrv1=0 */
-	REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPADRV1, 0);
-	/* 7820,b24,0, pdpadrv2=0 */
-	REG_RMW_FIELD(ah, AR9285_AN_RF2G1,AR9285_AN_RF2G1_PDPADRV2,0);
-	/* 7820,b23,0, pdpaout=0 */
-	REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPAOUT, 0);
-	/* 783c,b14-16,7, padrvgn2tab_0=7 */
-	REG_RMW_FIELD(ah, AR9285_AN_RF2G8,AR9285_AN_RF2G8_PADRVGN2TAB0, 7);
-	/*
-	 * 7838,b29-31,0, padrvgn1tab_0=0
-	 * does not matter since we turn it off
-	 */
-	REG_RMW_FIELD(ah, AR9285_AN_RF2G7,AR9285_AN_RF2G7_PADRVGN2TAB0, 0);
-
-	REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9271_AN_RF2G3_CCOMP, 0xfff);
-
-	/* Set:
-	 * localmode=1,bmode=1,bmoderxtx=1,synthon=1,
-	 * txon=1,paon=1,oscon=1,synthon_force=1
-	 */
-	REG_WRITE(ah, AR9285_AN_TOP2, 0xca0358a0);
-	udelay(30);
-	REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9271_AN_RF2G6_OFFS, 0);
-
-	/* find off_6_1; */
-	for (i = 6; i > 0; i--) {
-		regVal = REG_READ(ah, 0x7834);
-		regVal |= (1 << (20 + i));
-		REG_WRITE(ah, 0x7834, regVal);
-		udelay(1);
-		//regVal = REG_READ(ah, 0x7834);
-		regVal &= (~(0x1 << (20 + i)));
-		regVal |= (MS(REG_READ(ah, 0x7840), AR9285_AN_RXTXBB1_SPARE9)
-			    << (20 + i));
-		REG_WRITE(ah, 0x7834, regVal);
-	}
-
-	regVal = (regVal >>20) & 0x7f;
-
-	/* Update PA cal info */
-	if ((!is_reset) && (ah->pacal_info.prev_offset == regVal)) {
-		if (ah->pacal_info.max_skipcount < MAX_PACAL_SKIPCOUNT)
-			ah->pacal_info.max_skipcount =
-				2 * ah->pacal_info.max_skipcount;
-		ah->pacal_info.skipcount = ah->pacal_info.max_skipcount;
-	} else {
-		ah->pacal_info.max_skipcount = 1;
-		ah->pacal_info.skipcount = 0;
-		ah->pacal_info.prev_offset = regVal;
-	}
-
-	regVal = REG_READ(ah, 0x7834);
-	regVal |= 0x1;
-	REG_WRITE(ah, 0x7834, regVal);
-	regVal = REG_READ(ah, 0x9808);
-	regVal &= (~(0x1 << 27));
-	REG_WRITE(ah, 0x9808, regVal);
-
-	for (i = 0; i < ARRAY_SIZE(regList); i++)
-		REG_WRITE(ah, regList[i][0], regList[i][1]);
-}
-
-static inline void ar9285_hw_pa_cal(struct ath_hw *ah, bool is_reset)
-{
-	struct ath_common *common = ath9k_hw_common(ah);
-	u32 regVal;
-	int i, offset, offs_6_1, offs_0;
-	u32 ccomp_org, reg_field;
-	u32 regList[][2] = {
-		{ 0x786c, 0 },
-		{ 0x7854, 0 },
-		{ 0x7820, 0 },
-		{ 0x7824, 0 },
-		{ 0x7868, 0 },
-		{ 0x783c, 0 },
-		{ 0x7838, 0 },
-	};
-
-	ath_print(common, ATH_DBG_CALIBRATE, "Running PA Calibration\n");
-
-	/* PA CAL is not needed for high power solution */
-	if (ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE) ==
-	    AR5416_EEP_TXGAIN_HIGH_POWER)
-		return;
-
-	if (AR_SREV_9285_11(ah)) {
-		REG_WRITE(ah, AR9285_AN_TOP4, (AR9285_AN_TOP4_DEFAULT | 0x14));
-		udelay(10);
-	}
-
-	for (i = 0; i < ARRAY_SIZE(regList); i++)
-		regList[i][1] = REG_READ(ah, regList[i][0]);
-
-	regVal = REG_READ(ah, 0x7834);
-	regVal &= (~(0x1));
-	REG_WRITE(ah, 0x7834, regVal);
-	regVal = REG_READ(ah, 0x9808);
-	regVal |= (0x1 << 27);
-	REG_WRITE(ah, 0x9808, regVal);
-
-	REG_RMW_FIELD(ah, AR9285_AN_TOP3, AR9285_AN_TOP3_PWDDAC, 1);
-	REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDRXTXBB1, 1);
-	REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDV2I, 1);
-	REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDDACIF, 1);
-	REG_RMW_FIELD(ah, AR9285_AN_RF2G2, AR9285_AN_RF2G2_OFFCAL, 0);
-	REG_RMW_FIELD(ah, AR9285_AN_RF2G7, AR9285_AN_RF2G7_PWDDB, 0);
-	REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_ENPACAL, 0);
-	REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPADRV1, 0);
-	REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPADRV2, 0);
-	REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPAOUT, 0);
-	REG_RMW_FIELD(ah, AR9285_AN_RF2G8, AR9285_AN_RF2G8_PADRVGN2TAB0, 7);
-	REG_RMW_FIELD(ah, AR9285_AN_RF2G7, AR9285_AN_RF2G7_PADRVGN2TAB0, 0);
-	ccomp_org = MS(REG_READ(ah, AR9285_AN_RF2G6), AR9285_AN_RF2G6_CCOMP);
-	REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9285_AN_RF2G6_CCOMP, 0xf);
-
-	REG_WRITE(ah, AR9285_AN_TOP2, 0xca0358a0);
-	udelay(30);
-	REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9285_AN_RF2G6_OFFS, 0);
-	REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9285_AN_RF2G3_PDVCCOMP, 0);
-
-	for (i = 6; i > 0; i--) {
-		regVal = REG_READ(ah, 0x7834);
-		regVal |= (1 << (19 + i));
-		REG_WRITE(ah, 0x7834, regVal);
-		udelay(1);
-		regVal = REG_READ(ah, 0x7834);
-		regVal &= (~(0x1 << (19 + i)));
-		reg_field = MS(REG_READ(ah, 0x7840), AR9285_AN_RXTXBB1_SPARE9);
-		regVal |= (reg_field << (19 + i));
-		REG_WRITE(ah, 0x7834, regVal);
-	}
-
-	REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9285_AN_RF2G3_PDVCCOMP, 1);
-	udelay(1);
-	reg_field = MS(REG_READ(ah, AR9285_AN_RF2G9), AR9285_AN_RXTXBB1_SPARE9);
-	REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9285_AN_RF2G3_PDVCCOMP, reg_field);
-	offs_6_1 = MS(REG_READ(ah, AR9285_AN_RF2G6), AR9285_AN_RF2G6_OFFS);
-	offs_0   = MS(REG_READ(ah, AR9285_AN_RF2G3), AR9285_AN_RF2G3_PDVCCOMP);
-
-	offset = (offs_6_1<<1) | offs_0;
-	offset = offset - 0;
-	offs_6_1 = offset>>1;
-	offs_0 = offset & 1;
-
-	if ((!is_reset) && (ah->pacal_info.prev_offset == offset)) {
-		if (ah->pacal_info.max_skipcount < MAX_PACAL_SKIPCOUNT)
-			ah->pacal_info.max_skipcount =
-				2 * ah->pacal_info.max_skipcount;
-		ah->pacal_info.skipcount = ah->pacal_info.max_skipcount;
-	} else {
-		ah->pacal_info.max_skipcount = 1;
-		ah->pacal_info.skipcount = 0;
-		ah->pacal_info.prev_offset = offset;
-	}
-
-	REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9285_AN_RF2G6_OFFS, offs_6_1);
-	REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9285_AN_RF2G3_PDVCCOMP, offs_0);
-
-	regVal = REG_READ(ah, 0x7834);
-	regVal |= 0x1;
-	REG_WRITE(ah, 0x7834, regVal);
-	regVal = REG_READ(ah, 0x9808);
-	regVal &= (~(0x1 << 27));
-	REG_WRITE(ah, 0x9808, regVal);
-
-	for (i = 0; i < ARRAY_SIZE(regList); i++)
-		REG_WRITE(ah, regList[i][0], regList[i][1]);
-
-	REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9285_AN_RF2G6_CCOMP, ccomp_org);
-
-	if (AR_SREV_9285_11(ah))
-		REG_WRITE(ah, AR9285_AN_TOP4, AR9285_AN_TOP4_DEFAULT);
-
-}
-
-static void ar9002_hw_pa_cal(struct ath_hw *ah, bool is_reset)
-{
-	if (AR_SREV_9271(ah)) {
-		if (is_reset || !ah->pacal_info.skipcount)
-			ar9271_hw_pa_cal(ah, is_reset);
-		else
-			ah->pacal_info.skipcount--;
-	} else if (AR_SREV_9285_11_OR_LATER(ah)) {
-		if (is_reset || !ah->pacal_info.skipcount)
-			ar9285_hw_pa_cal(ah, is_reset);
-		else
-			ah->pacal_info.skipcount--;
-	}
-}
-
-static void ar9002_hw_olc_temp_compensation(struct ath_hw *ah)
-{
-	if (OLC_FOR_AR9287_10_LATER)
-		ar9287_hw_olc_temp_compensation(ah);
-	else if (OLC_FOR_AR9280_20_LATER)
-		ar9280_hw_olc_temp_compensation(ah);
-}
-
-bool ath9k_hw_calibrate(struct ath_hw *ah, struct ath9k_channel *chan,
-			u8 rxchainmask, bool longcal)
-{
-	bool iscaldone = true;
-	struct ath9k_cal_list *currCal = ah->cal_list_curr;
-
-	if (currCal &&
-	    (currCal->calState == CAL_RUNNING ||
-	     currCal->calState == CAL_WAITING)) {
-		iscaldone = ath9k_hw_per_calibration(ah, chan,
-						     rxchainmask, currCal);
-		if (iscaldone) {
-			ah->cal_list_curr = currCal = currCal->calNext;
-
-			if (currCal->calState == CAL_WAITING) {
-				iscaldone = false;
-				ath9k_hw_reset_calibration(ah, currCal);
-			}
-		}
-	}
-
-	/* Do NF cal only at longer intervals */
-	if (longcal) {
-		/* Do periodic PAOffset Cal */
-		ar9002_hw_pa_cal(ah, false);
-		ar9002_hw_olc_temp_compensation(ah);
-
-		/* Get the value from the previous NF cal and update history buffer */
-		ath9k_hw_getnf(ah, chan);
-
-		/*
-		 * Load the NF from history buffer of the current channel.
-		 * NF is slow time-variant, so it is OK to use a historical value.
-		 */
-		ath9k_hw_loadnf(ah, ah->curchan);
-
-		ath9k_hw_start_nfcal(ah);
-	}
-
-	return iscaldone;
-}
-EXPORT_SYMBOL(ath9k_hw_calibrate);
-
-/* Carrier leakage Calibration fix */
-static bool ar9285_cl_cal(struct ath_hw *ah, struct ath9k_channel *chan)
-{
-	struct ath_common *common = ath9k_hw_common(ah);
-
-	REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
-	if (IS_CHAN_HT20(chan)) {
-		REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_PARALLEL_CAL_ENABLE);
-		REG_SET_BIT(ah, AR_PHY_TURBO, AR_PHY_FC_DYN2040_EN);
-		REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
-			    AR_PHY_AGC_CONTROL_FLTR_CAL);
-		REG_CLR_BIT(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_CAL_ENABLE);
-		REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL);
-		if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL,
-				  AR_PHY_AGC_CONTROL_CAL, 0, AH_WAIT_TIMEOUT)) {
-			ath_print(common, ATH_DBG_CALIBRATE, "offset "
-				  "calibration failed to complete in "
-				  "1ms; noisy ??\n");
-			return false;
-		}
-		REG_CLR_BIT(ah, AR_PHY_TURBO, AR_PHY_FC_DYN2040_EN);
-		REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_PARALLEL_CAL_ENABLE);
-		REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
-	}
-	REG_CLR_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC);
-	REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL);
-	REG_SET_BIT(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_CAL_ENABLE);
-	REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL);
-	if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL,
-			  0, AH_WAIT_TIMEOUT)) {
-		ath_print(common, ATH_DBG_CALIBRATE, "offset calibration "
-			  "failed to complete in 1ms; noisy ??\n");
-		return false;
-	}
-
-	REG_SET_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC);
-	REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
-	REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL);
-
-	return true;
-}
-
-static bool ar9285_clc(struct ath_hw *ah, struct ath9k_channel *chan)
-{
-	int i;
-	u_int32_t txgain_max;
-	u_int32_t clc_gain, gain_mask = 0, clc_num = 0;
-	u_int32_t reg_clc_I0, reg_clc_Q0;
-	u_int32_t i0_num = 0;
-	u_int32_t q0_num = 0;
-	u_int32_t total_num = 0;
-	u_int32_t reg_rf2g5_org;
-	bool retv = true;
-
-	if (!(ar9285_cl_cal(ah, chan)))
-		return false;
-
-	txgain_max = MS(REG_READ(ah, AR_PHY_TX_PWRCTRL7),
-			AR_PHY_TX_PWRCTRL_TX_GAIN_TAB_MAX);
-
-	for (i = 0; i < (txgain_max+1); i++) {
-		clc_gain = (REG_READ(ah, (AR_PHY_TX_GAIN_TBL1+(i<<2))) &
-			   AR_PHY_TX_GAIN_CLC) >> AR_PHY_TX_GAIN_CLC_S;
-		if (!(gain_mask & (1 << clc_gain))) {
-			gain_mask |= (1 << clc_gain);
-			clc_num++;
-		}
-	}
-
-	for (i = 0; i < clc_num; i++) {
-		reg_clc_I0 = (REG_READ(ah, (AR_PHY_CLC_TBL1 + (i << 2)))
-			      & AR_PHY_CLC_I0) >> AR_PHY_CLC_I0_S;
-		reg_clc_Q0 = (REG_READ(ah, (AR_PHY_CLC_TBL1 + (i << 2)))
-			      & AR_PHY_CLC_Q0) >> AR_PHY_CLC_Q0_S;
-		if (reg_clc_I0 == 0)
-			i0_num++;
-
-		if (reg_clc_Q0 == 0)
-			q0_num++;
-	}
-	total_num = i0_num + q0_num;
-	if (total_num > AR9285_CLCAL_REDO_THRESH) {
-		reg_rf2g5_org = REG_READ(ah, AR9285_RF2G5);
-		if (AR_SREV_9285E_20(ah)) {
-			REG_WRITE(ah, AR9285_RF2G5,
-				  (reg_rf2g5_org & AR9285_RF2G5_IC50TX) |
-				  AR9285_RF2G5_IC50TX_XE_SET);
-		} else {
-			REG_WRITE(ah, AR9285_RF2G5,
-				  (reg_rf2g5_org & AR9285_RF2G5_IC50TX) |
-				  AR9285_RF2G5_IC50TX_SET);
-		}
-		retv = ar9285_cl_cal(ah, chan);
-		REG_WRITE(ah, AR9285_RF2G5, reg_rf2g5_org);
-	}
-	return retv;
-}
-
-bool ath9k_hw_init_cal(struct ath_hw *ah, struct ath9k_channel *chan)
-{
-	struct ath_common *common = ath9k_hw_common(ah);
-
-	if (AR_SREV_9271(ah) || AR_SREV_9285_12_OR_LATER(ah)) {
-		if (!ar9285_clc(ah, chan))
-			return false;
-	} else {
-		if (AR_SREV_9280_10_OR_LATER(ah)) {
-			if (!AR_SREV_9287_10_OR_LATER(ah))
-				REG_CLR_BIT(ah, AR_PHY_ADC_CTL,
-					    AR_PHY_ADC_CTL_OFF_PWDADC);
-			REG_SET_BIT(ah, AR_PHY_AGC_CONTROL,
-				    AR_PHY_AGC_CONTROL_FLTR_CAL);
-		}
-
-		/* Calibrate the AGC */
-		REG_WRITE(ah, AR_PHY_AGC_CONTROL,
-			  REG_READ(ah, AR_PHY_AGC_CONTROL) |
-			  AR_PHY_AGC_CONTROL_CAL);
-
-		/* Poll for offset calibration complete */
-		if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL,
-				   0, AH_WAIT_TIMEOUT)) {
-			ath_print(common, ATH_DBG_CALIBRATE,
-				  "offset calibration failed to "
-				  "complete in 1ms; noisy environment?\n");
-			return false;
-		}
-
-		if (AR_SREV_9280_10_OR_LATER(ah)) {
-			if (!AR_SREV_9287_10_OR_LATER(ah))
-				REG_SET_BIT(ah, AR_PHY_ADC_CTL,
-					    AR_PHY_ADC_CTL_OFF_PWDADC);
-			REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
-				    AR_PHY_AGC_CONTROL_FLTR_CAL);
-		}
-	}
-
-	/* Do PA Calibration */
-	ar9002_hw_pa_cal(ah, true);
-
-	/* Do NF Calibration after DC offset and other calibrations */
-	REG_WRITE(ah, AR_PHY_AGC_CONTROL,
-		  REG_READ(ah, AR_PHY_AGC_CONTROL) | AR_PHY_AGC_CONTROL_NF);
-
-	ah->cal_list = ah->cal_list_last = ah->cal_list_curr = NULL;
-
-	/* Enable IQ, ADC Gain and ADC DC offset CALs */
-	if (AR_SREV_9100(ah) || AR_SREV_9160_10_OR_LATER(ah)) {
-		if (ath9k_hw_iscal_supported(ah, ADC_GAIN_CAL)) {
-			INIT_CAL(&ah->adcgain_caldata);
-			INSERT_CAL(ah, &ah->adcgain_caldata);
-			ath_print(common, ATH_DBG_CALIBRATE,
-				  "enabling ADC Gain Calibration.\n");
-		}
-		if (ath9k_hw_iscal_supported(ah, ADC_DC_CAL)) {
-			INIT_CAL(&ah->adcdc_caldata);
-			INSERT_CAL(ah, &ah->adcdc_caldata);
-			ath_print(common, ATH_DBG_CALIBRATE,
-				  "enabling ADC DC Calibration.\n");
-		}
-		if (ath9k_hw_iscal_supported(ah, IQ_MISMATCH_CAL)) {
-			INIT_CAL(&ah->iq_caldata);
-			INSERT_CAL(ah, &ah->iq_caldata);
-			ath_print(common, ATH_DBG_CALIBRATE,
-				  "enabling IQ Calibration.\n");
-		}
-
-		ah->cal_list_curr = ah->cal_list;
-
-		if (ah->cal_list_curr)
-			ath9k_hw_reset_calibration(ah, ah->cal_list_curr);
-	}
-
-	chan->CalValid = 0;
-
-	return true;
-}
-
-const struct ath9k_percal_data iq_cal_multi_sample = {
-	IQ_MISMATCH_CAL,
-	MAX_CAL_SAMPLES,
-	PER_MIN_LOG_COUNT,
-	ath9k_hw_iqcal_collect,
-	ath9k_hw_iqcalibrate
-};
-const struct ath9k_percal_data iq_cal_single_sample = {
-	IQ_MISMATCH_CAL,
-	MIN_CAL_SAMPLES,
-	PER_MAX_LOG_COUNT,
-	ath9k_hw_iqcal_collect,
-	ath9k_hw_iqcalibrate
-};
-const struct ath9k_percal_data adc_gain_cal_multi_sample = {
-	ADC_GAIN_CAL,
-	MAX_CAL_SAMPLES,
-	PER_MIN_LOG_COUNT,
-	ath9k_hw_adc_gaincal_collect,
-	ath9k_hw_adc_gaincal_calibrate
-};
-const struct ath9k_percal_data adc_gain_cal_single_sample = {
-	ADC_GAIN_CAL,
-	MIN_CAL_SAMPLES,
-	PER_MAX_LOG_COUNT,
-	ath9k_hw_adc_gaincal_collect,
-	ath9k_hw_adc_gaincal_calibrate
-};
-const struct ath9k_percal_data adc_dc_cal_multi_sample = {
-	ADC_DC_CAL,
-	MAX_CAL_SAMPLES,
-	PER_MIN_LOG_COUNT,
-	ath9k_hw_adc_dccal_collect,
-	ath9k_hw_adc_dccal_calibrate
-};
-const struct ath9k_percal_data adc_dc_cal_single_sample = {
-	ADC_DC_CAL,
-	MIN_CAL_SAMPLES,
-	PER_MAX_LOG_COUNT,
-	ath9k_hw_adc_dccal_collect,
-	ath9k_hw_adc_dccal_calibrate
-};
-const struct ath9k_percal_data adc_init_dc_cal = {
-	ADC_DC_INIT_CAL,
-	MIN_CAL_SAMPLES,
-	INIT_LOG_COUNT,
-	ath9k_hw_adc_dccal_collect,
-	ath9k_hw_adc_dccal_calibrate
-};
diff --git a/drivers/net/wireless/ath/ath9k/calib.h b/drivers/net/wireless/ath/ath9k/calib.h
index b2c873e..9f6c21d 100644
--- a/drivers/net/wireless/ath/ath9k/calib.h
+++ b/drivers/net/wireless/ath/ath9k/calib.h
@@ -19,14 +19,6 @@
 
 #include "hw.h"
 
-extern const struct ath9k_percal_data iq_cal_multi_sample;
-extern const struct ath9k_percal_data iq_cal_single_sample;
-extern const struct ath9k_percal_data adc_gain_cal_multi_sample;
-extern const struct ath9k_percal_data adc_gain_cal_single_sample;
-extern const struct ath9k_percal_data adc_dc_cal_multi_sample;
-extern const struct ath9k_percal_data adc_dc_cal_single_sample;
-extern const struct ath9k_percal_data adc_init_dc_cal;
-
 #define AR_PHY_CCA_MAX_AR5416_GOOD_VALUE	-85
 #define AR_PHY_CCA_MAX_AR9280_GOOD_VALUE	-112
 #define AR_PHY_CCA_MAX_AR9285_GOOD_VALUE	-118
@@ -127,9 +119,8 @@ int16_t ath9k_hw_getnf(struct ath_hw *ah,
 		       struct ath9k_channel *chan);
 void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah);
 s16 ath9k_hw_getchan_noise(struct ath_hw *ah, struct ath9k_channel *chan);
-bool ath9k_hw_calibrate(struct ath_hw *ah, struct ath9k_channel *chan,
-			u8 rxchainmask, bool longcal);
-bool ath9k_hw_init_cal(struct ath_hw *ah,
-		       struct ath9k_channel *chan);
+void ath9k_hw_reset_calibration(struct ath_hw *ah,
+				struct ath9k_cal_list *currCal);
+
 
 #endif /* CALIB_H */
diff --git a/drivers/net/wireless/ath/ath9k/hw-ops.h b/drivers/net/wireless/ath/ath9k/hw-ops.h
index e2b8ad4..3848c0d 100644
--- a/drivers/net/wireless/ath/ath9k/hw-ops.h
+++ b/drivers/net/wireless/ath/ath9k/hw-ops.h
@@ -44,6 +44,14 @@ static inline void ath9k_hw_get_desc_link(struct ath_hw *ah, void *ds,
 {
 	ath9k_hw_ops(ah)->get_desc_link(ds, link);
 }
+static inline bool ath9k_hw_calibrate(struct ath_hw *ah,
+				      struct ath9k_channel *chan,
+				      u8 rxchainmask,
+				      bool longcal)
+{
+	return ath9k_hw_ops(ah)->calibrate(ah, chan, rxchainmask, longcal);
+}
+
 /* Private hardware call ops */
 
 /* PHY ops */
@@ -166,7 +174,25 @@ static inline bool ath9k_hw_ani_control(struct ath_hw *ah,
 static inline void ath9k_hw_do_getnf(struct ath_hw *ah,
 				     int16_t nfarray[NUM_NF_READINGS])
 {
-	return ath9k_hw_private_ops(ah)->do_getnf(ah, nfarray);
+	ath9k_hw_private_ops(ah)->do_getnf(ah, nfarray);
+}
+
+static inline bool ath9k_hw_init_cal(struct ath_hw *ah,
+				     struct ath9k_channel *chan)
+{
+	return ath9k_hw_private_ops(ah)->init_cal(ah, chan);
+}
+
+static inline void ath9k_hw_setup_calibration(struct ath_hw *ah,
+					      struct ath9k_cal_list *currCal)
+{
+	ath9k_hw_private_ops(ah)->setup_calibration(ah, currCal);
+}
+
+static inline bool ath9k_hw_iscal_supported(struct ath_hw *ah,
+					    enum ath9k_cal_types calType)
+{
+	return ath9k_hw_private_ops(ah)->iscal_supported(ah, calType);
 }
 
 #endif /* ATH9K_HW_OPS_H */
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 51f1e84..6c092ee 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -601,36 +601,6 @@ static bool ar9003_hw_macversion_supported(u32 macversion)
 	return false;
 }
 
-static void ar9002_hw_init_cal_settings(struct ath_hw *ah)
-{
-	if (AR_SREV_9100(ah)) {
-		ah->iq_caldata.calData = &iq_cal_multi_sample;
-		ah->supp_cals = IQ_MISMATCH_CAL;
-		return;
-	}
-
-	if (AR_SREV_9160_10_OR_LATER(ah)) {
-		if (AR_SREV_9280_10_OR_LATER(ah)) {
-			ah->iq_caldata.calData = &iq_cal_single_sample;
-			ah->adcgain_caldata.calData =
-				&adc_gain_cal_single_sample;
-			ah->adcdc_caldata.calData =
-				&adc_dc_cal_single_sample;
-			ah->adcdc_calinitdata.calData =
-				&adc_init_dc_cal;
-		} else {
-			ah->iq_caldata.calData = &iq_cal_multi_sample;
-			ah->adcgain_caldata.calData =
-				&adc_gain_cal_multi_sample;
-			ah->adcdc_caldata.calData =
-				&adc_dc_cal_multi_sample;
-			ah->adcdc_calinitdata.calData =
-				&adc_init_dc_cal;
-		}
-		ah->supp_cals = ADC_GAIN_CAL | ADC_DC_CAL | IQ_MISMATCH_CAL;
-	}
-}
-
 static void ar9002_hw_init_mode_regs(struct ath_hw *ah)
 {
 	if (AR_SREV_9271(ah)) {
@@ -3642,7 +3612,6 @@ static 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_cal_settings = ar9002_hw_init_cal_settings;
 	priv_ops->init_mode_regs = ar9002_hw_init_mode_regs;
 	priv_ops->macversion_supported = ar9002_hw_macversion_supported;
 
@@ -3652,6 +3621,7 @@ static void ar9002_hw_attach_ops(struct ath_hw *ah)
 	if (AR_SREV_9280_10_OR_LATER(ah))
 		ar9002_hw_attach_phy_ops(ah);
 
+	ar9002_hw_attach_calib_ops(ah);
 	ar9002_hw_attach_mac_ops(ah);
 }
 
@@ -3664,6 +3634,6 @@ static void ar9003_hw_attach_ops(struct ath_hw *ah)
 	priv_ops->macversion_supported = ar9003_hw_macversion_supported;
 
 	ar9003_hw_attach_phy_ops(ah);
-
+	ar9003_hw_attach_calib_ops(ah);
 	ar9003_hw_attach_mac_ops(ah);
 }
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 48fb5ce..7ef93c8 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -469,7 +469,9 @@ struct ath_gen_timer_table {
  * This structure contains private callbacks designed to only be used internally
  * by the hardware core.
  *
- * @init_cal_settings: Initializes calibration settings
+ * @init_cal_settings: setup types of calibrations supported
+ * @init_cal: starts actual calibration
+ *
  * @init_mode_regs: Initializes mode registers
  * @macversion_supported: If this specific mac revision is supported
  *
@@ -480,11 +482,20 @@ struct ath_gen_timer_table {
  * @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
  */
 struct ath_hw_private_ops {
+	/* Calibration ops */
 	void (*init_cal_settings)(struct ath_hw *ah);
+	bool (*init_cal)(struct ath_hw *ah, struct ath9k_channel *chan);
+
 	void (*init_mode_regs)(struct ath_hw *ah);
 	bool (*macversion_supported)(u32 macversion);
+	void (*setup_calibration)(struct ath_hw *ah,
+				  struct ath9k_cal_list *currCal);
+	bool (*iscal_supported)(struct ath_hw *ah,
+				enum ath9k_cal_types calType);
 
 	/* PHY ops */
 	int (*rf_set_freq)(struct ath_hw *ah,
@@ -523,6 +534,7 @@ struct ath_hw_private_ops {
  * 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,
@@ -531,6 +543,10 @@ struct ath_hw_ops {
 	void (*rx_enable)(struct ath_hw *ah);
 	void (*set_desc_link)(void *ds, u32 link);
 	void (*get_desc_link)(void *ds, u32 **link);
+	bool (*calibrate)(struct ath_hw *ah,
+			  struct ath9k_channel *chan,
+			  u8 rxchainmask,
+			  bool longcal);
 };
 
 struct ath_hw {
@@ -833,6 +849,9 @@ 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);
+
 #define ATH_PCIE_CAP_LINK_CTRL	0x70
 #define ATH_PCIE_CAP_LINK_L0S	1
 #define ATH_PCIE_CAP_LINK_L1	2
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 103+ messages in thread

* [PATCH v3 56/97] ath9k_hw: add the AR9003 ar9003_hw_init_cal callback
  2010-04-15 21:38 [PATCH v3 00/97] ath9k: add AR9003 support Luis R. Rodriguez
                   ` (54 preceding siblings ...)
  2010-04-15 21:39 ` [PATCH v3 55/97] ath9k_hw: split calib code by hardware families Luis R. Rodriguez
@ 2010-04-15 21:39 ` Luis R. Rodriguez
  2010-04-15 21:39 ` [PATCH v3 57/97] ath9k_hw: add the config_pci_powersave AR9003 callback Luis R. Rodriguez
                   ` (40 subsequent siblings)
  96 siblings, 0 replies; 103+ messages in thread
From: Luis R. Rodriguez @ 2010-04-15 21:39 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Luis R. Rodriguez

Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/ar9003_calib.c |  145 ++++++++++++++++++++++++-
 1 files changed, 144 insertions(+), 1 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ar9003_calib.c b/drivers/net/wireless/ath/ath9k/ar9003_calib.c
index 6a72677..00e4cb8 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c
@@ -40,9 +40,152 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah,
 	return false;
 }
 
+static void ar9003_hw_iqcal_collect(struct ath_hw *ah)
+{
+	int i;
+
+	/* Accumulate IQ cal measures for active chains */
+	for (i = 0; i < AR5416_MAX_CHAINS; i++) {
+		ah->totalPowerMeasI[i] +=
+			REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
+		ah->totalPowerMeasQ[i] +=
+			REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
+		ah->totalIqCorrMeas[i] +=
+			(int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
+		ath_print(ath9k_hw_common(ah), ATH_DBG_CALIBRATE,
+			  "%d: Chn %d pmi=0x%08x;pmq=0x%08x;iqcm=0x%08x;\n",
+			  ah->cal_samples, i, ah->totalPowerMeasI[i],
+			  ah->totalPowerMeasQ[i],
+			  ah->totalIqCorrMeas[i]);
+	}
+}
+
+static void ar9003_hw_iqcalibrate(struct ath_hw *ah, u8 numChains)
+{
+	struct ath_common *common = ath9k_hw_common(ah);
+	u32 powerMeasQ, powerMeasI, iqCorrMeas;
+	u32 qCoffDenom, iCoffDenom;
+	int32_t qCoff, iCoff;
+	int iqCorrNeg, i;
+	const u_int32_t offset_array[3] = {
+		AR_PHY_RX_IQCAL_CORR_B0,
+		AR_PHY_RX_IQCAL_CORR_B1,
+		AR_PHY_RX_IQCAL_CORR_B2,
+	};
+
+	for (i = 0; i < numChains; i++) {
+		powerMeasI = ah->totalPowerMeasI[i];
+		powerMeasQ = ah->totalPowerMeasQ[i];
+		iqCorrMeas = ah->totalIqCorrMeas[i];
+
+		ath_print(common, ATH_DBG_CALIBRATE,
+			  "Starting IQ Cal and Correction for Chain %d\n",
+			  i);
+
+		ath_print(common, ATH_DBG_CALIBRATE,
+			  "Orignal: Chn %diq_corr_meas = 0x%08x\n",
+			  i, ah->totalIqCorrMeas[i]);
+
+		iqCorrNeg = 0;
+
+		if (iqCorrMeas > 0x80000000) {
+			iqCorrMeas = (0xffffffff - iqCorrMeas) + 1;
+			iqCorrNeg = 1;
+		}
+
+		ath_print(common, ATH_DBG_CALIBRATE,
+			  "Chn %d pwr_meas_i = 0x%08x\n", i, powerMeasI);
+		ath_print(common, ATH_DBG_CALIBRATE,
+			  "Chn %d pwr_meas_q = 0x%08x\n", i, powerMeasQ);
+		ath_print(common, ATH_DBG_CALIBRATE, "iqCorrNeg is 0x%08x\n",
+			  iqCorrNeg);
+
+		iCoffDenom = (powerMeasI / 2 + powerMeasQ / 2) / 256;
+		qCoffDenom = powerMeasQ / 64;
+
+		if ((iCoffDenom != 0) && (qCoffDenom != 0)) {
+			iCoff = iqCorrMeas / iCoffDenom;
+			qCoff = powerMeasI / qCoffDenom - 64;
+			ath_print(common, ATH_DBG_CALIBRATE,
+				  "Chn %d iCoff = 0x%08x\n", i, iCoff);
+			ath_print(common, ATH_DBG_CALIBRATE,
+				  "Chn %d qCoff = 0x%08x\n", i, qCoff);
+
+			/* Force bounds on iCoff */
+			if (iCoff >= 63)
+				iCoff = 63;
+			else if (iCoff <= -63)
+				iCoff = -63;
+
+			/* Negate iCoff if iqCorrNeg == 0 */
+			if (iqCorrNeg == 0x0)
+				iCoff = -iCoff;
+
+			/* Force bounds on qCoff */
+			if (qCoff >= 63)
+				qCoff = 63;
+			else if (qCoff <= -63)
+				qCoff = -63;
+
+			iCoff = iCoff & 0x7f;
+			qCoff = qCoff & 0x7f;
+
+			ath_print(common, ATH_DBG_CALIBRATE,
+				  "Chn %d : iCoff = 0x%x  qCoff = 0x%x\n",
+				  i, iCoff, qCoff);
+			ath_print(common, ATH_DBG_CALIBRATE,
+				  "Register offset (0x%04x) "
+				  "before update = 0x%x\n",
+				  offset_array[i],
+				  REG_READ(ah, offset_array[i]));
+
+			REG_RMW_FIELD(ah, offset_array[i],
+				      AR_PHY_RX_IQCAL_CORR_IQCORR_Q_I_COFF,
+				      iCoff);
+			REG_RMW_FIELD(ah, offset_array[i],
+				      AR_PHY_RX_IQCAL_CORR_IQCORR_Q_Q_COFF,
+				      qCoff);
+			ath_print(common, ATH_DBG_CALIBRATE,
+				  "Register offset (0x%04x) QI COFF "
+				  "(bitfields 0x%08x) after update = 0x%x\n",
+				  offset_array[i],
+				  AR_PHY_RX_IQCAL_CORR_IQCORR_Q_I_COFF,
+				  REG_READ(ah, offset_array[i]));
+			ath_print(common, ATH_DBG_CALIBRATE,
+				  "Register offset (0x%04x) QQ COFF "
+				  "(bitfields 0x%08x) after update = 0x%x\n",
+				  offset_array[i],
+				  AR_PHY_RX_IQCAL_CORR_IQCORR_Q_Q_COFF,
+				  REG_READ(ah, offset_array[i]));
+
+			ath_print(common, ATH_DBG_CALIBRATE,
+				  "IQ Cal and Correction done for Chain %d\n",
+				  i);
+		}
+	}
+
+	REG_SET_BIT(ah, AR_PHY_RX_IQCAL_CORR_B0,
+		    AR_PHY_RX_IQCAL_CORR_IQCORR_ENABLE);
+	ath_print(common, ATH_DBG_CALIBRATE,
+		  "IQ Cal and Correction (offset 0x%04x) enabled "
+		  "(bit position 0x%08x). New Value 0x%08x\n",
+		  (unsigned) (AR_PHY_RX_IQCAL_CORR_B0),
+		  AR_PHY_RX_IQCAL_CORR_IQCORR_ENABLE,
+		  REG_READ(ah, AR_PHY_RX_IQCAL_CORR_B0));
+}
+
+static const struct ath9k_percal_data iq_cal_single_sample = {
+	IQ_MISMATCH_CAL,
+	MIN_CAL_SAMPLES,
+	PER_MAX_LOG_COUNT,
+	ar9003_hw_iqcal_collect,
+	ar9003_hw_iqcalibrate
+};
+
 static void ar9003_hw_init_cal_settings(struct ath_hw *ah)
 {
-	/* TODO */
+	ah->iq_caldata.calData = &iq_cal_single_sample;
+	ah->supp_cals = IQ_MISMATCH_CAL;
 }
 
 static bool ar9003_hw_iscal_supported(struct ath_hw *ah,
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 103+ messages in thread

* [PATCH v3 57/97] ath9k_hw: add the config_pci_powersave AR9003 callback
  2010-04-15 21:38 [PATCH v3 00/97] ath9k: add AR9003 support Luis R. Rodriguez
                   ` (55 preceding siblings ...)
  2010-04-15 21:39 ` [PATCH v3 56/97] ath9k_hw: add the AR9003 ar9003_hw_init_cal callback Luis R. Rodriguez
@ 2010-04-15 21:39 ` Luis R. Rodriguez
  2010-04-15 21:39 ` [PATCH v3 58/97] ath9k_hw: split the generic hardware code by hardware family Luis R. Rodriguez
                   ` (39 subsequent siblings)
  96 siblings, 0 replies; 103+ messages in thread
From: Luis R. Rodriguez @ 2010-04-15 21:39 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Luis R. Rodriguez

Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/hw.c |   34 ++++++++++++++++++++++++++++++++++
 1 files changed, 34 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 6c092ee..240ca4c 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -2595,6 +2595,37 @@ enum ath9k_int ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints)
 }
 EXPORT_SYMBOL(ath9k_hw_set_interrupts);
 
+/*
+ * Helper for ASPM support.
+ *
+ * Disable PLL when in L0s as well as receiver clock when in L1.
+ * This power saving option must be enabled through the SerDes.
+ *
+ * Programming the SerDes must go through the same 288 bit serial shift
+ * register as the other analog registers.  Hence the 9 writes.
+ */
+static void ar9003_hw_configpcipowersave(struct ath_hw *ah,
+					 int restore,
+					 int power_off)
+{
+	if (ah->is_pciexpress != true)
+		return;
+
+	/* Do not touch SerDes registers */
+	if (ah->config.pcie_powersave_enable == 2)
+		return;
+
+	/* Nothing to do on restore for 11N */
+	if (!restore) {
+		/* set bit 19 to allow forcing of pcie core into L1 state */
+		REG_SET_BIT(ah, AR_PCIE_PM_CTRL, AR_PCIE_PM_CTRL_ENA);
+
+		/* Several PCIe massages to ensure proper behaviour */
+		if (ah->config.pcie_waen)
+			REG_WRITE(ah, AR_WA, ah->config.pcie_waen);
+	}
+}
+
 /*******************/
 /* Beacon Handling */
 /*******************/
@@ -3629,10 +3660,13 @@ static void ar9002_hw_attach_ops(struct ath_hw *ah)
 static 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->macversion_supported = ar9003_hw_macversion_supported;
 
+	ops->config_pci_powersave = ar9003_hw_configpcipowersave;
+
 	ar9003_hw_attach_phy_ops(ah);
 	ar9003_hw_attach_calib_ops(ah);
 	ar9003_hw_attach_mac_ops(ah);
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 103+ messages in thread

* [PATCH v3 58/97] ath9k_hw: split the generic hardware code by hardware family
  2010-04-15 21:38 [PATCH v3 00/97] ath9k: add AR9003 support Luis R. Rodriguez
                   ` (56 preceding siblings ...)
  2010-04-15 21:39 ` [PATCH v3 57/97] ath9k_hw: add the config_pci_powersave AR9003 callback Luis R. Rodriguez
@ 2010-04-15 21:39 ` Luis R. Rodriguez
  2010-04-15 21:39 ` [PATCH v3 59/97] ath9k_hw: move the cck channel 14 INI to the AR9002 hw code Luis R. Rodriguez
                   ` (38 subsequent siblings)
  96 siblings, 0 replies; 103+ messages in thread
From: Luis R. Rodriguez @ 2010-04-15 21:39 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Luis R. Rodriguez

Move out the generic hardware family code out into their own
files, we have one for AR5008, AR9001, and AR9002 family (ar9002_hw.c)
and another file for the new AR9003 hardware family (ar9003_hw.c).

Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/Makefile    |    5 +-
 drivers/net/wireless/ath/ath9k/ar9002_hw.c |  383 +++++++++++++++++++++
 drivers/net/wireless/ath/ath9k/ar9003_hw.c |  149 +++++++++
 drivers/net/wireless/ath/ath9k/hw.c        |  498 +---------------------------
 drivers/net/wireless/ath/ath9k/hw.h        |    5 +-
 5 files changed, 541 insertions(+), 499 deletions(-)
 create mode 100644 drivers/net/wireless/ath/ath9k/ar9002_hw.c
 create mode 100644 drivers/net/wireless/ath/ath9k/ar9003_hw.c

diff --git a/drivers/net/wireless/ath/ath9k/Makefile b/drivers/net/wireless/ath/ath9k/Makefile
index d2417ed..ee8f7e8 100644
--- a/drivers/net/wireless/ath/ath9k/Makefile
+++ b/drivers/net/wireless/ath/ath9k/Makefile
@@ -13,7 +13,10 @@ ath9k-$(CONFIG_ATH9K_DEBUGFS) += debug.o
 
 obj-$(CONFIG_ATH9K) += ath9k.o
 
-ath9k_hw-y:=	hw.o \
+ath9k_hw-y:=	\
+		ar9002_hw.o \
+		ar9003_hw.o \
+		hw.o \
 		ar9003_phy.o \
 		ar9002_phy.o \
 		ar5008_phy.o \
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_hw.c b/drivers/net/wireless/ath/ath9k/ar9002_hw.c
new file mode 100644
index 0000000..aa52fd7
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/ar9002_hw.c
@@ -0,0 +1,383 @@
+/*
+ * Copyright (c) 2008-2010 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "hw.h"
+#include "ar5008_initvals.h"
+#include "ar9001_initvals.h"
+#include "ar9002_initvals.h"
+
+/* General hardware code for the A5008/AR9001/AR9002 hadware families */
+
+static bool ar9002_hw_macversion_supported(u32 macversion)
+{
+	switch (macversion) {
+	case AR_SREV_VERSION_5416_PCI:
+	case AR_SREV_VERSION_5416_PCIE:
+	case AR_SREV_VERSION_9160:
+	case AR_SREV_VERSION_9100:
+	case AR_SREV_VERSION_9280:
+	case AR_SREV_VERSION_9285:
+	case AR_SREV_VERSION_9287:
+	case AR_SREV_VERSION_9271:
+		return true;
+	default:
+		break;
+	}
+	return false;
+}
+
+static void ar9002_hw_init_mode_regs(struct ath_hw *ah)
+{
+	if (AR_SREV_9271(ah)) {
+		INIT_INI_ARRAY(&ah->iniModes, ar9271Modes_9271,
+			       ARRAY_SIZE(ar9271Modes_9271), 6);
+		INIT_INI_ARRAY(&ah->iniCommon, ar9271Common_9271,
+			       ARRAY_SIZE(ar9271Common_9271), 2);
+		INIT_INI_ARRAY(&ah->iniCommon_normal_cck_fir_coeff_9271,
+			       ar9271Common_normal_cck_fir_coeff_9271,
+			       ARRAY_SIZE(ar9271Common_normal_cck_fir_coeff_9271), 2);
+		INIT_INI_ARRAY(&ah->iniCommon_japan_2484_cck_fir_coeff_9271,
+			       ar9271Common_japan_2484_cck_fir_coeff_9271,
+			       ARRAY_SIZE(ar9271Common_japan_2484_cck_fir_coeff_9271), 2);
+		INIT_INI_ARRAY(&ah->iniModes_9271_1_0_only,
+			       ar9271Modes_9271_1_0_only,
+			       ARRAY_SIZE(ar9271Modes_9271_1_0_only), 6);
+		INIT_INI_ARRAY(&ah->iniModes_9271_ANI_reg, ar9271Modes_9271_ANI_reg,
+			       ARRAY_SIZE(ar9271Modes_9271_ANI_reg), 6);
+		INIT_INI_ARRAY(&ah->iniModes_high_power_tx_gain_9271,
+			       ar9271Modes_high_power_tx_gain_9271,
+			       ARRAY_SIZE(ar9271Modes_high_power_tx_gain_9271), 6);
+		INIT_INI_ARRAY(&ah->iniModes_normal_power_tx_gain_9271,
+			       ar9271Modes_normal_power_tx_gain_9271,
+			       ARRAY_SIZE(ar9271Modes_normal_power_tx_gain_9271), 6);
+		return;
+	}
+
+	if (AR_SREV_9287_11_OR_LATER(ah)) {
+		INIT_INI_ARRAY(&ah->iniModes, ar9287Modes_9287_1_1,
+				ARRAY_SIZE(ar9287Modes_9287_1_1), 6);
+		INIT_INI_ARRAY(&ah->iniCommon, ar9287Common_9287_1_1,
+				ARRAY_SIZE(ar9287Common_9287_1_1), 2);
+		if (ah->config.pcie_clock_req)
+			INIT_INI_ARRAY(&ah->iniPcieSerdes,
+			ar9287PciePhy_clkreq_off_L1_9287_1_1,
+			ARRAY_SIZE(ar9287PciePhy_clkreq_off_L1_9287_1_1), 2);
+		else
+			INIT_INI_ARRAY(&ah->iniPcieSerdes,
+			ar9287PciePhy_clkreq_always_on_L1_9287_1_1,
+			ARRAY_SIZE(ar9287PciePhy_clkreq_always_on_L1_9287_1_1),
+					2);
+	} else if (AR_SREV_9287_10_OR_LATER(ah)) {
+		INIT_INI_ARRAY(&ah->iniModes, ar9287Modes_9287_1_0,
+				ARRAY_SIZE(ar9287Modes_9287_1_0), 6);
+		INIT_INI_ARRAY(&ah->iniCommon, ar9287Common_9287_1_0,
+				ARRAY_SIZE(ar9287Common_9287_1_0), 2);
+
+		if (ah->config.pcie_clock_req)
+			INIT_INI_ARRAY(&ah->iniPcieSerdes,
+			ar9287PciePhy_clkreq_off_L1_9287_1_0,
+			ARRAY_SIZE(ar9287PciePhy_clkreq_off_L1_9287_1_0), 2);
+		else
+			INIT_INI_ARRAY(&ah->iniPcieSerdes,
+			ar9287PciePhy_clkreq_always_on_L1_9287_1_0,
+			ARRAY_SIZE(ar9287PciePhy_clkreq_always_on_L1_9287_1_0),
+				  2);
+	} else if (AR_SREV_9285_12_OR_LATER(ah)) {
+
+
+		INIT_INI_ARRAY(&ah->iniModes, ar9285Modes_9285_1_2,
+			       ARRAY_SIZE(ar9285Modes_9285_1_2), 6);
+		INIT_INI_ARRAY(&ah->iniCommon, ar9285Common_9285_1_2,
+			       ARRAY_SIZE(ar9285Common_9285_1_2), 2);
+
+		if (ah->config.pcie_clock_req) {
+			INIT_INI_ARRAY(&ah->iniPcieSerdes,
+			ar9285PciePhy_clkreq_off_L1_9285_1_2,
+			ARRAY_SIZE(ar9285PciePhy_clkreq_off_L1_9285_1_2), 2);
+		} else {
+			INIT_INI_ARRAY(&ah->iniPcieSerdes,
+			ar9285PciePhy_clkreq_always_on_L1_9285_1_2,
+			ARRAY_SIZE(ar9285PciePhy_clkreq_always_on_L1_9285_1_2),
+				  2);
+		}
+	} else if (AR_SREV_9285_10_OR_LATER(ah)) {
+		INIT_INI_ARRAY(&ah->iniModes, ar9285Modes_9285,
+			       ARRAY_SIZE(ar9285Modes_9285), 6);
+		INIT_INI_ARRAY(&ah->iniCommon, ar9285Common_9285,
+			       ARRAY_SIZE(ar9285Common_9285), 2);
+
+		if (ah->config.pcie_clock_req) {
+			INIT_INI_ARRAY(&ah->iniPcieSerdes,
+			ar9285PciePhy_clkreq_off_L1_9285,
+			ARRAY_SIZE(ar9285PciePhy_clkreq_off_L1_9285), 2);
+		} else {
+			INIT_INI_ARRAY(&ah->iniPcieSerdes,
+			ar9285PciePhy_clkreq_always_on_L1_9285,
+			ARRAY_SIZE(ar9285PciePhy_clkreq_always_on_L1_9285), 2);
+		}
+	} else if (AR_SREV_9280_20_OR_LATER(ah)) {
+		INIT_INI_ARRAY(&ah->iniModes, ar9280Modes_9280_2,
+			       ARRAY_SIZE(ar9280Modes_9280_2), 6);
+		INIT_INI_ARRAY(&ah->iniCommon, ar9280Common_9280_2,
+			       ARRAY_SIZE(ar9280Common_9280_2), 2);
+
+		if (ah->config.pcie_clock_req) {
+			INIT_INI_ARRAY(&ah->iniPcieSerdes,
+			       ar9280PciePhy_clkreq_off_L1_9280,
+			       ARRAY_SIZE(ar9280PciePhy_clkreq_off_L1_9280), 2);
+		} else {
+			INIT_INI_ARRAY(&ah->iniPcieSerdes,
+			       ar9280PciePhy_clkreq_always_on_L1_9280,
+			       ARRAY_SIZE(ar9280PciePhy_clkreq_always_on_L1_9280), 2);
+		}
+		INIT_INI_ARRAY(&ah->iniModesAdditional,
+			       ar9280Modes_fast_clock_9280_2,
+			       ARRAY_SIZE(ar9280Modes_fast_clock_9280_2), 3);
+	} else if (AR_SREV_9280_10_OR_LATER(ah)) {
+		INIT_INI_ARRAY(&ah->iniModes, ar9280Modes_9280,
+			       ARRAY_SIZE(ar9280Modes_9280), 6);
+		INIT_INI_ARRAY(&ah->iniCommon, ar9280Common_9280,
+			       ARRAY_SIZE(ar9280Common_9280), 2);
+	} else if (AR_SREV_9160_10_OR_LATER(ah)) {
+		INIT_INI_ARRAY(&ah->iniModes, ar5416Modes_9160,
+			       ARRAY_SIZE(ar5416Modes_9160), 6);
+		INIT_INI_ARRAY(&ah->iniCommon, ar5416Common_9160,
+			       ARRAY_SIZE(ar5416Common_9160), 2);
+		INIT_INI_ARRAY(&ah->iniBank0, ar5416Bank0_9160,
+			       ARRAY_SIZE(ar5416Bank0_9160), 2);
+		INIT_INI_ARRAY(&ah->iniBB_RfGain, ar5416BB_RfGain_9160,
+			       ARRAY_SIZE(ar5416BB_RfGain_9160), 3);
+		INIT_INI_ARRAY(&ah->iniBank1, ar5416Bank1_9160,
+			       ARRAY_SIZE(ar5416Bank1_9160), 2);
+		INIT_INI_ARRAY(&ah->iniBank2, ar5416Bank2_9160,
+			       ARRAY_SIZE(ar5416Bank2_9160), 2);
+		INIT_INI_ARRAY(&ah->iniBank3, ar5416Bank3_9160,
+			       ARRAY_SIZE(ar5416Bank3_9160), 3);
+		INIT_INI_ARRAY(&ah->iniBank6, ar5416Bank6_9160,
+			       ARRAY_SIZE(ar5416Bank6_9160), 3);
+		INIT_INI_ARRAY(&ah->iniBank6TPC, ar5416Bank6TPC_9160,
+			       ARRAY_SIZE(ar5416Bank6TPC_9160), 3);
+		INIT_INI_ARRAY(&ah->iniBank7, ar5416Bank7_9160,
+			       ARRAY_SIZE(ar5416Bank7_9160), 2);
+		if (AR_SREV_9160_11(ah)) {
+			INIT_INI_ARRAY(&ah->iniAddac,
+				       ar5416Addac_91601_1,
+				       ARRAY_SIZE(ar5416Addac_91601_1), 2);
+		} else {
+			INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac_9160,
+				       ARRAY_SIZE(ar5416Addac_9160), 2);
+		}
+	} else if (AR_SREV_9100_OR_LATER(ah)) {
+		INIT_INI_ARRAY(&ah->iniModes, ar5416Modes_9100,
+			       ARRAY_SIZE(ar5416Modes_9100), 6);
+		INIT_INI_ARRAY(&ah->iniCommon, ar5416Common_9100,
+			       ARRAY_SIZE(ar5416Common_9100), 2);
+		INIT_INI_ARRAY(&ah->iniBank0, ar5416Bank0_9100,
+			       ARRAY_SIZE(ar5416Bank0_9100), 2);
+		INIT_INI_ARRAY(&ah->iniBB_RfGain, ar5416BB_RfGain_9100,
+			       ARRAY_SIZE(ar5416BB_RfGain_9100), 3);
+		INIT_INI_ARRAY(&ah->iniBank1, ar5416Bank1_9100,
+			       ARRAY_SIZE(ar5416Bank1_9100), 2);
+		INIT_INI_ARRAY(&ah->iniBank2, ar5416Bank2_9100,
+			       ARRAY_SIZE(ar5416Bank2_9100), 2);
+		INIT_INI_ARRAY(&ah->iniBank3, ar5416Bank3_9100,
+			       ARRAY_SIZE(ar5416Bank3_9100), 3);
+		INIT_INI_ARRAY(&ah->iniBank6, ar5416Bank6_9100,
+			       ARRAY_SIZE(ar5416Bank6_9100), 3);
+		INIT_INI_ARRAY(&ah->iniBank6TPC, ar5416Bank6TPC_9100,
+			       ARRAY_SIZE(ar5416Bank6TPC_9100), 3);
+		INIT_INI_ARRAY(&ah->iniBank7, ar5416Bank7_9100,
+			       ARRAY_SIZE(ar5416Bank7_9100), 2);
+		INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac_9100,
+			       ARRAY_SIZE(ar5416Addac_9100), 2);
+	} else {
+		INIT_INI_ARRAY(&ah->iniModes, ar5416Modes,
+			       ARRAY_SIZE(ar5416Modes), 6);
+		INIT_INI_ARRAY(&ah->iniCommon, ar5416Common,
+			       ARRAY_SIZE(ar5416Common), 2);
+		INIT_INI_ARRAY(&ah->iniBank0, ar5416Bank0,
+			       ARRAY_SIZE(ar5416Bank0), 2);
+		INIT_INI_ARRAY(&ah->iniBB_RfGain, ar5416BB_RfGain,
+			       ARRAY_SIZE(ar5416BB_RfGain), 3);
+		INIT_INI_ARRAY(&ah->iniBank1, ar5416Bank1,
+			       ARRAY_SIZE(ar5416Bank1), 2);
+		INIT_INI_ARRAY(&ah->iniBank2, ar5416Bank2,
+			       ARRAY_SIZE(ar5416Bank2), 2);
+		INIT_INI_ARRAY(&ah->iniBank3, ar5416Bank3,
+			       ARRAY_SIZE(ar5416Bank3), 3);
+		INIT_INI_ARRAY(&ah->iniBank6, ar5416Bank6,
+			       ARRAY_SIZE(ar5416Bank6), 3);
+		INIT_INI_ARRAY(&ah->iniBank6TPC, ar5416Bank6TPC,
+			       ARRAY_SIZE(ar5416Bank6TPC), 3);
+		INIT_INI_ARRAY(&ah->iniBank7, ar5416Bank7,
+			       ARRAY_SIZE(ar5416Bank7), 2);
+		INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac,
+			       ARRAY_SIZE(ar5416Addac), 2);
+	}
+}
+
+/*
+ * Helper for ASPM support.
+ *
+ * Disable PLL when in L0s as well as receiver clock when in L1.
+ * This power saving option must be enabled through the SerDes.
+ *
+ * Programming the SerDes must go through the same 288 bit serial shift
+ * register as the other analog registers.  Hence the 9 writes.
+ */
+static void ar9002_hw_configpcipowersave(struct ath_hw *ah,
+					 int restore,
+					 int power_off)
+{
+	u8 i;
+	u32 val;
+
+	if (ah->is_pciexpress != true)
+		return;
+
+	/* Do not touch SerDes registers */
+	if (ah->config.pcie_powersave_enable == 2)
+		return;
+
+	/* Nothing to do on restore for 11N */
+	if (!restore) {
+		if (AR_SREV_9280_20_OR_LATER(ah)) {
+			/*
+			 * AR9280 2.0 or later chips use SerDes values from the
+			 * initvals.h initialized depending on chipset during
+			 * __ath9k_hw_init()
+			 */
+			for (i = 0; i < ah->iniPcieSerdes.ia_rows; i++) {
+				REG_WRITE(ah, INI_RA(&ah->iniPcieSerdes, i, 0),
+					  INI_RA(&ah->iniPcieSerdes, i, 1));
+			}
+		} else if (AR_SREV_9280(ah) &&
+			   (ah->hw_version.macRev == AR_SREV_REVISION_9280_10)) {
+			REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fd00);
+			REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924);
+
+			/* RX shut off when elecidle is asserted */
+			REG_WRITE(ah, AR_PCIE_SERDES, 0xa8000019);
+			REG_WRITE(ah, AR_PCIE_SERDES, 0x13160820);
+			REG_WRITE(ah, AR_PCIE_SERDES, 0xe5980560);
+
+			/* Shut off CLKREQ active in L1 */
+			if (ah->config.pcie_clock_req)
+				REG_WRITE(ah, AR_PCIE_SERDES, 0x401deffc);
+			else
+				REG_WRITE(ah, AR_PCIE_SERDES, 0x401deffd);
+
+			REG_WRITE(ah, AR_PCIE_SERDES, 0x1aaabe40);
+			REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554);
+			REG_WRITE(ah, AR_PCIE_SERDES, 0x00043007);
+
+			/* Load the new settings */
+			REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
+
+		} else {
+			REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fc00);
+			REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924);
+
+			/* RX shut off when elecidle is asserted */
+			REG_WRITE(ah, AR_PCIE_SERDES, 0x28000039);
+			REG_WRITE(ah, AR_PCIE_SERDES, 0x53160824);
+			REG_WRITE(ah, AR_PCIE_SERDES, 0xe5980579);
+
+			/*
+			 * Ignore ah->ah_config.pcie_clock_req setting for
+			 * pre-AR9280 11n
+			 */
+			REG_WRITE(ah, AR_PCIE_SERDES, 0x001defff);
+
+			REG_WRITE(ah, AR_PCIE_SERDES, 0x1aaabe40);
+			REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554);
+			REG_WRITE(ah, AR_PCIE_SERDES, 0x000e3007);
+
+			/* Load the new settings */
+			REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
+		}
+
+		udelay(1000);
+
+		/* set bit 19 to allow forcing of pcie core into L1 state */
+		REG_SET_BIT(ah, AR_PCIE_PM_CTRL, AR_PCIE_PM_CTRL_ENA);
+
+		/* Several PCIe massages to ensure proper behaviour */
+		if (ah->config.pcie_waen) {
+			val = ah->config.pcie_waen;
+			if (!power_off)
+				val &= (~AR_WA_D3_L1_DISABLE);
+		} else {
+			if (AR_SREV_9285(ah) || AR_SREV_9271(ah) ||
+			    AR_SREV_9287(ah)) {
+				val = AR9285_WA_DEFAULT;
+				if (!power_off)
+					val &= (~AR_WA_D3_L1_DISABLE);
+			} else if (AR_SREV_9280(ah)) {
+				/*
+				 * On AR9280 chips bit 22 of 0x4004 needs to be
+				 * set otherwise card may disappear.
+				 */
+				val = AR9280_WA_DEFAULT;
+				if (!power_off)
+					val &= (~AR_WA_D3_L1_DISABLE);
+			} else
+				val = AR_WA_DEFAULT;
+		}
+
+		REG_WRITE(ah, AR_WA, val);
+	}
+
+	if (power_off) {
+		/*
+		 * Set PCIe workaround bits
+		 * bit 14 in WA register (disable L1) should only
+		 * be set when device enters D3 and be cleared
+		 * when device comes back to D0.
+		 */
+		if (ah->config.pcie_waen) {
+			if (ah->config.pcie_waen & AR_WA_D3_L1_DISABLE)
+				REG_SET_BIT(ah, AR_WA, AR_WA_D3_L1_DISABLE);
+		} else {
+			if (((AR_SREV_9285(ah) || AR_SREV_9271(ah) ||
+			      AR_SREV_9287(ah)) &&
+			     (AR9285_WA_DEFAULT & AR_WA_D3_L1_DISABLE)) ||
+			    (AR_SREV_9280(ah) &&
+			     (AR9280_WA_DEFAULT & AR_WA_D3_L1_DISABLE))) {
+				REG_SET_BIT(ah, AR_WA, AR_WA_D3_L1_DISABLE);
+			}
+		}
+	}
+}
+
+/* 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->macversion_supported = ar9002_hw_macversion_supported;
+
+	ops->config_pci_powersave = ar9002_hw_configpcipowersave;
+
+	ar5008_hw_attach_phy_ops(ah);
+	if (AR_SREV_9280_10_OR_LATER(ah))
+		ar9002_hw_attach_phy_ops(ah);
+
+	ar9002_hw_attach_calib_ops(ah);
+	ar9002_hw_attach_mac_ops(ah);
+}
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_hw.c b/drivers/net/wireless/ath/ath9k/ar9003_hw.c
new file mode 100644
index 0000000..6111bdb
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/ar9003_hw.c
@@ -0,0 +1,149 @@
+/*
+ * Copyright (c) 2008-2010 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "hw.h"
+#include "ar9003_initvals.h"
+
+/* General hardware code for the AR9003 hadware family */
+
+static bool ar9003_hw_macversion_supported(u32 macversion)
+{
+	switch (macversion) {
+	case AR_SREV_VERSION_9300:
+		return true;
+	default:
+		break;
+	}
+	return false;
+}
+
+/* AR9003 2.0 - new INI format (pre, core, post arrays per subsystem) */
+static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
+{
+	/* mac */
+	INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0);
+	INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE],
+		       ar9300_2p0_mac_core,
+		       ARRAY_SIZE(ar9300_2p0_mac_core), 2);
+	INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST],
+		       ar9300_2p0_mac_postamble,
+		       ARRAY_SIZE(ar9300_2p0_mac_postamble), 5);
+
+	/* bb */
+	INIT_INI_ARRAY(&ah->iniBB[ATH_INI_PRE], NULL, 0, 0);
+	INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE],
+		       ar9300_2p0_baseband_core,
+		       ARRAY_SIZE(ar9300_2p0_baseband_core), 2);
+	INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST],
+		       ar9300_2p0_baseband_postamble,
+		       ARRAY_SIZE(ar9300_2p0_baseband_postamble), 5);
+
+	/* radio */
+	INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_PRE], NULL, 0, 0);
+	INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE],
+		       ar9300_2p0_radio_core,
+		       ARRAY_SIZE(ar9300_2p0_radio_core), 2);
+	INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST],
+		       ar9300_2p0_radio_postamble,
+		       ARRAY_SIZE(ar9300_2p0_radio_postamble), 5);
+
+	/* soc */
+	INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE],
+		       ar9300_2p0_soc_preamble,
+		       ARRAY_SIZE(ar9300_2p0_soc_preamble), 2);
+	INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_CORE], NULL, 0, 0);
+	INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST],
+		       ar9300_2p0_soc_postamble,
+		       ARRAY_SIZE(ar9300_2p0_soc_postamble), 5);
+
+	/* rx/tx gain */
+	INIT_INI_ARRAY(&ah->iniModesRxGain,
+		       ar9300Common_rx_gain_table_2p0,
+		       ARRAY_SIZE(ar9300Common_rx_gain_table_2p0), 2);
+	INIT_INI_ARRAY(&ah->iniModesTxGain,
+		       ar9300Modes_lowest_ob_db_tx_gain_table_2p0,
+		       ARRAY_SIZE(ar9300Modes_lowest_ob_db_tx_gain_table_2p0),
+		       5);
+
+	/* Load PCIE SERDES settings from INI */
+
+	/* Awake Setting */
+
+	INIT_INI_ARRAY(&ah->iniPcieSerdes,
+		       ar9300PciePhy_pll_on_clkreq_disable_L1_2p0,
+		       ARRAY_SIZE(ar9300PciePhy_pll_on_clkreq_disable_L1_2p0),
+		       2);
+
+	/* Sleep Setting */
+
+	INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower,
+		       ar9300PciePhy_clkreq_enable_L1_2p0,
+		       ARRAY_SIZE(ar9300PciePhy_clkreq_enable_L1_2p0),
+		       2);
+
+	/* Fast clock modal settings */
+	INIT_INI_ARRAY(&ah->iniModesAdditional,
+		       ar9300Modes_fast_clock_2p0,
+		       ARRAY_SIZE(ar9300Modes_fast_clock_2p0),
+		       3);
+}
+
+/*
+ * Helper for ASPM support.
+ *
+ * Disable PLL when in L0s as well as receiver clock when in L1.
+ * This power saving option must be enabled through the SerDes.
+ *
+ * Programming the SerDes must go through the same 288 bit serial shift
+ * register as the other analog registers.  Hence the 9 writes.
+ */
+static void ar9003_hw_configpcipowersave(struct ath_hw *ah,
+					 int restore,
+					 int power_off)
+{
+	if (ah->is_pciexpress != true)
+		return;
+
+	/* Do not touch SerDes registers */
+	if (ah->config.pcie_powersave_enable == 2)
+		return;
+
+	/* Nothing to do on restore for 11N */
+	if (!restore) {
+		/* set bit 19 to allow forcing of pcie core into L1 state */
+		REG_SET_BIT(ah, AR_PCIE_PM_CTRL, AR_PCIE_PM_CTRL_ENA);
+
+		/* Several PCIe massages to ensure proper behaviour */
+		if (ah->config.pcie_waen)
+			REG_WRITE(ah, AR_WA, ah->config.pcie_waen);
+	}
+}
+
+/* Sets up the AR9003 hardware familiy callbacks */
+void ar9003_hw_attach_ops(struct ath_hw *ah)
+{
+	struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
+	struct ath_hw_ops *ops = ath9k_hw_ops(ah);
+
+	priv_ops->init_mode_regs = ar9003_hw_init_mode_regs;
+	priv_ops->macversion_supported = ar9003_hw_macversion_supported;
+
+	ops->config_pci_powersave = ar9003_hw_configpcipowersave;
+
+	ar9003_hw_attach_phy_ops(ah);
+	ar9003_hw_attach_calib_ops(ah);
+	ar9003_hw_attach_mac_ops(ah);
+}
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 240ca4c..672c5ad 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008-2009 Atheros Communications Inc.
+ * Copyright (c) 2008-2010 Atheros Communications Inc.
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -21,18 +21,12 @@
 #include "hw.h"
 #include "hw-ops.h"
 #include "rc.h"
-#include "ar5008_initvals.h"
-#include "ar9001_initvals.h"
 #include "ar9002_initvals.h"
-#include "ar9003_initvals.h"
 
 #define ATH9K_CLOCK_RATE_CCK		22
 #define ATH9K_CLOCK_RATE_5GHZ_OFDM	40
 #define ATH9K_CLOCK_RATE_2GHZ_OFDM	44
 
-static void ar9002_hw_attach_ops(struct ath_hw *ah);
-static void ar9003_hw_attach_ops(struct ath_hw *ah);
-
 static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type);
 
 MODULE_AUTHOR("Atheros Communications");
@@ -572,296 +566,6 @@ static int ath9k_hw_post_init(struct ath_hw *ah)
 	return 0;
 }
 
-static bool ar9002_hw_macversion_supported(u32 macversion)
-{
-	switch (macversion) {
-	case AR_SREV_VERSION_5416_PCI:
-	case AR_SREV_VERSION_5416_PCIE:
-	case AR_SREV_VERSION_9160:
-	case AR_SREV_VERSION_9100:
-	case AR_SREV_VERSION_9280:
-	case AR_SREV_VERSION_9285:
-	case AR_SREV_VERSION_9287:
-	case AR_SREV_VERSION_9271:
-		return true;
-	default:
-		break;
-	}
-	return false;
-}
-
-static bool ar9003_hw_macversion_supported(u32 macversion)
-{
-	switch (macversion) {
-	case AR_SREV_VERSION_9300:
-		return true;
-	default:
-		break;
-	}
-	return false;
-}
-
-static void ar9002_hw_init_mode_regs(struct ath_hw *ah)
-{
-	if (AR_SREV_9271(ah)) {
-		INIT_INI_ARRAY(&ah->iniModes, ar9271Modes_9271,
-			       ARRAY_SIZE(ar9271Modes_9271), 6);
-		INIT_INI_ARRAY(&ah->iniCommon, ar9271Common_9271,
-			       ARRAY_SIZE(ar9271Common_9271), 2);
-		INIT_INI_ARRAY(&ah->iniCommon_normal_cck_fir_coeff_9271,
-			       ar9271Common_normal_cck_fir_coeff_9271,
-			       ARRAY_SIZE(ar9271Common_normal_cck_fir_coeff_9271), 2);
-		INIT_INI_ARRAY(&ah->iniCommon_japan_2484_cck_fir_coeff_9271,
-			       ar9271Common_japan_2484_cck_fir_coeff_9271,
-			       ARRAY_SIZE(ar9271Common_japan_2484_cck_fir_coeff_9271), 2);
-		INIT_INI_ARRAY(&ah->iniModes_9271_1_0_only,
-			       ar9271Modes_9271_1_0_only,
-			       ARRAY_SIZE(ar9271Modes_9271_1_0_only), 6);
-		INIT_INI_ARRAY(&ah->iniModes_9271_ANI_reg, ar9271Modes_9271_ANI_reg,
-			       ARRAY_SIZE(ar9271Modes_9271_ANI_reg), 6);
-		INIT_INI_ARRAY(&ah->iniModes_high_power_tx_gain_9271,
-			       ar9271Modes_high_power_tx_gain_9271,
-			       ARRAY_SIZE(ar9271Modes_high_power_tx_gain_9271), 6);
-		INIT_INI_ARRAY(&ah->iniModes_normal_power_tx_gain_9271,
-			       ar9271Modes_normal_power_tx_gain_9271,
-			       ARRAY_SIZE(ar9271Modes_normal_power_tx_gain_9271), 6);
-		return;
-	}
-
-	if (AR_SREV_9287_11_OR_LATER(ah)) {
-		INIT_INI_ARRAY(&ah->iniModes, ar9287Modes_9287_1_1,
-				ARRAY_SIZE(ar9287Modes_9287_1_1), 6);
-		INIT_INI_ARRAY(&ah->iniCommon, ar9287Common_9287_1_1,
-				ARRAY_SIZE(ar9287Common_9287_1_1), 2);
-		if (ah->config.pcie_clock_req)
-			INIT_INI_ARRAY(&ah->iniPcieSerdes,
-			ar9287PciePhy_clkreq_off_L1_9287_1_1,
-			ARRAY_SIZE(ar9287PciePhy_clkreq_off_L1_9287_1_1), 2);
-		else
-			INIT_INI_ARRAY(&ah->iniPcieSerdes,
-			ar9287PciePhy_clkreq_always_on_L1_9287_1_1,
-			ARRAY_SIZE(ar9287PciePhy_clkreq_always_on_L1_9287_1_1),
-					2);
-	} else if (AR_SREV_9287_10_OR_LATER(ah)) {
-		INIT_INI_ARRAY(&ah->iniModes, ar9287Modes_9287_1_0,
-				ARRAY_SIZE(ar9287Modes_9287_1_0), 6);
-		INIT_INI_ARRAY(&ah->iniCommon, ar9287Common_9287_1_0,
-				ARRAY_SIZE(ar9287Common_9287_1_0), 2);
-
-		if (ah->config.pcie_clock_req)
-			INIT_INI_ARRAY(&ah->iniPcieSerdes,
-			ar9287PciePhy_clkreq_off_L1_9287_1_0,
-			ARRAY_SIZE(ar9287PciePhy_clkreq_off_L1_9287_1_0), 2);
-		else
-			INIT_INI_ARRAY(&ah->iniPcieSerdes,
-			ar9287PciePhy_clkreq_always_on_L1_9287_1_0,
-			ARRAY_SIZE(ar9287PciePhy_clkreq_always_on_L1_9287_1_0),
-				  2);
-	} else if (AR_SREV_9285_12_OR_LATER(ah)) {
-
-
-		INIT_INI_ARRAY(&ah->iniModes, ar9285Modes_9285_1_2,
-			       ARRAY_SIZE(ar9285Modes_9285_1_2), 6);
-		INIT_INI_ARRAY(&ah->iniCommon, ar9285Common_9285_1_2,
-			       ARRAY_SIZE(ar9285Common_9285_1_2), 2);
-
-		if (ah->config.pcie_clock_req) {
-			INIT_INI_ARRAY(&ah->iniPcieSerdes,
-			ar9285PciePhy_clkreq_off_L1_9285_1_2,
-			ARRAY_SIZE(ar9285PciePhy_clkreq_off_L1_9285_1_2), 2);
-		} else {
-			INIT_INI_ARRAY(&ah->iniPcieSerdes,
-			ar9285PciePhy_clkreq_always_on_L1_9285_1_2,
-			ARRAY_SIZE(ar9285PciePhy_clkreq_always_on_L1_9285_1_2),
-				  2);
-		}
-	} else if (AR_SREV_9285_10_OR_LATER(ah)) {
-		INIT_INI_ARRAY(&ah->iniModes, ar9285Modes_9285,
-			       ARRAY_SIZE(ar9285Modes_9285), 6);
-		INIT_INI_ARRAY(&ah->iniCommon, ar9285Common_9285,
-			       ARRAY_SIZE(ar9285Common_9285), 2);
-
-		if (ah->config.pcie_clock_req) {
-			INIT_INI_ARRAY(&ah->iniPcieSerdes,
-			ar9285PciePhy_clkreq_off_L1_9285,
-			ARRAY_SIZE(ar9285PciePhy_clkreq_off_L1_9285), 2);
-		} else {
-			INIT_INI_ARRAY(&ah->iniPcieSerdes,
-			ar9285PciePhy_clkreq_always_on_L1_9285,
-			ARRAY_SIZE(ar9285PciePhy_clkreq_always_on_L1_9285), 2);
-		}
-	} else if (AR_SREV_9280_20_OR_LATER(ah)) {
-		INIT_INI_ARRAY(&ah->iniModes, ar9280Modes_9280_2,
-			       ARRAY_SIZE(ar9280Modes_9280_2), 6);
-		INIT_INI_ARRAY(&ah->iniCommon, ar9280Common_9280_2,
-			       ARRAY_SIZE(ar9280Common_9280_2), 2);
-
-		if (ah->config.pcie_clock_req) {
-			INIT_INI_ARRAY(&ah->iniPcieSerdes,
-			       ar9280PciePhy_clkreq_off_L1_9280,
-			       ARRAY_SIZE(ar9280PciePhy_clkreq_off_L1_9280),2);
-		} else {
-			INIT_INI_ARRAY(&ah->iniPcieSerdes,
-			       ar9280PciePhy_clkreq_always_on_L1_9280,
-			       ARRAY_SIZE(ar9280PciePhy_clkreq_always_on_L1_9280), 2);
-		}
-		INIT_INI_ARRAY(&ah->iniModesAdditional,
-			       ar9280Modes_fast_clock_9280_2,
-			       ARRAY_SIZE(ar9280Modes_fast_clock_9280_2), 3);
-	} else if (AR_SREV_9280_10_OR_LATER(ah)) {
-		INIT_INI_ARRAY(&ah->iniModes, ar9280Modes_9280,
-			       ARRAY_SIZE(ar9280Modes_9280), 6);
-		INIT_INI_ARRAY(&ah->iniCommon, ar9280Common_9280,
-			       ARRAY_SIZE(ar9280Common_9280), 2);
-	} else if (AR_SREV_9160_10_OR_LATER(ah)) {
-		INIT_INI_ARRAY(&ah->iniModes, ar5416Modes_9160,
-			       ARRAY_SIZE(ar5416Modes_9160), 6);
-		INIT_INI_ARRAY(&ah->iniCommon, ar5416Common_9160,
-			       ARRAY_SIZE(ar5416Common_9160), 2);
-		INIT_INI_ARRAY(&ah->iniBank0, ar5416Bank0_9160,
-			       ARRAY_SIZE(ar5416Bank0_9160), 2);
-		INIT_INI_ARRAY(&ah->iniBB_RfGain, ar5416BB_RfGain_9160,
-			       ARRAY_SIZE(ar5416BB_RfGain_9160), 3);
-		INIT_INI_ARRAY(&ah->iniBank1, ar5416Bank1_9160,
-			       ARRAY_SIZE(ar5416Bank1_9160), 2);
-		INIT_INI_ARRAY(&ah->iniBank2, ar5416Bank2_9160,
-			       ARRAY_SIZE(ar5416Bank2_9160), 2);
-		INIT_INI_ARRAY(&ah->iniBank3, ar5416Bank3_9160,
-			       ARRAY_SIZE(ar5416Bank3_9160), 3);
-		INIT_INI_ARRAY(&ah->iniBank6, ar5416Bank6_9160,
-			       ARRAY_SIZE(ar5416Bank6_9160), 3);
-		INIT_INI_ARRAY(&ah->iniBank6TPC, ar5416Bank6TPC_9160,
-			       ARRAY_SIZE(ar5416Bank6TPC_9160), 3);
-		INIT_INI_ARRAY(&ah->iniBank7, ar5416Bank7_9160,
-			       ARRAY_SIZE(ar5416Bank7_9160), 2);
-		if (AR_SREV_9160_11(ah)) {
-			INIT_INI_ARRAY(&ah->iniAddac,
-				       ar5416Addac_91601_1,
-				       ARRAY_SIZE(ar5416Addac_91601_1), 2);
-		} else {
-			INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac_9160,
-				       ARRAY_SIZE(ar5416Addac_9160), 2);
-		}
-	} else if (AR_SREV_9100_OR_LATER(ah)) {
-		INIT_INI_ARRAY(&ah->iniModes, ar5416Modes_9100,
-			       ARRAY_SIZE(ar5416Modes_9100), 6);
-		INIT_INI_ARRAY(&ah->iniCommon, ar5416Common_9100,
-			       ARRAY_SIZE(ar5416Common_9100), 2);
-		INIT_INI_ARRAY(&ah->iniBank0, ar5416Bank0_9100,
-			       ARRAY_SIZE(ar5416Bank0_9100), 2);
-		INIT_INI_ARRAY(&ah->iniBB_RfGain, ar5416BB_RfGain_9100,
-			       ARRAY_SIZE(ar5416BB_RfGain_9100), 3);
-		INIT_INI_ARRAY(&ah->iniBank1, ar5416Bank1_9100,
-			       ARRAY_SIZE(ar5416Bank1_9100), 2);
-		INIT_INI_ARRAY(&ah->iniBank2, ar5416Bank2_9100,
-			       ARRAY_SIZE(ar5416Bank2_9100), 2);
-		INIT_INI_ARRAY(&ah->iniBank3, ar5416Bank3_9100,
-			       ARRAY_SIZE(ar5416Bank3_9100), 3);
-		INIT_INI_ARRAY(&ah->iniBank6, ar5416Bank6_9100,
-			       ARRAY_SIZE(ar5416Bank6_9100), 3);
-		INIT_INI_ARRAY(&ah->iniBank6TPC, ar5416Bank6TPC_9100,
-			       ARRAY_SIZE(ar5416Bank6TPC_9100), 3);
-		INIT_INI_ARRAY(&ah->iniBank7, ar5416Bank7_9100,
-			       ARRAY_SIZE(ar5416Bank7_9100), 2);
-		INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac_9100,
-			       ARRAY_SIZE(ar5416Addac_9100), 2);
-	} else {
-		INIT_INI_ARRAY(&ah->iniModes, ar5416Modes,
-			       ARRAY_SIZE(ar5416Modes), 6);
-		INIT_INI_ARRAY(&ah->iniCommon, ar5416Common,
-			       ARRAY_SIZE(ar5416Common), 2);
-		INIT_INI_ARRAY(&ah->iniBank0, ar5416Bank0,
-			       ARRAY_SIZE(ar5416Bank0), 2);
-		INIT_INI_ARRAY(&ah->iniBB_RfGain, ar5416BB_RfGain,
-			       ARRAY_SIZE(ar5416BB_RfGain), 3);
-		INIT_INI_ARRAY(&ah->iniBank1, ar5416Bank1,
-			       ARRAY_SIZE(ar5416Bank1), 2);
-		INIT_INI_ARRAY(&ah->iniBank2, ar5416Bank2,
-			       ARRAY_SIZE(ar5416Bank2), 2);
-		INIT_INI_ARRAY(&ah->iniBank3, ar5416Bank3,
-			       ARRAY_SIZE(ar5416Bank3), 3);
-		INIT_INI_ARRAY(&ah->iniBank6, ar5416Bank6,
-			       ARRAY_SIZE(ar5416Bank6), 3);
-		INIT_INI_ARRAY(&ah->iniBank6TPC, ar5416Bank6TPC,
-			       ARRAY_SIZE(ar5416Bank6TPC), 3);
-		INIT_INI_ARRAY(&ah->iniBank7, ar5416Bank7,
-			       ARRAY_SIZE(ar5416Bank7), 2);
-		INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac,
-			       ARRAY_SIZE(ar5416Addac), 2);
-	}
-}
-
-/* AR9003 2.0 - new INI format (pre, core, post arrays per subsystem) */
-static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
-{
-	/* mac */
-	INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0);
-	INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE],
-		       ar9300_2p0_mac_core,
-		       ARRAY_SIZE(ar9300_2p0_mac_core), 2);
-	INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST],
-		       ar9300_2p0_mac_postamble,
-		       ARRAY_SIZE(ar9300_2p0_mac_postamble), 5);
-
-	/* bb */
-	INIT_INI_ARRAY(&ah->iniBB[ATH_INI_PRE], NULL, 0, 0);
-	INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE],
-		       ar9300_2p0_baseband_core,
-		       ARRAY_SIZE(ar9300_2p0_baseband_core), 2);
-	INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST],
-		       ar9300_2p0_baseband_postamble,
-		       ARRAY_SIZE(ar9300_2p0_baseband_postamble), 5);
-
-	/* radio */
-	INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_PRE], NULL, 0, 0);
-	INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE],
-		       ar9300_2p0_radio_core,
-		       ARRAY_SIZE(ar9300_2p0_radio_core), 2);
-	INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST],
-		       ar9300_2p0_radio_postamble,
-		       ARRAY_SIZE(ar9300_2p0_radio_postamble), 5);
-
-	/* soc */
-	INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE],
-		       ar9300_2p0_soc_preamble,
-		       ARRAY_SIZE(ar9300_2p0_soc_preamble), 2);
-	INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_CORE], NULL, 0, 0);
-	INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST],
-		       ar9300_2p0_soc_postamble,
-		       ARRAY_SIZE(ar9300_2p0_soc_postamble), 5);
-
-	/* rx/tx gain */
-	INIT_INI_ARRAY(&ah->iniModesRxGain,
-		       ar9300Common_rx_gain_table_2p0,
-		       ARRAY_SIZE(ar9300Common_rx_gain_table_2p0), 2);
-	INIT_INI_ARRAY(&ah->iniModesTxGain,
-		       ar9300Modes_lowest_ob_db_tx_gain_table_2p0,
-		       ARRAY_SIZE(ar9300Modes_lowest_ob_db_tx_gain_table_2p0),
-		       5);
-
-	/* Load PCIE SERDES settings from INI */
-
-	/* Awake Setting */
-
-	INIT_INI_ARRAY(&ah->iniPcieSerdes,
-		       ar9300PciePhy_pll_on_clkreq_disable_L1_2p0,
-		       ARRAY_SIZE(ar9300PciePhy_pll_on_clkreq_disable_L1_2p0),
-		       2);
-
-	/* Sleep Setting */
-
-	INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower,
-		       ar9300PciePhy_clkreq_enable_L1_2p0,
-		       ARRAY_SIZE(ar9300PciePhy_clkreq_enable_L1_2p0),
-		       2);
-
-	/* Fast clock modal settings */
-	INIT_INI_ARRAY(&ah->iniModesAdditional,
-		       ar9300Modes_fast_clock_2p0,
-		       ARRAY_SIZE(ar9300Modes_fast_clock_2p0),
-		       3);
-}
-
 static void ath9k_hw_init_mode_gain_regs(struct ath_hw *ah)
 {
 	if (AR_SREV_9287_11_OR_LATER(ah))
@@ -2180,140 +1884,6 @@ bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode)
 }
 EXPORT_SYMBOL(ath9k_hw_setpower);
 
-/*
- * Helper for ASPM support.
- *
- * Disable PLL when in L0s as well as receiver clock when in L1.
- * This power saving option must be enabled through the SerDes.
- *
- * Programming the SerDes must go through the same 288 bit serial shift
- * register as the other analog registers.  Hence the 9 writes.
- */
-static void ar9002_hw_configpcipowersave(struct ath_hw *ah,
-					 int restore,
-					 int power_off)
-{
-	u8 i;
-	u32 val;
-
-	if (ah->is_pciexpress != true)
-		return;
-
-	/* Do not touch SerDes registers */
-	if (ah->config.pcie_powersave_enable == 2)
-		return;
-
-	/* Nothing to do on restore for 11N */
-	if (!restore) {
-		if (AR_SREV_9280_20_OR_LATER(ah)) {
-			/*
-			 * AR9280 2.0 or later chips use SerDes values from the
-			 * initvals.h initialized depending on chipset during
-			 * __ath9k_hw_init()
-			 */
-			for (i = 0; i < ah->iniPcieSerdes.ia_rows; i++) {
-				REG_WRITE(ah, INI_RA(&ah->iniPcieSerdes, i, 0),
-					  INI_RA(&ah->iniPcieSerdes, i, 1));
-			}
-		} else if (AR_SREV_9280(ah) &&
-			   (ah->hw_version.macRev == AR_SREV_REVISION_9280_10)) {
-			REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fd00);
-			REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924);
-
-			/* RX shut off when elecidle is asserted */
-			REG_WRITE(ah, AR_PCIE_SERDES, 0xa8000019);
-			REG_WRITE(ah, AR_PCIE_SERDES, 0x13160820);
-			REG_WRITE(ah, AR_PCIE_SERDES, 0xe5980560);
-
-			/* Shut off CLKREQ active in L1 */
-			if (ah->config.pcie_clock_req)
-				REG_WRITE(ah, AR_PCIE_SERDES, 0x401deffc);
-			else
-				REG_WRITE(ah, AR_PCIE_SERDES, 0x401deffd);
-
-			REG_WRITE(ah, AR_PCIE_SERDES, 0x1aaabe40);
-			REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554);
-			REG_WRITE(ah, AR_PCIE_SERDES, 0x00043007);
-
-			/* Load the new settings */
-			REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
-
-		} else {
-			REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fc00);
-			REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924);
-
-			/* RX shut off when elecidle is asserted */
-			REG_WRITE(ah, AR_PCIE_SERDES, 0x28000039);
-			REG_WRITE(ah, AR_PCIE_SERDES, 0x53160824);
-			REG_WRITE(ah, AR_PCIE_SERDES, 0xe5980579);
-
-			/*
-			 * Ignore ah->ah_config.pcie_clock_req setting for
-			 * pre-AR9280 11n
-			 */
-			REG_WRITE(ah, AR_PCIE_SERDES, 0x001defff);
-
-			REG_WRITE(ah, AR_PCIE_SERDES, 0x1aaabe40);
-			REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554);
-			REG_WRITE(ah, AR_PCIE_SERDES, 0x000e3007);
-
-			/* Load the new settings */
-			REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
-		}
-
-		udelay(1000);
-
-		/* set bit 19 to allow forcing of pcie core into L1 state */
-		REG_SET_BIT(ah, AR_PCIE_PM_CTRL, AR_PCIE_PM_CTRL_ENA);
-
-		/* Several PCIe massages to ensure proper behaviour */
-		if (ah->config.pcie_waen) {
-			val = ah->config.pcie_waen;
-			if (!power_off)
-				val &= (~AR_WA_D3_L1_DISABLE);
-		} else {
-			if (AR_SREV_9285(ah) || AR_SREV_9271(ah) ||
-			    AR_SREV_9287(ah)) {
-				val = AR9285_WA_DEFAULT;
-				if (!power_off)
-					val &= (~AR_WA_D3_L1_DISABLE);
-			} else if (AR_SREV_9280(ah)) {
-				/*
-				 * On AR9280 chips bit 22 of 0x4004 needs to be
-				 * set otherwise card may disappear.
-				 */
-				val = AR9280_WA_DEFAULT;
-				if (!power_off)
-					val &= (~AR_WA_D3_L1_DISABLE);
-			} else
-				val = AR_WA_DEFAULT;
-		}
-
-		REG_WRITE(ah, AR_WA, val);
-	}
-
-	if (power_off) {
-		/*
-		 * Set PCIe workaround bits
-		 * bit 14 in WA register (disable L1) should only
-		 * be set when device enters D3 and be cleared
-		 * when device comes back to D0.
-		 */
-		if (ah->config.pcie_waen) {
-			if (ah->config.pcie_waen & AR_WA_D3_L1_DISABLE)
-				REG_SET_BIT(ah, AR_WA, AR_WA_D3_L1_DISABLE);
-		} else {
-			if (((AR_SREV_9285(ah) || AR_SREV_9271(ah) ||
-			      AR_SREV_9287(ah)) &&
-			     (AR9285_WA_DEFAULT & AR_WA_D3_L1_DISABLE)) ||
-			    (AR_SREV_9280(ah) &&
-			     (AR9280_WA_DEFAULT & AR_WA_D3_L1_DISABLE))) {
-				REG_SET_BIT(ah, AR_WA, AR_WA_D3_L1_DISABLE);
-			}
-		}
-	}
-}
-
 /**********************/
 /* Interrupt Handling */
 /**********************/
@@ -2595,37 +2165,6 @@ enum ath9k_int ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints)
 }
 EXPORT_SYMBOL(ath9k_hw_set_interrupts);
 
-/*
- * Helper for ASPM support.
- *
- * Disable PLL when in L0s as well as receiver clock when in L1.
- * This power saving option must be enabled through the SerDes.
- *
- * Programming the SerDes must go through the same 288 bit serial shift
- * register as the other analog registers.  Hence the 9 writes.
- */
-static void ar9003_hw_configpcipowersave(struct ath_hw *ah,
-					 int restore,
-					 int power_off)
-{
-	if (ah->is_pciexpress != true)
-		return;
-
-	/* Do not touch SerDes registers */
-	if (ah->config.pcie_powersave_enable == 2)
-		return;
-
-	/* Nothing to do on restore for 11N */
-	if (!restore) {
-		/* set bit 19 to allow forcing of pcie core into L1 state */
-		REG_SET_BIT(ah, AR_PCIE_PM_CTRL, AR_PCIE_PM_CTRL_ENA);
-
-		/* Several PCIe massages to ensure proper behaviour */
-		if (ah->config.pcie_waen)
-			REG_WRITE(ah, AR_WA, ah->config.pcie_waen);
-	}
-}
-
 /*******************/
 /* Beacon Handling */
 /*******************/
@@ -3636,38 +3175,3 @@ void ath9k_hw_name(struct ath_hw *ah, char *hw_name, size_t len)
 	hw_name[used] = '\0';
 }
 EXPORT_SYMBOL(ath9k_hw_name);
-
-/* Sets up the AR5008/AR9001/AR9002 hardware familiy callbacks */
-static 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->macversion_supported = ar9002_hw_macversion_supported;
-
-	ops->config_pci_powersave = ar9002_hw_configpcipowersave;
-
-	ar5008_hw_attach_phy_ops(ah);
-	if (AR_SREV_9280_10_OR_LATER(ah))
-		ar9002_hw_attach_phy_ops(ah);
-
-	ar9002_hw_attach_calib_ops(ah);
-	ar9002_hw_attach_mac_ops(ah);
-}
-
-/* Sets up the AR9003 hardware familiy callbacks */
-static 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->macversion_supported = ar9003_hw_macversion_supported;
-
-	ops->config_pci_powersave = ar9003_hw_configpcipowersave;
-
-	ar9003_hw_attach_phy_ops(ah);
-	ar9003_hw_attach_calib_ops(ah);
-	ar9003_hw_attach_mac_ops(ah);
-}
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 7ef93c8..9325095 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008-2009 Atheros Communications Inc.
+ * Copyright (c) 2008-2010 Atheros Communications Inc.
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -852,6 +852,9 @@ void ar9003_hw_attach_phy_ops(struct ath_hw *ah);
 void ar9002_hw_attach_calib_ops(struct ath_hw *ah);
 void ar9003_hw_attach_calib_ops(struct ath_hw *ah);
 
+void ar9002_hw_attach_ops(struct ath_hw *ah);
+void ar9003_hw_attach_ops(struct ath_hw *ah);
+
 #define ATH_PCIE_CAP_LINK_CTRL	0x70
 #define ATH_PCIE_CAP_LINK_L0S	1
 #define ATH_PCIE_CAP_LINK_L1	2
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 103+ messages in thread

* [PATCH v3 59/97] ath9k_hw: move the cck channel 14 INI to the AR9002 hw code
  2010-04-15 21:38 [PATCH v3 00/97] ath9k: add AR9003 support Luis R. Rodriguez
                   ` (57 preceding siblings ...)
  2010-04-15 21:39 ` [PATCH v3 58/97] ath9k_hw: split the generic hardware code by hardware family Luis R. Rodriguez
@ 2010-04-15 21:39 ` Luis R. Rodriguez
  2010-04-15 21:39 ` [PATCH v3 60/97] ath9k_hw: move TX/RX gain INI stuff to its own hardware family code Luis R. Rodriguez
                   ` (37 subsequent siblings)
  96 siblings, 0 replies; 103+ messages in thread
From: Luis R. Rodriguez @ 2010-04-15 21:39 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Luis R. Rodriguez

This is specific to the AR9002 family only.

Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/ar9002_hw.c |   15 +++++++++++++++
 drivers/net/wireless/ath/ath9k/hw.c        |   11 ++---------
 drivers/net/wireless/ath/ath9k/hw.h        |    2 ++
 3 files changed, 19 insertions(+), 9 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ar9002_hw.c b/drivers/net/wireless/ath/ath9k/ar9002_hw.c
index aa52fd7..ff81efa 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_hw.c
+++ b/drivers/net/wireless/ath/ath9k/ar9002_hw.c
@@ -229,6 +229,21 @@ static void ar9002_hw_init_mode_regs(struct ath_hw *ah)
 	}
 }
 
+/* Support for Japan ch.14 (2484) spread */
+void ar9002_hw_cck_chan14_spread(struct ath_hw *ah)
+{
+	if (AR_SREV_9287_11_OR_LATER(ah)) {
+		INIT_INI_ARRAY(&ah->iniCckfirNormal,
+		       ar9287Common_normal_cck_fir_coeff_92871_1,
+		       ARRAY_SIZE(ar9287Common_normal_cck_fir_coeff_92871_1),
+		       2);
+		INIT_INI_ARRAY(&ah->iniCckfirJapan2484,
+		       ar9287Common_japan_2484_cck_fir_coeff_92871_1,
+		       ARRAY_SIZE(ar9287Common_japan_2484_cck_fir_coeff_92871_1),
+		       2);
+	}
+}
+
 /*
  * Helper for ASPM support.
  *
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 672c5ad..a43e587 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -713,15 +713,8 @@ static int __ath9k_hw_init(struct ath_hw *ah)
 	else
 		ath9k_hw_disablepcie(ah);
 
-	/* Support for Japan ch.14 (2484) spread */
-	if (AR_SREV_9287_11_OR_LATER(ah)) {
-		INIT_INI_ARRAY(&ah->iniCckfirNormal,
-		       ar9287Common_normal_cck_fir_coeff_92871_1,
-		       ARRAY_SIZE(ar9287Common_normal_cck_fir_coeff_92871_1), 2);
-		INIT_INI_ARRAY(&ah->iniCckfirJapan2484,
-		       ar9287Common_japan_2484_cck_fir_coeff_92871_1,
-		       ARRAY_SIZE(ar9287Common_japan_2484_cck_fir_coeff_92871_1), 2);
-	}
+	if (!AR_SREV_9300_20_OR_LATER(ah))
+		ar9002_hw_cck_chan14_spread(ah);
 
 	r = ath9k_hw_post_init(ah);
 	if (r)
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 9325095..56c5735 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -838,6 +838,8 @@ void ath9k_hw_htc_resetinit(struct ath_hw *ah);
 void ath9k_hw_get_delta_slope_vals(struct ath_hw *ah, u32 coef_scaled,
 				   u32 *coef_mantissa, u32 *coef_exponent);
 
+void ar9002_hw_cck_chan14_spread(struct ath_hw *ah);
+
 /*
  * Code specifric to AR9003, we stuff these here to avoid callbacks
  * for older families
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 103+ messages in thread

* [PATCH v3 60/97] ath9k_hw: move TX/RX gain INI stuff to its own hardware family code
  2010-04-15 21:38 [PATCH v3 00/97] ath9k: add AR9003 support Luis R. Rodriguez
                   ` (58 preceding siblings ...)
  2010-04-15 21:39 ` [PATCH v3 59/97] ath9k_hw: move the cck channel 14 INI to the AR9002 hw code Luis R. Rodriguez
@ 2010-04-15 21:39 ` Luis R. Rodriguez
  2010-04-15 21:39 ` [PATCH v3 61/97] ath9k_hw: Abstract the routine which returns interrupt status Luis R. Rodriguez
                   ` (36 subsequent siblings)
  96 siblings, 0 replies; 103+ messages in thread
From: Luis R. Rodriguez @ 2010-04-15 21:39 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Luis R. Rodriguez

The AR9003 TX/RX gain is currently initialized with the other
components, so for now AR9003 does not implment this callback,
after hardware bring up  we can test moving the TX/RX gain there
as well and if it works well move them to its own callback as
well.

Since all INI stuff is now moved out hw.c no longer needs to
include and touch any original INI headers/structs.

Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/ar9002_hw.c |  106 ++++++++++++++++++++++++++
 drivers/net/wireless/ath/ath9k/ar9003_hw.c |    4 +
 drivers/net/wireless/ath/ath9k/hw.c        |  112 ++--------------------------
 drivers/net/wireless/ath/ath9k/hw.h        |    2 +
 4 files changed, 120 insertions(+), 104 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ar9002_hw.c b/drivers/net/wireless/ath/ath9k/ar9002_hw.c
index ff81efa..eeaea26 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_hw.c
+++ b/drivers/net/wireless/ath/ath9k/ar9002_hw.c
@@ -244,6 +244,111 @@ void ar9002_hw_cck_chan14_spread(struct ath_hw *ah)
 	}
 }
 
+static void ar9280_20_hw_init_rxgain_ini(struct ath_hw *ah)
+{
+	u32 rxgain_type;
+
+	if (ah->eep_ops->get_eeprom(ah, EEP_MINOR_REV) >=
+	    AR5416_EEP_MINOR_VER_17) {
+		rxgain_type = ah->eep_ops->get_eeprom(ah, EEP_RXGAIN_TYPE);
+
+		if (rxgain_type == AR5416_EEP_RXGAIN_13DB_BACKOFF)
+			INIT_INI_ARRAY(&ah->iniModesRxGain,
+			ar9280Modes_backoff_13db_rxgain_9280_2,
+			ARRAY_SIZE(ar9280Modes_backoff_13db_rxgain_9280_2), 6);
+		else if (rxgain_type == AR5416_EEP_RXGAIN_23DB_BACKOFF)
+			INIT_INI_ARRAY(&ah->iniModesRxGain,
+			ar9280Modes_backoff_23db_rxgain_9280_2,
+			ARRAY_SIZE(ar9280Modes_backoff_23db_rxgain_9280_2), 6);
+		else
+			INIT_INI_ARRAY(&ah->iniModesRxGain,
+			ar9280Modes_original_rxgain_9280_2,
+			ARRAY_SIZE(ar9280Modes_original_rxgain_9280_2), 6);
+	} else {
+		INIT_INI_ARRAY(&ah->iniModesRxGain,
+			ar9280Modes_original_rxgain_9280_2,
+			ARRAY_SIZE(ar9280Modes_original_rxgain_9280_2), 6);
+	}
+}
+
+static void ar9280_20_hw_init_txgain_ini(struct ath_hw *ah)
+{
+	u32 txgain_type;
+
+	if (ah->eep_ops->get_eeprom(ah, EEP_MINOR_REV) >=
+	    AR5416_EEP_MINOR_VER_19) {
+		txgain_type = ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE);
+
+		if (txgain_type == AR5416_EEP_TXGAIN_HIGH_POWER)
+			INIT_INI_ARRAY(&ah->iniModesTxGain,
+			ar9280Modes_high_power_tx_gain_9280_2,
+			ARRAY_SIZE(ar9280Modes_high_power_tx_gain_9280_2), 6);
+		else
+			INIT_INI_ARRAY(&ah->iniModesTxGain,
+			ar9280Modes_original_tx_gain_9280_2,
+			ARRAY_SIZE(ar9280Modes_original_tx_gain_9280_2), 6);
+	} else {
+		INIT_INI_ARRAY(&ah->iniModesTxGain,
+		ar9280Modes_original_tx_gain_9280_2,
+		ARRAY_SIZE(ar9280Modes_original_tx_gain_9280_2), 6);
+	}
+}
+
+static void ar9002_hw_init_mode_gain_regs(struct ath_hw *ah)
+{
+	if (AR_SREV_9287_11_OR_LATER(ah))
+		INIT_INI_ARRAY(&ah->iniModesRxGain,
+		ar9287Modes_rx_gain_9287_1_1,
+		ARRAY_SIZE(ar9287Modes_rx_gain_9287_1_1), 6);
+	else if (AR_SREV_9287_10(ah))
+		INIT_INI_ARRAY(&ah->iniModesRxGain,
+		ar9287Modes_rx_gain_9287_1_0,
+		ARRAY_SIZE(ar9287Modes_rx_gain_9287_1_0), 6);
+	else if (AR_SREV_9280_20(ah))
+		ar9280_20_hw_init_rxgain_ini(ah);
+
+	if (AR_SREV_9287_11_OR_LATER(ah)) {
+		INIT_INI_ARRAY(&ah->iniModesTxGain,
+		ar9287Modes_tx_gain_9287_1_1,
+		ARRAY_SIZE(ar9287Modes_tx_gain_9287_1_1), 6);
+	} else if (AR_SREV_9287_10(ah)) {
+		INIT_INI_ARRAY(&ah->iniModesTxGain,
+		ar9287Modes_tx_gain_9287_1_0,
+		ARRAY_SIZE(ar9287Modes_tx_gain_9287_1_0), 6);
+	} else if (AR_SREV_9280_20(ah)) {
+		ar9280_20_hw_init_txgain_ini(ah);
+	} else if (AR_SREV_9285_12_OR_LATER(ah)) {
+		u32 txgain_type = ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE);
+
+		/* txgain table */
+		if (txgain_type == AR5416_EEP_TXGAIN_HIGH_POWER) {
+			if (AR_SREV_9285E_20(ah)) {
+				INIT_INI_ARRAY(&ah->iniModesTxGain,
+				ar9285Modes_XE2_0_high_power,
+				ARRAY_SIZE(
+				  ar9285Modes_XE2_0_high_power), 6);
+			} else {
+				INIT_INI_ARRAY(&ah->iniModesTxGain,
+				ar9285Modes_high_power_tx_gain_9285_1_2,
+				ARRAY_SIZE(
+				  ar9285Modes_high_power_tx_gain_9285_1_2), 6);
+			}
+		} else {
+			if (AR_SREV_9285E_20(ah)) {
+				INIT_INI_ARRAY(&ah->iniModesTxGain,
+				ar9285Modes_XE2_0_normal_power,
+				ARRAY_SIZE(
+				  ar9285Modes_XE2_0_normal_power), 6);
+			} else {
+				INIT_INI_ARRAY(&ah->iniModesTxGain,
+				ar9285Modes_original_tx_gain_9285_1_2,
+				ARRAY_SIZE(
+				  ar9285Modes_original_tx_gain_9285_1_2), 6);
+			}
+		}
+	}
+}
+
 /*
  * Helper for ASPM support.
  *
@@ -385,6 +490,7 @@ void ar9002_hw_attach_ops(struct ath_hw *ah)
 	struct ath_hw_ops *ops = ath9k_hw_ops(ah);
 
 	priv_ops->init_mode_regs = ar9002_hw_init_mode_regs;
+	priv_ops->init_mode_gain_regs = ar9002_hw_init_mode_gain_regs;
 	priv_ops->macversion_supported = ar9002_hw_macversion_supported;
 
 	ops->config_pci_powersave = ar9002_hw_configpcipowersave;
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_hw.c b/drivers/net/wireless/ath/ath9k/ar9003_hw.c
index 6111bdb..1984b4f 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_hw.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_hw.c
@@ -31,6 +31,10 @@ static bool ar9003_hw_macversion_supported(u32 macversion)
 }
 
 /* AR9003 2.0 - new INI format (pre, core, post arrays per subsystem) */
+/*
+ * XXX: move TX/RX gain INI to its own init_mode_gain_regs after
+ * ensuring it does not affect hardware bring up
+ */
 static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
 {
 	/* mac */
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index a43e587..5d6df49 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -21,7 +21,6 @@
 #include "hw.h"
 #include "hw-ops.h"
 #include "rc.h"
-#include "ar9002_initvals.h"
 
 #define ATH9K_CLOCK_RATE_CCK		22
 #define ATH9K_CLOCK_RATE_5GHZ_OFDM	40
@@ -71,6 +70,14 @@ static u32 ath9k_hw_compute_pll_control(struct ath_hw *ah,
 	return ath9k_hw_private_ops(ah)->compute_pll_control(ah, chan);
 }
 
+static void ath9k_hw_init_mode_gain_regs(struct ath_hw *ah)
+{
+	if (!ath9k_hw_private_ops(ah)->init_mode_gain_regs)
+		return;
+
+	ath9k_hw_private_ops(ah)->init_mode_gain_regs(ah);
+}
+
 /********************/
 /* Helper Functions */
 /********************/
@@ -480,54 +487,6 @@ static int ath9k_hw_init_macaddr(struct ath_hw *ah)
 	return 0;
 }
 
-static void ath9k_hw_init_rxgain_ini(struct ath_hw *ah)
-{
-	u32 rxgain_type;
-
-	if (ah->eep_ops->get_eeprom(ah, EEP_MINOR_REV) >= AR5416_EEP_MINOR_VER_17) {
-		rxgain_type = ah->eep_ops->get_eeprom(ah, EEP_RXGAIN_TYPE);
-
-		if (rxgain_type == AR5416_EEP_RXGAIN_13DB_BACKOFF)
-			INIT_INI_ARRAY(&ah->iniModesRxGain,
-			ar9280Modes_backoff_13db_rxgain_9280_2,
-			ARRAY_SIZE(ar9280Modes_backoff_13db_rxgain_9280_2), 6);
-		else if (rxgain_type == AR5416_EEP_RXGAIN_23DB_BACKOFF)
-			INIT_INI_ARRAY(&ah->iniModesRxGain,
-			ar9280Modes_backoff_23db_rxgain_9280_2,
-			ARRAY_SIZE(ar9280Modes_backoff_23db_rxgain_9280_2), 6);
-		else
-			INIT_INI_ARRAY(&ah->iniModesRxGain,
-			ar9280Modes_original_rxgain_9280_2,
-			ARRAY_SIZE(ar9280Modes_original_rxgain_9280_2), 6);
-	} else {
-		INIT_INI_ARRAY(&ah->iniModesRxGain,
-			ar9280Modes_original_rxgain_9280_2,
-			ARRAY_SIZE(ar9280Modes_original_rxgain_9280_2), 6);
-	}
-}
-
-static void ath9k_hw_init_txgain_ini(struct ath_hw *ah)
-{
-	u32 txgain_type;
-
-	if (ah->eep_ops->get_eeprom(ah, EEP_MINOR_REV) >= AR5416_EEP_MINOR_VER_19) {
-		txgain_type = ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE);
-
-		if (txgain_type == AR5416_EEP_TXGAIN_HIGH_POWER)
-			INIT_INI_ARRAY(&ah->iniModesTxGain,
-			ar9280Modes_high_power_tx_gain_9280_2,
-			ARRAY_SIZE(ar9280Modes_high_power_tx_gain_9280_2), 6);
-		else
-			INIT_INI_ARRAY(&ah->iniModesTxGain,
-			ar9280Modes_original_tx_gain_9280_2,
-			ARRAY_SIZE(ar9280Modes_original_tx_gain_9280_2), 6);
-	} else {
-		INIT_INI_ARRAY(&ah->iniModesTxGain,
-		ar9280Modes_original_tx_gain_9280_2,
-		ARRAY_SIZE(ar9280Modes_original_tx_gain_9280_2), 6);
-	}
-}
-
 static int ath9k_hw_post_init(struct ath_hw *ah)
 {
 	int ecode;
@@ -566,61 +525,6 @@ static int ath9k_hw_post_init(struct ath_hw *ah)
 	return 0;
 }
 
-static void ath9k_hw_init_mode_gain_regs(struct ath_hw *ah)
-{
-	if (AR_SREV_9287_11_OR_LATER(ah))
-		INIT_INI_ARRAY(&ah->iniModesRxGain,
-		ar9287Modes_rx_gain_9287_1_1,
-		ARRAY_SIZE(ar9287Modes_rx_gain_9287_1_1), 6);
-	else if (AR_SREV_9287_10(ah))
-		INIT_INI_ARRAY(&ah->iniModesRxGain,
-		ar9287Modes_rx_gain_9287_1_0,
-		ARRAY_SIZE(ar9287Modes_rx_gain_9287_1_0), 6);
-	else if (AR_SREV_9280_20(ah))
-		ath9k_hw_init_rxgain_ini(ah);
-
-	if (AR_SREV_9287_11_OR_LATER(ah)) {
-		INIT_INI_ARRAY(&ah->iniModesTxGain,
-		ar9287Modes_tx_gain_9287_1_1,
-		ARRAY_SIZE(ar9287Modes_tx_gain_9287_1_1), 6);
-	} else if (AR_SREV_9287_10(ah)) {
-		INIT_INI_ARRAY(&ah->iniModesTxGain,
-		ar9287Modes_tx_gain_9287_1_0,
-		ARRAY_SIZE(ar9287Modes_tx_gain_9287_1_0), 6);
-	} else if (AR_SREV_9280_20(ah)) {
-		ath9k_hw_init_txgain_ini(ah);
-	} else if (AR_SREV_9285_12_OR_LATER(ah)) {
-		u32 txgain_type = ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE);
-
-		/* txgain table */
-		if (txgain_type == AR5416_EEP_TXGAIN_HIGH_POWER) {
-			if (AR_SREV_9285E_20(ah)) {
-				INIT_INI_ARRAY(&ah->iniModesTxGain,
-				ar9285Modes_XE2_0_high_power,
-				ARRAY_SIZE(
-				  ar9285Modes_XE2_0_high_power), 6);
-			} else {
-				INIT_INI_ARRAY(&ah->iniModesTxGain,
-				ar9285Modes_high_power_tx_gain_9285_1_2,
-				ARRAY_SIZE(
-				  ar9285Modes_high_power_tx_gain_9285_1_2), 6);
-			}
-		} else {
-			if (AR_SREV_9285E_20(ah)) {
-				INIT_INI_ARRAY(&ah->iniModesTxGain,
-				ar9285Modes_XE2_0_normal_power,
-				ARRAY_SIZE(
-				  ar9285Modes_XE2_0_normal_power), 6);
-			} else {
-				INIT_INI_ARRAY(&ah->iniModesTxGain,
-				ar9285Modes_original_tx_gain_9285_1_2,
-				ARRAY_SIZE(
-				  ar9285Modes_original_tx_gain_9285_1_2), 6);
-			}
-		}
-	}
-}
-
 static void ath9k_hw_init_eeprom_fix(struct ath_hw *ah)
 {
 	struct base_eep_header *pBase = &(ah->eeprom.def.baseEepHeader);
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 56c5735..b27e76b 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -473,6 +473,7 @@ struct ath_gen_timer_table {
  * @init_cal: starts actual calibration
  *
  * @init_mode_regs: Initializes mode registers
+ * @init_mode_gain_regs: Initialize TX/RX gain registers
  * @macversion_supported: If this specific mac revision is supported
  *
  * @rf_set_freq: change frequency
@@ -491,6 +492,7 @@ struct ath_hw_private_ops {
 	bool (*init_cal)(struct ath_hw *ah, struct ath9k_channel *chan);
 
 	void (*init_mode_regs)(struct ath_hw *ah);
+	void (*init_mode_gain_regs)(struct ath_hw *ah);
 	bool (*macversion_supported)(u32 macversion);
 	void (*setup_calibration)(struct ath_hw *ah,
 				  struct ath9k_cal_list *currCal);
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 103+ messages in thread

* [PATCH v3 61/97] ath9k_hw: Abstract the routine which returns interrupt status
  2010-04-15 21:38 [PATCH v3 00/97] ath9k: add AR9003 support Luis R. Rodriguez
                   ` (59 preceding siblings ...)
  2010-04-15 21:39 ` [PATCH v3 60/97] ath9k_hw: move TX/RX gain INI stuff to its own hardware family code Luis R. Rodriguez
@ 2010-04-15 21:39 ` Luis R. Rodriguez
  2010-04-15 21:39 ` [PATCH v3 62/97] ath9k_hw: Initialize interrupt mask for AR9003 Luis R. Rodriguez
                   ` (35 subsequent siblings)
  96 siblings, 0 replies; 103+ messages in thread
From: Luis R. Rodriguez @ 2010-04-15 21:39 UTC (permalink / raw)
  To: linville
  Cc: linux-wireless, Vasanthakumar Thiagarajan, Luis R. Rodriguez,
	Felix Fietkau

From: Vasanthakumar Thiagarajan <vasanth@atheros.com>

Also move interrupt related code to mac.c

Signed-off-by: Vasanthakumar Thiagarajan <vasanth@atheros.com>
Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
 drivers/net/wireless/ath/ath9k/ar9003_mac.c |    6 +
 drivers/net/wireless/ath/ath9k/hw-ops.h     |    5 +
 drivers/net/wireless/ath/ath9k/hw.c         |  281 --------------------------
 drivers/net/wireless/ath/ath9k/hw.h         |    7 +-
 drivers/net/wireless/ath/ath9k/mac.c        |  290 +++++++++++++++++++++++++++
 drivers/net/wireless/ath/ath9k/mac.h        |    5 +
 drivers/net/wireless/ath/ath9k/reg.h        |    2 +
 7 files changed, 310 insertions(+), 286 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.c b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
index b229597..15f1b0f 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
@@ -30,6 +30,11 @@ static void ar9003_hw_get_desc_link(void *ds, u32 **ds_link)
 	*ds_link = &((struct ar9003_txc *) ds)->link;
 }
 
+static bool ar9003_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked)
+{
+	return true;
+}
+
 void ar9003_hw_attach_mac_ops(struct ath_hw *hw)
 {
 	struct ath_hw_ops *ops = ath9k_hw_ops(hw);
@@ -37,6 +42,7 @@ void ar9003_hw_attach_mac_ops(struct ath_hw *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;
 }
 
 void ath9k_hw_set_rx_bufsize(struct ath_hw *ah, u16 buf_size)
diff --git a/drivers/net/wireless/ath/ath9k/hw-ops.h b/drivers/net/wireless/ath/ath9k/hw-ops.h
index 3848c0d..b777fd1 100644
--- a/drivers/net/wireless/ath/ath9k/hw-ops.h
+++ b/drivers/net/wireless/ath/ath9k/hw-ops.h
@@ -52,6 +52,11 @@ static inline bool ath9k_hw_calibrate(struct ath_hw *ah,
 	return ath9k_hw_ops(ah)->calibrate(ah, chan, rxchainmask, longcal);
 }
 
+static inline bool ath9k_hw_getisr(struct ath_hw *ah, enum ath9k_int *masked)
+{
+	return ath9k_hw_ops(ah)->get_isr(ah, masked);
+}
+
 /* Private hardware call ops */
 
 /* PHY ops */
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 5d6df49..ab3a87b 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -1781,287 +1781,6 @@ bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode)
 }
 EXPORT_SYMBOL(ath9k_hw_setpower);
 
-/**********************/
-/* Interrupt Handling */
-/**********************/
-
-bool ath9k_hw_intrpend(struct ath_hw *ah)
-{
-	u32 host_isr;
-
-	if (AR_SREV_9100(ah))
-		return true;
-
-	host_isr = REG_READ(ah, AR_INTR_ASYNC_CAUSE);
-	if ((host_isr & AR_INTR_MAC_IRQ) && (host_isr != AR_INTR_SPURIOUS))
-		return true;
-
-	host_isr = REG_READ(ah, AR_INTR_SYNC_CAUSE);
-	if ((host_isr & AR_INTR_SYNC_DEFAULT)
-	    && (host_isr != AR_INTR_SPURIOUS))
-		return true;
-
-	return false;
-}
-EXPORT_SYMBOL(ath9k_hw_intrpend);
-
-bool ath9k_hw_getisr(struct ath_hw *ah, enum ath9k_int *masked)
-{
-	u32 isr = 0;
-	u32 mask2 = 0;
-	struct ath9k_hw_capabilities *pCap = &ah->caps;
-	u32 sync_cause = 0;
-	bool fatal_int = false;
-	struct ath_common *common = ath9k_hw_common(ah);
-
-	if (!AR_SREV_9100(ah)) {
-		if (REG_READ(ah, AR_INTR_ASYNC_CAUSE) & AR_INTR_MAC_IRQ) {
-			if ((REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M)
-			    == AR_RTC_STATUS_ON) {
-				isr = REG_READ(ah, AR_ISR);
-			}
-		}
-
-		sync_cause = REG_READ(ah, AR_INTR_SYNC_CAUSE) &
-			AR_INTR_SYNC_DEFAULT;
-
-		*masked = 0;
-
-		if (!isr && !sync_cause)
-			return false;
-	} else {
-		*masked = 0;
-		isr = REG_READ(ah, AR_ISR);
-	}
-
-	if (isr) {
-		if (isr & AR_ISR_BCNMISC) {
-			u32 isr2;
-			isr2 = REG_READ(ah, AR_ISR_S2);
-			if (isr2 & AR_ISR_S2_TIM)
-				mask2 |= ATH9K_INT_TIM;
-			if (isr2 & AR_ISR_S2_DTIM)
-				mask2 |= ATH9K_INT_DTIM;
-			if (isr2 & AR_ISR_S2_DTIMSYNC)
-				mask2 |= ATH9K_INT_DTIMSYNC;
-			if (isr2 & (AR_ISR_S2_CABEND))
-				mask2 |= ATH9K_INT_CABEND;
-			if (isr2 & AR_ISR_S2_GTT)
-				mask2 |= ATH9K_INT_GTT;
-			if (isr2 & AR_ISR_S2_CST)
-				mask2 |= ATH9K_INT_CST;
-			if (isr2 & AR_ISR_S2_TSFOOR)
-				mask2 |= ATH9K_INT_TSFOOR;
-		}
-
-		isr = REG_READ(ah, AR_ISR_RAC);
-		if (isr == 0xffffffff) {
-			*masked = 0;
-			return false;
-		}
-
-		*masked = isr & ATH9K_INT_COMMON;
-
-		if (ah->config.rx_intr_mitigation) {
-			if (isr & (AR_ISR_RXMINTR | AR_ISR_RXINTM))
-				*masked |= ATH9K_INT_RX;
-		}
-
-		if (isr & (AR_ISR_RXOK | AR_ISR_RXERR))
-			*masked |= ATH9K_INT_RX;
-		if (isr &
-		    (AR_ISR_TXOK | AR_ISR_TXDESC | AR_ISR_TXERR |
-		     AR_ISR_TXEOL)) {
-			u32 s0_s, s1_s;
-
-			*masked |= ATH9K_INT_TX;
-
-			s0_s = REG_READ(ah, AR_ISR_S0_S);
-			ah->intr_txqs |= MS(s0_s, AR_ISR_S0_QCU_TXOK);
-			ah->intr_txqs |= MS(s0_s, AR_ISR_S0_QCU_TXDESC);
-
-			s1_s = REG_READ(ah, AR_ISR_S1_S);
-			ah->intr_txqs |= MS(s1_s, AR_ISR_S1_QCU_TXERR);
-			ah->intr_txqs |= MS(s1_s, AR_ISR_S1_QCU_TXEOL);
-		}
-
-		if (isr & AR_ISR_RXORN) {
-			ath_print(common, ATH_DBG_INTERRUPT,
-				  "receive FIFO overrun interrupt\n");
-		}
-
-		if (!AR_SREV_9100(ah)) {
-			if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) {
-				u32 isr5 = REG_READ(ah, AR_ISR_S5_S);
-				if (isr5 & AR_ISR_S5_TIM_TIMER)
-					*masked |= ATH9K_INT_TIM_TIMER;
-			}
-		}
-
-		*masked |= mask2;
-	}
-
-	if (AR_SREV_9100(ah))
-		return true;
-
-	if (isr & AR_ISR_GENTMR) {
-		u32 s5_s;
-
-		s5_s = REG_READ(ah, AR_ISR_S5_S);
-		if (isr & AR_ISR_GENTMR) {
-			ah->intr_gen_timer_trigger =
-				MS(s5_s, AR_ISR_S5_GENTIMER_TRIG);
-
-			ah->intr_gen_timer_thresh =
-				MS(s5_s, AR_ISR_S5_GENTIMER_THRESH);
-
-			if (ah->intr_gen_timer_trigger)
-				*masked |= ATH9K_INT_GENTIMER;
-
-		}
-	}
-
-	if (sync_cause) {
-		fatal_int =
-			(sync_cause &
-			 (AR_INTR_SYNC_HOST1_FATAL | AR_INTR_SYNC_HOST1_PERR))
-			? true : false;
-
-		if (fatal_int) {
-			if (sync_cause & AR_INTR_SYNC_HOST1_FATAL) {
-				ath_print(common, ATH_DBG_ANY,
-					  "received PCI FATAL interrupt\n");
-			}
-			if (sync_cause & AR_INTR_SYNC_HOST1_PERR) {
-				ath_print(common, ATH_DBG_ANY,
-					  "received PCI PERR interrupt\n");
-			}
-			*masked |= ATH9K_INT_FATAL;
-		}
-		if (sync_cause & AR_INTR_SYNC_RADM_CPL_TIMEOUT) {
-			ath_print(common, ATH_DBG_INTERRUPT,
-				  "AR_INTR_SYNC_RADM_CPL_TIMEOUT\n");
-			REG_WRITE(ah, AR_RC, AR_RC_HOSTIF);
-			REG_WRITE(ah, AR_RC, 0);
-			*masked |= ATH9K_INT_FATAL;
-		}
-		if (sync_cause & AR_INTR_SYNC_LOCAL_TIMEOUT) {
-			ath_print(common, ATH_DBG_INTERRUPT,
-				  "AR_INTR_SYNC_LOCAL_TIMEOUT\n");
-		}
-
-		REG_WRITE(ah, AR_INTR_SYNC_CAUSE_CLR, sync_cause);
-		(void) REG_READ(ah, AR_INTR_SYNC_CAUSE_CLR);
-	}
-
-	return true;
-}
-EXPORT_SYMBOL(ath9k_hw_getisr);
-
-enum ath9k_int ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints)
-{
-	enum ath9k_int omask = ah->imask;
-	u32 mask, mask2;
-	struct ath9k_hw_capabilities *pCap = &ah->caps;
-	struct ath_common *common = ath9k_hw_common(ah);
-
-	ath_print(common, ATH_DBG_INTERRUPT, "0x%x => 0x%x\n", omask, ints);
-
-	if (omask & ATH9K_INT_GLOBAL) {
-		ath_print(common, ATH_DBG_INTERRUPT, "disable IER\n");
-		REG_WRITE(ah, AR_IER, AR_IER_DISABLE);
-		(void) REG_READ(ah, AR_IER);
-		if (!AR_SREV_9100(ah)) {
-			REG_WRITE(ah, AR_INTR_ASYNC_ENABLE, 0);
-			(void) REG_READ(ah, AR_INTR_ASYNC_ENABLE);
-
-			REG_WRITE(ah, AR_INTR_SYNC_ENABLE, 0);
-			(void) REG_READ(ah, AR_INTR_SYNC_ENABLE);
-		}
-	}
-
-	mask = ints & ATH9K_INT_COMMON;
-	mask2 = 0;
-
-	if (ints & ATH9K_INT_TX) {
-		if (ah->txok_interrupt_mask)
-			mask |= AR_IMR_TXOK;
-		if (ah->txdesc_interrupt_mask)
-			mask |= AR_IMR_TXDESC;
-		if (ah->txerr_interrupt_mask)
-			mask |= AR_IMR_TXERR;
-		if (ah->txeol_interrupt_mask)
-			mask |= AR_IMR_TXEOL;
-	}
-	if (ints & ATH9K_INT_RX) {
-		mask |= AR_IMR_RXERR;
-		if (ah->config.rx_intr_mitigation)
-			mask |= AR_IMR_RXMINTR | AR_IMR_RXINTM;
-		else
-			mask |= AR_IMR_RXOK | AR_IMR_RXDESC;
-		if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP))
-			mask |= AR_IMR_GENTMR;
-	}
-
-	if (ints & (ATH9K_INT_BMISC)) {
-		mask |= AR_IMR_BCNMISC;
-		if (ints & ATH9K_INT_TIM)
-			mask2 |= AR_IMR_S2_TIM;
-		if (ints & ATH9K_INT_DTIM)
-			mask2 |= AR_IMR_S2_DTIM;
-		if (ints & ATH9K_INT_DTIMSYNC)
-			mask2 |= AR_IMR_S2_DTIMSYNC;
-		if (ints & ATH9K_INT_CABEND)
-			mask2 |= AR_IMR_S2_CABEND;
-		if (ints & ATH9K_INT_TSFOOR)
-			mask2 |= AR_IMR_S2_TSFOOR;
-	}
-
-	if (ints & (ATH9K_INT_GTT | ATH9K_INT_CST)) {
-		mask |= AR_IMR_BCNMISC;
-		if (ints & ATH9K_INT_GTT)
-			mask2 |= AR_IMR_S2_GTT;
-		if (ints & ATH9K_INT_CST)
-			mask2 |= AR_IMR_S2_CST;
-	}
-
-	ath_print(common, ATH_DBG_INTERRUPT, "new IMR 0x%x\n", mask);
-	REG_WRITE(ah, AR_IMR, mask);
-	ah->imrs2_reg &= ~(AR_IMR_S2_TIM | AR_IMR_S2_DTIM | AR_IMR_S2_DTIMSYNC |
-			   AR_IMR_S2_CABEND | AR_IMR_S2_CABTO |
-			   AR_IMR_S2_TSFOOR | AR_IMR_S2_GTT | AR_IMR_S2_CST);
-	ah->imrs2_reg |= mask2;
-	REG_WRITE(ah, AR_IMR_S2, ah->imrs2_reg);
-
-	if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) {
-		if (ints & ATH9K_INT_TIM_TIMER)
-			REG_SET_BIT(ah, AR_IMR_S5, AR_IMR_S5_TIM_TIMER);
-		else
-			REG_CLR_BIT(ah, AR_IMR_S5, AR_IMR_S5_TIM_TIMER);
-	}
-
-	if (ints & ATH9K_INT_GLOBAL) {
-		ath_print(common, ATH_DBG_INTERRUPT, "enable IER\n");
-		REG_WRITE(ah, AR_IER, AR_IER_ENABLE);
-		if (!AR_SREV_9100(ah)) {
-			REG_WRITE(ah, AR_INTR_ASYNC_ENABLE,
-				  AR_INTR_MAC_IRQ);
-			REG_WRITE(ah, AR_INTR_ASYNC_MASK, AR_INTR_MAC_IRQ);
-
-
-			REG_WRITE(ah, AR_INTR_SYNC_ENABLE,
-				  AR_INTR_SYNC_DEFAULT);
-			REG_WRITE(ah, AR_INTR_SYNC_MASK,
-				  AR_INTR_SYNC_DEFAULT);
-		}
-		ath_print(common, ATH_DBG_INTERRUPT, "AR_IMR 0x%x IER 0x%x\n",
-			  REG_READ(ah, AR_IMR), REG_READ(ah, AR_IER));
-	}
-
-	return omask;
-}
-EXPORT_SYMBOL(ath9k_hw_set_interrupts);
-
 /*******************/
 /* Beacon Handling */
 /*******************/
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index b27e76b..7a32733 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -227,6 +227,7 @@ struct ath9k_ops_config {
 	u32 enable_ani;
 	int serialize_regmode;
 	bool rx_intr_mitigation;
+	bool tx_intr_mitigation;
 #define SPUR_DISABLE        	0
 #define SPUR_ENABLE_IOCTL   	1
 #define SPUR_ENABLE_EEPROM  	2
@@ -549,6 +550,7 @@ struct ath_hw_ops {
 			  struct ath9k_channel *chan,
 			  u8 rxchainmask,
 			  bool longcal);
+	bool (*get_isr)(struct ath_hw *ah, enum ath9k_int *masked);
 };
 
 struct ath_hw {
@@ -810,11 +812,6 @@ void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah,
 
 bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode);
 
-/* Interrupt Handling */
-bool ath9k_hw_intrpend(struct ath_hw *ah);
-bool ath9k_hw_getisr(struct ath_hw *ah, enum ath9k_int *masked);
-enum ath9k_int ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints);
-
 /* Generic hw timer primitives */
 struct ath_gen_timer *ath_gen_timer_alloc(struct ath_hw *ah,
 					  void (*trigger)(void *),
diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c
index a8dab23..4a36ec5 100644
--- a/drivers/net/wireless/ath/ath9k/mac.c
+++ b/drivers/net/wireless/ath/ath9k/mac.c
@@ -31,6 +31,158 @@ static void ar9002_hw_get_desc_link(void *ds, u32 **ds_link)
 	*ds_link = &((struct ath_desc *)ds)->ds_link;
 }
 
+static bool ar9002_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked)
+{
+	u32 isr = 0;
+	u32 mask2 = 0;
+	struct ath9k_hw_capabilities *pCap = &ah->caps;
+	u32 sync_cause = 0;
+	bool fatal_int = false;
+	struct ath_common *common = ath9k_hw_common(ah);
+
+	if (!AR_SREV_9100(ah)) {
+		if (REG_READ(ah, AR_INTR_ASYNC_CAUSE) & AR_INTR_MAC_IRQ) {
+			if ((REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M)
+			    == AR_RTC_STATUS_ON) {
+				isr = REG_READ(ah, AR_ISR);
+			}
+		}
+
+		sync_cause = REG_READ(ah, AR_INTR_SYNC_CAUSE) &
+			AR_INTR_SYNC_DEFAULT;
+
+		*masked = 0;
+
+		if (!isr && !sync_cause)
+			return false;
+	} else {
+		*masked = 0;
+		isr = REG_READ(ah, AR_ISR);
+	}
+
+	if (isr) {
+		if (isr & AR_ISR_BCNMISC) {
+			u32 isr2;
+			isr2 = REG_READ(ah, AR_ISR_S2);
+			if (isr2 & AR_ISR_S2_TIM)
+				mask2 |= ATH9K_INT_TIM;
+			if (isr2 & AR_ISR_S2_DTIM)
+				mask2 |= ATH9K_INT_DTIM;
+			if (isr2 & AR_ISR_S2_DTIMSYNC)
+				mask2 |= ATH9K_INT_DTIMSYNC;
+			if (isr2 & (AR_ISR_S2_CABEND))
+				mask2 |= ATH9K_INT_CABEND;
+			if (isr2 & AR_ISR_S2_GTT)
+				mask2 |= ATH9K_INT_GTT;
+			if (isr2 & AR_ISR_S2_CST)
+				mask2 |= ATH9K_INT_CST;
+			if (isr2 & AR_ISR_S2_TSFOOR)
+				mask2 |= ATH9K_INT_TSFOOR;
+		}
+
+		isr = REG_READ(ah, AR_ISR_RAC);
+		if (isr == 0xffffffff) {
+			*masked = 0;
+			return false;
+		}
+
+		*masked = isr & ATH9K_INT_COMMON;
+
+		if (ah->config.rx_intr_mitigation) {
+			if (isr & (AR_ISR_RXMINTR | AR_ISR_RXINTM))
+				*masked |= ATH9K_INT_RX;
+		}
+
+		if (isr & (AR_ISR_RXOK | AR_ISR_RXERR))
+			*masked |= ATH9K_INT_RX;
+		if (isr &
+		    (AR_ISR_TXOK | AR_ISR_TXDESC | AR_ISR_TXERR |
+		     AR_ISR_TXEOL)) {
+			u32 s0_s, s1_s;
+
+			*masked |= ATH9K_INT_TX;
+
+			s0_s = REG_READ(ah, AR_ISR_S0_S);
+			ah->intr_txqs |= MS(s0_s, AR_ISR_S0_QCU_TXOK);
+			ah->intr_txqs |= MS(s0_s, AR_ISR_S0_QCU_TXDESC);
+
+			s1_s = REG_READ(ah, AR_ISR_S1_S);
+			ah->intr_txqs |= MS(s1_s, AR_ISR_S1_QCU_TXERR);
+			ah->intr_txqs |= MS(s1_s, AR_ISR_S1_QCU_TXEOL);
+		}
+
+		if (isr & AR_ISR_RXORN) {
+			ath_print(common, ATH_DBG_INTERRUPT,
+				  "receive FIFO overrun interrupt\n");
+		}
+
+		if (!AR_SREV_9100(ah)) {
+			if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) {
+				u32 isr5 = REG_READ(ah, AR_ISR_S5_S);
+				if (isr5 & AR_ISR_S5_TIM_TIMER)
+					*masked |= ATH9K_INT_TIM_TIMER;
+			}
+		}
+
+		*masked |= mask2;
+	}
+
+	if (AR_SREV_9100(ah))
+		return true;
+
+	if (isr & AR_ISR_GENTMR) {
+		u32 s5_s;
+
+		s5_s = REG_READ(ah, AR_ISR_S5_S);
+		if (isr & AR_ISR_GENTMR) {
+			ah->intr_gen_timer_trigger =
+				MS(s5_s, AR_ISR_S5_GENTIMER_TRIG);
+
+			ah->intr_gen_timer_thresh =
+				MS(s5_s, AR_ISR_S5_GENTIMER_THRESH);
+
+			if (ah->intr_gen_timer_trigger)
+				*masked |= ATH9K_INT_GENTIMER;
+
+		}
+	}
+
+	if (sync_cause) {
+		fatal_int =
+			(sync_cause &
+			 (AR_INTR_SYNC_HOST1_FATAL | AR_INTR_SYNC_HOST1_PERR))
+			? true : false;
+
+		if (fatal_int) {
+			if (sync_cause & AR_INTR_SYNC_HOST1_FATAL) {
+				ath_print(common, ATH_DBG_ANY,
+					  "received PCI FATAL interrupt\n");
+			}
+			if (sync_cause & AR_INTR_SYNC_HOST1_PERR) {
+				ath_print(common, ATH_DBG_ANY,
+					  "received PCI PERR interrupt\n");
+			}
+			*masked |= ATH9K_INT_FATAL;
+		}
+		if (sync_cause & AR_INTR_SYNC_RADM_CPL_TIMEOUT) {
+			ath_print(common, ATH_DBG_INTERRUPT,
+				  "AR_INTR_SYNC_RADM_CPL_TIMEOUT\n");
+			REG_WRITE(ah, AR_RC, AR_RC_HOSTIF);
+			REG_WRITE(ah, AR_RC, 0);
+			*masked |= ATH9K_INT_FATAL;
+		}
+		if (sync_cause & AR_INTR_SYNC_LOCAL_TIMEOUT) {
+			ath_print(common, ATH_DBG_INTERRUPT,
+				  "AR_INTR_SYNC_LOCAL_TIMEOUT\n");
+		}
+
+		REG_WRITE(ah, AR_INTR_SYNC_CAUSE_CLR, sync_cause);
+		(void) REG_READ(ah, AR_INTR_SYNC_CAUSE_CLR);
+	}
+
+	return true;
+}
+
 void ar9002_hw_attach_mac_ops(struct ath_hw *ah)
 {
 	struct ath_hw_ops *ops = ath9k_hw_ops(ah);
@@ -38,6 +190,7 @@ void ar9002_hw_attach_mac_ops(struct ath_hw *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;
 }
 
 static void ath9k_hw_set_txq_interrupts(struct ath_hw *ah,
@@ -1089,3 +1242,140 @@ int ath9k_hw_beaconq_setup(struct ath_hw *ah)
 	return ath9k_hw_setuptxqueue(ah, ATH9K_TX_QUEUE_BEACON, &qi);
 }
 EXPORT_SYMBOL(ath9k_hw_beaconq_setup);
+
+bool ath9k_hw_intrpend(struct ath_hw *ah)
+{
+	u32 host_isr;
+
+	if (AR_SREV_9100(ah))
+		return true;
+
+	host_isr = REG_READ(ah, AR_INTR_ASYNC_CAUSE);
+	if ((host_isr & AR_INTR_MAC_IRQ) && (host_isr != AR_INTR_SPURIOUS))
+		return true;
+
+	host_isr = REG_READ(ah, AR_INTR_SYNC_CAUSE);
+	if ((host_isr & AR_INTR_SYNC_DEFAULT)
+	    && (host_isr != AR_INTR_SPURIOUS))
+		return true;
+
+	return false;
+}
+EXPORT_SYMBOL(ath9k_hw_intrpend);
+
+enum ath9k_int ath9k_hw_set_interrupts(struct ath_hw *ah,
+					      enum ath9k_int ints)
+{
+	enum ath9k_int omask = ah->imask;
+	u32 mask, mask2;
+	struct ath9k_hw_capabilities *pCap = &ah->caps;
+	struct ath_common *common = ath9k_hw_common(ah);
+
+	ath_print(common, ATH_DBG_INTERRUPT, "0x%x => 0x%x\n", omask, ints);
+
+	if (omask & ATH9K_INT_GLOBAL) {
+		ath_print(common, ATH_DBG_INTERRUPT, "disable IER\n");
+		REG_WRITE(ah, AR_IER, AR_IER_DISABLE);
+		(void) REG_READ(ah, AR_IER);
+		if (!AR_SREV_9100(ah)) {
+			REG_WRITE(ah, AR_INTR_ASYNC_ENABLE, 0);
+			(void) REG_READ(ah, AR_INTR_ASYNC_ENABLE);
+
+			REG_WRITE(ah, AR_INTR_SYNC_ENABLE, 0);
+			(void) REG_READ(ah, AR_INTR_SYNC_ENABLE);
+		}
+	}
+
+	/* TODO: global int Ref count */
+	mask = ints & ATH9K_INT_COMMON;
+	mask2 = 0;
+
+	if (ints & ATH9K_INT_TX) {
+		if (ah->config.tx_intr_mitigation)
+			mask |= AR_IMR_TXMINTR | AR_IMR_TXINTM;
+		if (ah->txok_interrupt_mask)
+			mask |= AR_IMR_TXOK;
+		if (ah->txdesc_interrupt_mask)
+			mask |= AR_IMR_TXDESC;
+		if (ah->txerr_interrupt_mask)
+			mask |= AR_IMR_TXERR;
+		if (ah->txeol_interrupt_mask)
+			mask |= AR_IMR_TXEOL;
+	}
+	if (ints & ATH9K_INT_RX) {
+		if (AR_SREV_9300_20_OR_LATER(ah)) {
+			mask |= AR_IMR_RXERR | AR_IMR_RXOK_HP;
+			if (ah->config.rx_intr_mitigation) {
+				mask &= ~AR_IMR_RXOK_LP;
+				mask |=  AR_IMR_RXMINTR | AR_IMR_RXINTM;
+			} else {
+				mask |= AR_IMR_RXOK_LP;
+			}
+		} else {
+			if (ah->config.rx_intr_mitigation)
+				mask |= AR_IMR_RXMINTR | AR_IMR_RXINTM;
+			else
+				mask |= AR_IMR_RXOK | AR_IMR_RXDESC;
+		}
+		if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP))
+			mask |= AR_IMR_GENTMR;
+	}
+
+	if (ints & (ATH9K_INT_BMISC)) {
+		mask |= AR_IMR_BCNMISC;
+		if (ints & ATH9K_INT_TIM)
+			mask2 |= AR_IMR_S2_TIM;
+		if (ints & ATH9K_INT_DTIM)
+			mask2 |= AR_IMR_S2_DTIM;
+		if (ints & ATH9K_INT_DTIMSYNC)
+			mask2 |= AR_IMR_S2_DTIMSYNC;
+		if (ints & ATH9K_INT_CABEND)
+			mask2 |= AR_IMR_S2_CABEND;
+		if (ints & ATH9K_INT_TSFOOR)
+			mask2 |= AR_IMR_S2_TSFOOR;
+	}
+
+	if (ints & (ATH9K_INT_GTT | ATH9K_INT_CST)) {
+		mask |= AR_IMR_BCNMISC;
+		if (ints & ATH9K_INT_GTT)
+			mask2 |= AR_IMR_S2_GTT;
+		if (ints & ATH9K_INT_CST)
+			mask2 |= AR_IMR_S2_CST;
+	}
+
+	ath_print(common, ATH_DBG_INTERRUPT, "new IMR 0x%x\n", mask);
+	REG_WRITE(ah, AR_IMR, mask);
+	ah->imrs2_reg &= ~(AR_IMR_S2_TIM | AR_IMR_S2_DTIM | AR_IMR_S2_DTIMSYNC |
+			   AR_IMR_S2_CABEND | AR_IMR_S2_CABTO |
+			   AR_IMR_S2_TSFOOR | AR_IMR_S2_GTT | AR_IMR_S2_CST);
+	ah->imrs2_reg |= mask2;
+	REG_WRITE(ah, AR_IMR_S2, ah->imrs2_reg);
+
+	if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) {
+		if (ints & ATH9K_INT_TIM_TIMER)
+			REG_SET_BIT(ah, AR_IMR_S5, AR_IMR_S5_TIM_TIMER);
+		else
+			REG_CLR_BIT(ah, AR_IMR_S5, AR_IMR_S5_TIM_TIMER);
+	}
+
+	if (ints & ATH9K_INT_GLOBAL) {
+		ath_print(common, ATH_DBG_INTERRUPT, "enable IER\n");
+		REG_WRITE(ah, AR_IER, AR_IER_ENABLE);
+		if (!AR_SREV_9100(ah)) {
+			REG_WRITE(ah, AR_INTR_ASYNC_ENABLE,
+				  AR_INTR_MAC_IRQ);
+			REG_WRITE(ah, AR_INTR_ASYNC_MASK, AR_INTR_MAC_IRQ);
+
+
+			REG_WRITE(ah, AR_INTR_SYNC_ENABLE,
+				  AR_INTR_SYNC_DEFAULT);
+			REG_WRITE(ah, AR_INTR_SYNC_MASK,
+				  AR_INTR_SYNC_DEFAULT);
+		}
+		ath_print(common, ATH_DBG_INTERRUPT, "AR_IMR 0x%x IER 0x%x\n",
+			  REG_READ(ah, AR_IMR), REG_READ(ah, AR_IER));
+	}
+
+	return omask;
+}
+EXPORT_SYMBOL(ath9k_hw_set_interrupts);
diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h
index 99f81eb..7c0d754 100644
--- a/drivers/net/wireless/ath/ath9k/mac.h
+++ b/drivers/net/wireless/ath/ath9k/mac.h
@@ -736,6 +736,11 @@ void ath9k_hw_stoppcurecv(struct ath_hw *ah);
 bool ath9k_hw_stopdmarecv(struct ath_hw *ah);
 int ath9k_hw_beaconq_setup(struct ath_hw *ah);
 
+/* Interrupt Handling */
+bool ath9k_hw_intrpend(struct ath_hw *ah);
+enum ath9k_int ath9k_hw_set_interrupts(struct ath_hw *ah,
+				       enum ath9k_int ints);
+
 void ar9002_hw_attach_mac_ops(struct ath_hw *ah);
 
 #endif /* MAC_H */
diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h
index 96b2cfe..7f85633 100644
--- a/drivers/net/wireless/ath/ath9k/reg.h
+++ b/drivers/net/wireless/ath/ath9k/reg.h
@@ -253,6 +253,8 @@
 #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
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 103+ messages in thread

* [PATCH v3 62/97] ath9k_hw: Initialize interrupt mask for AR9003
  2010-04-15 21:38 [PATCH v3 00/97] ath9k: add AR9003 support Luis R. Rodriguez
                   ` (60 preceding siblings ...)
  2010-04-15 21:39 ` [PATCH v3 61/97] ath9k_hw: Abstract the routine which returns interrupt status Luis R. Rodriguez
@ 2010-04-15 21:39 ` Luis R. Rodriguez
  2010-04-15 21:39 ` [PATCH v3 63/97] ath9k_hw: abstract the AR_PHY_AGC_CONTROL register access Luis R. Rodriguez
                   ` (34 subsequent siblings)
  96 siblings, 0 replies; 103+ messages in thread
From: Luis R. Rodriguez @ 2010-04-15 21:39 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Vasanthakumar Thiagarajan

From: Vasanthakumar Thiagarajan <vasanth@atheros.com>

Signed-off-by: Vasanthakumar Thiagarajan <vasanth@atheros.com>
---
 drivers/net/wireless/ath/ath9k/hw.c  |   29 ++++++++++++++++++++++++-----
 drivers/net/wireless/ath/ath9k/reg.h |    5 +++++
 2 files changed, 29 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index ab3a87b..b8ef2e1 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -737,12 +737,24 @@ static void ath9k_hw_init_interrupt_masks(struct ath_hw *ah,
 		AR_IMR_RXORN |
 		AR_IMR_BCNMISC;
 
-	if (ah->config.rx_intr_mitigation)
-		imr_reg |= AR_IMR_RXINTM | AR_IMR_RXMINTR;
-	else
-		imr_reg |= AR_IMR_RXOK;
+	if (AR_SREV_9300_20_OR_LATER(ah)) {
+		imr_reg |= AR_IMR_RXOK_HP;
+		if (ah->config.rx_intr_mitigation)
+			imr_reg |= AR_IMR_RXINTM | AR_IMR_RXMINTR;
+		else
+			imr_reg |= AR_IMR_RXOK_LP;
 
-	imr_reg |= AR_IMR_TXOK;
+	} else {
+		if (ah->config.rx_intr_mitigation)
+			imr_reg |= AR_IMR_RXINTM | AR_IMR_RXMINTR;
+		else
+			imr_reg |= AR_IMR_RXOK;
+	}
+
+	if (ah->config.tx_intr_mitigation)
+		imr_reg |= AR_IMR_TXINTM | AR_IMR_TXMINTR;
+	else
+		imr_reg |= AR_IMR_TXOK;
 
 	if (opmode == NL80211_IFTYPE_AP)
 		imr_reg |= AR_IMR_MIB;
@@ -756,6 +768,13 @@ static void ath9k_hw_init_interrupt_masks(struct ath_hw *ah,
 		REG_WRITE(ah, AR_INTR_SYNC_ENABLE, AR_INTR_SYNC_DEFAULT);
 		REG_WRITE(ah, AR_INTR_SYNC_MASK, 0);
 	}
+
+	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)
diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h
index 7f85633..7758d99 100644
--- a/drivers/net/wireless/ath/ath9k/reg.h
+++ b/drivers/net/wireless/ath/ath9k/reg.h
@@ -1042,6 +1042,11 @@ enum {
 #define AR_PCIE_MSI                              (AR_SREV_9300_20_OR_LATER(ah) ? 0x40a4 : 0x4094)
 #define AR_PCIE_MSI_ENABLE                       0x00000001
 
+#define AR_INTR_PRIO_SYNC_ENABLE  0x40c4
+#define AR_INTR_PRIO_ASYNC_MASK   0x40c8
+#define AR_INTR_PRIO_SYNC_MASK    0x40cc
+#define AR_INTR_PRIO_ASYNC_ENABLE 0x40d4
+
 #define AR_RTC_9300_PLL_DIV          0x000003ff
 #define AR_RTC_9300_PLL_DIV_S        0
 #define AR_RTC_9300_PLL_REFDIV       0x00003C00
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 103+ messages in thread

* [PATCH v3 63/97] ath9k_hw: abstract the AR_PHY_AGC_CONTROL register access
  2010-04-15 21:38 [PATCH v3 00/97] ath9k: add AR9003 support Luis R. Rodriguez
                   ` (61 preceding siblings ...)
  2010-04-15 21:39 ` [PATCH v3 62/97] ath9k_hw: Initialize interrupt mask for AR9003 Luis R. Rodriguez
@ 2010-04-15 21:39 ` Luis R. Rodriguez
  2010-04-15 21:39 ` [PATCH v3 64/97] ath9k_hw: abstract loading noisefloor Luis R. Rodriguez
                   ` (33 subsequent siblings)
  96 siblings, 0 replies; 103+ messages in thread
From: Luis R. Rodriguez @ 2010-04-15 21:39 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Luis R. Rodriguez

This is so we can share routines which access this register
on calib.c

Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/ar9002_phy.h |    7 -------
 drivers/net/wireless/ath/ath9k/ar9003_phy.h |   13 -------------
 drivers/net/wireless/ath/ath9k/reg.h        |   15 +++++++++++++++
 3 files changed, 15 insertions(+), 20 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ar9002_phy.h b/drivers/net/wireless/ath/ath9k/ar9002_phy.h
index 4fe204e..afe4808 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_phy.h
+++ b/drivers/net/wireless/ath/ath9k/ar9002_phy.h
@@ -120,13 +120,6 @@
 #define AR_PHY_AGC_CTL1_COARSE_HIGH      0x003F8000
 #define AR_PHY_AGC_CTL1_COARSE_HIGH_S    15
 
-#define AR_PHY_AGC_CONTROL               0x9860
-#define AR_PHY_AGC_CONTROL_CAL           0x00000001
-#define AR_PHY_AGC_CONTROL_NF            0x00000002
-#define AR_PHY_AGC_CONTROL_ENABLE_NF     0x00008000
-#define AR_PHY_AGC_CONTROL_FLTR_CAL      0x00010000
-#define AR_PHY_AGC_CONTROL_NO_UPDATE_NF  0x00020000
-
 #define AR_PHY_CCA                  0x9864
 #define AR_PHY_MINCCA_PWR           0x0FF80000
 #define AR_PHY_MINCCA_PWR_S         19
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.h b/drivers/net/wireless/ath/ath9k/ar9003_phy.h
index 70e647b..4e1177d 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.h
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.h
@@ -359,7 +359,6 @@
 #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_AGC_CONTROL       (AR_SM_BASE + 0xc4)
 #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)
@@ -509,18 +508,6 @@
 #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_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
-
 #define AR_PHY_CALMODE_IQ           0x00000000
 #define AR_PHY_CALMODE_ADC_GAIN     0x00000001
 #define AR_PHY_CALMODE_ADC_DC_PER   0x00000002
diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h
index 7758d99..aacc29a 100644
--- a/drivers/net/wireless/ath/ath9k/reg.h
+++ b/drivers/net/wireless/ath/ath9k/reg.h
@@ -1776,4 +1776,19 @@ enum {
 						     * 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
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 103+ messages in thread

* [PATCH v3 64/97] ath9k_hw: abstract loading noisefloor
  2010-04-15 21:38 [PATCH v3 00/97] ath9k: add AR9003 support Luis R. Rodriguez
                   ` (62 preceding siblings ...)
  2010-04-15 21:39 ` [PATCH v3 63/97] ath9k_hw: abstract the AR_PHY_AGC_CONTROL register access Luis R. Rodriguez
@ 2010-04-15 21:39 ` Luis R. Rodriguez
  2010-04-15 21:39 ` [PATCH v3 65/97] ath9k_hw: fill in the callbacks for calibration for AR9003 Luis R. Rodriguez
                   ` (32 subsequent siblings)
  96 siblings, 0 replies; 103+ messages in thread
From: Luis R. Rodriguez @ 2010-04-15 21:39 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Luis R. Rodriguez, Felix Fietkau

This is the last call on calib.c which acceses PHY stuff,
with this change we calib.c is now generic between both
all supported hardware families.

Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
 drivers/net/wireless/ath/ath9k/ar5008_phy.c   |   67 +++++++++++++++++++++++++
 drivers/net/wireless/ath/ath9k/ar9003_calib.c |    6 ++
 drivers/net/wireless/ath/ath9k/calib.c        |   67 -------------------------
 drivers/net/wireless/ath/ath9k/calib.h        |    1 -
 drivers/net/wireless/ath/ath9k/hw-ops.h       |    6 ++
 drivers/net/wireless/ath/ath9k/hw.h           |    2 +
 6 files changed, 81 insertions(+), 68 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
index bd3792c..94eb069 100644
--- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
@@ -1247,6 +1247,72 @@ static void ar5008_hw_do_getnf(struct ath_hw *ah,
 	nfarray[5] = nf;
 }
 
+static void ar5008_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)
+{
+	struct ath9k_nfcal_hist *h;
+	int i, j;
+	int32_t val;
+	const u32 ar5416_cca_regs[6] = {
+		AR_PHY_CCA,
+		AR_PHY_CH1_CCA,
+		AR_PHY_CH2_CCA,
+		AR_PHY_EXT_CCA,
+		AR_PHY_CH1_EXT_CCA,
+		AR_PHY_CH2_EXT_CCA
+	};
+	u8 chainmask, rx_chain_status;
+
+	rx_chain_status = REG_READ(ah, AR_PHY_RX_CHAINMASK);
+	if (AR_SREV_9285(ah) || AR_SREV_9271(ah))
+		chainmask = 0x9;
+	else if (AR_SREV_9280(ah) || AR_SREV_9287(ah)) {
+		if ((rx_chain_status & 0x2) || (rx_chain_status & 0x4))
+			chainmask = 0x1B;
+		else
+			chainmask = 0x09;
+	} else {
+		if (rx_chain_status & 0x4)
+			chainmask = 0x3F;
+		else if (rx_chain_status & 0x2)
+			chainmask = 0x1B;
+		else
+			chainmask = 0x09;
+	}
+
+	h = ah->nfCalHist;
+
+	for (i = 0; i < NUM_NF_READINGS; i++) {
+		if (chainmask & (1 << i)) {
+			val = REG_READ(ah, ar5416_cca_regs[i]);
+			val &= 0xFFFFFE00;
+			val |= (((u32) (h[i].privNF) << 1) & 0x1ff);
+			REG_WRITE(ah, ar5416_cca_regs[i], val);
+		}
+	}
+
+	REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
+		    AR_PHY_AGC_CONTROL_ENABLE_NF);
+	REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
+		    AR_PHY_AGC_CONTROL_NO_UPDATE_NF);
+	REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
+
+	for (j = 0; j < 5; j++) {
+		if ((REG_READ(ah, AR_PHY_AGC_CONTROL) &
+		     AR_PHY_AGC_CONTROL_NF) == 0)
+			break;
+		udelay(50);
+	}
+
+	for (i = 0; i < NUM_NF_READINGS; i++) {
+		if (chainmask & (1 << i)) {
+			val = REG_READ(ah, ar5416_cca_regs[i]);
+			val &= 0xFFFFFE00;
+			val |= (((u32) (-50) << 1) & 0x1ff);
+			REG_WRITE(ah, ar5416_cca_regs[i], val);
+		}
+	}
+}
+
 void ar5008_hw_attach_phy_ops(struct ath_hw *ah)
 {
 	struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
@@ -1270,6 +1336,7 @@ void ar5008_hw_attach_phy_ops(struct ath_hw *ah)
 	priv_ops->set_diversity = ar5008_set_diversity;
 	priv_ops->ani_control = ar5008_hw_ani_control;
 	priv_ops->do_getnf = ar5008_hw_do_getnf;
+	priv_ops->loadnf = ar5008_hw_loadnf;
 
 	if (AR_SREV_9100(ah))
 		priv_ops->compute_pll_control = ar9100_hw_compute_pll_control;
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_calib.c b/drivers/net/wireless/ath/ath9k/ar9003_calib.c
index 00e4cb8..cd80a43 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c
@@ -195,6 +195,11 @@ static bool ar9003_hw_iscal_supported(struct ath_hw *ah,
 	return false;
 }
 
+static void ar9003_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)
+{
+	/* TODO */
+}
+
 void ar9003_hw_attach_calib_ops(struct ath_hw *ah)
 {
 	struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
@@ -204,6 +209,7 @@ void ar9003_hw_attach_calib_ops(struct ath_hw *ah)
 	priv_ops->init_cal = ar9003_hw_init_cal;
 	priv_ops->setup_calibration = ar9003_hw_setup_calibration;
 	priv_ops->iscal_supported = ar9003_hw_iscal_supported;
+	priv_ops->loadnf = ar9003_hw_loadnf;
 
 	ops->calibrate = ar9003_hw_calibrate;
 }
diff --git a/drivers/net/wireless/ath/ath9k/calib.c b/drivers/net/wireless/ath/ath9k/calib.c
index 085e126..6982577 100644
--- a/drivers/net/wireless/ath/ath9k/calib.c
+++ b/drivers/net/wireless/ath/ath9k/calib.c
@@ -16,7 +16,6 @@
 
 #include "hw.h"
 #include "hw-ops.h"
-#include "ar9002_phy.h"
 
 /* Common calibration code */
 
@@ -174,72 +173,6 @@ void ath9k_hw_start_nfcal(struct ath_hw *ah)
 	REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
 }
 
-void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)
-{
-	struct ath9k_nfcal_hist *h;
-	int i, j;
-	int32_t val;
-	const u32 ar5416_cca_regs[6] = {
-		AR_PHY_CCA,
-		AR_PHY_CH1_CCA,
-		AR_PHY_CH2_CCA,
-		AR_PHY_EXT_CCA,
-		AR_PHY_CH1_EXT_CCA,
-		AR_PHY_CH2_EXT_CCA
-	};
-	u8 chainmask, rx_chain_status;
-
-	rx_chain_status = REG_READ(ah, AR_PHY_RX_CHAINMASK);
-	if (AR_SREV_9285(ah) || AR_SREV_9271(ah))
-		chainmask = 0x9;
-	else if (AR_SREV_9280(ah) || AR_SREV_9287(ah)) {
-		if ((rx_chain_status & 0x2) || (rx_chain_status & 0x4))
-			chainmask = 0x1B;
-		else
-			chainmask = 0x09;
-	} else {
-		if (rx_chain_status & 0x4)
-			chainmask = 0x3F;
-		else if (rx_chain_status & 0x2)
-			chainmask = 0x1B;
-		else
-			chainmask = 0x09;
-	}
-
-	h = ah->nfCalHist;
-
-	for (i = 0; i < NUM_NF_READINGS; i++) {
-		if (chainmask & (1 << i)) {
-			val = REG_READ(ah, ar5416_cca_regs[i]);
-			val &= 0xFFFFFE00;
-			val |= (((u32) (h[i].privNF) << 1) & 0x1ff);
-			REG_WRITE(ah, ar5416_cca_regs[i], val);
-		}
-	}
-
-	REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
-		    AR_PHY_AGC_CONTROL_ENABLE_NF);
-	REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
-		    AR_PHY_AGC_CONTROL_NO_UPDATE_NF);
-	REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
-
-	for (j = 0; j < 5; j++) {
-		if ((REG_READ(ah, AR_PHY_AGC_CONTROL) &
-		     AR_PHY_AGC_CONTROL_NF) == 0)
-			break;
-		udelay(50);
-	}
-
-	for (i = 0; i < NUM_NF_READINGS; i++) {
-		if (chainmask & (1 << i)) {
-			val = REG_READ(ah, ar5416_cca_regs[i]);
-			val &= 0xFFFFFE00;
-			val |= (((u32) (-50) << 1) & 0x1ff);
-			REG_WRITE(ah, ar5416_cca_regs[i], val);
-		}
-	}
-}
-
 int16_t ath9k_hw_getnf(struct ath_hw *ah,
 		       struct ath9k_channel *chan)
 {
diff --git a/drivers/net/wireless/ath/ath9k/calib.h b/drivers/net/wireless/ath/ath9k/calib.h
index 9f6c21d..25828e8 100644
--- a/drivers/net/wireless/ath/ath9k/calib.h
+++ b/drivers/net/wireless/ath/ath9k/calib.h
@@ -114,7 +114,6 @@ struct ath9k_pacal_info{
 
 bool ath9k_hw_reset_calvalid(struct ath_hw *ah);
 void ath9k_hw_start_nfcal(struct ath_hw *ah);
-void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan);
 int16_t ath9k_hw_getnf(struct ath_hw *ah,
 		       struct ath9k_channel *chan);
 void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah);
diff --git a/drivers/net/wireless/ath/ath9k/hw-ops.h b/drivers/net/wireless/ath/ath9k/hw-ops.h
index b777fd1..b444ce5 100644
--- a/drivers/net/wireless/ath/ath9k/hw-ops.h
+++ b/drivers/net/wireless/ath/ath9k/hw-ops.h
@@ -182,6 +182,12 @@ static inline void ath9k_hw_do_getnf(struct ath_hw *ah,
 	ath9k_hw_private_ops(ah)->do_getnf(ah, nfarray);
 }
 
+static inline void ath9k_hw_loadnf(struct ath_hw *ah,
+				   struct ath9k_channel *chan)
+{
+	ath9k_hw_private_ops(ah)->loadnf(ah, chan);
+}
+
 static inline bool ath9k_hw_init_cal(struct ath_hw *ah,
 				     struct ath9k_channel *chan)
 {
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 7a32733..d28a904 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -486,6 +486,7 @@ struct ath_gen_timer_table {
  *	AR_RTC_PLL_CONTROL for a given channel
  * @setup_calibration: set up calibration
  * @iscal_supported: used to query if a type of calibration is supported
+ * @loadnf: load noise floor read from each chain on the CCA registers
  */
 struct ath_hw_private_ops {
 	/* Calibration ops */
@@ -528,6 +529,7 @@ struct ath_hw_private_ops {
 	bool (*ani_control)(struct ath_hw *ah, enum ath9k_ani_cmd cmd,
 			    int param);
 	void (*do_getnf)(struct ath_hw *ah, int16_t nfarray[NUM_NF_READINGS]);
+	void (*loadnf)(struct ath_hw *ah, struct ath9k_channel *chan);
 };
 
 /**
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 103+ messages in thread

* [PATCH v3 65/97] ath9k_hw: fill in the callbacks for calibration for AR9003
  2010-04-15 21:38 [PATCH v3 00/97] ath9k: add AR9003 support Luis R. Rodriguez
                   ` (63 preceding siblings ...)
  2010-04-15 21:39 ` [PATCH v3 64/97] ath9k_hw: abstract loading noisefloor Luis R. Rodriguez
@ 2010-04-15 21:39 ` Luis R. Rodriguez
  2010-04-15 21:39 ` [PATCH v3 66/97] ath9k_hw: complete AR9003 calibration Luis R. Rodriguez
                   ` (31 subsequent siblings)
  96 siblings, 0 replies; 103+ messages in thread
From: Luis R. Rodriguez @ 2010-04-15 21:39 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Luis R. Rodriguez

Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/ar9002_calib.c |    2 +
 drivers/net/wireless/ath/ath9k/ar9003_calib.c |   36 ++++++++++++++++++++++++-
 drivers/net/wireless/ath/ath9k/calib.h        |    3 +-
 3 files changed, 39 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ar9002_calib.c b/drivers/net/wireless/ath/ath9k/ar9002_calib.c
index cd234aa..968529b 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_calib.c
+++ b/drivers/net/wireless/ath/ath9k/ar9002_calib.c
@@ -50,6 +50,8 @@ static void ar9002_hw_setup_calibration(struct ath_hw *ah,
 		ath_print(common, ATH_DBG_CALIBRATE,
 			  "starting Init ADC DC Calibration\n");
 		break;
+	case TEMP_COMP_CAL:
+		break; /* Not supported */
 	}
 
 	REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4(0),
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_calib.c b/drivers/net/wireless/ath/ath9k/ar9003_calib.c
index cd80a43..f0e8f63 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c
@@ -21,7 +21,41 @@
 static void ar9003_hw_setup_calibration(struct ath_hw *ah,
 					struct ath9k_cal_list *currCal)
 {
-	/* TODO */
+	struct ath_common *common = ath9k_hw_common(ah);
+
+	/* Select calibration to run */
+	switch (currCal->calData->calType) {
+	case IQ_MISMATCH_CAL:
+		/*
+		 * Start calibration with
+		 * 2^(INIT_IQCAL_LOG_COUNT_MAX+1) samples
+		 */
+		REG_RMW_FIELD(ah, AR_PHY_TIMING4,
+			      AR_PHY_TIMING4_IQCAL_LOG_COUNT_MAX,
+		currCal->calData->calCountMax);
+		REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_IQ);
+
+		ath_print(common, ATH_DBG_CALIBRATE,
+			  "starting IQ Mismatch Calibration\n");
+
+		/* Kick-off cal */
+		REG_SET_BIT(ah, AR_PHY_TIMING4, AR_PHY_TIMING4_DO_CAL);
+		break;
+	case TEMP_COMP_CAL:
+		REG_RMW_FIELD(ah, AR_PHY_65NM_CH0_THERM,
+			      AR_PHY_65NM_CH0_THERM_LOCAL, 1);
+		REG_RMW_FIELD(ah, AR_PHY_65NM_CH0_THERM,
+			      AR_PHY_65NM_CH0_THERM_START, 1);
+
+		ath_print(common, ATH_DBG_CALIBRATE,
+			  "starting Temperature Compensation Calibration\n");
+		break;
+	case ADC_DC_INIT_CAL:
+	case ADC_GAIN_CAL:
+	case ADC_DC_CAL:
+		/* Not yet */
+		break;
+	}
 }
 
 static bool ar9003_hw_calibrate(struct ath_hw *ah,
diff --git a/drivers/net/wireless/ath/ath9k/calib.h b/drivers/net/wireless/ath/ath9k/calib.h
index 25828e8..24538bd 100644
--- a/drivers/net/wireless/ath/ath9k/calib.h
+++ b/drivers/net/wireless/ath/ath9k/calib.h
@@ -68,7 +68,8 @@ enum ath9k_cal_types {
 	ADC_DC_INIT_CAL = 0x1,
 	ADC_GAIN_CAL = 0x2,
 	ADC_DC_CAL = 0x4,
-	IQ_MISMATCH_CAL = 0x8
+	IQ_MISMATCH_CAL = 0x8,
+	TEMP_COMP_CAL = 0x10,
 };
 
 enum ath9k_cal_state {
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 103+ messages in thread

* [PATCH v3 66/97] ath9k_hw: complete AR9003 calibration
  2010-04-15 21:38 [PATCH v3 00/97] ath9k: add AR9003 support Luis R. Rodriguez
                   ` (64 preceding siblings ...)
  2010-04-15 21:39 ` [PATCH v3 65/97] ath9k_hw: fill in the callbacks for calibration for AR9003 Luis R. Rodriguez
@ 2010-04-15 21:39 ` Luis R. Rodriguez
  2010-04-15 21:39 ` [PATCH v3 67/97] ath9k_hw: rename eep_AR9287_ops to eep_ar9287_ops Luis R. Rodriguez
                   ` (30 subsequent siblings)
  96 siblings, 0 replies; 103+ messages in thread
From: Luis R. Rodriguez @ 2010-04-15 21:39 UTC (permalink / raw)
  To: linville
  Cc: linux-wireless, Luis R. Rodriguez, Vasanthakumar Thiagarajan,
	Felix Fietkau

This goes with some new shiny TX IQ calibration that AR9003
hardware family supports.

Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
Signed-off-by: Vasanthakumar Thiagarajan <vasanth@atheros.com>
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
 drivers/net/wireless/ath/ath9k/ar9003_calib.c |  577 ++++++++++++++++++++++++-
 drivers/net/wireless/ath/ath9k/ar9003_phy.c   |  100 +++++
 drivers/net/wireless/ath/ath9k/eeprom.h       |    1 +
 drivers/net/wireless/ath/ath9k/hw.h           |    1 +
 4 files changed, 667 insertions(+), 12 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ar9003_calib.c b/drivers/net/wireless/ath/ath9k/ar9003_calib.c
index f0e8f63..5e20b48 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c
@@ -58,20 +58,108 @@ static void ar9003_hw_setup_calibration(struct ath_hw *ah,
 	}
 }
 
+/*
+ * Generic calibration routine.
+ * Recalibrate the lower PHY chips to account for temperature/environment
+ * changes.
+ */
+static bool ar9003_hw_per_calibration(struct ath_hw *ah,
+				      struct ath9k_channel *ichan,
+				      u8 rxchainmask,
+				      struct ath9k_cal_list *currCal)
+{
+	/* Cal is assumed not done until explicitly set below */
+	bool iscaldone = false;
+
+	/* Calibration in progress. */
+	if (currCal->calState == CAL_RUNNING) {
+		/* Check to see if it has finished. */
+		if (!(REG_READ(ah, AR_PHY_TIMING4) & AR_PHY_TIMING4_DO_CAL)) {
+			/*
+			* Accumulate cal measures for active chains
+			*/
+			currCal->calData->calCollect(ah);
+			ah->cal_samples++;
+
+			if (ah->cal_samples >=
+			    currCal->calData->calNumSamples) {
+				unsigned int i, numChains = 0;
+				for (i = 0; i < AR9300_MAX_CHAINS; i++) {
+					if (rxchainmask & (1 << i))
+						numChains++;
+				}
+
+				/*
+				* Process accumulated data
+				*/
+				currCal->calData->calPostProc(ah, numChains);
+
+				/* Calibration has finished. */
+				ichan->CalValid |= currCal->calData->calType;
+				currCal->calState = CAL_DONE;
+				iscaldone = true;
+			} else {
+			/*
+			 * Set-up collection of another sub-sample until we
+			 * get desired number
+			 */
+			ar9003_hw_setup_calibration(ah, currCal);
+			}
+		}
+	} else if (!(ichan->CalValid & currCal->calData->calType)) {
+		/* If current cal is marked invalid in channel, kick it off */
+		ath9k_hw_reset_calibration(ah, currCal);
+	}
+
+	return iscaldone;
+}
+
 static bool ar9003_hw_calibrate(struct ath_hw *ah,
 				struct ath9k_channel *chan,
 				u8 rxchainmask,
 				bool longcal)
 {
-	/* TODO */
-	return false;
-}
+	bool iscaldone = true;
+	struct ath9k_cal_list *currCal = ah->cal_list_curr;
+
+	/*
+	 * For given calibration:
+	 * 1. Call generic cal routine
+	 * 2. When this cal is done (isCalDone) if we have more cals waiting
+	 *    (eg after reset), mask this to upper layers by not propagating
+	 *    isCalDone if it is set to TRUE.
+	 *    Instead, change isCalDone to FALSE and setup the waiting cal(s)
+	 *    to be run.
+	 */
+	if (currCal &&
+	    (currCal->calState == CAL_RUNNING ||
+	     currCal->calState == CAL_WAITING)) {
+		iscaldone = ar9003_hw_per_calibration(ah, chan,
+						      rxchainmask, currCal);
+		if (iscaldone) {
+			ah->cal_list_curr = currCal = currCal->calNext;
+
+			if (currCal->calState == CAL_WAITING) {
+				iscaldone = false;
+				ath9k_hw_reset_calibration(ah, currCal);
+			}
+		}
+	}
 
-static bool ar9003_hw_init_cal(struct ath_hw *ah,
-			       struct ath9k_channel *chan)
-{
-	/* TODO */
-	return false;
+	/* Do NF cal only at longer intervals */
+	if (longcal) {
+		/*
+		 * Load the NF from history buffer of the current channel.
+		 * NF is slow time-variant, so it is OK to use a historical
+		 * value.
+		 */
+		ath9k_hw_loadnf(ah, ah->curchan);
+
+		/* start NF calibration, without updating BB NF register */
+		ath9k_hw_start_nfcal(ah);
+	}
+
+	return iscaldone;
 }
 
 static void ar9003_hw_iqcal_collect(struct ath_hw *ah)
@@ -225,13 +313,479 @@ static void ar9003_hw_init_cal_settings(struct ath_hw *ah)
 static bool ar9003_hw_iscal_supported(struct ath_hw *ah,
 				      enum ath9k_cal_types calType)
 {
-	/* TODO */
+	switch (calType & ah->supp_cals) {
+	case IQ_MISMATCH_CAL:
+		/*
+		 * XXX: Run IQ Mismatch for non-CCK only
+		 * Note that CHANNEL_B is never set though.
+		 */
+		return true;
+	case ADC_GAIN_CAL:
+	case ADC_DC_CAL:
+		return false;
+	case TEMP_COMP_CAL:
+		return true;
+	}
+
 	return false;
 }
 
-static void ar9003_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)
+/*
+ * solve 4x4 linear equation used in loopback iq cal.
+ */
+static bool ar9003_hw_solve_iq_cal(struct ath_hw *ah,
+				   s32 sin_2phi_1,
+				   s32 cos_2phi_1,
+				   s32 sin_2phi_2,
+				   s32 cos_2phi_2,
+				   s32 mag_a0_d0,
+				   s32 phs_a0_d0,
+				   s32 mag_a1_d0,
+				   s32 phs_a1_d0,
+				   s32 solved_eq[])
+{
+	s32 f1 = cos_2phi_1 - cos_2phi_2,
+	    f3 = sin_2phi_1 - sin_2phi_2,
+	    f2;
+	s32 mag_tx, phs_tx, mag_rx, phs_rx;
+	const s32 result_shift = 1 << 15;
+	struct ath_common *common = ath9k_hw_common(ah);
+
+	f2 = (f1 * f1 + f3 * f3) / result_shift;
+
+	if (!f2) {
+		ath_print(common, ATH_DBG_CALIBRATE, "Divide by 0\n");
+		return false;
+	}
+
+	/* mag mismatch, tx */
+	mag_tx = f1 * (mag_a0_d0  - mag_a1_d0) + f3 * (phs_a0_d0 - phs_a1_d0);
+	/* phs mismatch, tx */
+	phs_tx = f3 * (-mag_a0_d0 + mag_a1_d0) + f1 * (phs_a0_d0 - phs_a1_d0);
+
+	mag_tx = (mag_tx / f2);
+	phs_tx = (phs_tx / f2);
+
+	/* mag mismatch, rx */
+	mag_rx = mag_a0_d0 - (cos_2phi_1 * mag_tx + sin_2phi_1 * phs_tx) /
+		 result_shift;
+	/* phs mismatch, rx */
+	phs_rx = phs_a0_d0 + (sin_2phi_1 * mag_tx - cos_2phi_1 * phs_tx) /
+		 result_shift;
+
+	solved_eq[0] = mag_tx;
+	solved_eq[1] = phs_tx;
+	solved_eq[2] = mag_rx;
+	solved_eq[3] = phs_rx;
+
+	return true;
+}
+
+static s32 ar9003_hw_find_mag_approx(struct ath_hw *ah, s32 in_re, s32 in_im)
 {
-	/* TODO */
+	s32 abs_i = abs(in_re),
+	    abs_q = abs(in_im),
+	    max_abs, min_abs;
+
+	if (abs_i > abs_q) {
+		max_abs = abs_i;
+		min_abs = abs_q;
+	} else {
+		max_abs = abs_q;
+		min_abs = abs_i;
+	}
+
+	return max_abs - (max_abs / 32) + (min_abs / 8) + (min_abs / 4);
+}
+
+#define DELPT 32
+
+static bool ar9003_hw_calc_iq_corr(struct ath_hw *ah,
+				   s32 chain_idx,
+				   const s32 iq_res[],
+				   s32 iqc_coeff[])
+{
+	s32 i2_m_q2_a0_d0, i2_p_q2_a0_d0, iq_corr_a0_d0,
+	    i2_m_q2_a0_d1, i2_p_q2_a0_d1, iq_corr_a0_d1,
+	    i2_m_q2_a1_d0, i2_p_q2_a1_d0, iq_corr_a1_d0,
+	    i2_m_q2_a1_d1, i2_p_q2_a1_d1, iq_corr_a1_d1;
+	s32 mag_a0_d0, mag_a1_d0, mag_a0_d1, mag_a1_d1,
+	    phs_a0_d0, phs_a1_d0, phs_a0_d1, phs_a1_d1,
+	    sin_2phi_1, cos_2phi_1,
+	    sin_2phi_2, cos_2phi_2;
+	s32 mag_tx, phs_tx, mag_rx, phs_rx;
+	s32 solved_eq[4], mag_corr_tx, phs_corr_tx, mag_corr_rx, phs_corr_rx,
+	    q_q_coff, q_i_coff;
+	const s32 res_scale = 1 << 15;
+	const s32 delpt_shift = 1 << 8;
+	s32 mag1, mag2;
+	struct ath_common *common = ath9k_hw_common(ah);
+
+	i2_m_q2_a0_d0 = iq_res[0] & 0xfff;
+	i2_p_q2_a0_d0 = (iq_res[0] >> 12) & 0xfff;
+	iq_corr_a0_d0 = ((iq_res[0] >> 24) & 0xff) + ((iq_res[1] & 0xf) << 8);
+
+	if (i2_m_q2_a0_d0 > 0x800)
+		i2_m_q2_a0_d0 = -((0xfff - i2_m_q2_a0_d0) + 1);
+
+	if (i2_p_q2_a0_d0 > 0x800)
+		i2_p_q2_a0_d0 = -((0xfff - i2_p_q2_a0_d0) + 1);
+
+	if (iq_corr_a0_d0 > 0x800)
+		iq_corr_a0_d0 = -((0xfff - iq_corr_a0_d0) + 1);
+
+	i2_m_q2_a0_d1 = (iq_res[1] >> 4) & 0xfff;
+	i2_p_q2_a0_d1 = (iq_res[2] & 0xfff);
+	iq_corr_a0_d1 = (iq_res[2] >> 12) & 0xfff;
+
+	if (i2_m_q2_a0_d1 > 0x800)
+		i2_m_q2_a0_d1 = -((0xfff - i2_m_q2_a0_d1) + 1);
+
+	if (i2_p_q2_a0_d1 > 0x800)
+		i2_p_q2_a0_d1 = -((0xfff - i2_p_q2_a0_d1) + 1);
+
+	if (iq_corr_a0_d1 > 0x800)
+		iq_corr_a0_d1 = -((0xfff - iq_corr_a0_d1) + 1);
+
+	i2_m_q2_a1_d0 = ((iq_res[2] >> 24) & 0xff) + ((iq_res[3] & 0xf) << 8);
+	i2_p_q2_a1_d0 = (iq_res[3] >> 4) & 0xfff;
+	iq_corr_a1_d0 = iq_res[4] & 0xfff;
+
+	if (i2_m_q2_a1_d0 > 0x800)
+		i2_m_q2_a1_d0 = -((0xfff - i2_m_q2_a1_d0) + 1);
+
+	if (i2_p_q2_a1_d0 > 0x800)
+		i2_p_q2_a1_d0 = -((0xfff - i2_p_q2_a1_d0) + 1);
+
+	if (iq_corr_a1_d0 > 0x800)
+		iq_corr_a1_d0 = -((0xfff - iq_corr_a1_d0) + 1);
+
+	i2_m_q2_a1_d1 = (iq_res[4] >> 12) & 0xfff;
+	i2_p_q2_a1_d1 = ((iq_res[4] >> 24) & 0xff) + ((iq_res[5] & 0xf) << 8);
+	iq_corr_a1_d1 = (iq_res[5] >> 4) & 0xfff;
+
+	if (i2_m_q2_a1_d1 > 0x800)
+		i2_m_q2_a1_d1 = -((0xfff - i2_m_q2_a1_d1) + 1);
+
+	if (i2_p_q2_a1_d1 > 0x800)
+		i2_p_q2_a1_d1 = -((0xfff - i2_p_q2_a1_d1) + 1);
+
+	if (iq_corr_a1_d1 > 0x800)
+		iq_corr_a1_d1 = -((0xfff - iq_corr_a1_d1) + 1);
+
+	if ((i2_p_q2_a0_d0 == 0) || (i2_p_q2_a0_d1 == 0) ||
+	    (i2_p_q2_a1_d0 == 0) || (i2_p_q2_a1_d1 == 0)) {
+		ath_print(common, ATH_DBG_CALIBRATE,
+			  "Divide by 0:\na0_d0=%d\n"
+			  "a0_d1=%d\na2_d0=%d\na1_d1=%d\n",
+			  i2_p_q2_a0_d0, i2_p_q2_a0_d1,
+			  i2_p_q2_a1_d0, i2_p_q2_a1_d1);
+		return false;
+	}
+
+	mag_a0_d0 = (i2_m_q2_a0_d0 * res_scale) / i2_p_q2_a0_d0;
+	phs_a0_d0 = (iq_corr_a0_d0 * res_scale) / i2_p_q2_a0_d0;
+
+	mag_a0_d1 = (i2_m_q2_a0_d1 * res_scale) / i2_p_q2_a0_d1;
+	phs_a0_d1 = (iq_corr_a0_d1 * res_scale) / i2_p_q2_a0_d1;
+
+	mag_a1_d0 = (i2_m_q2_a1_d0 * res_scale) / i2_p_q2_a1_d0;
+	phs_a1_d0 = (iq_corr_a1_d0 * res_scale) / i2_p_q2_a1_d0;
+
+	mag_a1_d1 = (i2_m_q2_a1_d1 * res_scale) / i2_p_q2_a1_d1;
+	phs_a1_d1 = (iq_corr_a1_d1 * res_scale) / i2_p_q2_a1_d1;
+
+	/* w/o analog phase shift */
+	sin_2phi_1 = (((mag_a0_d0 - mag_a0_d1) * delpt_shift) / DELPT);
+	/* w/o analog phase shift */
+	cos_2phi_1 = (((phs_a0_d1 - phs_a0_d0) * delpt_shift) / DELPT);
+	/* w/  analog phase shift */
+	sin_2phi_2 = (((mag_a1_d0 - mag_a1_d1) * delpt_shift) / DELPT);
+	/* w/  analog phase shift */
+	cos_2phi_2 = (((phs_a1_d1 - phs_a1_d0) * delpt_shift) / DELPT);
+
+	/*
+	 * force sin^2 + cos^2 = 1;
+	 * find magnitude by approximation
+	 */
+	mag1 = ar9003_hw_find_mag_approx(ah, cos_2phi_1, sin_2phi_1);
+	mag2 = ar9003_hw_find_mag_approx(ah, cos_2phi_2, sin_2phi_2);
+
+	if ((mag1 == 0) || (mag2 == 0)) {
+		ath_print(common, ATH_DBG_CALIBRATE,
+			  "Divide by 0: mag1=%d, mag2=%d\n",
+			  mag1, mag2);
+		return false;
+	}
+
+	/* normalization sin and cos by mag */
+	sin_2phi_1 = (sin_2phi_1 * res_scale / mag1);
+	cos_2phi_1 = (cos_2phi_1 * res_scale / mag1);
+	sin_2phi_2 = (sin_2phi_2 * res_scale / mag2);
+	cos_2phi_2 = (cos_2phi_2 * res_scale / mag2);
+
+	/* calculate IQ mismatch */
+	if (!ar9003_hw_solve_iq_cal(ah,
+			     sin_2phi_1, cos_2phi_1,
+			     sin_2phi_2, cos_2phi_2,
+			     mag_a0_d0, phs_a0_d0,
+			     mag_a1_d0,
+			     phs_a1_d0, solved_eq)) {
+		ath_print(common, ATH_DBG_CALIBRATE,
+			  "Call to ar9003_hw_solve_iq_cal() failed.\n");
+		return false;
+	}
+
+	mag_tx = solved_eq[0];
+	phs_tx = solved_eq[1];
+	mag_rx = solved_eq[2];
+	phs_rx = solved_eq[3];
+
+	ath_print(common, ATH_DBG_CALIBRATE,
+		  "chain %d: mag mismatch=%d phase mismatch=%d\n",
+		  chain_idx, mag_tx/res_scale, phs_tx/res_scale);
+
+	if (res_scale == mag_tx) {
+		ath_print(common, ATH_DBG_CALIBRATE,
+			  "Divide by 0: mag_tx=%d, res_scale=%d\n",
+			  mag_tx, res_scale);
+		return false;
+	}
+
+	/* calculate and quantize Tx IQ correction factor */
+	mag_corr_tx = (mag_tx * res_scale) / (res_scale - mag_tx);
+	phs_corr_tx = -phs_tx;
+
+	q_q_coff = (mag_corr_tx * 128 / res_scale);
+	q_i_coff = (phs_corr_tx * 256 / res_scale);
+
+	ath_print(common, ATH_DBG_CALIBRATE,
+		  "tx chain %d: mag corr=%d  phase corr=%d\n",
+		  chain_idx, q_q_coff, q_i_coff);
+
+	if (q_i_coff < -63)
+		q_i_coff = -63;
+	if (q_i_coff > 63)
+		q_i_coff = 63;
+	if (q_q_coff < -63)
+		q_q_coff = -63;
+	if (q_q_coff > 63)
+		q_q_coff = 63;
+
+	iqc_coeff[0] = (q_q_coff * 128) + q_i_coff;
+
+	ath_print(common, ATH_DBG_CALIBRATE,
+		  "tx chain %d: iq corr coeff=%x\n",
+		  chain_idx, iqc_coeff[0]);
+
+	if (-mag_rx == res_scale) {
+		ath_print(common, ATH_DBG_CALIBRATE,
+			  "Divide by 0: mag_rx=%d, res_scale=%d\n",
+			  mag_rx, res_scale);
+		return false;
+	}
+
+	/* calculate and quantize Rx IQ correction factors */
+	mag_corr_rx = (-mag_rx * res_scale) / (res_scale + mag_rx);
+	phs_corr_rx = -phs_rx;
+
+	q_q_coff = (mag_corr_rx * 128 / res_scale);
+	q_i_coff = (phs_corr_rx * 256 / res_scale);
+
+	ath_print(common, ATH_DBG_CALIBRATE,
+		  "rx chain %d: mag corr=%d  phase corr=%d\n",
+		  chain_idx, q_q_coff, q_i_coff);
+
+	if (q_i_coff < -63)
+		q_i_coff = -63;
+	if (q_i_coff > 63)
+		q_i_coff = 63;
+	if (q_q_coff < -63)
+		q_q_coff = -63;
+	if (q_q_coff > 63)
+		q_q_coff = 63;
+
+	iqc_coeff[1] = (q_q_coff * 128) + q_i_coff;
+
+	ath_print(common, ATH_DBG_CALIBRATE,
+		  "rx chain %d: iq corr coeff=%x\n",
+		  chain_idx, iqc_coeff[1]);
+
+	return true;
+}
+
+static void ar9003_hw_tx_iq_cal(struct ath_hw *ah)
+{
+	struct ath_common *common = ath9k_hw_common(ah);
+	const u32 txiqcal_status[AR9300_MAX_CHAINS] = {
+		AR_PHY_TX_IQCAL_STATUS_B0,
+		AR_PHY_TX_IQCAL_STATUS_B1,
+		AR_PHY_TX_IQCAL_STATUS_B2,
+	};
+	const u32 tx_corr_coeff[AR9300_MAX_CHAINS] = {
+		AR_PHY_TX_IQCAL_CORR_COEFF_01_B0,
+		AR_PHY_TX_IQCAL_CORR_COEFF_01_B1,
+		AR_PHY_TX_IQCAL_CORR_COEFF_01_B2,
+	};
+	const u32 rx_corr[AR9300_MAX_CHAINS] = {
+		AR_PHY_RX_IQCAL_CORR_B0,
+		AR_PHY_RX_IQCAL_CORR_B1,
+		AR_PHY_RX_IQCAL_CORR_B2,
+	};
+	const u_int32_t chan_info_tab[] = {
+		AR_PHY_CHAN_INFO_TAB_0,
+		AR_PHY_CHAN_INFO_TAB_1,
+		AR_PHY_CHAN_INFO_TAB_2,
+	};
+	s32 iq_res[6];
+	s32 iqc_coeff[2];
+	s32 i, j;
+	u32 num_chains = 0;
+
+	for (i = 0; i < AR9300_MAX_CHAINS; i++) {
+		if (ah->txchainmask & (1 << i))
+			num_chains++;
+	}
+
+	REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_1,
+		      AR_PHY_TX_IQCAQL_CONTROL_1_IQCORR_I_Q_COFF_DELPT,
+		      DELPT);
+	REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_START,
+		      AR_PHY_TX_IQCAL_START_DO_CAL,
+		      AR_PHY_TX_IQCAL_START_DO_CAL);
+
+	if (!ath9k_hw_wait(ah, AR_PHY_TX_IQCAL_START,
+			   AR_PHY_TX_IQCAL_START_DO_CAL,
+			   0, AH_WAIT_TIMEOUT)) {
+		ath_print(common, ATH_DBG_CALIBRATE,
+			  "Tx IQ Cal not complete.\n");
+		goto TX_IQ_CAL_FAILED;
+	}
+
+	for (i = 0; i < num_chains; i++) {
+		ath_print(common, ATH_DBG_CALIBRATE,
+			  "Doing Tx IQ Cal for chain %d.\n", i);
+
+		if (REG_READ(ah, txiqcal_status[i]) &
+			     AR_PHY_TX_IQCAL_STATUS_FAILED) {
+			ath_print(common, ATH_DBG_CALIBRATE,
+				  "Tx IQ Cal failed for chain %d.\n", i);
+			goto TX_IQ_CAL_FAILED;
+		}
+
+		for (j = 0; j < 3; j++) {
+			u_int8_t idx = 2 * j,
+			offset = 4 * j;
+
+			REG_RMW_FIELD(ah, AR_PHY_CHAN_INFO_MEMORY,
+				      AR_PHY_CHAN_INFO_TAB_S2_READ, 0);
+
+			/* 32 bits */
+			iq_res[idx] = REG_READ(ah, chan_info_tab[i] + offset);
+
+			REG_RMW_FIELD(ah, AR_PHY_CHAN_INFO_MEMORY,
+				      AR_PHY_CHAN_INFO_TAB_S2_READ, 1);
+
+			/* 16 bits */
+			iq_res[idx+1] = 0xffff & REG_READ(ah,
+							  chan_info_tab[i] +
+							  offset);
+
+			ath_print(common, ATH_DBG_CALIBRATE,
+				  "IQ RES[%d]=0x%x IQ_RES[%d]=0x%x\n",
+				  idx, iq_res[idx], idx+1, iq_res[idx+1]);
+		}
+
+		if (!ar9003_hw_calc_iq_corr(ah, i, iq_res, iqc_coeff)) {
+			ath_print(common, ATH_DBG_CALIBRATE,
+				  "Failed in calculation of IQ correction.\n");
+			goto TX_IQ_CAL_FAILED;
+		}
+
+		ath_print(common, ATH_DBG_CALIBRATE,
+			  "IQ_COEFF[0] = 0x%x IQ_COEFF[1] = 0x%x\n",
+			  iqc_coeff[0], iqc_coeff[1]);
+
+		REG_RMW_FIELD(ah, tx_corr_coeff[i],
+			      AR_PHY_TX_IQCAL_CORR_COEFF_01_COEFF_TABLE,
+			      iqc_coeff[0]);
+		REG_RMW_FIELD(ah, rx_corr[i],
+			      AR_PHY_RX_IQCAL_CORR_LOOPBACK_IQCORR_Q_Q_COFF,
+			      iqc_coeff[1] >> 7);
+		REG_RMW_FIELD(ah, rx_corr[i],
+			      AR_PHY_RX_IQCAL_CORR_LOOPBACK_IQCORR_Q_I_COFF,
+			      iqc_coeff[1]);
+	}
+
+	REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_3,
+		      AR_PHY_TX_IQCAL_CONTROL_3_IQCORR_EN, 0x1);
+	REG_RMW_FIELD(ah, AR_PHY_RX_IQCAL_CORR_B0,
+		      AR_PHY_RX_IQCAL_CORR_B0_LOOPBACK_IQCORR_EN, 0x1);
+
+	return;
+
+TX_IQ_CAL_FAILED:
+	ath_print(common, ATH_DBG_CALIBRATE, "Tx IQ Cal failed\n");
+	return;
+}
+
+static bool ar9003_hw_init_cal(struct ath_hw *ah,
+			       struct ath9k_channel *chan)
+{
+	struct ath_common *common = ath9k_hw_common(ah);
+
+	/*
+	 * 0x7 = 0b111 , AR9003 needs to be configured for 3-chain mode before
+	 * running AGC/TxIQ cals
+	 */
+	ar9003_hw_set_chain_masks(ah, 0x7, 0x7);
+
+	/* Calibrate the AGC */
+	REG_WRITE(ah, AR_PHY_AGC_CONTROL,
+		  REG_READ(ah, AR_PHY_AGC_CONTROL) |
+		  AR_PHY_AGC_CONTROL_CAL);
+
+	/* Poll for offset calibration complete */
+	if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL,
+			   0, AH_WAIT_TIMEOUT)) {
+		ath_print(common, ATH_DBG_CALIBRATE,
+			  "offset calibration failed to "
+			  "complete in 1ms; noisy environment?\n");
+		return false;
+	}
+
+	/* Do Tx IQ Calibration */
+	ar9003_hw_tx_iq_cal(ah);
+
+	/* Revert chainmasks to their original values before NF cal */
+	ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask);
+
+	/* Initialize list pointers */
+	ah->cal_list = ah->cal_list_last = ah->cal_list_curr = NULL;
+
+	if (ar9003_hw_iscal_supported(ah, IQ_MISMATCH_CAL)) {
+		INIT_CAL(&ah->iq_caldata);
+		INSERT_CAL(ah, &ah->iq_caldata);
+		ath_print(common, ATH_DBG_CALIBRATE,
+			  "enabling IQ Calibration.\n");
+	}
+
+	if (ar9003_hw_iscal_supported(ah, TEMP_COMP_CAL)) {
+		INIT_CAL(&ah->tempCompCalData);
+		INSERT_CAL(ah, &ah->tempCompCalData);
+		ath_print(common, ATH_DBG_CALIBRATE,
+			  "enabling Temperature Compensation Calibration.\n");
+	}
+
+	/* Initialize current pointer to first element in list */
+	ah->cal_list_curr = ah->cal_list;
+
+	if (ah->cal_list_curr)
+		ath9k_hw_reset_calibration(ah, ah->cal_list_curr);
+
+	chan->CalValid = 0;
+
+	return true;
 }
 
 void ar9003_hw_attach_calib_ops(struct ath_hw *ah)
@@ -243,7 +797,6 @@ void ar9003_hw_attach_calib_ops(struct ath_hw *ah)
 	priv_ops->init_cal = ar9003_hw_init_cal;
 	priv_ops->setup_calibration = ar9003_hw_setup_calibration;
 	priv_ops->iscal_supported = ar9003_hw_iscal_supported;
-	priv_ops->loadnf = ar9003_hw_loadnf;
 
 	ops->calibrate = ar9003_hw_calibrate;
 }
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
index 67b3b65..fee07fd 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
@@ -814,6 +814,105 @@ void ar9003_hw_set_nf_limits(struct ath_hw *ah)
 	ah->nf_5g_min = AR_PHY_CCA_MIN_GOOD_VAL_9300_5GHZ;
 }
 
+/*
+ * Find out which of the RX chains are enabled
+ */
+static u32 ar9003_hw_get_rx_chainmask(struct ath_hw *ah)
+{
+	u32 chain = REG_READ(ah, AR_PHY_RX_CHAINMASK);
+	/*
+	 * The bits [2:0] indicate the rx chain mask and are to be
+	 * interpreted as follows:
+	 * 00x => Only chain 0 is enabled
+	 * 01x => Chain 1 and 0 enabled
+	 * 1xx => Chain 2,1 and 0 enabled
+	 */
+	return chain & 0x7;
+}
+
+static void ar9003_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)
+{
+	struct ath9k_nfcal_hist *h;
+	unsigned i, j;
+	int32_t val;
+	const u32 ar9300_cca_regs[6] = {
+		AR_PHY_CCA_0,
+		AR_PHY_CCA_1,
+		AR_PHY_CCA_2,
+		AR_PHY_EXT_CCA,
+		AR_PHY_EXT_CCA_1,
+		AR_PHY_EXT_CCA_2,
+	};
+	u8 chainmask, rx_chain_status;
+	struct ath_common *common = ath9k_hw_common(ah);
+
+	rx_chain_status = ar9003_hw_get_rx_chainmask(ah);
+
+	chainmask = 0x3F;
+	h = ah->nfCalHist;
+
+	for (i = 0; i < NUM_NF_READINGS; i++) {
+		if (chainmask & (1 << i)) {
+			val = REG_READ(ah, ar9300_cca_regs[i]);
+			val &= 0xFFFFFE00;
+			val |= (((u32) (h[i].privNF) << 1) & 0x1ff);
+			REG_WRITE(ah, ar9300_cca_regs[i], val);
+		}
+	}
+
+	/*
+	 * Load software filtered NF value into baseband internal minCCApwr
+	 * variable.
+	 */
+	REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
+		    AR_PHY_AGC_CONTROL_ENABLE_NF);
+	REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
+		    AR_PHY_AGC_CONTROL_NO_UPDATE_NF);
+	REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
+
+	/*
+	 * Wait for load to complete, should be fast, a few 10s of us.
+	 * The max delay was changed from an original 250us to 10000us
+	 * since 250us often results in NF load timeout and causes deaf
+	 * condition during stress testing 12/12/2009
+	 */
+	for (j = 0; j < 1000; j++) {
+		if ((REG_READ(ah, AR_PHY_AGC_CONTROL) &
+		     AR_PHY_AGC_CONTROL_NF) == 0)
+			break;
+		udelay(10);
+	}
+
+	/*
+	 * We timed out waiting for the noisefloor to load, probably due to an
+	 * in-progress rx. Simply return here and allow the load plenty of time
+	 * to complete before the next calibration interval.  We need to avoid
+	 * trying to load -50 (which happens below) while the previous load is
+	 * still in progress as this can cause rx deafness. Instead by returning
+	 * here, the baseband nf cal will just be capped by our present
+	 * noisefloor until the next calibration timer.
+	 */
+	if (j == 1000) {
+		ath_print(common, ATH_DBG_ANY, "Timeout while waiting for nf "
+			  "to load: AR_PHY_AGC_CONTROL=0x%x\n",
+			  REG_READ(ah, AR_PHY_AGC_CONTROL));
+	}
+
+	/*
+	 * Restore maxCCAPower register parameter again so that we're not capped
+	 * by the median we just loaded.  This will be initial (and max) value
+	 * of next noise floor calibration the baseband does.
+	 */
+	for (i = 0; i < NUM_NF_READINGS; i++) {
+		if (chainmask & (1 << i)) {
+			val = REG_READ(ah, ar9300_cca_regs[i]);
+			val &= 0xFFFFFE00;
+			val |= (((u32) (-50) << 1) & 0x1ff);
+			REG_WRITE(ah, ar9300_cca_regs[i], val);
+		}
+	}
+}
+
 void ar9003_hw_attach_phy_ops(struct ath_hw *ah)
 {
 	struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
@@ -833,4 +932,5 @@ void ar9003_hw_attach_phy_ops(struct ath_hw *ah)
 	priv_ops->set_diversity = ar9003_hw_set_diversity;
 	priv_ops->ani_control = ar9003_hw_ani_control;
 	priv_ops->do_getnf = ar9003_hw_do_getnf;
+	priv_ops->loadnf = ar9003_hw_loadnf;
 }
diff --git a/drivers/net/wireless/ath/ath9k/eeprom.h b/drivers/net/wireless/ath/ath9k/eeprom.h
index e087e2d..c0cd717 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom.h
+++ b/drivers/net/wireless/ath/ath9k/eeprom.h
@@ -155,6 +155,7 @@
 #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 */
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index d28a904..cb0421a 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -611,6 +611,7 @@ struct ath_hw {
 	struct ath9k_cal_list adcgain_caldata;
 	struct ath9k_cal_list adcdc_calinitdata;
 	struct ath9k_cal_list adcdc_caldata;
+	struct ath9k_cal_list tempCompCalData;
 	struct ath9k_cal_list *cal_list;
 	struct ath9k_cal_list *cal_list_last;
 	struct ath9k_cal_list *cal_list_curr;
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 103+ messages in thread

* [PATCH v3 67/97] ath9k_hw: rename eep_AR9287_ops to eep_ar9287_ops
  2010-04-15 21:38 [PATCH v3 00/97] ath9k: add AR9003 support Luis R. Rodriguez
                   ` (65 preceding siblings ...)
  2010-04-15 21:39 ` [PATCH v3 66/97] ath9k_hw: complete AR9003 calibration Luis R. Rodriguez
@ 2010-04-15 21:39 ` Luis R. Rodriguez
  2010-04-15 21:39 ` [PATCH v3 68/97] ath9k_hw: restore mac address reading logic Luis R. Rodriguez
                   ` (29 subsequent siblings)
  96 siblings, 0 replies; 103+ messages in thread
From: Luis R. Rodriguez @ 2010-04-15 21:39 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Luis R. Rodriguez, Senthil Balasubramanian

Signed-off-by: Senthil Balasubramanian <senthilkumar@atheros.com>
Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/eeprom.c      |    2 +-
 drivers/net/wireless/ath/ath9k/eeprom.h      |    2 +-
 drivers/net/wireless/ath/ath9k/eeprom_9287.c |    2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/eeprom.c b/drivers/net/wireless/ath/ath9k/eeprom.c
index 1a48f43..aec6ebb 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom.c
@@ -257,7 +257,7 @@ int ath9k_hw_eeprom_init(struct ath_hw *ah)
 	int status;
 
 	if (AR_SREV_9287(ah)) {
-		ah->eep_ops = &eep_AR9287_ops;
+		ah->eep_ops = &eep_ar9287_ops;
 	} else if (AR_SREV_9285(ah) || AR_SREV_9271(ah)) {
 		ah->eep_ops = &eep_4k_ops;
 	} else {
diff --git a/drivers/net/wireless/ath/ath9k/eeprom.h b/drivers/net/wireless/ath/ath9k/eeprom.h
index c0cd717..60fd5b6 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom.h
+++ b/drivers/net/wireless/ath/ath9k/eeprom.h
@@ -707,6 +707,6 @@ int ath9k_hw_eeprom_init(struct ath_hw *ah);
 
 extern const struct eeprom_ops eep_def_ops;
 extern const struct eeprom_ops eep_4k_ops;
-extern const struct eeprom_ops eep_AR9287_ops;
+extern const struct eeprom_ops eep_ar9287_ops;
 
 #endif /* EEPROM_H */
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_9287.c b/drivers/net/wireless/ath/ath9k/eeprom_9287.c
index e57c5b4..0b1e885 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom_9287.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom_9287.c
@@ -1170,7 +1170,7 @@ static u16 ath9k_hw_AR9287_get_spur_channel(struct ath_hw *ah,
 #undef EEP_MAP9287_SPURCHAN
 }
 
-const struct eeprom_ops eep_AR9287_ops = {
+const struct eeprom_ops eep_ar9287_ops = {
 	.check_eeprom		= ath9k_hw_AR9287_check_eeprom,
 	.get_eeprom		= ath9k_hw_AR9287_get_eeprom,
 	.fill_eeprom		= ath9k_hw_AR9287_fill_eeprom,
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 103+ messages in thread

* [PATCH v3 68/97] ath9k_hw: restore mac address reading logic
  2010-04-15 21:38 [PATCH v3 00/97] ath9k: add AR9003 support Luis R. Rodriguez
                   ` (66 preceding siblings ...)
  2010-04-15 21:39 ` [PATCH v3 67/97] ath9k_hw: rename eep_AR9287_ops to eep_ar9287_ops Luis R. Rodriguez
@ 2010-04-15 21:39 ` Luis R. Rodriguez
  2010-04-15 21:39 ` [PATCH v3 69/97] ath9k_hw: Implement AR9003 eeprom callbacks Luis R. Rodriguez
                   ` (28 subsequent siblings)
  96 siblings, 0 replies; 103+ messages in thread
From: Luis R. Rodriguez @ 2010-04-15 21:39 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Luis R. Rodriguez

Once upon a time the AR_EEPROM_MAC macro was added to let us
add a random attribute to the three 4-bytes of MAC addresses
entries we read from the EEPROM. This was good while a random
high-enough value was used which did not conflict with any
of the already existing enum eeprom_param values. With AR9003
support the enums overlap and it means we either increment
the random offset or just restore the reading logic to match
what the HAL has. I choose to do the later to synchronize
the logic on both code bases.

This should fix reading the MAC address from the EEPROM
on AR9003 hardware.

Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/eeprom.h      |    1 -
 drivers/net/wireless/ath/ath9k/eeprom_4k.c   |    6 +++---
 drivers/net/wireless/ath/ath9k/eeprom_9287.c |    6 +++---
 drivers/net/wireless/ath/ath9k/eeprom_def.c  |    6 +++---
 drivers/net/wireless/ath/ath9k/hw.c          |    3 ++-
 5 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/eeprom.h b/drivers/net/wireless/ath/ath9k/eeprom.h
index 60fd5b6..289084c 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom.h
+++ b/drivers/net/wireless/ath/ath9k/eeprom.h
@@ -93,7 +93,6 @@
  */
 #define AR9285_RDEXT_DEFAULT    0x1F
 
-#define AR_EEPROM_MAC(i)	(0x1d+(i))
 #define ATH9K_POW_SM(_r, _s)	(((_r) & 0x3f) << (_s))
 #define FREQ2FBIN(x, y)		((y) ? ((x) - 2300) : (((x) - 4800) / 5))
 #define ath9k_hw_use_flash(_ah)	(!(_ah->ah_flags & AH_USE_EEPROM))
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_4k.c b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
index 97279a5..2384a9f 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
@@ -183,11 +183,11 @@ static u32 ath9k_hw_4k_get_eeprom(struct ath_hw *ah,
 	switch (param) {
 	case EEP_NFTHRESH_2:
 		return pModal->noiseFloorThreshCh[0];
-	case AR_EEPROM_MAC(0):
+	case EEP_MAC_LSW:
 		return pBase->macAddr[0] << 8 | pBase->macAddr[1];
-	case AR_EEPROM_MAC(1):
+	case EEP_MAC_MID:
 		return pBase->macAddr[2] << 8 | pBase->macAddr[3];
-	case AR_EEPROM_MAC(2):
+	case EEP_MAC_MSW:
 		return pBase->macAddr[4] << 8 | pBase->macAddr[5];
 	case EEP_REG_0:
 		return pBase->regDmn[0];
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_9287.c b/drivers/net/wireless/ath/ath9k/eeprom_9287.c
index 0b1e885..b471db5 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom_9287.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom_9287.c
@@ -173,11 +173,11 @@ static u32 ath9k_hw_AR9287_get_eeprom(struct ath_hw *ah,
 	switch (param) {
 	case EEP_NFTHRESH_2:
 		return pModal->noiseFloorThreshCh[0];
-	case AR_EEPROM_MAC(0):
+	case EEP_MAC_LSW:
 		return pBase->macAddr[0] << 8 | pBase->macAddr[1];
-	case AR_EEPROM_MAC(1):
+	case EEP_MAC_MID:
 		return pBase->macAddr[2] << 8 | pBase->macAddr[3];
-	case AR_EEPROM_MAC(2):
+	case EEP_MAC_MSW:
 		return pBase->macAddr[4] << 8 | pBase->macAddr[5];
 	case EEP_REG_0:
 		return pBase->regDmn[0];
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_def.c b/drivers/net/wireless/ath/ath9k/eeprom_def.c
index 99f16a3..3d1b86b 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom_def.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom_def.c
@@ -238,11 +238,11 @@ static u32 ath9k_hw_def_get_eeprom(struct ath_hw *ah,
 		return pModal[0].noiseFloorThreshCh[0];
 	case EEP_NFTHRESH_2:
 		return pModal[1].noiseFloorThreshCh[0];
-	case AR_EEPROM_MAC(0):
+	case EEP_MAC_LSW:
 		return pBase->macAddr[0] << 8 | pBase->macAddr[1];
-	case AR_EEPROM_MAC(1):
+	case EEP_MAC_MID:
 		return pBase->macAddr[2] << 8 | pBase->macAddr[3];
-	case AR_EEPROM_MAC(2):
+	case EEP_MAC_MSW:
 		return pBase->macAddr[4] << 8 | pBase->macAddr[5];
 	case EEP_REG_0:
 		return pBase->regDmn[0];
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index b8ef2e1..8c25059 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -473,10 +473,11 @@ static int ath9k_hw_init_macaddr(struct ath_hw *ah)
 	u32 sum;
 	int i;
 	u16 eeval;
+	u32 EEP_MAC[] = { EEP_MAC_LSW, EEP_MAC_MID, EEP_MAC_MSW };
 
 	sum = 0;
 	for (i = 0; i < 3; i++) {
-		eeval = ah->eep_ops->get_eeprom(ah, AR_EEPROM_MAC(i));
+		eeval = ah->eep_ops->get_eeprom(ah, EEP_MAC[i]);
 		sum += eeval;
 		common->macaddr[2 * i] = eeval >> 8;
 		common->macaddr[2 * i + 1] = eeval & 0xff;
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 103+ messages in thread

* [PATCH v3 69/97] ath9k_hw: Implement AR9003 eeprom callbacks
  2010-04-15 21:38 [PATCH v3 00/97] ath9k: add AR9003 support Luis R. Rodriguez
                   ` (67 preceding siblings ...)
  2010-04-15 21:39 ` [PATCH v3 68/97] ath9k_hw: restore mac address reading logic Luis R. Rodriguez
@ 2010-04-15 21:39 ` Luis R. Rodriguez
  2010-04-15 21:39 ` [PATCH v3 70/97] ath9k_hw: add OFDM spur mitigation for AR9003 Luis R. Rodriguez
                   ` (27 subsequent siblings)
  96 siblings, 0 replies; 103+ messages in thread
From: Luis R. Rodriguez @ 2010-04-15 21:39 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Senthil Balasubramanian, Luis R. Rodriguez

From: Senthil Balasubramanian <senthilkumar@atheros.com>

Signed-off-by: Senthil Balasubramanian <senthilkumar@atheros.com>
Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/Makefile        |    3 +-
 drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | 1842 ++++++++++++++++++++++++
 drivers/net/wireless/ath/ath9k/ar9003_eeprom.h |  319 ++++
 drivers/net/wireless/ath/ath9k/eeprom.c        |    4 +-
 drivers/net/wireless/ath/ath9k/eeprom.h        |   11 +-
 drivers/net/wireless/ath/ath9k/hw.h            |    1 +
 drivers/net/wireless/ath/ath9k/reg.h           |   11 +
 7 files changed, 2187 insertions(+), 4 deletions(-)
 create mode 100644 drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
 create mode 100644 drivers/net/wireless/ath/ath9k/ar9003_eeprom.h

diff --git a/drivers/net/wireless/ath/ath9k/Makefile b/drivers/net/wireless/ath/ath9k/Makefile
index ee8f7e8..b0702fc 100644
--- a/drivers/net/wireless/ath/ath9k/Makefile
+++ b/drivers/net/wireless/ath/ath9k/Makefile
@@ -30,7 +30,8 @@ ath9k_hw-y:=	\
 		ani.o \
 		btcoex.o \
 		mac.o \
-		ar9003_mac.o
+		ar9003_mac.o \
+		ar9003_eeprom.o
 
 obj-$(CONFIG_ATH9K_HW) += ath9k_hw.o
 
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
new file mode 100644
index 0000000..fb39e39
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
@@ -0,0 +1,1842 @@
+/*
+ * Copyright (c) 2010 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "hw.h"
+#include "ar9003_phy.h"
+#include "ar9003_eeprom.h"
+
+#define COMP_HDR_LEN 4
+#define COMP_CKSUM_LEN 2
+
+#define AR_CH0_TOP (0x00016288)
+#define AR_CH0_TOP_XPABIASLVL (0x3)
+#define AR_CH0_TOP_XPABIASLVL_S (8)
+
+#define AR_CH0_THERM (0x00016290)
+#define AR_CH0_THERM_SPARE (0x3f)
+#define AR_CH0_THERM_SPARE_S (0)
+
+#define AR_SWITCH_TABLE_COM_ALL (0xffff)
+#define AR_SWITCH_TABLE_COM_ALL_S (0)
+
+#define AR_SWITCH_TABLE_COM2_ALL (0xffffff)
+#define AR_SWITCH_TABLE_COM2_ALL_S (0)
+
+#define AR_SWITCH_TABLE_ALL (0xfff)
+#define AR_SWITCH_TABLE_ALL_S (0)
+
+static const struct ar9300_eeprom ar9300_default = {
+	.eepromVersion = 2,
+	.templateVersion = 2,
+	.macAddr = {1, 2, 3, 4, 5, 6},
+	.custData = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+		     0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+	.baseEepHeader = {
+		.regDmn = {0, 0x1f},
+		.txrxMask =  0x77, /* 4 bits tx and 4 bits rx */
+		.opCapFlags = {
+			.opFlags = AR9300_OPFLAGS_11G | AR9300_OPFLAGS_11A,
+			.eepMisc = 0,
+		},
+		.rfSilent = 0,
+		.blueToothOptions = 0,
+		.deviceCap = 0,
+		.deviceType = 5, /* takes lower byte in eeprom location */
+		.pwrTableOffset = AR9300_PWR_TABLE_OFFSET,
+		.params_for_tuning_caps = {0, 0},
+		.featureEnable = 0x0c,
+		 /*
+		  * bit0 - enable tx temp comp - disabled
+		  * bit1 - enable tx volt comp - disabled
+		  * bit2 - enable fastClock - enabled
+		  * bit3 - enable doubling - enabled
+		  * bit4 - enable internal regulator - disabled
+		  */
+		.miscConfiguration = 0, /* bit0 - turn down drivestrength */
+		.eepromWriteEnableGpio = 3,
+		.wlanDisableGpio = 0,
+		.wlanLedGpio = 8,
+		.rxBandSelectGpio = 0xff,
+		.txrxgain = 0,
+		.swreg = 0,
+	 },
+	.modalHeader2G = {
+	/* ar9300_modal_eep_header  2g */
+		/* 4 idle,t1,t2,b(4 bits per setting) */
+		.antCtrlCommon = 0x110,
+		/* 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12 */
+		.antCtrlCommon2 = 0x22222,
+
+		/*
+		 * antCtrlChain[AR9300_MAX_CHAINS]; 6 idle, t, r,
+		 * rx1, rx12, b (2 bits each)
+		 */
+		.antCtrlChain = {0x150, 0x150, 0x150},
+
+		/*
+		 * xatten1DB[AR9300_MAX_CHAINS];  3 xatten1_db
+		 * for ar9280 (0xa20c/b20c 5:0)
+		 */
+		.xatten1DB = {0, 0, 0},
+
+		/*
+		 * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
+		 * for ar9280 (0xa20c/b20c 16:12
+		 */
+		.xatten1Margin = {0, 0, 0},
+		.tempSlope = 36,
+		.voltSlope = 0,
+
+		/*
+		 * spurChans[OSPREY_EEPROM_MODAL_SPURS]; spur
+		 * channels in usual fbin coding format
+		 */
+		.spurChans = {0, 0, 0, 0, 0},
+
+		/*
+		 * noiseFloorThreshCh[AR9300_MAX_CHAINS]; 3 Check
+		 * if the register is per chain
+		 */
+		.noiseFloorThreshCh = {-1, 0, 0},
+		.ob = {1, 1, 1},/* 3 chain */
+		.db_stage2 = {1, 1, 1}, /* 3 chain  */
+		.db_stage3 = {0, 0, 0},
+		.db_stage4 = {0, 0, 0},
+		.xpaBiasLvl = 0,
+		.txFrameToDataStart = 0x0e,
+		.txFrameToPaOn = 0x0e,
+		.txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
+		.antennaGain = 0,
+		.switchSettling = 0x2c,
+		.adcDesiredSize = -30,
+		.txEndToXpaOff = 0,
+		.txEndToRxOn = 0x2,
+		.txFrameToXpaOn = 0xe,
+		.thresh62 = 28,
+		.futureModal = { /* [32] */
+			0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+			0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+		},
+	 },
+	.calFreqPier2G = {
+		FREQ2FBIN(2412, 1),
+		FREQ2FBIN(2437, 1),
+		FREQ2FBIN(2472, 1),
+	 },
+	/* ar9300_cal_data_per_freq_op_loop 2g */
+	.calPierData2G = {
+		{ {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
+		{ {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
+		{ {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
+	 },
+	.calTarget_freqbin_Cck = {
+		FREQ2FBIN(2412, 1),
+		FREQ2FBIN(2484, 1),
+	 },
+	.calTarget_freqbin_2G = {
+		FREQ2FBIN(2412, 1),
+		FREQ2FBIN(2437, 1),
+		FREQ2FBIN(2472, 1)
+	 },
+	.calTarget_freqbin_2GHT20 = {
+		FREQ2FBIN(2412, 1),
+		FREQ2FBIN(2437, 1),
+		FREQ2FBIN(2472, 1)
+	 },
+	.calTarget_freqbin_2GHT40 = {
+		FREQ2FBIN(2412, 1),
+		FREQ2FBIN(2437, 1),
+		FREQ2FBIN(2472, 1)
+	 },
+	.calTargetPowerCck = {
+		 /* 1L-5L,5S,11L,11S */
+		 { {36, 36, 36, 36} },
+		 { {36, 36, 36, 36} },
+	},
+	.calTargetPower2G = {
+		 /* 6-24,36,48,54 */
+		 { {32, 32, 28, 24} },
+		 { {32, 32, 28, 24} },
+		 { {32, 32, 28, 24} },
+	},
+	.calTargetPower2GHT20 = {
+		{ {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
+		{ {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
+		{ {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
+	},
+	.calTargetPower2GHT40 = {
+		{ {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
+		{ {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
+		{ {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
+	},
+	.ctlIndex_2G =  {
+		0x11, 0x12, 0x15, 0x17, 0x41, 0x42,
+		0x45, 0x47, 0x31, 0x32, 0x35, 0x37,
+	},
+	.ctl_freqbin_2G = {
+		{
+			FREQ2FBIN(2412, 1),
+			FREQ2FBIN(2417, 1),
+			FREQ2FBIN(2457, 1),
+			FREQ2FBIN(2462, 1)
+		},
+		{
+			FREQ2FBIN(2412, 1),
+			FREQ2FBIN(2417, 1),
+			FREQ2FBIN(2462, 1),
+			0xFF,
+		},
+
+		{
+			FREQ2FBIN(2412, 1),
+			FREQ2FBIN(2417, 1),
+			FREQ2FBIN(2462, 1),
+			0xFF,
+		},
+		{
+			FREQ2FBIN(2422, 1),
+			FREQ2FBIN(2427, 1),
+			FREQ2FBIN(2447, 1),
+			FREQ2FBIN(2452, 1)
+		},
+
+		{
+			/* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
+			/* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
+			/* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
+			/* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(2484, 1),
+		},
+
+		{
+			/* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
+			/* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
+			/* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
+			0,
+		},
+
+		{
+			/* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
+			/* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
+			FREQ2FBIN(2472, 1),
+			0,
+		},
+
+		{
+			/* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
+			/* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
+			/* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
+			/* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
+		},
+
+		{
+			/* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
+			/* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
+			/* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
+		},
+
+		{
+			/* Data[9].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
+			/* Data[9].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
+			/* Data[9].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
+			0
+		},
+
+		{
+			/* Data[10].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
+			/* Data[10].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
+			/* Data[10].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
+			0
+		},
+
+		{
+			/* Data[11].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
+			/* Data[11].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
+			/* Data[11].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
+			/* Data[11].ctlEdges[3].bChannel */
+			FREQ2FBIN(2462, 1),
+		}
+	 },
+	.ctlPowerData_2G = {
+		 { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } },
+		 { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } },
+		 { { {60, 1}, {60, 0}, {60, 0}, {60, 1} } },
+
+		 { { {60, 1}, {60, 0}, {0, 0}, {0, 0} } },
+		 { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } },
+		 { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } },
+
+		 { { {60, 0}, {60, 1}, {60, 1}, {60, 0} } },
+		 { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } },
+		 { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } },
+
+		 { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } },
+		 { { {60, 0}, {60, 1}, {60, 1}, {60, 1} } },
+	 },
+	.modalHeader5G = {
+		/* 4 idle,t1,t2,b (4 bits per setting) */
+		.antCtrlCommon = 0x110,
+		/* 4 ra1l1, ra2l1, ra1l2,ra2l2,ra12 */
+		.antCtrlCommon2 = 0x22222,
+		 /* antCtrlChain 6 idle, t,r,rx1,rx12,b (2 bits each) */
+		.antCtrlChain = {
+			0x000, 0x000, 0x000,
+		},
+		 /* xatten1DB 3 xatten1_db for AR9280 (0xa20c/b20c 5:0) */
+		.xatten1DB = {0, 0, 0},
+
+		/*
+		 * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
+		 * for merlin (0xa20c/b20c 16:12
+		 */
+		.xatten1Margin = {0, 0, 0},
+		.tempSlope = 68,
+		.voltSlope = 0,
+		/* spurChans spur channels in usual fbin coding format */
+		.spurChans = {0, 0, 0, 0, 0},
+		/* noiseFloorThreshCh Check if the register is per chain */
+		.noiseFloorThreshCh = {-1, 0, 0},
+		.ob = {3, 3, 3}, /* 3 chain */
+		.db_stage2 = {3, 3, 3}, /* 3 chain */
+		.db_stage3 = {3, 3, 3}, /* doesn't exist for 2G */
+		.db_stage4 = {3, 3, 3},	 /* don't exist for 2G */
+		.xpaBiasLvl = 0,
+		.txFrameToDataStart = 0x0e,
+		.txFrameToPaOn = 0x0e,
+		.txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
+		.antennaGain = 0,
+		.switchSettling = 0x2d,
+		.adcDesiredSize = -30,
+		.txEndToXpaOff = 0,
+		.txEndToRxOn = 0x2,
+		.txFrameToXpaOn = 0xe,
+		.thresh62 = 28,
+		.futureModal = {
+			0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+			0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+		},
+	 },
+	.calFreqPier5G = {
+		FREQ2FBIN(5180, 0),
+		FREQ2FBIN(5220, 0),
+		FREQ2FBIN(5320, 0),
+		FREQ2FBIN(5400, 0),
+		FREQ2FBIN(5500, 0),
+		FREQ2FBIN(5600, 0),
+		FREQ2FBIN(5725, 0),
+		FREQ2FBIN(5825, 0)
+	},
+	.calPierData5G = {
+			{
+				{0, 0, 0, 0, 0},
+				{0, 0, 0, 0, 0},
+				{0, 0, 0, 0, 0},
+				{0, 0, 0, 0, 0},
+				{0, 0, 0, 0, 0},
+				{0, 0, 0, 0, 0},
+				{0, 0, 0, 0, 0},
+				{0, 0, 0, 0, 0},
+			},
+			{
+				{0, 0, 0, 0, 0},
+				{0, 0, 0, 0, 0},
+				{0, 0, 0, 0, 0},
+				{0, 0, 0, 0, 0},
+				{0, 0, 0, 0, 0},
+				{0, 0, 0, 0, 0},
+				{0, 0, 0, 0, 0},
+				{0, 0, 0, 0, 0},
+			},
+			{
+				{0, 0, 0, 0, 0},
+				{0, 0, 0, 0, 0},
+				{0, 0, 0, 0, 0},
+				{0, 0, 0, 0, 0},
+				{0, 0, 0, 0, 0},
+				{0, 0, 0, 0, 0},
+				{0, 0, 0, 0, 0},
+				{0, 0, 0, 0, 0},
+			},
+
+	},
+	.calTarget_freqbin_5G = {
+		FREQ2FBIN(5180, 0),
+		FREQ2FBIN(5220, 0),
+		FREQ2FBIN(5320, 0),
+		FREQ2FBIN(5400, 0),
+		FREQ2FBIN(5500, 0),
+		FREQ2FBIN(5600, 0),
+		FREQ2FBIN(5725, 0),
+		FREQ2FBIN(5825, 0)
+	},
+	.calTarget_freqbin_5GHT20 = {
+		FREQ2FBIN(5180, 0),
+		FREQ2FBIN(5240, 0),
+		FREQ2FBIN(5320, 0),
+		FREQ2FBIN(5500, 0),
+		FREQ2FBIN(5700, 0),
+		FREQ2FBIN(5745, 0),
+		FREQ2FBIN(5725, 0),
+		FREQ2FBIN(5825, 0)
+	},
+	.calTarget_freqbin_5GHT40 = {
+		FREQ2FBIN(5180, 0),
+		FREQ2FBIN(5240, 0),
+		FREQ2FBIN(5320, 0),
+		FREQ2FBIN(5500, 0),
+		FREQ2FBIN(5700, 0),
+		FREQ2FBIN(5745, 0),
+		FREQ2FBIN(5725, 0),
+		FREQ2FBIN(5825, 0)
+	 },
+	.calTargetPower5G = {
+		/* 6-24,36,48,54 */
+		{ {20, 20, 20, 10} },
+		{ {20, 20, 20, 10} },
+		{ {20, 20, 20, 10} },
+		{ {20, 20, 20, 10} },
+		{ {20, 20, 20, 10} },
+		{ {20, 20, 20, 10} },
+		{ {20, 20, 20, 10} },
+		{ {20, 20, 20, 10} },
+	 },
+	.calTargetPower5GHT20 = {
+		/*
+		 * 0_8_16,1-3_9-11_17-19,
+		 * 4,5,6,7,12,13,14,15,20,21,22,23
+		 */
+		{ {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
+		{ {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
+		{ {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
+		{ {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
+		{ {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
+		{ {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
+		{ {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
+		{ {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
+	 },
+	.calTargetPower5GHT40 =  {
+		/*
+		 * 0_8_16,1-3_9-11_17-19,
+		 * 4,5,6,7,12,13,14,15,20,21,22,23
+		 */
+		{ {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
+		{ {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
+		{ {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
+		{ {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
+		{ {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
+		{ {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
+		{ {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
+		{ {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
+	 },
+	.ctlIndex_5G =  {
+		0x10, 0x16, 0x18, 0x40, 0x46,
+		0x48, 0x30, 0x36, 0x38
+	},
+	.ctl_freqbin_5G =  {
+		{
+			/* Data[0].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
+			/* Data[0].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
+			/* Data[0].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
+			/* Data[0].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
+			/* Data[0].ctlEdges[4].bChannel */ FREQ2FBIN(5600, 0),
+			/* Data[0].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
+			/* Data[0].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
+			/* Data[0].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
+		},
+		{
+			/* Data[1].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
+			/* Data[1].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
+			/* Data[1].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
+			/* Data[1].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
+			/* Data[1].ctlEdges[4].bChannel */ FREQ2FBIN(5520, 0),
+			/* Data[1].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
+			/* Data[1].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
+			/* Data[1].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
+		},
+
+		{
+			/* Data[2].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
+			/* Data[2].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
+			/* Data[2].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
+			/* Data[2].ctlEdges[3].bChannel */ FREQ2FBIN(5310, 0),
+			/* Data[2].ctlEdges[4].bChannel */ FREQ2FBIN(5510, 0),
+			/* Data[2].ctlEdges[5].bChannel */ FREQ2FBIN(5550, 0),
+			/* Data[2].ctlEdges[6].bChannel */ FREQ2FBIN(5670, 0),
+			/* Data[2].ctlEdges[7].bChannel */ FREQ2FBIN(5755, 0)
+		},
+
+		{
+			/* Data[3].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
+			/* Data[3].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
+			/* Data[3].ctlEdges[2].bChannel */ FREQ2FBIN(5260, 0),
+			/* Data[3].ctlEdges[3].bChannel */ FREQ2FBIN(5320, 0),
+			/* Data[3].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
+			/* Data[3].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
+			/* Data[3].ctlEdges[6].bChannel */ 0xFF,
+			/* Data[3].ctlEdges[7].bChannel */ 0xFF,
+		},
+
+		{
+			/* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
+			/* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
+			/* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(5500, 0),
+			/* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(5700, 0),
+			/* Data[4].ctlEdges[4].bChannel */ 0xFF,
+			/* Data[4].ctlEdges[5].bChannel */ 0xFF,
+			/* Data[4].ctlEdges[6].bChannel */ 0xFF,
+			/* Data[4].ctlEdges[7].bChannel */ 0xFF,
+		},
+
+		{
+			/* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
+			/* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(5270, 0),
+			/* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(5310, 0),
+			/* Data[5].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
+			/* Data[5].ctlEdges[4].bChannel */ FREQ2FBIN(5590, 0),
+			/* Data[5].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
+			/* Data[5].ctlEdges[6].bChannel */ 0xFF,
+			/* Data[5].ctlEdges[7].bChannel */ 0xFF
+		},
+
+		{
+			/* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
+			/* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
+			/* Data[6].ctlEdges[2].bChannel */ FREQ2FBIN(5220, 0),
+			/* Data[6].ctlEdges[3].bChannel */ FREQ2FBIN(5260, 0),
+			/* Data[6].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
+			/* Data[6].ctlEdges[5].bChannel */ FREQ2FBIN(5600, 0),
+			/* Data[6].ctlEdges[6].bChannel */ FREQ2FBIN(5700, 0),
+			/* Data[6].ctlEdges[7].bChannel */ FREQ2FBIN(5745, 0)
+		},
+
+		{
+			/* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
+			/* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
+			/* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(5320, 0),
+			/* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
+			/* Data[7].ctlEdges[4].bChannel */ FREQ2FBIN(5560, 0),
+			/* Data[7].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
+			/* Data[7].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
+			/* Data[7].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
+		},
+
+		{
+			/* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
+			/* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
+			/* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
+			/* Data[8].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
+			/* Data[8].ctlEdges[4].bChannel */ FREQ2FBIN(5550, 0),
+			/* Data[8].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
+			/* Data[8].ctlEdges[6].bChannel */ FREQ2FBIN(5755, 0),
+			/* Data[8].ctlEdges[7].bChannel */ FREQ2FBIN(5795, 0)
+		}
+	 },
+	.ctlPowerData_5G = {
+		{
+			{
+				{60, 1}, {60, 1}, {60, 1}, {60, 1},
+				{60, 1}, {60, 1}, {60, 1}, {60, 0},
+			}
+		},
+		{
+			{
+				{60, 1}, {60, 1}, {60, 1}, {60, 1},
+				{60, 1}, {60, 1}, {60, 1}, {60, 0},
+			}
+		},
+		{
+			{
+				{60, 0}, {60, 1}, {60, 0}, {60, 1},
+				{60, 1}, {60, 1}, {60, 1}, {60, 1},
+			}
+		},
+		{
+			{
+				{60, 0}, {60, 1}, {60, 1}, {60, 0},
+				{60, 1}, {60, 0}, {60, 0}, {60, 0},
+			}
+		},
+		{
+			{
+				{60, 1}, {60, 1}, {60, 1}, {60, 0},
+				{60, 0}, {60, 0}, {60, 0}, {60, 0},
+			}
+		},
+		{
+			{
+				{60, 1}, {60, 1}, {60, 1}, {60, 1},
+				{60, 1}, {60, 0}, {60, 0}, {60, 0},
+			}
+		},
+		{
+			{
+				{60, 1}, {60, 1}, {60, 1}, {60, 1},
+				{60, 1}, {60, 1}, {60, 1}, {60, 1},
+			}
+		},
+		{
+			{
+				{60, 1}, {60, 1}, {60, 0}, {60, 1},
+				{60, 1}, {60, 1}, {60, 1}, {60, 0},
+			}
+		},
+		{
+			{
+				{60, 1}, {60, 0}, {60, 1}, {60, 1},
+				{60, 1}, {60, 1}, {60, 0}, {60, 1},
+			}
+		},
+	 }
+};
+
+static int ath9k_hw_ar9300_check_eeprom(struct ath_hw *ah)
+{
+	return 0;
+}
+
+static u32 ath9k_hw_ar9300_get_eeprom(struct ath_hw *ah,
+				      enum eeprom_param param)
+{
+	struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
+	struct ar9300_base_eep_hdr *pBase = &eep->baseEepHeader;
+
+	switch (param) {
+	case EEP_MAC_LSW:
+		return eep->macAddr[0] << 8 | eep->macAddr[1];
+	case EEP_MAC_MID:
+		return eep->macAddr[2] << 8 | eep->macAddr[3];
+	case EEP_MAC_MSW:
+		return eep->macAddr[4] << 8 | eep->macAddr[5];
+	case EEP_REG_0:
+		return pBase->regDmn[0];
+	case EEP_REG_1:
+		return pBase->regDmn[1];
+	case EEP_OP_CAP:
+		return pBase->deviceCap;
+	case EEP_OP_MODE:
+		return pBase->opCapFlags.opFlags;
+	case EEP_RF_SILENT:
+		return pBase->rfSilent;
+	case EEP_TX_MASK:
+		return (pBase->txrxMask >> 4) & 0xf;
+	case EEP_RX_MASK:
+		return pBase->txrxMask & 0xf;
+	case EEP_DRIVE_STRENGTH:
+#define AR9300_EEP_BASE_DRIV_STRENGTH	0x1
+		return pBase->miscConfiguration & AR9300_EEP_BASE_DRIV_STRENGTH;
+	case EEP_INTERNAL_REGULATOR:
+		/* Bit 4 is internal regulator flag */
+		return (pBase->featureEnable & 0x10) >> 4;
+	case EEP_SWREG:
+		return pBase->swreg;
+	default:
+		return 0;
+	}
+}
+
+#ifdef __BIG_ENDIAN
+static void ar9300_swap_eeprom(struct ar9300_eeprom *eep)
+{
+	u32 dword;
+	u16 word;
+	int i;
+
+	word = swab16(eep->baseEepHeader.regDmn[0]);
+	eep->baseEepHeader.regDmn[0] = word;
+
+	word = swab16(eep->baseEepHeader.regDmn[1]);
+	eep->baseEepHeader.regDmn[1] = word;
+
+	dword = swab32(eep->modalHeader2G.antCtrlCommon);
+	eep->modalHeader2G.antCtrlCommon = dword;
+
+	dword = swab32(eep->modalHeader2G.antCtrlCommon2);
+	eep->modalHeader2G.antCtrlCommon2 = dword;
+
+	dword = swab32(eep->modalHeader5G.antCtrlCommon);
+	eep->modalHeader5G.antCtrlCommon = dword;
+
+	dword = swab32(eep->modalHeader5G.antCtrlCommon2);
+	eep->modalHeader5G.antCtrlCommon2 = dword;
+
+	for (i = 0; i < AR9300_MAX_CHAINS; i++) {
+		word = swab16(eep->modalHeader2G.antCtrlChain[i]);
+		eep->modalHeader2G.antCtrlChain[i] = word;
+
+		word = swab16(eep->modalHeader5G.antCtrlChain[i]);
+		eep->modalHeader5G.antCtrlChain[i] = word;
+	}
+}
+#endif
+
+static bool ar9300_hw_read_eeprom(struct ath_hw *ah,
+				  long address, u8 *buffer, int many)
+{
+	int i;
+	u8 value[2];
+	unsigned long eepAddr;
+	unsigned long byteAddr;
+	u16 *svalue;
+	struct ath_common *common = ath9k_hw_common(ah);
+
+	if ((address < 0) || ((address + many) > AR9300_EEPROM_SIZE - 1)) {
+		ath_print(common, ATH_DBG_EEPROM,
+			  "eeprom address not in range\n");
+		return false;
+	}
+
+	for (i = 0; i < many; i++) {
+		eepAddr = (u16) (address + i) / 2;
+		byteAddr = (u16) (address + i) % 2;
+		svalue = (u16 *) value;
+		if (!ath9k_hw_nvram_read(common, eepAddr, svalue)) {
+			ath_print(common, ATH_DBG_EEPROM,
+				  "unable to read eeprom region\n");
+			return false;
+		}
+		*svalue = le16_to_cpu(*svalue);
+		buffer[i] = value[byteAddr];
+	}
+
+	return true;
+}
+
+static bool ar9300_read_eeprom(struct ath_hw *ah,
+			       int address, u8 *buffer, int many)
+{
+	int it;
+
+	for (it = 0; it < many; it++)
+		if (!ar9300_hw_read_eeprom(ah,
+					   (address - it),
+					   (buffer + it), 1))
+			return false;
+	return true;
+}
+
+static void ar9300_comp_hdr_unpack(u8 *best, int *code, int *reference,
+				   int *length, int *major, int *minor)
+{
+	unsigned long value[4];
+
+	value[0] = best[0];
+	value[1] = best[1];
+	value[2] = best[2];
+	value[3] = best[3];
+	*code = ((value[0] >> 5) & 0x0007);
+	*reference = (value[0] & 0x001f) | ((value[1] >> 2) & 0x0020);
+	*length = ((value[1] << 4) & 0x07f0) | ((value[2] >> 4) & 0x000f);
+	*major = (value[2] & 0x000f);
+	*minor = (value[3] & 0x00ff);
+}
+
+static u16 ar9300_comp_cksum(u8 *data, int dsize)
+{
+	int it, checksum = 0;
+
+	for (it = 0; it < dsize; it++) {
+		checksum += data[it];
+		checksum &= 0xffff;
+	}
+
+	return checksum;
+}
+
+static bool ar9300_uncompress_block(struct ath_hw *ah,
+				    u8 *mptr,
+				    int mdataSize,
+				    u8 *block,
+				    int size)
+{
+	int it;
+	int spot;
+	int offset;
+	int length;
+	struct ath_common *common = ath9k_hw_common(ah);
+
+	spot = 0;
+
+	for (it = 0; it < size; it += (length+2)) {
+		offset = block[it];
+		offset &= 0xff;
+		spot += offset;
+		length = block[it+1];
+		length &= 0xff;
+
+		if (length > 0 && spot >= 0 && spot+length < mdataSize) {
+			ath_print(common, ATH_DBG_EEPROM,
+				  "Restore at %d: spot=%d "
+				  "offset=%d length=%d\n",
+				   it, spot, offset, length);
+			memcpy(&mptr[spot], &block[it+2], length);
+			spot += length;
+		} else if (length > 0) {
+			ath_print(common, ATH_DBG_EEPROM,
+				  "Bad restore at %d: spot=%d "
+				  "offset=%d length=%d\n",
+				  it, spot, offset, length);
+			return false;
+		}
+	}
+	return true;
+}
+
+static int ar9300_compress_decision(struct ath_hw *ah,
+				    int it,
+				    int code,
+				    int reference,
+				    u8 *mptr,
+				    u8 *word, int length, int mdata_size)
+{
+	struct ath_common *common = ath9k_hw_common(ah);
+	u8 *dptr;
+
+	switch (code) {
+	case _CompressNone:
+		if (length != mdata_size) {
+			ath_print(common, ATH_DBG_EEPROM,
+				  "EEPROM structure size mismatch"
+				  "memory=%d eeprom=%d\n", mdata_size, length);
+			return -1;
+		}
+		memcpy(mptr, (u8 *) (word + COMP_HDR_LEN), length);
+		ath_print(common, ATH_DBG_EEPROM, "restored eeprom %d:"
+			  " uncompressed, length %d\n", it, length);
+		break;
+	case _CompressBlock:
+		if (reference == 0) {
+			dptr = mptr;
+		} else {
+			if (reference != 2) {
+				ath_print(common, ATH_DBG_EEPROM,
+					  "cant find reference eeprom"
+					  "struct %d\n", reference);
+				return -1;
+			}
+			memcpy(mptr, &ar9300_default, mdata_size);
+		}
+		ath_print(common, ATH_DBG_EEPROM,
+			  "restore eeprom %d: block, reference %d,"
+			  " length %d\n", it, reference, length);
+		ar9300_uncompress_block(ah, mptr, mdata_size,
+					(u8 *) (word + COMP_HDR_LEN), length);
+		break;
+	default:
+		ath_print(common, ATH_DBG_EEPROM, "unknown compression"
+			  " code %d\n", code);
+		return -1;
+	}
+	return 0;
+}
+
+/*
+ * Read the configuration data from the eeprom.
+ * The data can be put in any specified memory buffer.
+ *
+ * Returns -1 on error.
+ * Returns address of next memory location on success.
+ */
+static int ar9300_eeprom_restore_internal(struct ath_hw *ah,
+					  u8 *mptr, int mdata_size)
+{
+#define MDEFAULT 15
+#define MSTATE 100
+	int cptr;
+	u8 *word;
+	int code;
+	int reference, length, major, minor;
+	int osize;
+	int it;
+	u16 checksum, mchecksum;
+	struct ath_common *common = ath9k_hw_common(ah);
+
+	word = kzalloc(2048, GFP_KERNEL);
+	if (!word)
+		return -1;
+
+	memcpy(mptr, &ar9300_default, mdata_size);
+
+	cptr = AR9300_BASE_ADDR;
+	for (it = 0; it < MSTATE; it++) {
+		if (!ar9300_read_eeprom(ah, cptr, word, COMP_HDR_LEN))
+			goto fail;
+
+		if ((word[0] == 0 && word[1] == 0 && word[2] == 0 &&
+		     word[3] == 0) || (word[0] == 0xff && word[1] == 0xff
+				       && word[2] == 0xff && word[3] == 0xff))
+			break;
+
+		ar9300_comp_hdr_unpack(word, &code, &reference,
+				       &length, &major, &minor);
+		ath_print(common, ATH_DBG_EEPROM,
+			  "Found block at %x: code=%d ref=%d"
+			  "length=%d major=%d minor=%d\n", cptr, code,
+			  reference, length, major, minor);
+		if (length >= 1024) {
+			ath_print(common, ATH_DBG_EEPROM,
+				  "Skipping bad header\n");
+			cptr -= COMP_HDR_LEN;
+			continue;
+		}
+
+		osize = length;
+		ar9300_read_eeprom(ah, cptr, word,
+				   COMP_HDR_LEN + osize + COMP_CKSUM_LEN);
+		checksum = ar9300_comp_cksum(&word[COMP_HDR_LEN], length);
+		mchecksum = word[COMP_HDR_LEN + osize] |
+		    (word[COMP_HDR_LEN + osize + 1] << 8);
+		ath_print(common, ATH_DBG_EEPROM,
+			  "checksum %x %x\n", checksum, mchecksum);
+		if (checksum == mchecksum) {
+			ar9300_compress_decision(ah, it, code, reference, mptr,
+						 word, length, mdata_size);
+		} else {
+			ath_print(common, ATH_DBG_EEPROM,
+				  "skipping block with bad checksum\n");
+		}
+		cptr -= (COMP_HDR_LEN + osize + COMP_CKSUM_LEN);
+	}
+
+	kfree(word);
+	return cptr;
+
+fail:
+	kfree(word);
+	return -1;
+}
+
+/*
+ * Restore the configuration structure by reading the eeprom.
+ * This function destroys any existing in-memory structure
+ * content.
+ */
+static bool ath9k_hw_ar9300_fill_eeprom(struct ath_hw *ah)
+{
+	u8 *mptr = NULL;
+	int mdata_size;
+
+	mptr = (u8 *) &ah->eeprom.ar9300_eep;
+	mdata_size = sizeof(struct ar9300_eeprom);
+
+	if (mptr && mdata_size > 0) {
+		/* At this point, mptr points to the eeprom data structure
+		 * in it's "default" state. If this is big endian, swap the
+		 * data structures back to "little endian"
+		 */
+		/* First swap, default to Little Endian */
+#ifdef __BIG_ENDIAN
+		ar9300_swap_eeprom((struct ar9300_eeprom *)mptr);
+#endif
+		if (ar9300_eeprom_restore_internal(ah, mptr, mdata_size) >= 0)
+			return true;
+
+		/* Second Swap, back to Big Endian */
+#ifdef __BIG_ENDIAN
+		ar9300_swap_eeprom((struct ar9300_eeprom *)mptr);
+#endif
+	}
+	return false;
+}
+
+/* XXX: review hardware docs */
+static int ath9k_hw_ar9300_get_eeprom_ver(struct ath_hw *ah)
+{
+	return ah->eeprom.ar9300_eep.eepromVersion;
+}
+
+/* XXX: could be read from the eepromVersion, not sure yet */
+static int ath9k_hw_ar9300_get_eeprom_rev(struct ath_hw *ah)
+{
+	return 0;
+}
+
+static u8 ath9k_hw_ar9300_get_num_ant_config(struct ath_hw *ah,
+					     enum ieee80211_band freq_band)
+{
+	return 1;
+}
+
+static u16 ath9k_hw_ar9300_get_eeprom_antenna_cfg(struct ath_hw *ah,
+						  struct ath9k_channel *chan)
+{
+	return -EINVAL;
+}
+
+static s32 ar9003_hw_xpa_bias_level_get(struct ath_hw *ah, bool is2ghz)
+{
+	struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
+
+	if (is2ghz)
+		return eep->modalHeader2G.xpaBiasLvl;
+	else
+		return eep->modalHeader5G.xpaBiasLvl;
+}
+
+static void ar9003_hw_xpa_bias_level_apply(struct ath_hw *ah, bool is2ghz)
+{
+	int bias = ar9003_hw_xpa_bias_level_get(ah, is2ghz);
+	REG_RMW_FIELD(ah, AR_CH0_TOP, AR_CH0_TOP_XPABIASLVL, (bias & 0x3));
+	REG_RMW_FIELD(ah, AR_CH0_THERM, AR_CH0_THERM_SPARE,
+		      ((bias >> 2) & 0x3));
+}
+
+static u32 ar9003_hw_ant_ctrl_common_get(struct ath_hw *ah, bool is2ghz)
+{
+	struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
+
+	if (is2ghz)
+		return eep->modalHeader2G.antCtrlCommon;
+	else
+		return eep->modalHeader5G.antCtrlCommon;
+}
+
+static u32 ar9003_hw_ant_ctrl_common_2_get(struct ath_hw *ah, bool is2ghz)
+{
+	struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
+
+	if (is2ghz)
+		return eep->modalHeader2G.antCtrlCommon2;
+	else
+		return eep->modalHeader5G.antCtrlCommon2;
+}
+
+static u16 ar9003_hw_ant_ctrl_chain_get(struct ath_hw *ah,
+					int chain,
+					bool is2ghz)
+{
+	struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
+
+	if (chain >= 0 && chain < AR9300_MAX_CHAINS) {
+		if (is2ghz)
+			return eep->modalHeader2G.antCtrlChain[chain];
+		else
+			return eep->modalHeader5G.antCtrlChain[chain];
+	}
+
+	return 0;
+}
+
+static void ar9003_hw_ant_ctrl_apply(struct ath_hw *ah, bool is2ghz)
+{
+	u32 value = ar9003_hw_ant_ctrl_common_get(ah, is2ghz);
+	REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM, AR_SWITCH_TABLE_COM_ALL, value);
+
+	value = ar9003_hw_ant_ctrl_common_2_get(ah, is2ghz);
+	REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM_2, AR_SWITCH_TABLE_COM2_ALL, value);
+
+	value = ar9003_hw_ant_ctrl_chain_get(ah, 0, is2ghz);
+	REG_RMW_FIELD(ah, AR_PHY_SWITCH_CHAIN_0, AR_SWITCH_TABLE_ALL, value);
+
+	value = ar9003_hw_ant_ctrl_chain_get(ah, 1, is2ghz);
+	REG_RMW_FIELD(ah, AR_PHY_SWITCH_CHAIN_1, AR_SWITCH_TABLE_ALL, value);
+
+	value = ar9003_hw_ant_ctrl_chain_get(ah, 2, is2ghz);
+	REG_RMW_FIELD(ah, AR_PHY_SWITCH_CHAIN_2, AR_SWITCH_TABLE_ALL, value);
+}
+
+static void ar9003_hw_drive_strength_apply(struct ath_hw *ah)
+{
+	int drive_strength;
+	unsigned long reg;
+
+	drive_strength = ath9k_hw_ar9300_get_eeprom(ah, EEP_DRIVE_STRENGTH);
+
+	if (!drive_strength)
+		return;
+
+	reg = REG_READ(ah, AR_PHY_65NM_CH0_BIAS1);
+	reg &= ~0x00ffffc0;
+	reg |= 0x5 << 21;
+	reg |= 0x5 << 18;
+	reg |= 0x5 << 15;
+	reg |= 0x5 << 12;
+	reg |= 0x5 << 9;
+	reg |= 0x5 << 6;
+	REG_WRITE(ah, AR_PHY_65NM_CH0_BIAS1, reg);
+
+	reg = REG_READ(ah, AR_PHY_65NM_CH0_BIAS2);
+	reg &= ~0xffffffe0;
+	reg |= 0x5 << 29;
+	reg |= 0x5 << 26;
+	reg |= 0x5 << 23;
+	reg |= 0x5 << 20;
+	reg |= 0x5 << 17;
+	reg |= 0x5 << 14;
+	reg |= 0x5 << 11;
+	reg |= 0x5 << 8;
+	reg |= 0x5 << 5;
+	REG_WRITE(ah, AR_PHY_65NM_CH0_BIAS2, reg);
+
+	reg = REG_READ(ah, AR_PHY_65NM_CH0_BIAS4);
+	reg &= ~0xff800000;
+	reg |= 0x5 << 29;
+	reg |= 0x5 << 26;
+	reg |= 0x5 << 23;
+	REG_WRITE(ah, AR_PHY_65NM_CH0_BIAS4, reg);
+}
+
+static void ar9003_hw_internal_regulator_apply(struct ath_hw *ah)
+{
+	int internal_regulator =
+		ath9k_hw_ar9300_get_eeprom(ah, EEP_INTERNAL_REGULATOR);
+
+	if (internal_regulator) {
+		/* Internal regulator is ON. Write swreg register. */
+		int swreg = ath9k_hw_ar9300_get_eeprom(ah, EEP_SWREG);
+		REG_WRITE(ah, AR_RTC_REG_CONTROL1,
+		REG_READ(ah, AR_RTC_REG_CONTROL1) &
+			 (~AR_RTC_REG_CONTROL1_SWREG_PROGRAM));
+		REG_WRITE(ah, AR_RTC_REG_CONTROL0, swreg);
+		/* Set REG_CONTROL1.SWREG_PROGRAM */
+		REG_WRITE(ah, AR_RTC_REG_CONTROL1,
+			  REG_READ(ah,
+				   AR_RTC_REG_CONTROL1) |
+				   AR_RTC_REG_CONTROL1_SWREG_PROGRAM);
+	} else {
+		REG_WRITE(ah, AR_RTC_SLEEP_CLK,
+			  (REG_READ(ah,
+				    AR_RTC_SLEEP_CLK) |
+				    AR_RTC_FORCE_SWREG_PRD));
+	}
+}
+
+static void ath9k_hw_ar9300_set_board_values(struct ath_hw *ah,
+					     struct ath9k_channel *chan)
+{
+	ar9003_hw_xpa_bias_level_apply(ah, IS_CHAN_2GHZ(chan));
+	ar9003_hw_ant_ctrl_apply(ah, IS_CHAN_2GHZ(chan));
+	ar9003_hw_drive_strength_apply(ah);
+	ar9003_hw_internal_regulator_apply(ah);
+}
+
+static void ath9k_hw_ar9300_set_addac(struct ath_hw *ah,
+				      struct ath9k_channel *chan)
+{
+}
+
+/*
+ * Returns the interpolated y value corresponding to the specified x value
+ * from the np ordered pairs of data (px,py).
+ * The pairs do not have to be in any order.
+ * If the specified x value is less than any of the px,
+ * the returned y value is equal to the py for the lowest px.
+ * If the specified x value is greater than any of the px,
+ * the returned y value is equal to the py for the highest px.
+ */
+static int ar9003_hw_power_interpolate(int32_t x,
+				       int32_t *px, int32_t *py, u_int16_t np)
+{
+	int ip = 0;
+	int lx = 0, ly = 0, lhave = 0;
+	int hx = 0, hy = 0, hhave = 0;
+	int dx = 0;
+	int y = 0;
+
+	lhave = 0;
+	hhave = 0;
+
+	/* identify best lower and higher x calibration measurement */
+	for (ip = 0; ip < np; ip++) {
+		dx = x - px[ip];
+
+		/* this measurement is higher than our desired x */
+		if (dx <= 0) {
+			if (!hhave || dx > (x - hx)) {
+				/* new best higher x measurement */
+				hx = px[ip];
+				hy = py[ip];
+				hhave = 1;
+			}
+		}
+		/* this measurement is lower than our desired x */
+		if (dx >= 0) {
+			if (!lhave || dx < (x - lx)) {
+				/* new best lower x measurement */
+				lx = px[ip];
+				ly = py[ip];
+				lhave = 1;
+			}
+		}
+	}
+
+	/* the low x is good */
+	if (lhave) {
+		/* so is the high x */
+		if (hhave) {
+			/* they're the same, so just pick one */
+			if (hx == lx)
+				y = ly;
+			else	/* interpolate  */
+				y = ly + (((x - lx) * (hy - ly)) / (hx - lx));
+		} else		/* only low is good, use it */
+			y = ly;
+	} else if (hhave)	/* only high is good, use it */
+		y = hy;
+	else /* nothing is good,this should never happen unless np=0, ???? */
+		y = -(1 << 30);
+	return y;
+}
+
+static u8 ar9003_hw_eeprom_get_tgt_pwr(struct ath_hw *ah,
+				       u16 rateIndex, u16 freq, bool is2GHz)
+{
+	u16 numPiers, i;
+	s32 targetPowerArray[AR9300_NUM_5G_20_TARGET_POWERS];
+	s32 freqArray[AR9300_NUM_5G_20_TARGET_POWERS];
+	struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
+	struct cal_tgt_pow_legacy *pEepromTargetPwr;
+	u8 *pFreqBin;
+
+	if (is2GHz) {
+		numPiers = AR9300_NUM_5G_20_TARGET_POWERS;
+		pEepromTargetPwr = eep->calTargetPower2G;
+		pFreqBin = eep->calTarget_freqbin_2G;
+	} else {
+		numPiers = AR9300_NUM_5G_20_TARGET_POWERS;
+		pEepromTargetPwr = eep->calTargetPower5G;
+		pFreqBin = eep->calTarget_freqbin_5G;
+	}
+
+	/*
+	 * create array of channels and targetpower from
+	 * targetpower piers stored on eeprom
+	 */
+	for (i = 0; i < numPiers; i++) {
+		freqArray[i] = FBIN2FREQ(pFreqBin[i], is2GHz);
+		targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex];
+	}
+
+	/* interpolate to get target power for given frequency */
+	return (u8) ar9003_hw_power_interpolate((s32) freq,
+						 freqArray,
+						 targetPowerArray, numPiers);
+}
+
+static u8 ar9003_hw_eeprom_get_ht20_tgt_pwr(struct ath_hw *ah,
+					    u16 rateIndex,
+					    u16 freq, bool is2GHz)
+{
+	u16 numPiers, i;
+	s32 targetPowerArray[AR9300_NUM_5G_20_TARGET_POWERS];
+	s32 freqArray[AR9300_NUM_5G_20_TARGET_POWERS];
+	struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
+	struct cal_tgt_pow_ht *pEepromTargetPwr;
+	u8 *pFreqBin;
+
+	if (is2GHz) {
+		numPiers = AR9300_NUM_5G_20_TARGET_POWERS;
+		pEepromTargetPwr = eep->calTargetPower2GHT20;
+		pFreqBin = eep->calTarget_freqbin_2GHT20;
+	} else {
+		numPiers = AR9300_NUM_5G_20_TARGET_POWERS;
+		pEepromTargetPwr = eep->calTargetPower5GHT20;
+		pFreqBin = eep->calTarget_freqbin_5GHT20;
+	}
+
+	/*
+	 * create array of channels and targetpower
+	 * from targetpower piers stored on eeprom
+	 */
+	for (i = 0; i < numPiers; i++) {
+		freqArray[i] = FBIN2FREQ(pFreqBin[i], is2GHz);
+		targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex];
+	}
+
+	/* interpolate to get target power for given frequency */
+	return (u8) ar9003_hw_power_interpolate((s32) freq,
+						 freqArray,
+						 targetPowerArray, numPiers);
+}
+
+static u8 ar9003_hw_eeprom_get_ht40_tgt_pwr(struct ath_hw *ah,
+					    u16 rateIndex,
+					    u16 freq, bool is2GHz)
+{
+	u16 numPiers, i;
+	s32 targetPowerArray[AR9300_NUM_5G_40_TARGET_POWERS];
+	s32 freqArray[AR9300_NUM_5G_40_TARGET_POWERS];
+	struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
+	struct cal_tgt_pow_ht *pEepromTargetPwr;
+	u8 *pFreqBin;
+
+	if (is2GHz) {
+		numPiers = AR9300_NUM_2G_40_TARGET_POWERS;
+		pEepromTargetPwr = eep->calTargetPower2GHT40;
+		pFreqBin = eep->calTarget_freqbin_2GHT40;
+	} else {
+		numPiers = AR9300_NUM_5G_40_TARGET_POWERS;
+		pEepromTargetPwr = eep->calTargetPower5GHT40;
+		pFreqBin = eep->calTarget_freqbin_5GHT40;
+	}
+
+	/*
+	 * create array of channels and targetpower from
+	 * targetpower piers stored on eeprom
+	 */
+	for (i = 0; i < numPiers; i++) {
+		freqArray[i] = FBIN2FREQ(pFreqBin[i], is2GHz);
+		targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex];
+	}
+
+	/* interpolate to get target power for given frequency */
+	return (u8) ar9003_hw_power_interpolate((s32) freq,
+						 freqArray,
+						 targetPowerArray, numPiers);
+}
+
+static u8 ar9003_hw_eeprom_get_cck_tgt_pwr(struct ath_hw *ah,
+					   u16 rateIndex, u16 freq)
+{
+	u16 numPiers = AR9300_NUM_2G_CCK_TARGET_POWERS, i;
+	s32 targetPowerArray[AR9300_NUM_2G_CCK_TARGET_POWERS];
+	s32 freqArray[AR9300_NUM_2G_CCK_TARGET_POWERS];
+	struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
+	struct cal_tgt_pow_legacy *pEepromTargetPwr = eep->calTargetPowerCck;
+	u8 *pFreqBin = eep->calTarget_freqbin_Cck;
+
+	/*
+	 * create array of channels and targetpower from
+	 * targetpower piers stored on eeprom
+	 */
+	for (i = 0; i < numPiers; i++) {
+		freqArray[i] = FBIN2FREQ(pFreqBin[i], 1);
+		targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex];
+	}
+
+	/* interpolate to get target power for given frequency */
+	return (u8) ar9003_hw_power_interpolate((s32) freq,
+						 freqArray,
+						 targetPowerArray, numPiers);
+}
+
+/* Set tx power registers to array of values passed in */
+static int ar9003_hw_tx_power_regwrite(struct ath_hw *ah, u8 * pPwrArray)
+{
+#define POW_SM(_r, _s)     (((_r) & 0x3f) << (_s))
+	/* make sure forced gain is not set */
+	REG_WRITE(ah, 0xa458, 0);
+
+	/* Write the OFDM power per rate set */
+
+	/* 6 (LSB), 9, 12, 18 (MSB) */
+	REG_WRITE(ah, 0xa3c0,
+		  POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 24) |
+		  POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 16) |
+		  POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 8) |
+		  POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 0));
+
+	/* 24 (LSB), 36, 48, 54 (MSB) */
+	REG_WRITE(ah, 0xa3c4,
+		  POW_SM(pPwrArray[ALL_TARGET_LEGACY_54], 24) |
+		  POW_SM(pPwrArray[ALL_TARGET_LEGACY_48], 16) |
+		  POW_SM(pPwrArray[ALL_TARGET_LEGACY_36], 8) |
+		  POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 0));
+
+	/* Write the CCK power per rate set */
+
+	/* 1L (LSB), reserved, 2L, 2S (MSB) */
+	REG_WRITE(ah, 0xa3c8,
+		  POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 24) |
+		  POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 16) |
+		  /* POW_SM(txPowerTimes2,  8) | this is reserved for AR9003 */
+		  POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 0));
+
+	/* 5.5L (LSB), 5.5S, 11L, 11S (MSB) */
+	REG_WRITE(ah, 0xa3cc,
+		  POW_SM(pPwrArray[ALL_TARGET_LEGACY_11S], 24) |
+		  POW_SM(pPwrArray[ALL_TARGET_LEGACY_11L], 16) |
+		  POW_SM(pPwrArray[ALL_TARGET_LEGACY_5S], 8) |
+		  POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 0)
+	    );
+
+	/* Write the HT20 power per rate set */
+
+	/* 0/8/16 (LSB), 1-3/9-11/17-19, 4, 5 (MSB) */
+	REG_WRITE(ah, 0xa3d0,
+		  POW_SM(pPwrArray[ALL_TARGET_HT20_5], 24) |
+		  POW_SM(pPwrArray[ALL_TARGET_HT20_4], 16) |
+		  POW_SM(pPwrArray[ALL_TARGET_HT20_1_3_9_11_17_19], 8) |
+		  POW_SM(pPwrArray[ALL_TARGET_HT20_0_8_16], 0)
+	    );
+
+	/* 6 (LSB), 7, 12, 13 (MSB) */
+	REG_WRITE(ah, 0xa3d4,
+		  POW_SM(pPwrArray[ALL_TARGET_HT20_13], 24) |
+		  POW_SM(pPwrArray[ALL_TARGET_HT20_12], 16) |
+		  POW_SM(pPwrArray[ALL_TARGET_HT20_7], 8) |
+		  POW_SM(pPwrArray[ALL_TARGET_HT20_6], 0)
+	    );
+
+	/* 14 (LSB), 15, 20, 21 */
+	REG_WRITE(ah, 0xa3e4,
+		  POW_SM(pPwrArray[ALL_TARGET_HT20_21], 24) |
+		  POW_SM(pPwrArray[ALL_TARGET_HT20_20], 16) |
+		  POW_SM(pPwrArray[ALL_TARGET_HT20_15], 8) |
+		  POW_SM(pPwrArray[ALL_TARGET_HT20_14], 0)
+	    );
+
+	/* Mixed HT20 and HT40 rates */
+
+	/* HT20 22 (LSB), HT20 23, HT40 22, HT40 23 (MSB) */
+	REG_WRITE(ah, 0xa3e8,
+		  POW_SM(pPwrArray[ALL_TARGET_HT40_23], 24) |
+		  POW_SM(pPwrArray[ALL_TARGET_HT40_22], 16) |
+		  POW_SM(pPwrArray[ALL_TARGET_HT20_23], 8) |
+		  POW_SM(pPwrArray[ALL_TARGET_HT20_22], 0)
+	    );
+
+	/*
+	 * Write the HT40 power per rate set
+	 * correct PAR difference between HT40 and HT20/LEGACY
+	 * 0/8/16 (LSB), 1-3/9-11/17-19, 4, 5 (MSB)
+	 */
+	REG_WRITE(ah, 0xa3d8,
+		  POW_SM(pPwrArray[ALL_TARGET_HT40_5], 24) |
+		  POW_SM(pPwrArray[ALL_TARGET_HT40_4], 16) |
+		  POW_SM(pPwrArray[ALL_TARGET_HT40_1_3_9_11_17_19], 8) |
+		  POW_SM(pPwrArray[ALL_TARGET_HT40_0_8_16], 0)
+	    );
+
+	/* 6 (LSB), 7, 12, 13 (MSB) */
+	REG_WRITE(ah, 0xa3dc,
+		  POW_SM(pPwrArray[ALL_TARGET_HT40_13], 24) |
+		  POW_SM(pPwrArray[ALL_TARGET_HT40_12], 16) |
+		  POW_SM(pPwrArray[ALL_TARGET_HT40_7], 8) |
+		  POW_SM(pPwrArray[ALL_TARGET_HT40_6], 0)
+	    );
+
+	/* 14 (LSB), 15, 20, 21 */
+	REG_WRITE(ah, 0xa3ec,
+		  POW_SM(pPwrArray[ALL_TARGET_HT40_21], 24) |
+		  POW_SM(pPwrArray[ALL_TARGET_HT40_20], 16) |
+		  POW_SM(pPwrArray[ALL_TARGET_HT40_15], 8) |
+		  POW_SM(pPwrArray[ALL_TARGET_HT40_14], 0)
+	    );
+
+	return 0;
+#undef POW_SM
+}
+
+static void ar9003_hw_set_target_power_eeprom(struct ath_hw *ah, u16 freq)
+{
+	u8 targetPowerValT2[ar9300RateSize];
+	/* XXX: hard code for now, need to get from eeprom struct */
+	u8 ht40PowerIncForPdadc = 0;
+	bool is2GHz = false;
+	unsigned int i = 0;
+	struct ath_common *common = ath9k_hw_common(ah);
+
+	if (freq < 4000)
+		is2GHz = true;
+
+	targetPowerValT2[ALL_TARGET_LEGACY_6_24] =
+	    ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_6_24, freq,
+					 is2GHz);
+	targetPowerValT2[ALL_TARGET_LEGACY_36] =
+	    ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_36, freq,
+					 is2GHz);
+	targetPowerValT2[ALL_TARGET_LEGACY_48] =
+	    ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_48, freq,
+					 is2GHz);
+	targetPowerValT2[ALL_TARGET_LEGACY_54] =
+	    ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_54, freq,
+					 is2GHz);
+	targetPowerValT2[ALL_TARGET_LEGACY_1L_5L] =
+	    ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_1L_5L,
+					     freq);
+	targetPowerValT2[ALL_TARGET_LEGACY_5S] =
+	    ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_5S, freq);
+	targetPowerValT2[ALL_TARGET_LEGACY_11L] =
+	    ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_11L, freq);
+	targetPowerValT2[ALL_TARGET_LEGACY_11S] =
+	    ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_11S, freq);
+	targetPowerValT2[ALL_TARGET_HT20_0_8_16] =
+	    ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_0_8_16, freq,
+					      is2GHz);
+	targetPowerValT2[ALL_TARGET_HT20_1_3_9_11_17_19] =
+	    ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_1_3_9_11_17_19,
+					      freq, is2GHz);
+	targetPowerValT2[ALL_TARGET_HT20_4] =
+	    ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_4, freq,
+					      is2GHz);
+	targetPowerValT2[ALL_TARGET_HT20_5] =
+	    ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_5, freq,
+					      is2GHz);
+	targetPowerValT2[ALL_TARGET_HT20_6] =
+	    ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_6, freq,
+					      is2GHz);
+	targetPowerValT2[ALL_TARGET_HT20_7] =
+	    ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_7, freq,
+					      is2GHz);
+	targetPowerValT2[ALL_TARGET_HT20_12] =
+	    ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_12, freq,
+					      is2GHz);
+	targetPowerValT2[ALL_TARGET_HT20_13] =
+	    ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_13, freq,
+					      is2GHz);
+	targetPowerValT2[ALL_TARGET_HT20_14] =
+	    ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_14, freq,
+					      is2GHz);
+	targetPowerValT2[ALL_TARGET_HT20_15] =
+	    ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_15, freq,
+					      is2GHz);
+	targetPowerValT2[ALL_TARGET_HT20_20] =
+	    ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_20, freq,
+					      is2GHz);
+	targetPowerValT2[ALL_TARGET_HT20_21] =
+	    ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_21, freq,
+					      is2GHz);
+	targetPowerValT2[ALL_TARGET_HT20_22] =
+	    ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_22, freq,
+					      is2GHz);
+	targetPowerValT2[ALL_TARGET_HT20_23] =
+	    ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_23, freq,
+					      is2GHz);
+	targetPowerValT2[ALL_TARGET_HT40_0_8_16] =
+	    ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_0_8_16, freq,
+					      is2GHz) + ht40PowerIncForPdadc;
+	targetPowerValT2[ALL_TARGET_HT40_1_3_9_11_17_19] =
+	    ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_1_3_9_11_17_19,
+					      freq,
+					      is2GHz) + ht40PowerIncForPdadc;
+	targetPowerValT2[ALL_TARGET_HT40_4] =
+	    ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_4, freq,
+					      is2GHz) + ht40PowerIncForPdadc;
+	targetPowerValT2[ALL_TARGET_HT40_5] =
+	    ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_5, freq,
+					      is2GHz) + ht40PowerIncForPdadc;
+	targetPowerValT2[ALL_TARGET_HT40_6] =
+	    ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_6, freq,
+					      is2GHz) + ht40PowerIncForPdadc;
+	targetPowerValT2[ALL_TARGET_HT40_7] =
+	    ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_7, freq,
+					      is2GHz) + ht40PowerIncForPdadc;
+	targetPowerValT2[ALL_TARGET_HT40_12] =
+	    ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_12, freq,
+					      is2GHz) + ht40PowerIncForPdadc;
+	targetPowerValT2[ALL_TARGET_HT40_13] =
+	    ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_13, freq,
+					      is2GHz) + ht40PowerIncForPdadc;
+	targetPowerValT2[ALL_TARGET_HT40_14] =
+	    ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_14, freq,
+					      is2GHz) + ht40PowerIncForPdadc;
+	targetPowerValT2[ALL_TARGET_HT40_15] =
+	    ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_15, freq,
+					      is2GHz) + ht40PowerIncForPdadc;
+	targetPowerValT2[ALL_TARGET_HT40_20] =
+	    ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_20, freq,
+					      is2GHz) + ht40PowerIncForPdadc;
+	targetPowerValT2[ALL_TARGET_HT40_21] =
+	    ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_21, freq,
+					      is2GHz) + ht40PowerIncForPdadc;
+	targetPowerValT2[ALL_TARGET_HT40_22] =
+	    ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_22, freq,
+					      is2GHz) + ht40PowerIncForPdadc;
+	targetPowerValT2[ALL_TARGET_HT40_23] =
+	    ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_23, freq,
+					      is2GHz) + ht40PowerIncForPdadc;
+
+	while (i < ar9300RateSize) {
+		ath_print(common, ATH_DBG_EEPROM,
+			  "TPC[%02d] 0x%08x ", i, targetPowerValT2[i]);
+		i++;
+
+		ath_print(common, ATH_DBG_EEPROM,
+			  "TPC[%02d] 0x%08x ", i, targetPowerValT2[i]);
+		i++;
+
+		ath_print(common, ATH_DBG_EEPROM,
+			  "TPC[%02d] 0x%08x ", i, targetPowerValT2[i]);
+		i++;
+
+		ath_print(common, ATH_DBG_EEPROM,
+			  "TPC[%02d] 0x%08x\n", i, targetPowerValT2[i]);
+		i++;
+	}
+
+	/* Write target power array to registers */
+	ar9003_hw_tx_power_regwrite(ah, targetPowerValT2);
+}
+
+static int ar9003_hw_cal_pier_get(struct ath_hw *ah,
+				  int mode,
+				  int ipier,
+				  int ichain,
+				  int *pfrequency,
+				  int *pcorrection,
+				  int *ptemperature, int *pvoltage)
+{
+	u8 *pCalPier;
+	struct ar9300_cal_data_per_freq_op_loop *pCalPierStruct;
+	int is2GHz;
+	struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
+	struct ath_common *common = ath9k_hw_common(ah);
+
+	if (ichain >= AR9300_MAX_CHAINS) {
+		ath_print(common, ATH_DBG_EEPROM,
+			  "Invalid chain index, must be less than %d\n",
+			  AR9300_MAX_CHAINS);
+		return -1;
+	}
+
+	if (mode) {		/* 5GHz */
+		if (ipier >= AR9300_NUM_5G_CAL_PIERS) {
+			ath_print(common, ATH_DBG_EEPROM,
+				  "Invalid 5GHz cal pier index, must "
+				  "be less than %d\n",
+				  AR9300_NUM_5G_CAL_PIERS);
+			return -1;
+		}
+		pCalPier = &(eep->calFreqPier5G[ipier]);
+		pCalPierStruct = &(eep->calPierData5G[ichain][ipier]);
+		is2GHz = 0;
+	} else {
+		if (ipier >= AR9300_NUM_2G_CAL_PIERS) {
+			ath_print(common, ATH_DBG_EEPROM,
+				  "Invalid 2GHz cal pier index, must "
+				  "be less than %d\n", AR9300_NUM_2G_CAL_PIERS);
+			return -1;
+		}
+
+		pCalPier = &(eep->calFreqPier2G[ipier]);
+		pCalPierStruct = &(eep->calPierData2G[ichain][ipier]);
+		is2GHz = 1;
+	}
+
+	*pfrequency = FBIN2FREQ(*pCalPier, is2GHz);
+	*pcorrection = pCalPierStruct->refPower;
+	*ptemperature = pCalPierStruct->tempMeas;
+	*pvoltage = pCalPierStruct->voltMeas;
+
+	return 0;
+}
+
+static int ar9003_hw_power_control_override(struct ath_hw *ah,
+					    int frequency,
+					    int *correction,
+					    int *voltage, int *temperature)
+{
+	int tempSlope = 0;
+	struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
+
+	REG_RMW(ah, AR_PHY_TPC_11_B0,
+		(correction[0] << AR_PHY_TPC_OLPC_GAIN_DELTA_S),
+		AR_PHY_TPC_OLPC_GAIN_DELTA);
+	REG_RMW(ah, AR_PHY_TPC_11_B1,
+		(correction[1] << AR_PHY_TPC_OLPC_GAIN_DELTA_S),
+		AR_PHY_TPC_OLPC_GAIN_DELTA);
+	REG_RMW(ah, AR_PHY_TPC_11_B2,
+		(correction[2] << AR_PHY_TPC_OLPC_GAIN_DELTA_S),
+		AR_PHY_TPC_OLPC_GAIN_DELTA);
+
+	/* enable open loop power control on chip */
+	REG_RMW(ah, AR_PHY_TPC_6_B0,
+		(3 << AR_PHY_TPC_6_ERROR_EST_MODE_S),
+		AR_PHY_TPC_6_ERROR_EST_MODE);
+	REG_RMW(ah, AR_PHY_TPC_6_B1,
+		(3 << AR_PHY_TPC_6_ERROR_EST_MODE_S),
+		AR_PHY_TPC_6_ERROR_EST_MODE);
+	REG_RMW(ah, AR_PHY_TPC_6_B2,
+		(3 << AR_PHY_TPC_6_ERROR_EST_MODE_S),
+		AR_PHY_TPC_6_ERROR_EST_MODE);
+
+	/*
+	 * enable temperature compensation
+	 * Need to use register names
+	 */
+	if (frequency < 4000)
+		tempSlope = eep->modalHeader2G.tempSlope;
+	else
+		tempSlope = eep->modalHeader5G.tempSlope;
+
+	REG_RMW_FIELD(ah, AR_PHY_TPC_19, AR_PHY_TPC_19_ALPHA_THERM, tempSlope);
+	REG_RMW_FIELD(ah, AR_PHY_TPC_18, AR_PHY_TPC_18_THERM_CAL_VALUE,
+		      temperature[0]);
+
+	return 0;
+}
+
+/* Apply the recorded correction values. */
+static int ar9003_hw_calibration_apply(struct ath_hw *ah, int frequency)
+{
+	int ichain, ipier, npier;
+	int mode;
+	int lfrequency[AR9300_MAX_CHAINS],
+	    lcorrection[AR9300_MAX_CHAINS],
+	    ltemperature[AR9300_MAX_CHAINS], lvoltage[AR9300_MAX_CHAINS];
+	int hfrequency[AR9300_MAX_CHAINS],
+	    hcorrection[AR9300_MAX_CHAINS],
+	    htemperature[AR9300_MAX_CHAINS], hvoltage[AR9300_MAX_CHAINS];
+	int fdiff;
+	int correction[AR9300_MAX_CHAINS],
+	    voltage[AR9300_MAX_CHAINS], temperature[AR9300_MAX_CHAINS];
+	int pfrequency, pcorrection, ptemperature, pvoltage;
+	struct ath_common *common = ath9k_hw_common(ah);
+
+	mode = (frequency >= 4000);
+	if (mode)
+		npier = AR9300_NUM_5G_CAL_PIERS;
+	else
+		npier = AR9300_NUM_2G_CAL_PIERS;
+
+	for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) {
+		lfrequency[ichain] = 0;
+		hfrequency[ichain] = 100000;
+	}
+	/* identify best lower and higher frequency calibration measurement */
+	for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) {
+		for (ipier = 0; ipier < npier; ipier++) {
+			if (!ar9003_hw_cal_pier_get(ah, mode, ipier, ichain,
+						    &pfrequency, &pcorrection,
+						    &ptemperature, &pvoltage)) {
+				fdiff = frequency - pfrequency;
+
+				/*
+				 * this measurement is higher than
+				 * our desired frequency
+				 */
+				if (fdiff <= 0) {
+					if (hfrequency[ichain] <= 0 ||
+					    hfrequency[ichain] >= 100000 ||
+					    fdiff >
+					    (frequency - hfrequency[ichain])) {
+						/*
+						 * new best higher
+						 * frequency measurement
+						 */
+						hfrequency[ichain] = pfrequency;
+						hcorrection[ichain] =
+						    pcorrection;
+						htemperature[ichain] =
+						    ptemperature;
+						hvoltage[ichain] = pvoltage;
+					}
+				}
+				if (fdiff >= 0) {
+					if (lfrequency[ichain] <= 0
+					    || fdiff <
+					    (frequency - lfrequency[ichain])) {
+						/*
+						 * new best lower
+						 * frequency measurement
+						 */
+						lfrequency[ichain] = pfrequency;
+						lcorrection[ichain] =
+						    pcorrection;
+						ltemperature[ichain] =
+						    ptemperature;
+						lvoltage[ichain] = pvoltage;
+					}
+				}
+			}
+		}
+	}
+
+	/* interpolate  */
+	for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) {
+		ath_print(common, ATH_DBG_EEPROM,
+			  "ch=%d f=%d low=%d %d h=%d %d\n",
+			  ichain, frequency, lfrequency[ichain],
+			  lcorrection[ichain], hfrequency[ichain],
+			  hcorrection[ichain]);
+		/* they're the same, so just pick one */
+		if (hfrequency[ichain] == lfrequency[ichain]) {
+			correction[ichain] = lcorrection[ichain];
+			voltage[ichain] = lvoltage[ichain];
+			temperature[ichain] = ltemperature[ichain];
+		}
+		/* the low frequency is good */
+		else if (frequency - lfrequency[ichain] < 1000) {
+			/* so is the high frequency, interpolate */
+			if (hfrequency[ichain] - frequency < 1000) {
+
+				correction[ichain] = lcorrection[ichain] +
+				    (((frequency - lfrequency[ichain]) *
+				      (hcorrection[ichain] -
+				       lcorrection[ichain])) /
+				     (hfrequency[ichain] - lfrequency[ichain]));
+
+				temperature[ichain] = ltemperature[ichain] +
+				    (((frequency - lfrequency[ichain]) *
+				      (htemperature[ichain] -
+				       ltemperature[ichain])) /
+				     (hfrequency[ichain] - lfrequency[ichain]));
+
+				voltage[ichain] =
+				    lvoltage[ichain] +
+				    (((frequency -
+				       lfrequency[ichain]) * (hvoltage[ichain] -
+							      lvoltage[ichain]))
+				     / (hfrequency[ichain] -
+					lfrequency[ichain]));
+			}
+			/* only low is good, use it */
+			else {
+				correction[ichain] = lcorrection[ichain];
+				temperature[ichain] = ltemperature[ichain];
+				voltage[ichain] = lvoltage[ichain];
+			}
+		}
+		/* only high is good, use it */
+		else if (hfrequency[ichain] - frequency < 1000) {
+			correction[ichain] = hcorrection[ichain];
+			temperature[ichain] = htemperature[ichain];
+			voltage[ichain] = hvoltage[ichain];
+		} else {	/* nothing is good, presume 0???? */
+			correction[ichain] = 0;
+			temperature[ichain] = 0;
+			voltage[ichain] = 0;
+		}
+	}
+
+	ar9003_hw_power_control_override(ah, frequency, correction, voltage,
+					 temperature);
+
+	ath_print(common, ATH_DBG_EEPROM,
+		  "for frequency=%d, calibration correction = %d %d %d\n",
+		  frequency, correction[0], correction[1], correction[2]);
+
+	return 0;
+}
+
+static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah,
+					struct ath9k_channel *chan, u16 cfgCtl,
+					u8 twiceAntennaReduction,
+					u8 twiceMaxRegulatoryPower,
+					u8 powerLimit)
+{
+	ar9003_hw_set_target_power_eeprom(ah, chan->channel);
+	ar9003_hw_calibration_apply(ah, chan->channel);
+}
+
+static u16 ath9k_hw_ar9300_get_spur_channel(struct ath_hw *ah,
+					    u16 i, bool is2GHz)
+{
+	return AR_NO_SPUR;
+}
+
+const struct eeprom_ops eep_ar9300_ops = {
+	.check_eeprom = ath9k_hw_ar9300_check_eeprom,
+	.get_eeprom = ath9k_hw_ar9300_get_eeprom,
+	.fill_eeprom = ath9k_hw_ar9300_fill_eeprom,
+	.get_eeprom_ver = ath9k_hw_ar9300_get_eeprom_ver,
+	.get_eeprom_rev = ath9k_hw_ar9300_get_eeprom_rev,
+	.get_num_ant_config = ath9k_hw_ar9300_get_num_ant_config,
+	.get_eeprom_antenna_cfg = ath9k_hw_ar9300_get_eeprom_antenna_cfg,
+	.set_board_values = ath9k_hw_ar9300_set_board_values,
+	.set_addac = ath9k_hw_ar9300_set_addac,
+	.set_txpower = ath9k_hw_ar9300_set_txpower,
+	.get_spur_channel = ath9k_hw_ar9300_get_spur_channel
+};
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h
new file mode 100644
index 0000000..3ca520c
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h
@@ -0,0 +1,319 @@
+#ifndef AR9003_EEPROM_H
+#define AR9003_EEPROM_H
+
+#include <linux/types.h>
+
+#define AR9300_EEP_VER               0xD000
+#define AR9300_EEP_VER_MINOR_MASK    0xFFF
+#define AR9300_EEP_MINOR_VER_1       0x1
+#define AR9300_EEP_MINOR_VER         AR9300_EEP_MINOR_VER_1
+
+/* 16-bit offset location start of calibration struct */
+#define AR9300_EEP_START_LOC         256
+#define AR9300_NUM_5G_CAL_PIERS      8
+#define AR9300_NUM_2G_CAL_PIERS      3
+#define AR9300_NUM_5G_20_TARGET_POWERS  8
+#define AR9300_NUM_5G_40_TARGET_POWERS  8
+#define AR9300_NUM_2G_CCK_TARGET_POWERS 2
+#define AR9300_NUM_2G_20_TARGET_POWERS  3
+#define AR9300_NUM_2G_40_TARGET_POWERS  3
+/* #define AR9300_NUM_CTLS              21 */
+#define AR9300_NUM_CTLS_5G           9
+#define AR9300_NUM_CTLS_2G           12
+#define AR9300_CTL_MODE_M            0xF
+#define AR9300_NUM_BAND_EDGES_5G     8
+#define AR9300_NUM_BAND_EDGES_2G     4
+#define AR9300_NUM_PD_GAINS          4
+#define AR9300_PD_GAINS_IN_MASK      4
+#define AR9300_PD_GAIN_ICEPTS        5
+#define AR9300_EEPROM_MODAL_SPURS    5
+#define AR9300_MAX_RATE_POWER        63
+#define AR9300_NUM_PDADC_VALUES      128
+#define AR9300_NUM_RATES             16
+#define AR9300_BCHAN_UNUSED          0xFF
+#define AR9300_MAX_PWR_RANGE_IN_HALF_DB 64
+#define AR9300_OPFLAGS_11A           0x01
+#define AR9300_OPFLAGS_11G           0x02
+#define AR9300_OPFLAGS_5G_HT40       0x04
+#define AR9300_OPFLAGS_2G_HT40       0x08
+#define AR9300_OPFLAGS_5G_HT20       0x10
+#define AR9300_OPFLAGS_2G_HT20       0x20
+#define AR9300_EEPMISC_BIG_ENDIAN    0x01
+#define AR9300_EEPMISC_WOW           0x02
+#define AR9300_CUSTOMER_DATA_SIZE    20
+
+#define FREQ2FBIN(x, y) ((y) ? ((x) - 2300) : (((x) - 4800) / 5))
+#define FBIN2FREQ(x, y) ((y) ? (2300 + x) : (4800 + 5 * x))
+#define AR9300_MAX_CHAINS            3
+#define AR9300_ANT_16S               25
+#define AR9300_FUTURE_MODAL_SZ       6
+
+#define AR9300_NUM_ANT_CHAIN_FIELDS     7
+#define AR9300_NUM_ANT_COMMON_FIELDS    4
+#define AR9300_SIZE_ANT_CHAIN_FIELD     3
+#define AR9300_SIZE_ANT_COMMON_FIELD    4
+#define AR9300_ANT_CHAIN_MASK           0x7
+#define AR9300_ANT_COMMON_MASK          0xf
+#define AR9300_CHAIN_0_IDX              0
+#define AR9300_CHAIN_1_IDX              1
+#define AR9300_CHAIN_2_IDX              2
+
+#define AR928X_NUM_ANT_CHAIN_FIELDS     6
+#define AR928X_SIZE_ANT_CHAIN_FIELD     2
+#define AR928X_ANT_CHAIN_MASK           0x3
+
+/* Delta from which to start power to pdadc table */
+/* This offset is used in both open loop and closed loop power control
+ * schemes. In open loop power control, it is not really needed, but for
+ * the "sake of consistency" it was kept. For certain AP designs, this
+ * value is overwritten by the value in the flag "pwrTableOffset" just
+ * before writing the pdadc vs pwr into the chip registers.
+ */
+#define AR9300_PWR_TABLE_OFFSET  0
+
+/* enable flags for voltage and temp compensation */
+#define ENABLE_TEMP_COMPENSATION 0x01
+#define ENABLE_VOLT_COMPENSATION 0x02
+/* byte addressable */
+#define AR9300_EEPROM_SIZE (16*1024)
+#define FIXED_CCA_THRESHOLD 15
+
+#define AR9300_BASE_ADDR 0x3ff
+
+enum targetPowerHTRates {
+	HT_TARGET_RATE_0_8_16,
+	HT_TARGET_RATE_1_3_9_11_17_19,
+	HT_TARGET_RATE_4,
+	HT_TARGET_RATE_5,
+	HT_TARGET_RATE_6,
+	HT_TARGET_RATE_7,
+	HT_TARGET_RATE_12,
+	HT_TARGET_RATE_13,
+	HT_TARGET_RATE_14,
+	HT_TARGET_RATE_15,
+	HT_TARGET_RATE_20,
+	HT_TARGET_RATE_21,
+	HT_TARGET_RATE_22,
+	HT_TARGET_RATE_23
+};
+
+enum targetPowerLegacyRates {
+	LEGACY_TARGET_RATE_6_24,
+	LEGACY_TARGET_RATE_36,
+	LEGACY_TARGET_RATE_48,
+	LEGACY_TARGET_RATE_54
+};
+
+enum targetPowerCckRates {
+	LEGACY_TARGET_RATE_1L_5L,
+	LEGACY_TARGET_RATE_5S,
+	LEGACY_TARGET_RATE_11L,
+	LEGACY_TARGET_RATE_11S
+};
+
+enum ar9300_Rates {
+	ALL_TARGET_LEGACY_6_24,
+	ALL_TARGET_LEGACY_36,
+	ALL_TARGET_LEGACY_48,
+	ALL_TARGET_LEGACY_54,
+	ALL_TARGET_LEGACY_1L_5L,
+	ALL_TARGET_LEGACY_5S,
+	ALL_TARGET_LEGACY_11L,
+	ALL_TARGET_LEGACY_11S,
+	ALL_TARGET_HT20_0_8_16,
+	ALL_TARGET_HT20_1_3_9_11_17_19,
+	ALL_TARGET_HT20_4,
+	ALL_TARGET_HT20_5,
+	ALL_TARGET_HT20_6,
+	ALL_TARGET_HT20_7,
+	ALL_TARGET_HT20_12,
+	ALL_TARGET_HT20_13,
+	ALL_TARGET_HT20_14,
+	ALL_TARGET_HT20_15,
+	ALL_TARGET_HT20_20,
+	ALL_TARGET_HT20_21,
+	ALL_TARGET_HT20_22,
+	ALL_TARGET_HT20_23,
+	ALL_TARGET_HT40_0_8_16,
+	ALL_TARGET_HT40_1_3_9_11_17_19,
+	ALL_TARGET_HT40_4,
+	ALL_TARGET_HT40_5,
+	ALL_TARGET_HT40_6,
+	ALL_TARGET_HT40_7,
+	ALL_TARGET_HT40_12,
+	ALL_TARGET_HT40_13,
+	ALL_TARGET_HT40_14,
+	ALL_TARGET_HT40_15,
+	ALL_TARGET_HT40_20,
+	ALL_TARGET_HT40_21,
+	ALL_TARGET_HT40_22,
+	ALL_TARGET_HT40_23,
+	ar9300RateSize,
+};
+
+
+struct eepFlags {
+	u8 opFlags;
+	u8 eepMisc;
+} __packed;
+
+enum CompressAlgorithm {
+	_CompressNone = 0,
+	_CompressLzma,
+	_CompressPairs,
+	_CompressBlock,
+	_Compress4,
+	_Compress5,
+	_Compress6,
+	_Compress7,
+};
+
+struct ar9300_base_eep_hdr {
+	u16 regDmn[2];
+	/* 4 bits tx and 4 bits rx */
+	u8 txrxMask;
+	struct eepFlags opCapFlags;
+	u8 rfSilent;
+	u8 blueToothOptions;
+	u8 deviceCap;
+	/* takes lower byte in eeprom location */
+	u8 deviceType;
+	/* offset in dB to be added to beginning
+	 * of pdadc table in calibration
+	 */
+	int8_t pwrTableOffset;
+	u8 params_for_tuning_caps[2];
+	/*
+	 * bit0 - enable tx temp comp
+	 * bit1 - enable tx volt comp
+	 * bit2 - enable fastClock - default to 1
+	 * bit3 - enable doubling - default to 1
+	 * bit4 - enable internal regulator - default to 1
+	 */
+	u8 featureEnable;
+	/* misc flags: bit0 - turn down drivestrength */
+	u8 miscConfiguration;
+	u8 eepromWriteEnableGpio;
+	u8 wlanDisableGpio;
+	u8 wlanLedGpio;
+	u8 rxBandSelectGpio;
+	u8 txrxgain;
+	/* SW controlled internal regulator fields */
+	u32 swreg;
+} __packed;
+
+struct ar9300_modal_eep_header {
+	/* 4 idle, t1, t2, b (4 bits per setting) */
+	u32 antCtrlCommon;
+	/* 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12 */
+	u32 antCtrlCommon2;
+	/* 6 idle, t, r, rx1, rx12, b (2 bits each) */
+	u16 antCtrlChain[AR9300_MAX_CHAINS];
+	/* 3 xatten1_db for AR9280 (0xa20c/b20c 5:0) */
+	u8 xatten1DB[AR9300_MAX_CHAINS];
+	/* 3  xatten1_margin for merlin (0xa20c/b20c 16:12 */
+	u8 xatten1Margin[AR9300_MAX_CHAINS];
+	int8_t tempSlope;
+	int8_t voltSlope;
+	/* spur channels in usual fbin coding format */
+	u8 spurChans[AR9300_EEPROM_MODAL_SPURS];
+	/* 3  Check if the register is per chain */
+	int8_t noiseFloorThreshCh[AR9300_MAX_CHAINS];
+	u8 ob[AR9300_MAX_CHAINS];
+	u8 db_stage2[AR9300_MAX_CHAINS];
+	u8 db_stage3[AR9300_MAX_CHAINS];
+	u8 db_stage4[AR9300_MAX_CHAINS];
+	u8 xpaBiasLvl;
+	u8 txFrameToDataStart;
+	u8 txFrameToPaOn;
+	u8 txClip;
+	int8_t antennaGain;
+	u8 switchSettling;
+	int8_t adcDesiredSize;
+	u8 txEndToXpaOff;
+	u8 txEndToRxOn;
+	u8 txFrameToXpaOn;
+	u8 thresh62;
+	u8 futureModal[32];
+} __packed;
+
+struct ar9300_cal_data_per_freq_op_loop {
+	int8_t refPower;
+	/* pdadc voltage at power measurement */
+	u8 voltMeas;
+	/* pcdac used for power measurement   */
+	u8 tempMeas;
+	/* range is -60 to -127 create a mapping equation 1db resolution */
+	int8_t rxNoisefloorCal;
+	/*range is same as noisefloor */
+	int8_t rxNoisefloorPower;
+	/* temp measured when noisefloor cal was performed */
+	u8 rxTempMeas;
+} __packed;
+
+struct cal_tgt_pow_legacy {
+	u8 tPow2x[4];
+} __packed;
+
+struct cal_tgt_pow_ht {
+	u8 tPow2x[14];
+} __packed;
+
+struct cal_ctl_edge_pwr {
+	u8 tPower:6,
+	   flag:2;
+} __packed;
+
+struct cal_ctl_data_2g {
+	struct cal_ctl_edge_pwr ctlEdges[AR9300_NUM_BAND_EDGES_5G];
+} __packed;
+
+struct cal_ctl_data_5g {
+	struct cal_ctl_edge_pwr ctlEdges[AR9300_NUM_BAND_EDGES_5G];
+} __packed;
+
+struct ar9300_eeprom {
+	u8 eepromVersion;
+	u8 templateVersion;
+	u8 macAddr[6];
+	u8 custData[AR9300_CUSTOMER_DATA_SIZE];
+
+	struct ar9300_base_eep_hdr baseEepHeader;
+
+	struct ar9300_modal_eep_header modalHeader2G;
+	u8 calFreqPier2G[AR9300_NUM_2G_CAL_PIERS];
+	struct ar9300_cal_data_per_freq_op_loop
+	 calPierData2G[AR9300_MAX_CHAINS][AR9300_NUM_2G_CAL_PIERS];
+	u8 calTarget_freqbin_Cck[AR9300_NUM_2G_CCK_TARGET_POWERS];
+	u8 calTarget_freqbin_2G[AR9300_NUM_2G_20_TARGET_POWERS];
+	u8 calTarget_freqbin_2GHT20[AR9300_NUM_2G_20_TARGET_POWERS];
+	u8 calTarget_freqbin_2GHT40[AR9300_NUM_2G_40_TARGET_POWERS];
+	struct cal_tgt_pow_legacy
+	 calTargetPowerCck[AR9300_NUM_2G_CCK_TARGET_POWERS];
+	struct cal_tgt_pow_legacy
+	 calTargetPower2G[AR9300_NUM_2G_20_TARGET_POWERS];
+	struct cal_tgt_pow_ht
+	 calTargetPower2GHT20[AR9300_NUM_2G_20_TARGET_POWERS];
+	struct cal_tgt_pow_ht
+	 calTargetPower2GHT40[AR9300_NUM_2G_40_TARGET_POWERS];
+	u8 ctlIndex_2G[AR9300_NUM_CTLS_2G];
+	u8 ctl_freqbin_2G[AR9300_NUM_CTLS_2G][AR9300_NUM_BAND_EDGES_2G];
+	struct cal_ctl_data_2g ctlPowerData_2G[AR9300_NUM_CTLS_2G];
+	struct ar9300_modal_eep_header modalHeader5G;
+	u8 calFreqPier5G[AR9300_NUM_5G_CAL_PIERS];
+	struct ar9300_cal_data_per_freq_op_loop
+	 calPierData5G[AR9300_MAX_CHAINS][AR9300_NUM_5G_CAL_PIERS];
+	u8 calTarget_freqbin_5G[AR9300_NUM_5G_20_TARGET_POWERS];
+	u8 calTarget_freqbin_5GHT20[AR9300_NUM_5G_20_TARGET_POWERS];
+	u8 calTarget_freqbin_5GHT40[AR9300_NUM_5G_40_TARGET_POWERS];
+	struct cal_tgt_pow_legacy
+	 calTargetPower5G[AR9300_NUM_5G_20_TARGET_POWERS];
+	struct cal_tgt_pow_ht
+	 calTargetPower5GHT20[AR9300_NUM_5G_20_TARGET_POWERS];
+	struct cal_tgt_pow_ht
+	 calTargetPower5GHT40[AR9300_NUM_5G_40_TARGET_POWERS];
+	u8 ctlIndex_5G[AR9300_NUM_CTLS_5G];
+	u8 ctl_freqbin_5G[AR9300_NUM_CTLS_5G][AR9300_NUM_BAND_EDGES_5G];
+	struct cal_ctl_data_5g ctlPowerData_5G[AR9300_NUM_CTLS_5G];
+} __packed;
+#endif
diff --git a/drivers/net/wireless/ath/ath9k/eeprom.c b/drivers/net/wireless/ath/ath9k/eeprom.c
index aec6ebb..bd9dff3 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom.c
@@ -256,7 +256,9 @@ int ath9k_hw_eeprom_init(struct ath_hw *ah)
 {
 	int status;
 
-	if (AR_SREV_9287(ah)) {
+	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;
diff --git a/drivers/net/wireless/ath/ath9k/eeprom.h b/drivers/net/wireless/ath/ath9k/eeprom.h
index 289084c..fb9c8c9 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom.h
+++ b/drivers/net/wireless/ath/ath9k/eeprom.h
@@ -19,6 +19,7 @@
 
 #include "../ath.h"
 #include <net/cfg80211.h>
+#include "ar9003_eeprom.h"
 
 #define AH_USE_EEPROM   0x1
 
@@ -249,16 +250,20 @@ enum eeprom_param {
 	EEP_MINOR_REV,
 	EEP_TX_MASK,
 	EEP_RX_MASK,
+	EEP_FSTCLK_5G,
 	EEP_RXGAIN_TYPE,
-	EEP_TXGAIN_TYPE,
 	EEP_OL_PWRCTRL,
+	EEP_TXGAIN_TYPE,
 	EEP_RC_CHAIN_MASK,
 	EEP_DAC_HPWR_5G,
 	EEP_FRAC_N_5G,
 	EEP_DEV_TYPE,
 	EEP_TEMPSENSE_SLOPE,
 	EEP_TEMPSENSE_SLOPE_PAL_ON,
-	EEP_PWR_TABLE_OFFSET
+	EEP_PWR_TABLE_OFFSET,
+	EEP_DRIVE_STRENGTH,
+	EEP_INTERNAL_REGULATOR,
+	EEP_SWREG
 };
 
 enum ar5416_rates {
@@ -707,5 +712,7 @@ int ath9k_hw_eeprom_init(struct ath_hw *ah);
 extern const struct eeprom_ops eep_def_ops;
 extern const struct eeprom_ops eep_4k_ops;
 extern const struct eeprom_ops eep_ar9287_ops;
+extern const struct eeprom_ops eep_ar9287_ops;
+extern const struct eeprom_ops eep_ar9300_ops;
 
 #endif /* EEPROM_H */
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index cb0421a..d1b9940 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -568,6 +568,7 @@ struct ath_hw {
 		struct ar5416_eeprom_def def;
 		struct ar5416_eeprom_4k map4k;
 		struct ar9287_eeprom map9287;
+		struct ar9300_eeprom ar9300_eep;
 	} eeprom;
 	const struct eeprom_ops *eep_ops;
 
diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h
index aacc29a..12de95e 100644
--- a/drivers/net/wireless/ath/ath9k/reg.h
+++ b/drivers/net/wireless/ath/ath9k/reg.h
@@ -1070,6 +1070,16 @@ enum {
 #define AR_RTC_RC_COLD_RESET    0x00000004
 #define AR_RTC_RC_WARM_RESET    0x00000008
 
+/* Crystal Control */
+#define AR_RTC_XTAL_CONTROL     0x7004
+
+/* Reg Control 0 */
+#define AR_RTC_REG_CONTROL0     0x7008
+
+/* Reg Control 1 */
+#define AR_RTC_REG_CONTROL1     0x700c
+#define AR_RTC_REG_CONTROL1_SWREG_PROGRAM       0x00000001
+
 #define AR_RTC_PLL_CONTROL \
 	((AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x0014) : 0x7014)
 
@@ -1100,6 +1110,7 @@ enum {
 #define AR_RTC_SLEEP_CLK \
 	((AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x0048) : 0x7048)
 #define AR_RTC_FORCE_DERIVED_CLK    0x2
+#define AR_RTC_FORCE_SWREG_PRD      0x00000004
 
 #define AR_RTC_FORCE_WAKE \
 	((AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x004c) : 0x704c)
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 103+ messages in thread

* [PATCH v3 70/97] ath9k_hw: add OFDM spur mitigation for AR9003
  2010-04-15 21:38 [PATCH v3 00/97] ath9k: add AR9003 support Luis R. Rodriguez
                   ` (68 preceding siblings ...)
  2010-04-15 21:39 ` [PATCH v3 69/97] ath9k_hw: Implement AR9003 eeprom callbacks Luis R. Rodriguez
@ 2010-04-15 21:39 ` Luis R. Rodriguez
  2010-04-15 21:39 ` [PATCH v3 71/97] ath9k_hw: Fill get_isr() " Luis R. Rodriguez
                   ` (26 subsequent siblings)
  96 siblings, 0 replies; 103+ messages in thread
From: Luis R. Rodriguez @ 2010-04-15 21:39 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Luis R. Rodriguez

We add this now as OFDM spur mitigation required accessing
the EEPROM for the AR9003 devices.

Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/ar9002_phy.h |    2 -
 drivers/net/wireless/ath/ath9k/ar9003_phy.c |  210 ++++++++++++++++++++++++++-
 drivers/net/wireless/ath/ath9k/ar9003_phy.h |   54 +++++++
 drivers/net/wireless/ath/ath9k/hw.h         |    2 +
 drivers/net/wireless/ath/ath9k/phy.h        |    3 +
 5 files changed, 267 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ar9002_phy.h b/drivers/net/wireless/ath/ath9k/ar9002_phy.h
index afe4808..81bf6e5 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_phy.h
+++ b/drivers/net/wireless/ath/ath9k/ar9002_phy.h
@@ -289,8 +289,6 @@
 #define	AR_PHY_TIMING11			        0x99a0
 #define	AR_PHY_TIMING11_SPUR_DELTA_PHASE	0x000FFFFF
 #define	AR_PHY_TIMING11_SPUR_DELTA_PHASE_S	0
-#define	AR_PHY_TIMING11_SPUR_FREQ_SD		0x3FF00000
-#define	AR_PHY_TIMING11_SPUR_FREQ_SD_S		20
 #define AR_PHY_TIMING11_USE_SPUR_IN_AGC		0x40000000
 #define AR_PHY_TIMING11_USE_SPUR_IN_SELFCOR	0x80000000
 
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
index fee07fd..137543b 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
@@ -103,8 +103,8 @@ static int ar9003_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan)
  *
  * Spur mitigation for MRC CCK
  */
-static void ar9003_hw_spur_mitigate(struct ath_hw *ah,
-				    struct ath9k_channel *chan)
+static void ar9003_hw_spur_mitigate_mrc_cck(struct ath_hw *ah,
+					    struct ath9k_channel *chan)
 {
 	u32 spur_freq[4] = { 2420, 2440, 2464, 2480 };
 	int cur_bb_spur, negative = 0, cck_spur_freq;
@@ -157,6 +157,212 @@ static void ar9003_hw_spur_mitigate(struct ath_hw *ah,
 		      AR_PHY_CCK_SPUR_MIT_CCK_SPUR_FREQ, 0x0);
 }
 
+/* Clean all spur register fields */
+static void ar9003_hw_spur_ofdm_clear(struct ath_hw *ah)
+{
+	REG_RMW_FIELD(ah, AR_PHY_TIMING4,
+		      AR_PHY_TIMING4_ENABLE_SPUR_FILTER, 0);
+	REG_RMW_FIELD(ah, AR_PHY_TIMING11,
+		      AR_PHY_TIMING11_SPUR_FREQ_SD, 0);
+	REG_RMW_FIELD(ah, AR_PHY_TIMING11,
+		      AR_PHY_TIMING11_SPUR_DELTA_PHASE, 0);
+	REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
+		      AR_PHY_SFCORR_EXT_SPUR_SUBCHANNEL_SD, 0);
+	REG_RMW_FIELD(ah, AR_PHY_TIMING11,
+		      AR_PHY_TIMING11_USE_SPUR_FILTER_IN_AGC, 0);
+	REG_RMW_FIELD(ah, AR_PHY_TIMING11,
+		      AR_PHY_TIMING11_USE_SPUR_FILTER_IN_SELFCOR, 0);
+	REG_RMW_FIELD(ah, AR_PHY_TIMING4,
+		      AR_PHY_TIMING4_ENABLE_SPUR_RSSI, 0);
+	REG_RMW_FIELD(ah, AR_PHY_SPUR_REG,
+		      AR_PHY_SPUR_REG_EN_VIT_SPUR_RSSI, 0);
+	REG_RMW_FIELD(ah, AR_PHY_SPUR_REG,
+		      AR_PHY_SPUR_REG_ENABLE_NF_RSSI_SPUR_MIT, 0);
+
+	REG_RMW_FIELD(ah, AR_PHY_SPUR_REG,
+		      AR_PHY_SPUR_REG_ENABLE_MASK_PPM, 0);
+	REG_RMW_FIELD(ah, AR_PHY_TIMING4,
+		      AR_PHY_TIMING4_ENABLE_PILOT_MASK, 0);
+	REG_RMW_FIELD(ah, AR_PHY_TIMING4,
+		      AR_PHY_TIMING4_ENABLE_CHAN_MASK, 0);
+	REG_RMW_FIELD(ah, AR_PHY_PILOT_SPUR_MASK,
+		      AR_PHY_PILOT_SPUR_MASK_CF_PILOT_MASK_IDX_A, 0);
+	REG_RMW_FIELD(ah, AR_PHY_SPUR_MASK_A,
+		      AR_PHY_SPUR_MASK_A_CF_PUNC_MASK_IDX_A, 0);
+	REG_RMW_FIELD(ah, AR_PHY_CHAN_SPUR_MASK,
+		      AR_PHY_CHAN_SPUR_MASK_CF_CHAN_MASK_IDX_A, 0);
+	REG_RMW_FIELD(ah, AR_PHY_PILOT_SPUR_MASK,
+		      AR_PHY_PILOT_SPUR_MASK_CF_PILOT_MASK_A, 0);
+	REG_RMW_FIELD(ah, AR_PHY_CHAN_SPUR_MASK,
+		      AR_PHY_CHAN_SPUR_MASK_CF_CHAN_MASK_A, 0);
+	REG_RMW_FIELD(ah, AR_PHY_SPUR_MASK_A,
+		      AR_PHY_SPUR_MASK_A_CF_PUNC_MASK_A, 0);
+	REG_RMW_FIELD(ah, AR_PHY_SPUR_REG,
+		      AR_PHY_SPUR_REG_MASK_RATE_CNTL, 0);
+}
+
+static void ar9003_hw_spur_ofdm(struct ath_hw *ah,
+				int freq_offset,
+				int spur_freq_sd,
+				int spur_delta_phase,
+				int spur_subchannel_sd)
+{
+	int mask_index = 0;
+
+	/* OFDM Spur mitigation */
+	REG_RMW_FIELD(ah, AR_PHY_TIMING4,
+		 AR_PHY_TIMING4_ENABLE_SPUR_FILTER, 0x1);
+	REG_RMW_FIELD(ah, AR_PHY_TIMING11,
+		      AR_PHY_TIMING11_SPUR_FREQ_SD, spur_freq_sd);
+	REG_RMW_FIELD(ah, AR_PHY_TIMING11,
+		      AR_PHY_TIMING11_SPUR_DELTA_PHASE, spur_delta_phase);
+	REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
+		      AR_PHY_SFCORR_EXT_SPUR_SUBCHANNEL_SD, spur_subchannel_sd);
+	REG_RMW_FIELD(ah, AR_PHY_TIMING11,
+		      AR_PHY_TIMING11_USE_SPUR_FILTER_IN_AGC, 0x1);
+	REG_RMW_FIELD(ah, AR_PHY_TIMING11,
+		      AR_PHY_TIMING11_USE_SPUR_FILTER_IN_SELFCOR, 0x1);
+	REG_RMW_FIELD(ah, AR_PHY_TIMING4,
+		      AR_PHY_TIMING4_ENABLE_SPUR_RSSI, 0x1);
+	REG_RMW_FIELD(ah, AR_PHY_SPUR_REG,
+		      AR_PHY_SPUR_REG_SPUR_RSSI_THRESH, 34);
+	REG_RMW_FIELD(ah, AR_PHY_SPUR_REG,
+		      AR_PHY_SPUR_REG_EN_VIT_SPUR_RSSI, 1);
+
+	if (REG_READ_FIELD(ah, AR_PHY_MODE,
+			   AR_PHY_MODE_DYNAMIC) == 0x1)
+		REG_RMW_FIELD(ah, AR_PHY_SPUR_REG,
+			      AR_PHY_SPUR_REG_ENABLE_NF_RSSI_SPUR_MIT, 1);
+
+	mask_index = (freq_offset << 4) / 5;
+	if (mask_index < 0)
+		mask_index = mask_index - 1;
+
+	mask_index = mask_index & 0x7f;
+
+	REG_RMW_FIELD(ah, AR_PHY_SPUR_REG,
+		      AR_PHY_SPUR_REG_ENABLE_MASK_PPM, 0x1);
+	REG_RMW_FIELD(ah, AR_PHY_TIMING4,
+		      AR_PHY_TIMING4_ENABLE_PILOT_MASK, 0x1);
+	REG_RMW_FIELD(ah, AR_PHY_TIMING4,
+		      AR_PHY_TIMING4_ENABLE_CHAN_MASK, 0x1);
+	REG_RMW_FIELD(ah, AR_PHY_PILOT_SPUR_MASK,
+		      AR_PHY_PILOT_SPUR_MASK_CF_PILOT_MASK_IDX_A, mask_index);
+	REG_RMW_FIELD(ah, AR_PHY_SPUR_MASK_A,
+		      AR_PHY_SPUR_MASK_A_CF_PUNC_MASK_IDX_A, mask_index);
+	REG_RMW_FIELD(ah, AR_PHY_CHAN_SPUR_MASK,
+		      AR_PHY_CHAN_SPUR_MASK_CF_CHAN_MASK_IDX_A, mask_index);
+	REG_RMW_FIELD(ah, AR_PHY_PILOT_SPUR_MASK,
+		      AR_PHY_PILOT_SPUR_MASK_CF_PILOT_MASK_A, 0xc);
+	REG_RMW_FIELD(ah, AR_PHY_CHAN_SPUR_MASK,
+		      AR_PHY_CHAN_SPUR_MASK_CF_CHAN_MASK_A, 0xc);
+	REG_RMW_FIELD(ah, AR_PHY_SPUR_MASK_A,
+		      AR_PHY_SPUR_MASK_A_CF_PUNC_MASK_A, 0xa0);
+	REG_RMW_FIELD(ah, AR_PHY_SPUR_REG,
+		      AR_PHY_SPUR_REG_MASK_RATE_CNTL, 0xff);
+}
+
+static void ar9003_hw_spur_ofdm_work(struct ath_hw *ah,
+				     struct ath9k_channel *chan,
+				     int freq_offset)
+{
+	int spur_freq_sd = 0;
+	int spur_subchannel_sd = 0;
+	int spur_delta_phase = 0;
+
+	if (IS_CHAN_HT40(chan)) {
+		if (freq_offset < 0) {
+			if (REG_READ_FIELD(ah, AR_PHY_GEN_CTRL,
+					   AR_PHY_GC_DYN2040_PRI_CH) == 0x0)
+				spur_subchannel_sd = 1;
+			else
+				spur_subchannel_sd = 0;
+
+			spur_freq_sd = ((freq_offset + 10) << 9) / 11;
+
+		} else {
+			if (REG_READ_FIELD(ah, AR_PHY_GEN_CTRL,
+			    AR_PHY_GC_DYN2040_PRI_CH) == 0x0)
+				spur_subchannel_sd = 0;
+			else
+				spur_subchannel_sd = 1;
+
+			spur_freq_sd = ((freq_offset - 10) << 9) / 11;
+
+		}
+
+		spur_delta_phase = (freq_offset << 17) / 5;
+
+	} else {
+		spur_subchannel_sd = 0;
+		spur_freq_sd = (freq_offset << 9) /11;
+		spur_delta_phase = (freq_offset << 18) / 5;
+	}
+
+	spur_freq_sd = spur_freq_sd & 0x3ff;
+	spur_delta_phase = spur_delta_phase & 0xfffff;
+
+	ar9003_hw_spur_ofdm(ah,
+			    freq_offset,
+			    spur_freq_sd,
+			    spur_delta_phase,
+			    spur_subchannel_sd);
+}
+
+/* Spur mitigation for OFDM */
+static void ar9003_hw_spur_mitigate_ofdm(struct ath_hw *ah,
+					 struct ath9k_channel *chan)
+{
+	int synth_freq;
+	int range = 10;
+	int freq_offset = 0;
+	int mode;
+	u8* spurChansPtr;
+	unsigned int i;
+	struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
+
+	if (IS_CHAN_5GHZ(chan)) {
+		spurChansPtr = &(eep->modalHeader5G.spurChans[0]);
+		mode = 0;
+	}
+	else {
+		spurChansPtr = &(eep->modalHeader2G.spurChans[0]);
+		mode = 1;
+	}
+
+	if (spurChansPtr[0] == 0)
+		return; /* No spur in the mode */
+
+	if (IS_CHAN_HT40(chan)) {
+		range = 19;
+		if (REG_READ_FIELD(ah, AR_PHY_GEN_CTRL,
+				   AR_PHY_GC_DYN2040_PRI_CH) == 0x0)
+			synth_freq = chan->channel - 10;
+		else
+			synth_freq = chan->channel + 10;
+	} else {
+		range = 10;
+		synth_freq = chan->channel;
+	}
+
+	ar9003_hw_spur_ofdm_clear(ah);
+
+	for (i = 0; spurChansPtr[i] && i < 5; i++) {
+		freq_offset = FBIN2FREQ(spurChansPtr[i], mode) - synth_freq;
+		if (abs(freq_offset) < range) {
+			ar9003_hw_spur_ofdm_work(ah, chan, freq_offset);
+			break;
+		}
+	}
+}
+
+static void ar9003_hw_spur_mitigate(struct ath_hw *ah,
+				    struct ath9k_channel *chan)
+{
+	ar9003_hw_spur_mitigate_mrc_cck(ah, chan);
+	ar9003_hw_spur_mitigate_ofdm(ah, chan);
+}
+
 static u32 ar9003_hw_compute_pll_control(struct ath_hw *ah,
 					 struct ath9k_channel *chan)
 {
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.h b/drivers/net/wireless/ath/ath9k/ar9003_phy.h
index 4e1177d..f08cc8b 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.h
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.h
@@ -33,6 +33,30 @@
 #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
 
@@ -84,6 +108,17 @@
 #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
@@ -107,6 +142,8 @@
 #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
@@ -184,6 +221,16 @@
 #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
  */
@@ -372,6 +419,11 @@
 #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
@@ -499,6 +551,7 @@
 #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 */
@@ -516,6 +569,7 @@
 #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
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index d1b9940..25713be 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -76,6 +76,8 @@
 #define REG_RMW_FIELD(_a, _r, _f, _v) \
 	REG_WRITE(_a, _r, \
 	(REG_READ(_a, _r) & ~_f) | (((_v) << _f##_S) & _f))
+#define REG_READ_FIELD(_a, _r, _f) \
+	(((REG_READ(_a, _r) & _f) >> _f##_S))
 #define REG_SET_BIT(_a, _r, _f) \
 	REG_WRITE(_a, _r, REG_READ(_a, _r) | _f)
 #define REG_CLR_BIT(_a, _r, _f) \
diff --git a/drivers/net/wireless/ath/ath9k/phy.h b/drivers/net/wireless/ath/ath9k/phy.h
index 7d397fd..e724c2c 100644
--- a/drivers/net/wireless/ath/ath9k/phy.h
+++ b/drivers/net/wireless/ath/ath9k/phy.h
@@ -59,4 +59,7 @@
 			(_bank)[i] = INI_RA((_iniarray), i, _col);;	\
 	} while (0)
 
+#define	AR_PHY_TIMING11_SPUR_FREQ_SD		0x3FF00000
+#define	AR_PHY_TIMING11_SPUR_FREQ_SD_S		20
+
 #endif
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 103+ messages in thread

* [PATCH v3 71/97] ath9k_hw: Fill get_isr() for AR9003
  2010-04-15 21:38 [PATCH v3 00/97] ath9k: add AR9003 support Luis R. Rodriguez
                   ` (69 preceding siblings ...)
  2010-04-15 21:39 ` [PATCH v3 70/97] ath9k_hw: add OFDM spur mitigation for AR9003 Luis R. Rodriguez
@ 2010-04-15 21:39 ` Luis R. Rodriguez
  2010-04-15 21:39 ` [PATCH v3 72/97] ath9k_hw: move AR9280 PCI EEPROM fix to eeprom_def.c Luis R. Rodriguez
                   ` (25 subsequent siblings)
  96 siblings, 0 replies; 103+ messages in thread
From: Luis R. Rodriguez @ 2010-04-15 21:39 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Vasanthakumar Thiagarajan

From: Vasanthakumar Thiagarajan <vasanth@atheros.com>

Signed-off-by: Vasanthakumar Thiagarajan <vasanth@atheros.com>
---
 drivers/net/wireless/ath/ath9k/ar9003_mac.c |  132 +++++++++++++++++++++++++++
 drivers/net/wireless/ath/ath9k/ar9003_mac.h |    8 ++
 drivers/net/wireless/ath/ath9k/hw.c         |    3 +
 drivers/net/wireless/ath/ath9k/hw.h         |    1 +
 drivers/net/wireless/ath/ath9k/reg.h        |    2 +
 5 files changed, 146 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.c b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
index 15f1b0f..2319456 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
@@ -32,6 +32,138 @@ static void ar9003_hw_get_desc_link(void *ds, u32 **ds_link)
 
 static bool ar9003_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked)
 {
+	u32 isr = 0;
+	u32 mask2 = 0;
+	struct ath9k_hw_capabilities *pCap = &ah->caps;
+	u32 sync_cause = 0;
+	struct ath_common *common = ath9k_hw_common(ah);
+
+	if (REG_READ(ah, AR_INTR_ASYNC_CAUSE) & AR_INTR_MAC_IRQ) {
+		if ((REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M)
+				== AR_RTC_STATUS_ON)
+			isr = REG_READ(ah, AR_ISR);
+	}
+
+	sync_cause = REG_READ(ah, AR_INTR_SYNC_CAUSE) & AR_INTR_SYNC_DEFAULT;
+
+	*masked = 0;
+
+	if (!isr && !sync_cause)
+		return false;
+
+	if (isr) {
+		if (isr & AR_ISR_BCNMISC) {
+			u32 isr2;
+			isr2 = REG_READ(ah, AR_ISR_S2);
+
+			mask2 |= ((isr2 & AR_ISR_S2_TIM) >>
+				  MAP_ISR_S2_TIM);
+			mask2 |= ((isr2 & AR_ISR_S2_DTIM) >>
+				  MAP_ISR_S2_DTIM);
+			mask2 |= ((isr2 & AR_ISR_S2_DTIMSYNC) >>
+				  MAP_ISR_S2_DTIMSYNC);
+			mask2 |= ((isr2 & AR_ISR_S2_CABEND) >>
+				  MAP_ISR_S2_CABEND);
+			mask2 |= ((isr2 & AR_ISR_S2_GTT) <<
+				  MAP_ISR_S2_GTT);
+			mask2 |= ((isr2 & AR_ISR_S2_CST) <<
+				  MAP_ISR_S2_CST);
+			mask2 |= ((isr2 & AR_ISR_S2_TSFOOR) >>
+				  MAP_ISR_S2_TSFOOR);
+
+			if (!(pCap->hw_caps & ATH9K_HW_CAP_RAC_SUPPORTED)) {
+				REG_WRITE(ah, AR_ISR_S2, isr2);
+				isr &= ~AR_ISR_BCNMISC;
+			}
+		}
+
+		if ((pCap->hw_caps & ATH9K_HW_CAP_RAC_SUPPORTED))
+			isr = REG_READ(ah, AR_ISR_RAC);
+
+		if (isr == 0xffffffff) {
+			*masked = 0;
+			return false;
+		}
+
+		*masked = isr & ATH9K_INT_COMMON;
+
+		if (ah->config.rx_intr_mitigation)
+			if (isr & (AR_ISR_RXMINTR | AR_ISR_RXINTM))
+				*masked |= ATH9K_INT_RXLP;
+
+		if (ah->config.tx_intr_mitigation)
+			if (isr & (AR_ISR_TXMINTR | AR_ISR_TXINTM))
+				*masked |= ATH9K_INT_TX;
+
+		if (isr & (AR_ISR_LP_RXOK | AR_ISR_RXERR))
+			*masked |= ATH9K_INT_RXLP;
+
+		if (isr & AR_ISR_HP_RXOK)
+			*masked |= ATH9K_INT_RXHP;
+
+		if (isr & (AR_ISR_TXOK | AR_ISR_TXERR | AR_ISR_TXEOL)) {
+			*masked |= ATH9K_INT_TX;
+
+			if (!(pCap->hw_caps & ATH9K_HW_CAP_RAC_SUPPORTED)) {
+				u32 s0, s1;
+				s0 = REG_READ(ah, AR_ISR_S0);
+				REG_WRITE(ah, AR_ISR_S0, s0);
+				s1 = REG_READ(ah, AR_ISR_S1);
+				REG_WRITE(ah, AR_ISR_S1, s1);
+
+				isr &= ~(AR_ISR_TXOK | AR_ISR_TXERR |
+					 AR_ISR_TXEOL);
+			}
+		}
+
+		if (isr & AR_ISR_GENTMR) {
+			u32 s5;
+
+			if (pCap->hw_caps & ATH9K_HW_CAP_RAC_SUPPORTED)
+				s5 = REG_READ(ah, AR_ISR_S5_S);
+			else
+				s5 = REG_READ(ah, AR_ISR_S5);
+
+			ah->intr_gen_timer_trigger =
+				MS(s5, AR_ISR_S5_GENTIMER_TRIG);
+
+			ah->intr_gen_timer_thresh =
+				MS(s5, AR_ISR_S5_GENTIMER_THRESH);
+
+			if (ah->intr_gen_timer_trigger)
+				*masked |= ATH9K_INT_GENTIMER;
+
+			if (!(pCap->hw_caps & ATH9K_HW_CAP_RAC_SUPPORTED)) {
+				REG_WRITE(ah, AR_ISR_S5, s5);
+				isr &= ~AR_ISR_GENTMR;
+			}
+
+		}
+
+		*masked |= mask2;
+
+		if (!(pCap->hw_caps & ATH9K_HW_CAP_RAC_SUPPORTED)) {
+			REG_WRITE(ah, AR_ISR, isr);
+
+			(void) REG_READ(ah, AR_ISR);
+		}
+	}
+
+	if (sync_cause) {
+		if (sync_cause & AR_INTR_SYNC_RADM_CPL_TIMEOUT) {
+			REG_WRITE(ah, AR_RC, AR_RC_HOSTIF);
+			REG_WRITE(ah, AR_RC, 0);
+			*masked |= ATH9K_INT_FATAL;
+		}
+
+		if (sync_cause & AR_INTR_SYNC_LOCAL_TIMEOUT)
+			ath_print(common, ATH_DBG_INTERRUPT,
+				  "AR_INTR_SYNC_LOCAL_TIMEOUT\n");
+
+			REG_WRITE(ah, AR_INTR_SYNC_CAUSE_CLR, sync_cause);
+		(void) REG_READ(ah, AR_INTR_SYNC_CAUSE_CLR);
+
+	}
 	return true;
 }
 
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.h b/drivers/net/wireless/ath/ath9k/ar9003_mac.h
index 7374439..2ba06d7 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_mac.h
+++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.h
@@ -22,6 +22,14 @@
 #define AR_CtrlStat	0x00004000
 #define AR_TxRxDesc	0x00008000
 
+#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
+
 struct ar9003_rxs {
 	u32 ds_info;
 	u32 status1;
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 8c25059..e8b88be 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -2146,6 +2146,9 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
 		pCap->tx_desc_len = sizeof(struct ath_desc);
 	}
 
+	if (AR_SREV_9300_20_OR_LATER(ah))
+		pCap->hw_caps |= ATH9K_HW_CAP_RAC_SUPPORTED;
+
 	return 0;
 }
 
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 25713be..fcf7842 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -179,6 +179,7 @@ enum ath9k_hw_caps {
 	ATH9K_HW_CAP_AUTOSLEEP                  = BIT(15),
 	ATH9K_HW_CAP_4KB_SPLITTRANS             = BIT(16),
 	ATH9K_HW_CAP_EDMA			= BIT(17),
+	ATH9K_HW_CAP_RAC_SUPPORTED		= BIT(18),
 };
 
 enum ath9k_capability_type {
diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h
index 12de95e..12f1621 100644
--- a/drivers/net/wireless/ath/ath9k/reg.h
+++ b/drivers/net/wireless/ath/ath9k/reg.h
@@ -169,6 +169,8 @@
 #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
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 103+ messages in thread

* [PATCH v3 72/97] ath9k_hw: move AR9280 PCI EEPROM fix to eeprom_def.c
  2010-04-15 21:38 [PATCH v3 00/97] ath9k: add AR9003 support Luis R. Rodriguez
                   ` (70 preceding siblings ...)
  2010-04-15 21:39 ` [PATCH v3 71/97] ath9k_hw: Fill get_isr() " Luis R. Rodriguez
@ 2010-04-15 21:39 ` Luis R. Rodriguez
  2010-04-15 21:39 ` [PATCH v3 73/97] ath9k_hw: move the RF claim stuff to AR9002 hardware family Luis R. Rodriguez
                   ` (24 subsequent siblings)
  96 siblings, 0 replies; 103+ messages in thread
From: Luis R. Rodriguez @ 2010-04-15 21:39 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Felix Fietkau

From: Felix Fietkau <nbd@openwrt.org>

Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
 drivers/net/wireless/ath/ath9k/eeprom_def.c |    6 ++++++
 drivers/net/wireless/ath/ath9k/hw.c         |   17 -----------------
 2 files changed, 6 insertions(+), 17 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/eeprom_def.c b/drivers/net/wireless/ath/ath9k/eeprom_def.c
index 3d1b86b..cf59799 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom_def.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom_def.c
@@ -223,6 +223,12 @@ static int ath9k_hw_def_check_eeprom(struct ath_hw *ah)
 		return -EINVAL;
 	}
 
+	/* Enable fixup for AR_AN_TOP2 if necessary */
+	if (AR_SREV_9280_10_OR_LATER(ah) &&
+	    (eep->baseEepHeader.version & 0xff) > 0x0a &&
+	    eep->baseEepHeader.pwdclkind == 0)
+		ah->need_an_top2_fixup = 1;
+
 	return 0;
 }
 
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index e8b88be..c224f21 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -526,21 +526,6 @@ static int ath9k_hw_post_init(struct ath_hw *ah)
 	return 0;
 }
 
-static void ath9k_hw_init_eeprom_fix(struct ath_hw *ah)
-{
-	struct base_eep_header *pBase = &(ah->eeprom.def.baseEepHeader);
-	struct ath_common *common = ath9k_hw_common(ah);
-
-	ah->need_an_top2_fixup = (ah->hw_version.devid == AR9280_DEVID_PCI) &&
-				 !AR_SREV_9285(ah) && !AR_SREV_9271(ah) &&
-				 ((pBase->version & 0xff) > 0x0a) &&
-				 (pBase->pwdclkind == 0);
-
-	if (ah->need_an_top2_fixup)
-		ath_print(common, ATH_DBG_EEPROM,
-			  "needs fixup for AR_AN_TOP2 register\n");
-}
-
 static void ath9k_hw_attach_ops(struct ath_hw *ah)
 {
 	if (AR_SREV_9300_20_OR_LATER(ah))
@@ -630,8 +615,6 @@ static int __ath9k_hw_init(struct ath_hw *ah)
 	if (r)
 		return r;
 
-	ath9k_hw_init_eeprom_fix(ah);
-
 	r = ath9k_hw_init_macaddr(ah);
 	if (r) {
 		ath_print(common, ATH_DBG_FATAL,
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 103+ messages in thread

* [PATCH v3 73/97] ath9k_hw: move the RF claim stuff to AR9002 hardware family
  2010-04-15 21:38 [PATCH v3 00/97] ath9k: add AR9003 support Luis R. Rodriguez
                   ` (71 preceding siblings ...)
  2010-04-15 21:39 ` [PATCH v3 72/97] ath9k_hw: move AR9280 PCI EEPROM fix to eeprom_def.c Luis R. Rodriguez
@ 2010-04-15 21:39 ` Luis R. Rodriguez
  2010-04-15 21:39 ` [PATCH v3 74/97] ath9k_hw: Configure Tx interrupt mitigation timer Luis R. Rodriguez
                   ` (23 subsequent siblings)
  96 siblings, 0 replies; 103+ messages in thread
From: Luis R. Rodriguez @ 2010-04-15 21:39 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Luis R. Rodriguez

Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/ar9002_hw.c |   43 +++++++++++++++++++++++
 drivers/net/wireless/ath/ath9k/hw.c        |   51 +++-------------------------
 drivers/net/wireless/ath/ath9k/hw.h        |    5 +++
 3 files changed, 53 insertions(+), 46 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ar9002_hw.c b/drivers/net/wireless/ath/ath9k/ar9002_hw.c
index eeaea26..5b21e69 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_hw.c
+++ b/drivers/net/wireless/ath/ath9k/ar9002_hw.c
@@ -483,6 +483,49 @@ static void ar9002_hw_configpcipowersave(struct ath_hw *ah,
 	}
 }
 
+static int ar9002_hw_get_radiorev(struct ath_hw *ah)
+{
+	u32 val;
+	int i;
+
+	REG_WRITE(ah, AR_PHY(0x36), 0x00007058);
+
+	for (i = 0; i < 8; i++)
+		REG_WRITE(ah, AR_PHY(0x20), 0x00010000);
+	val = (REG_READ(ah, AR_PHY(256)) >> 24) & 0xff;
+	val = ((val & 0xf0) >> 4) | ((val & 0x0f) << 4);
+
+	return ath9k_hw_reverse_bits(val, 8);
+}
+
+int ar9002_hw_rf_claim(struct ath_hw *ah)
+{
+	u32 val;
+
+	REG_WRITE(ah, AR_PHY(0), 0x00000007);
+
+	val = ar9002_hw_get_radiorev(ah);
+	switch (val & AR_RADIO_SREV_MAJOR) {
+	case 0:
+		val = AR_RAD5133_SREV_MAJOR;
+		break;
+	case AR_RAD5133_SREV_MAJOR:
+	case AR_RAD5122_SREV_MAJOR:
+	case AR_RAD2133_SREV_MAJOR:
+	case AR_RAD2122_SREV_MAJOR:
+		break;
+	default:
+		ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL,
+			  "Radio Chip Rev 0x%02X not supported\n",
+			  val & AR_RADIO_SREV_MAJOR);
+		return -EOPNOTSUPP;
+	}
+
+	ah->hw_version.analog5GhzRev = val;
+
+	return 0;
+}
+
 /* Sets up the AR5008/AR9001/AR9002 hardware familiy callbacks */
 void ar9002_hw_attach_ops(struct ath_hw *ah)
 {
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index c224f21..eeecc72 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -265,21 +265,6 @@ static void ath9k_hw_read_revisions(struct ath_hw *ah)
 	}
 }
 
-static int ath9k_hw_get_radiorev(struct ath_hw *ah)
-{
-	u32 val;
-	int i;
-
-	REG_WRITE(ah, AR_PHY(0x36), 0x00007058);
-
-	for (i = 0; i < 8; i++)
-		REG_WRITE(ah, AR_PHY(0x20), 0x00010000);
-	val = (REG_READ(ah, AR_PHY(256)) >> 24) & 0xff;
-	val = ((val & 0xf0) >> 4) | ((val & 0x0f) << 4);
-
-	return ath9k_hw_reverse_bits(val, 8);
-}
-
 /************************************/
 /* HW Attach, Detach, Init Routines */
 /************************************/
@@ -439,34 +424,6 @@ static void ath9k_hw_init_defaults(struct ath_hw *ah)
 	ah->power_mode = ATH9K_PM_UNDEFINED;
 }
 
-static int ath9k_hw_rf_claim(struct ath_hw *ah)
-{
-	u32 val;
-
-	REG_WRITE(ah, AR_PHY(0), 0x00000007);
-
-	val = ath9k_hw_get_radiorev(ah);
-	switch (val & AR_RADIO_SREV_MAJOR) {
-	case 0:
-		val = AR_RAD5133_SREV_MAJOR;
-		break;
-	case AR_RAD5133_SREV_MAJOR:
-	case AR_RAD5122_SREV_MAJOR:
-	case AR_RAD2133_SREV_MAJOR:
-	case AR_RAD2122_SREV_MAJOR:
-		break;
-	default:
-		ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL,
-			  "Radio Chip Rev 0x%02X not supported\n",
-			  val & AR_RADIO_SREV_MAJOR);
-		return -EOPNOTSUPP;
-	}
-
-	ah->hw_version.analog5GhzRev = val;
-
-	return 0;
-}
-
 static int ath9k_hw_init_macaddr(struct ath_hw *ah)
 {
 	struct ath_common *common = ath9k_hw_common(ah);
@@ -497,9 +454,11 @@ static int ath9k_hw_post_init(struct ath_hw *ah)
 			return -ENODEV;
 	}
 
-	ecode = ath9k_hw_rf_claim(ah);
-	if (ecode != 0)
-		return ecode;
+	if (!AR_SREV_9300_20_OR_LATER(ah)) {
+		ecode = ar9002_hw_rf_claim(ah);
+		if (ecode != 0)
+			return ecode;
+	}
 
 	ecode = ath9k_hw_eeprom_init(ah);
 	if (ecode != 0)
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index fcf7842..16f0f98 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -844,7 +844,12 @@ void ath9k_hw_htc_resetinit(struct ath_hw *ah);
 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);
 
 /*
  * Code specifric to AR9003, we stuff these here to avoid callbacks
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 103+ messages in thread

* [PATCH v3 74/97] ath9k_hw: Configure Tx interrupt mitigation timer
  2010-04-15 21:38 [PATCH v3 00/97] ath9k: add AR9003 support Luis R. Rodriguez
                   ` (72 preceding siblings ...)
  2010-04-15 21:39 ` [PATCH v3 73/97] ath9k_hw: move the RF claim stuff to AR9002 hardware family Luis R. Rodriguez
@ 2010-04-15 21:39 ` Luis R. Rodriguez
  2010-04-15 21:39 ` [PATCH v3 75/97] ath9k_hw: add the AR9300 SREV hw name print Luis R. Rodriguez
                   ` (22 subsequent siblings)
  96 siblings, 0 replies; 103+ messages in thread
From: Luis R. Rodriguez @ 2010-04-15 21:39 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Vasanthakumar Thiagarajan

From: Vasanthakumar Thiagarajan <vasanth@atheros.com>

Signed-off-by: Vasanthakumar Thiagarajan <vasanth@atheros.com>
---
 drivers/net/wireless/ath/ath9k/hw.c |    5 +++++
 1 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index eeecc72..9e4288a 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -1287,6 +1287,11 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
 		REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_FIRST, 2000);
 	}
 
+	if (ah->config.tx_intr_mitigation) {
+		REG_RMW_FIELD(ah, AR_TIMT, AR_TIMT_LAST, 300);
+		REG_RMW_FIELD(ah, AR_TIMT, AR_TIMT_FIRST, 750);
+	}
+
 	ath9k_hw_init_bb(ah, chan);
 
 	if (!ath9k_hw_init_cal(ah, chan))
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 103+ messages in thread

* [PATCH v3 75/97] ath9k_hw: add the AR9300 SREV hw name print
  2010-04-15 21:38 [PATCH v3 00/97] ath9k: add AR9003 support Luis R. Rodriguez
                   ` (73 preceding siblings ...)
  2010-04-15 21:39 ` [PATCH v3 74/97] ath9k_hw: Configure Tx interrupt mitigation timer Luis R. Rodriguez
@ 2010-04-15 21:39 ` Luis R. Rodriguez
  2010-04-15 21:39 ` [PATCH v3 76/97] ath9k_hw: add TX/RX gain register initialization for AR9003 Luis R. Rodriguez
                   ` (21 subsequent siblings)
  96 siblings, 0 replies; 103+ messages in thread
From: Luis R. Rodriguez @ 2010-04-15 21:39 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Luis R. Rodriguez

Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/hw.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 9e4288a..de7ee90 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -2690,6 +2690,7 @@ static struct {
 	{ AR_SREV_VERSION_9285,		"9285" },
 	{ AR_SREV_VERSION_9287,         "9287" },
 	{ AR_SREV_VERSION_9271,         "9271" },
+	{ AR_SREV_VERSION_9300,         "9300" },
 };
 
 /* For devices with external radios */
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 103+ messages in thread

* [PATCH v3 76/97] ath9k_hw: add TX/RX gain register initialization for AR9003
  2010-04-15 21:38 [PATCH v3 00/97] ath9k: add AR9003 support Luis R. Rodriguez
                   ` (74 preceding siblings ...)
  2010-04-15 21:39 ` [PATCH v3 75/97] ath9k_hw: add the AR9300 SREV hw name print Luis R. Rodriguez
@ 2010-04-15 21:39 ` Luis R. Rodriguez
  2010-04-15 21:39 ` [PATCH v3 77/97] ath9k_hw: Update ath9k_hw_set_dma for AR9300 Luis R. Rodriguez
                   ` (20 subsequent siblings)
  96 siblings, 0 replies; 103+ messages in thread
From: Luis R. Rodriguez @ 2010-04-15 21:39 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Luis R. Rodriguez

This is done depending on what the EEPROM settings indicates.

Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/ar9003_eeprom.c |   14 ++++++
 drivers/net/wireless/ath/ath9k/ar9003_eeprom.h |    4 ++
 drivers/net/wireless/ath/ath9k/ar9003_hw.c     |   51 ++++++++++++++++++++++++
 3 files changed, 69 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
index fb39e39..5d92be4 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
@@ -1827,6 +1827,20 @@ static u16 ath9k_hw_ar9300_get_spur_channel(struct ath_hw *ah,
 	return AR_NO_SPUR;
 }
 
+s32 ar9003_hw_get_tx_gain_idx(struct ath_hw *ah)
+{
+	struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
+
+	return (eep->baseEepHeader.txrxgain >> 4) & 0xf; /* bits 7:4 */
+}
+
+s32 ar9003_hw_get_rx_gain_idx(struct ath_hw *ah)
+{
+	struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
+
+	return (eep->baseEepHeader.txrxgain) & 0xf; /* bits 3:0 */
+}
+
 const struct eeprom_ops eep_ar9300_ops = {
 	.check_eeprom = ath9k_hw_ar9300_check_eeprom,
 	.get_eeprom = ath9k_hw_ar9300_get_eeprom,
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h
index 3ca520c..5fe335e 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h
+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h
@@ -316,4 +316,8 @@ struct ar9300_eeprom {
 	u8 ctl_freqbin_5G[AR9300_NUM_CTLS_5G][AR9300_NUM_BAND_EDGES_5G];
 	struct cal_ctl_data_5g ctlPowerData_5G[AR9300_NUM_CTLS_5G];
 } __packed;
+
+s32 ar9003_hw_get_tx_gain_idx(struct ath_hw *ah);
+s32 ar9003_hw_get_rx_gain_idx(struct ath_hw *ah);
+
 #endif
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_hw.c b/drivers/net/wireless/ath/ath9k/ar9003_hw.c
index 1984b4f..f32665d 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_hw.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_hw.c
@@ -105,6 +105,56 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
 		       3);
 }
 
+static void ar9003_tx_gain_table_apply(struct ath_hw *ah)
+{
+	switch (ar9003_hw_get_tx_gain_idx(ah)) {
+	case 0:
+	default:
+		INIT_INI_ARRAY(&ah->iniModesTxGain,
+			       ar9300Modes_lowest_ob_db_tx_gain_table_2p0,
+			       ARRAY_SIZE(ar9300Modes_lowest_ob_db_tx_gain_table_2p0),
+			       5);
+		break;
+	case 1:
+		INIT_INI_ARRAY(&ah->iniModesTxGain,
+			       ar9300Modes_high_ob_db_tx_gain_table_2p0,
+			       ARRAY_SIZE(ar9300Modes_high_ob_db_tx_gain_table_2p0),
+			       5);
+		break;
+	case 2:
+		INIT_INI_ARRAY(&ah->iniModesTxGain,
+			       ar9300Modes_low_ob_db_tx_gain_table_2p0,
+			       ARRAY_SIZE(ar9300Modes_low_ob_db_tx_gain_table_2p0),
+			       5);
+		break;
+	}
+}
+
+static void ar9003_rx_gain_table_apply(struct ath_hw *ah)
+{
+	switch (ar9003_hw_get_rx_gain_idx(ah)) {
+	case 0:
+	default:
+		INIT_INI_ARRAY(&ah->iniModesRxGain, ar9300Common_rx_gain_table_2p0,
+			       ARRAY_SIZE(ar9300Common_rx_gain_table_2p0),
+			       2);
+		break;
+	case 1:
+		INIT_INI_ARRAY(&ah->iniModesRxGain,
+			       ar9300Common_wo_xlna_rx_gain_table_2p0,
+			       ARRAY_SIZE(ar9300Common_wo_xlna_rx_gain_table_2p0),
+			       2);
+		break;
+	}
+}
+
+/* set gain table pointers according to values read from the eeprom */
+static void ar9003_hw_init_mode_gain_regs(struct ath_hw *ah)
+{
+	ar9003_tx_gain_table_apply(ah);
+	ar9003_rx_gain_table_apply(ah);
+}
+
 /*
  * Helper for ASPM support.
  *
@@ -143,6 +193,7 @@ void ar9003_hw_attach_ops(struct ath_hw *ah)
 	struct ath_hw_ops *ops = ath9k_hw_ops(ah);
 
 	priv_ops->init_mode_regs = ar9003_hw_init_mode_regs;
+	priv_ops->init_mode_gain_regs = ar9003_hw_init_mode_gain_regs;
 	priv_ops->macversion_supported = ar9003_hw_macversion_supported;
 
 	ops->config_pci_powersave = ar9003_hw_configpcipowersave;
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 103+ messages in thread

* [PATCH v3 77/97] ath9k_hw: Update ath9k_hw_set_dma for AR9300
  2010-04-15 21:38 [PATCH v3 00/97] ath9k: add AR9003 support Luis R. Rodriguez
                   ` (75 preceding siblings ...)
  2010-04-15 21:39 ` [PATCH v3 76/97] ath9k_hw: add TX/RX gain register initialization for AR9003 Luis R. Rodriguez
@ 2010-04-15 21:39 ` Luis R. Rodriguez
  2010-04-15 21:39 ` [PATCH v3 78/97] ath9k_hw: skip asynch fifo enablement to AR9003 Luis R. Rodriguez
                   ` (19 subsequent siblings)
  96 siblings, 0 replies; 103+ messages in thread
From: Luis R. Rodriguez @ 2010-04-15 21:39 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Felix Fietkau

From: Felix Fietkau <nbd@openwrt.org>

Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
 drivers/net/wireless/ath/ath9k/hw.c  |   18 +++++++++++++++---
 drivers/net/wireless/ath/ath9k/reg.h |    6 ++++++
 2 files changed, 21 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index de7ee90..953911d 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -837,13 +837,16 @@ u32 ath9k_regd_get_ctl(struct ath_regulatory *reg, struct ath9k_channel *chan)
 
 static inline void ath9k_hw_set_dma(struct ath_hw *ah)
 {
+	struct ath_common *common = ath9k_hw_common(ah);
 	u32 regval;
 
 	/*
 	 * set AHB_MODE not to do cacheline prefetches
 	*/
-	regval = REG_READ(ah, AR_AHB_MODE);
-	REG_WRITE(ah, AR_AHB_MODE, regval | AR_AHB_PREFETCH_RD_EN);
+	if (!AR_SREV_9300_20_OR_LATER(ah)) {
+		regval = REG_READ(ah, AR_AHB_MODE);
+		REG_WRITE(ah, AR_AHB_MODE, regval | AR_AHB_PREFETCH_RD_EN);
+	}
 
 	/*
 	 * let mac dma reads be in 128 byte chunks
@@ -856,7 +859,8 @@ static inline void ath9k_hw_set_dma(struct ath_hw *ah)
 	 * The initial value depends on whether aggregation is enabled, and is
 	 * adjusted whenever underruns are detected.
 	 */
-	REG_RMW_FIELD(ah, AR_TXCFG, AR_FTRIG, ah->tx_trig_level);
+	if (!AR_SREV_9300_20_OR_LATER(ah))
+		REG_RMW_FIELD(ah, AR_TXCFG, AR_FTRIG, ah->tx_trig_level);
 
 	/*
 	 * let mac dma writes be in 128 byte chunks
@@ -869,6 +873,14 @@ static inline void ath9k_hw_set_dma(struct ath_hw *ah)
 	 */
 	REG_WRITE(ah, AR_RXFIFO_CFG, 0x200);
 
+	if (AR_SREV_9300_20_OR_LATER(ah)) {
+		REG_RMW_FIELD(ah, AR_RXBP_THRESH, AR_RXBP_THRESH_HP, 0x1);
+		REG_RMW_FIELD(ah, AR_RXBP_THRESH, AR_RXBP_THRESH_LP, 0x1);
+
+		ath9k_hw_set_rx_bufsize(ah, common->rx_bufsize -
+			ah->caps.rx_status_len);
+	}
+
 	/*
 	 * reduce the number of usable entries in PCU TXBUF to avoid
 	 * wrap around issues.
diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h
index 12f1621..2ca478c 100644
--- a/drivers/net/wireless/ath/ath9k/reg.h
+++ b/drivers/net/wireless/ath/ath9k/reg.h
@@ -39,6 +39,12 @@
 #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
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 103+ messages in thread

* [PATCH v3 78/97] ath9k_hw: skip asynch fifo enablement to AR9003
  2010-04-15 21:38 [PATCH v3 00/97] ath9k: add AR9003 support Luis R. Rodriguez
                   ` (76 preceding siblings ...)
  2010-04-15 21:39 ` [PATCH v3 77/97] ath9k_hw: Update ath9k_hw_set_dma for AR9300 Luis R. Rodriguez
@ 2010-04-15 21:39 ` Luis R. Rodriguez
  2010-04-15 21:39 ` [PATCH v3 79/97] ath9k_hw: skip WEP aggregation enable code for AR9003 Luis R. Rodriguez
                   ` (18 subsequent siblings)
  96 siblings, 0 replies; 103+ messages in thread
From: Luis R. Rodriguez @ 2010-04-15 21:39 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Luis R. Rodriguez

The asynch fifo code is specific to >= AR9287 so stuff it
into the AR9002 hardware family code and skip it for AR9003
cards.

Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/ar9002_hw.c |   29 ++++++++++++++++++++++++++++
 drivers/net/wireless/ath/ath9k/hw.c        |   19 ++---------------
 drivers/net/wireless/ath/ath9k/hw.h        |    1 +
 3 files changed, 33 insertions(+), 16 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ar9002_hw.c b/drivers/net/wireless/ath/ath9k/ar9002_hw.c
index 5b21e69..cf36f64 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_hw.c
+++ b/drivers/net/wireless/ath/ath9k/ar9002_hw.c
@@ -526,6 +526,35 @@ int ar9002_hw_rf_claim(struct ath_hw *ah)
 	return 0;
 }
 
+/*
+ * Enable ASYNC FIFO
+ *
+ * If Async FIFO is enabled, the following counters change as MAC now runs
+ * at 117 Mhz instead of 88/44MHz when async FIFO is disabled.
+ *
+ * The values below tested for ht40 2 chain.
+ * Overwrite the delay/timeouts initialized in process ini.
+ */
+void ar9002_hw_enable_async_fifo(struct ath_hw *ah)
+{
+	if (AR_SREV_9287_12_OR_LATER(ah)) {
+		REG_WRITE(ah, AR_D_GBL_IFS_SIFS,
+			  AR_D_GBL_IFS_SIFS_ASYNC_FIFO_DUR);
+		REG_WRITE(ah, AR_D_GBL_IFS_SLOT,
+			  AR_D_GBL_IFS_SLOT_ASYNC_FIFO_DUR);
+		REG_WRITE(ah, AR_D_GBL_IFS_EIFS,
+			  AR_D_GBL_IFS_EIFS_ASYNC_FIFO_DUR);
+
+		REG_WRITE(ah, AR_TIME_OUT, AR_TIME_OUT_ACK_CTS_ASYNC_FIFO_DUR);
+		REG_WRITE(ah, AR_USEC, AR_USEC_ASYNC_FIFO_DUR);
+
+		REG_SET_BIT(ah, AR_MAC_PCU_LOGIC_ANALYZER,
+			    AR_MAC_PCU_LOGIC_ANALYZER_DISBUG20768);
+		REG_RMW_FIELD(ah, AR_AHB_MODE, AR_AHB_CUSTOM_BURST_EN,
+			      AR_AHB_CUSTOM_BURST_ASYNC_FIFO_VAL);
+	}
+}
+
 /* Sets up the AR5008/AR9001/AR9002 hardware familiy callbacks */
 void ar9002_hw_attach_ops(struct ath_hw *ah)
 {
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 953911d..ab223c6 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -1266,22 +1266,9 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
 
 	ath9k_hw_init_global_settings(ah);
 
-	if (AR_SREV_9287_12_OR_LATER(ah)) {
-		REG_WRITE(ah, AR_D_GBL_IFS_SIFS,
-			  AR_D_GBL_IFS_SIFS_ASYNC_FIFO_DUR);
-		REG_WRITE(ah, AR_D_GBL_IFS_SLOT,
-			  AR_D_GBL_IFS_SLOT_ASYNC_FIFO_DUR);
-		REG_WRITE(ah, AR_D_GBL_IFS_EIFS,
-			  AR_D_GBL_IFS_EIFS_ASYNC_FIFO_DUR);
-
-		REG_WRITE(ah, AR_TIME_OUT, AR_TIME_OUT_ACK_CTS_ASYNC_FIFO_DUR);
-		REG_WRITE(ah, AR_USEC, AR_USEC_ASYNC_FIFO_DUR);
+	if (!AR_SREV_9300_20_OR_LATER(ah))
+		ar9002_hw_enable_async_fifo(ah);
 
-		REG_SET_BIT(ah, AR_MAC_PCU_LOGIC_ANALYZER,
-			    AR_MAC_PCU_LOGIC_ANALYZER_DISBUG20768);
-		REG_RMW_FIELD(ah, AR_AHB_MODE, AR_AHB_CUSTOM_BURST_EN,
-			      AR_AHB_CUSTOM_BURST_ASYNC_FIFO_VAL);
-	}
 	if (AR_SREV_9287_12_OR_LATER(ah)) {
 		REG_SET_BIT(ah, AR_PCU_MISC_MODE2,
 				AR_PCU_MISC_MODE2_ENABLE_AGGWEP);
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 16f0f98..e4eacdd 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -850,6 +850,7 @@ void ath9k_hw_get_delta_slope_vals(struct ath_hw *ah, u32 coef_scaled,
  */
 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);
 
 /*
  * Code specifric to AR9003, we stuff these here to avoid callbacks
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 103+ messages in thread

* [PATCH v3 79/97] ath9k_hw: skip WEP aggregation enable code for AR9003
  2010-04-15 21:38 [PATCH v3 00/97] ath9k: add AR9003 support Luis R. Rodriguez
                   ` (77 preceding siblings ...)
  2010-04-15 21:39 ` [PATCH v3 78/97] ath9k_hw: skip asynch fifo enablement to AR9003 Luis R. Rodriguez
@ 2010-04-15 21:39 ` Luis R. Rodriguez
  2010-04-15 21:39 ` [PATCH v3 80/97] ath9k: Load SW filtered NF values and start NF cal during full reset " Luis R. Rodriguez
                   ` (17 subsequent siblings)
  96 siblings, 0 replies; 103+ messages in thread
From: Luis R. Rodriguez @ 2010-04-15 21:39 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Luis R. Rodriguez

The AR9002 hardware code enables aggregation for WEP but
mac80211 doesn't enable aggregation with WEP, and the AR9003
code family does not need this so skip it for now for AR9003
but leave the code and annotate we should eventually consider
how to remove this in consideration for the HAL unification
goals.

Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/ar9002_hw.c |   12 ++++++++++++
 drivers/net/wireless/ath/ath9k/hw.c        |    7 ++-----
 drivers/net/wireless/ath/ath9k/hw.h        |    1 +
 3 files changed, 15 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ar9002_hw.c b/drivers/net/wireless/ath/ath9k/ar9002_hw.c
index cf36f64..17b98a3 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_hw.c
+++ b/drivers/net/wireless/ath/ath9k/ar9002_hw.c
@@ -555,6 +555,18 @@ void ar9002_hw_enable_async_fifo(struct ath_hw *ah)
 	}
 }
 
+/*
+ * We don't enable WEP aggregation on mac80211 but we keep this
+ * around for HAL unification purposes.
+ */
+void ar9002_hw_enable_wep_aggregation(struct ath_hw *ah)
+{
+	if (AR_SREV_9287_12_OR_LATER(ah)) {
+		REG_SET_BIT(ah, AR_PCU_MISC_MODE2,
+				AR_PCU_MISC_MODE2_ENABLE_AGGWEP);
+	}
+}
+
 /* Sets up the AR5008/AR9001/AR9002 hardware familiy callbacks */
 void ar9002_hw_attach_ops(struct ath_hw *ah)
 {
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index ab223c6..5260c43 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -1266,12 +1266,9 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
 
 	ath9k_hw_init_global_settings(ah);
 
-	if (!AR_SREV_9300_20_OR_LATER(ah))
+	if (!AR_SREV_9300_20_OR_LATER(ah)) {
 		ar9002_hw_enable_async_fifo(ah);
-
-	if (AR_SREV_9287_12_OR_LATER(ah)) {
-		REG_SET_BIT(ah, AR_PCU_MISC_MODE2,
-				AR_PCU_MISC_MODE2_ENABLE_AGGWEP);
+		ar9002_hw_enable_wep_aggregation(ah);
 	}
 
 	REG_WRITE(ah, AR_STA_ID1,
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index e4eacdd..affb848 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -851,6 +851,7 @@ void ath9k_hw_get_delta_slope_vals(struct ath_hw *ah, u32 coef_scaled,
 void ar9002_hw_cck_chan14_spread(struct ath_hw *ah);
 int ar9002_hw_rf_claim(struct ath_hw *ah);
 void ar9002_hw_enable_async_fifo(struct ath_hw *ah);
+void ar9002_hw_enable_wep_aggregation(struct ath_hw *ah);
 
 /*
  * Code specifric to AR9003, we stuff these here to avoid callbacks
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 103+ messages in thread

* [PATCH v3 80/97] ath9k: Load SW filtered NF values and start NF cal during full reset for AR9003
  2010-04-15 21:38 [PATCH v3 00/97] ath9k: add AR9003 support Luis R. Rodriguez
                   ` (78 preceding siblings ...)
  2010-04-15 21:39 ` [PATCH v3 79/97] ath9k_hw: skip WEP aggregation enable code for AR9003 Luis R. Rodriguez
@ 2010-04-15 21:39 ` Luis R. Rodriguez
  2010-04-15 21:39 ` [PATCH v3 81/97] ath9k_hw: Define abstraction for tx desc access Luis R. Rodriguez
                   ` (16 subsequent siblings)
  96 siblings, 0 replies; 103+ messages in thread
From: Luis R. Rodriguez @ 2010-04-15 21:39 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Vasanthakumar Thiagarajan

From: Vasanthakumar Thiagarajan <vasanth@atheros.com>

Signed-off-by: Vasanthakumar Thiagarajan <vasanth@atheros.com>
---
 drivers/net/wireless/ath/ath9k/hw.c |    5 +++++
 1 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 5260c43..8155e23 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -1325,6 +1325,11 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
 	if (ah->btcoex_hw.enabled)
 		ath9k_hw_btcoex_enable(ah);
 
+	if (AR_SREV_9300_20_OR_LATER(ah)) {
+		ath9k_hw_loadnf(ah, curchan);
+		ath9k_hw_start_nfcal(ah);
+	}
+
 	return 0;
 }
 EXPORT_SYMBOL(ath9k_hw_reset);
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 103+ messages in thread

* [PATCH v3 81/97] ath9k_hw: Define abstraction for tx desc access
  2010-04-15 21:38 [PATCH v3 00/97] ath9k: add AR9003 support Luis R. Rodriguez
                   ` (79 preceding siblings ...)
  2010-04-15 21:39 ` [PATCH v3 80/97] ath9k: Load SW filtered NF values and start NF cal during full reset " Luis R. Rodriguez
@ 2010-04-15 21:39 ` Luis R. Rodriguez
  2010-04-15 21:39 ` [PATCH v3 82/97] ath9k_hw: Add function to configure tx status ring buffer Luis R. Rodriguez
                   ` (15 subsequent siblings)
  96 siblings, 0 replies; 103+ messages in thread
From: Luis R. Rodriguez @ 2010-04-15 21:39 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Vasanthakumar Thiagarajan

From: Vasanthakumar Thiagarajan <vasanth@atheros.com>

Signed-off-by: Vasanthakumar Thiagarajan <vasanth@atheros.com>
---
 drivers/net/wireless/ath/ath9k/ar9003_mac.c |   73 ++++
 drivers/net/wireless/ath/ath9k/beacon.c     |    3 +-
 drivers/net/wireless/ath/ath9k/hw-ops.h     |   71 ++++
 drivers/net/wireless/ath/ath9k/hw.h         |   27 ++
 drivers/net/wireless/ath/ath9k/mac.c        |  508 ++++++++++++++-------------
 drivers/net/wireless/ath/ath9k/mac.h        |   27 +--
 drivers/net/wireless/ath/ath9k/xmit.c       |    3 +-
 7 files changed, 431 insertions(+), 281 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.c b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
index 2319456..c270bbe 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
@@ -167,6 +167,69 @@ static bool ar9003_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked)
 	return true;
 }
 
+static void ar9003_hw_fill_txdesc(struct ath_hw *ah, void *ds, u32 seglen,
+				  bool is_firstseg, bool is_lastseg,
+				  const void *ds0, dma_addr_t buf_addr,
+				  unsigned int qcu)
+{
+}
+
+static int ar9003_hw_proc_txdesc(struct ath_hw *ah, void *ds,
+				 struct ath_tx_status *ts)
+{
+	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)
+{
+
+}
+
+static void ar9003_hw_set11n_ratescenario(struct ath_hw *ah, void *ds,
+					  void *lastds,
+					  u32 durUpdateEn, u32 rtsctsRate,
+					  u32 rtsctsDuration,
+					  struct ath9k_11n_rate_series series[],
+					  u32 nseries, u32 flags)
+{
+
+}
+
+static void ar9003_hw_set11n_aggr_first(struct ath_hw *ah, void *ds,
+					u32 aggrLen)
+{
+
+}
+
+static void ar9003_hw_set11n_aggr_middle(struct ath_hw *ah, void *ds,
+					 u32 numDelims)
+{
+
+}
+
+static void ar9003_hw_set11n_aggr_last(struct ath_hw *ah, void *ds)
+{
+
+}
+
+static void ar9003_hw_clr11n_aggr(struct ath_hw *ah, void *ds)
+{
+
+}
+
+static void ar9003_hw_set11n_burstduration(struct ath_hw *ah, void *ds,
+					   u32 burstDuration)
+{
+
+}
+
+static void ar9003_hw_set11n_virtualmorefrag(struct ath_hw *ah, void *ds,
+					    u32 vmf)
+{
+
+}
+
 void ar9003_hw_attach_mac_ops(struct ath_hw *hw)
 {
 	struct ath_hw_ops *ops = ath9k_hw_ops(hw);
@@ -175,6 +238,16 @@ void ar9003_hw_attach_mac_ops(struct ath_hw *hw)
 	ops->set_desc_link = ar9003_hw_set_desc_link;
 	ops->get_desc_link = ar9003_hw_get_desc_link;
 	ops->get_isr = ar9003_hw_get_isr;
+	ops->fill_txdesc = ar9003_hw_fill_txdesc;
+	ops->proc_txdesc = ar9003_hw_proc_txdesc;
+	ops->set11n_txdesc = ar9003_hw_set11n_txdesc;
+	ops->set11n_ratescenario = ar9003_hw_set11n_ratescenario;
+	ops->set11n_aggr_first = ar9003_hw_set11n_aggr_first;
+	ops->set11n_aggr_middle = ar9003_hw_set11n_aggr_middle;
+	ops->set11n_aggr_last = ar9003_hw_set11n_aggr_last;
+	ops->clr11n_aggr = ar9003_hw_clr11n_aggr;
+	ops->set11n_burstduration = ar9003_hw_set11n_burstduration;
+	ops->set11n_virtualmorefrag = ar9003_hw_set11n_virtualmorefrag;
 }
 
 void ath9k_hw_set_rx_bufsize(struct ath_hw *ah, u16 buf_size)
diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c
index 268b598..c8a4558 100644
--- a/drivers/net/wireless/ath/ath9k/beacon.c
+++ b/drivers/net/wireless/ath/ath9k/beacon.c
@@ -107,7 +107,8 @@ static void ath_beacon_setup(struct ath_softc *sc, struct ath_vif *avp,
 
 	/* NB: beacon's BufLen must be a multiple of 4 bytes */
 	ath9k_hw_filltxdesc(ah, ds, roundup(skb->len, 4),
-			    true, true, ds, bf->bf_buf_addr);
+			    true, true, ds, bf->bf_buf_addr,
+			    sc->beacon.beaconq);
 
 	memset(series, 0, sizeof(struct ath9k_11n_rate_series) * 4);
 	series[0].Tries = 1;
diff --git a/drivers/net/wireless/ath/ath9k/hw-ops.h b/drivers/net/wireless/ath/ath9k/hw-ops.h
index b444ce5..624422a 100644
--- a/drivers/net/wireless/ath/ath9k/hw-ops.h
+++ b/drivers/net/wireless/ath/ath9k/hw-ops.h
@@ -57,6 +57,77 @@ static inline bool ath9k_hw_getisr(struct ath_hw *ah, enum ath9k_int *masked)
 	return ath9k_hw_ops(ah)->get_isr(ah, masked);
 }
 
+static inline void ath9k_hw_filltxdesc(struct ath_hw *ah, void *ds, u32 seglen,
+				  bool is_firstseg, bool is_lastseg,
+				  const void *ds0, dma_addr_t buf_addr,
+				  unsigned int qcu)
+{
+	ath9k_hw_ops(ah)->fill_txdesc(ah, ds, seglen, is_firstseg, is_lastseg,
+				      ds0, buf_addr, qcu);
+}
+
+static inline int ath9k_hw_txprocdesc(struct ath_hw *ah, void *ds,
+				      struct ath_tx_status *ts)
+{
+	return ath9k_hw_ops(ah)->proc_txdesc(ah, ds, ts);
+}
+
+static inline void ath9k_hw_set11n_txdesc(struct ath_hw *ah, void *ds,
+					  u32 pktLen, enum ath9k_pkt_type type,
+					  u32 txPower, u32 keyIx,
+					  enum ath9k_key_type keyType,
+					  u32 flags)
+{
+	ath9k_hw_ops(ah)->set11n_txdesc(ah, ds, pktLen, type, txPower, keyIx,
+				      keyType, flags);
+}
+
+static inline void ath9k_hw_set11n_ratescenario(struct ath_hw *ah, void *ds,
+					void *lastds,
+					u32 durUpdateEn, u32 rtsctsRate,
+					u32 rtsctsDuration,
+					struct ath9k_11n_rate_series series[],
+					u32 nseries, u32 flags)
+{
+	ath9k_hw_ops(ah)->set11n_ratescenario(ah, ds, lastds, durUpdateEn,
+					    rtsctsRate, rtsctsDuration, series,
+					    nseries, flags);
+}
+
+static inline void ath9k_hw_set11n_aggr_first(struct ath_hw *ah, void *ds,
+					u32 aggrLen)
+{
+	ath9k_hw_ops(ah)->set11n_aggr_first(ah, ds, aggrLen);
+}
+
+static inline void ath9k_hw_set11n_aggr_middle(struct ath_hw *ah, void *ds,
+					       u32 numDelims)
+{
+	ath9k_hw_ops(ah)->set11n_aggr_middle(ah, ds, numDelims);
+}
+
+static inline void ath9k_hw_set11n_aggr_last(struct ath_hw *ah, void *ds)
+{
+	ath9k_hw_ops(ah)->set11n_aggr_last(ah, ds);
+}
+
+static inline void ath9k_hw_clr11n_aggr(struct ath_hw *ah, void *ds)
+{
+	ath9k_hw_ops(ah)->clr11n_aggr(ah, ds);
+}
+
+static inline void ath9k_hw_set11n_burstduration(struct ath_hw *ah, void *ds,
+						 u32 burstDuration)
+{
+	ath9k_hw_ops(ah)->set11n_burstduration(ah, ds, burstDuration);
+}
+
+static inline void ath9k_hw_set11n_virtualmorefrag(struct ath_hw *ah, void *ds,
+						   u32 vmf)
+{
+	ath9k_hw_ops(ah)->set11n_virtualmorefrag(ah, ds, vmf);
+}
+
 /* Private hardware call ops */
 
 /* PHY ops */
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index affb848..457d8dd 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -556,6 +556,33 @@ struct ath_hw_ops {
 			  u8 rxchainmask,
 			  bool longcal);
 	bool (*get_isr)(struct ath_hw *ah, enum ath9k_int *masked);
+	void (*fill_txdesc)(struct ath_hw *ah, void *ds, u32 seglen,
+			    bool is_firstseg, bool is_is_lastseg,
+			    const void *ds0, dma_addr_t buf_addr,
+			    unsigned int qcu);
+	int (*proc_txdesc)(struct ath_hw *ah, void *ds,
+			   struct ath_tx_status *ts);
+	void (*set11n_txdesc)(struct ath_hw *ah, void *ds,
+			      u32 pktLen, enum ath9k_pkt_type type,
+			      u32 txPower, u32 keyIx,
+			      enum ath9k_key_type keyType,
+			      u32 flags);
+	void (*set11n_ratescenario)(struct ath_hw *ah, void *ds,
+				void *lastds,
+				u32 durUpdateEn, u32 rtsctsRate,
+				u32 rtsctsDuration,
+				struct ath9k_11n_rate_series series[],
+				u32 nseries, u32 flags);
+	void (*set11n_aggr_first)(struct ath_hw *ah, void *ds,
+				  u32 aggrLen);
+	void (*set11n_aggr_middle)(struct ath_hw *ah, void *ds,
+				   u32 numDelims);
+	void (*set11n_aggr_last)(struct ath_hw *ah, void *ds);
+	void (*clr11n_aggr)(struct ath_hw *ah, void *ds);
+	void (*set11n_burstduration)(struct ath_hw *ah, void *ds,
+				     u32 burstDuration);
+	void (*set11n_virtualmorefrag)(struct ath_hw *ah, void *ds,
+				       u32 vmf);
 };
 
 struct ath_hw {
diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c
index 4a36ec5..22fa512 100644
--- a/drivers/net/wireless/ath/ath9k/mac.c
+++ b/drivers/net/wireless/ath/ath9k/mac.c
@@ -183,226 +183,25 @@ static bool ar9002_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked)
 	return true;
 }
 
-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;
-}
-
-static void ath9k_hw_set_txq_interrupts(struct ath_hw *ah,
-					struct ath9k_tx_queue_info *qi)
-{
-	ath_print(ath9k_hw_common(ah), ATH_DBG_INTERRUPT,
-		  "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);
-
-	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);
-}
-
-u32 ath9k_hw_gettxbuf(struct ath_hw *ah, u32 q)
-{
-	return REG_READ(ah, AR_QTXDP(q));
-}
-EXPORT_SYMBOL(ath9k_hw_gettxbuf);
-
-void ath9k_hw_puttxbuf(struct ath_hw *ah, u32 q, u32 txdp)
-{
-	REG_WRITE(ah, AR_QTXDP(q), txdp);
-}
-EXPORT_SYMBOL(ath9k_hw_puttxbuf);
-
-void ath9k_hw_txstart(struct ath_hw *ah, u32 q)
-{
-	ath_print(ath9k_hw_common(ah), ATH_DBG_QUEUE,
-		  "Enable TXE on queue: %u\n", q);
-	REG_WRITE(ah, AR_Q_TXE, 1 << q);
-}
-EXPORT_SYMBOL(ath9k_hw_txstart);
-
-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;
-}
-EXPORT_SYMBOL(ath9k_hw_numtxpending);
-
-/**
- * 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.
- */
-bool ath9k_hw_updatetxtriglevel(struct ath_hw *ah, bool bIncTrigLevel)
-{
-	u32 txcfg, curLevel, newLevel;
-	enum ath9k_int omask;
-
-	if (ah->tx_trig_level >= ah->config.max_txtrig_level)
-		return false;
-
-	omask = ath9k_hw_set_interrupts(ah, ah->imask & ~ATH9K_INT_GLOBAL);
-
-	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_set_interrupts(ah, omask);
-
-	ah->tx_trig_level = newLevel;
-
-	return newLevel != curLevel;
-}
-EXPORT_SYMBOL(ath9k_hw_updatetxtriglevel);
-
-bool ath9k_hw_stoptxdma(struct ath_hw *ah, u32 q)
-{
-#define ATH9K_TX_STOP_DMA_TIMEOUT	4000    /* usec */
-#define ATH9K_TIME_QUANTUM		100     /* usec */
-	struct ath_common *common = ath9k_hw_common(ah);
-	struct ath9k_hw_capabilities *pCap = &ah->caps;
-	struct ath9k_tx_queue_info *qi;
-	u32 tsfLow, j, wait;
-	u32 wait_time = ATH9K_TX_STOP_DMA_TIMEOUT / ATH9K_TIME_QUANTUM;
-
-	if (q >= pCap->total_queues) {
-		ath_print(common, ATH_DBG_QUEUE, "Stopping TX DMA, "
-			  "invalid queue: %u\n", q);
-		return false;
-	}
-
-	qi = &ah->txq[q];
-	if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
-		ath_print(common, ATH_DBG_QUEUE, "Stopping TX DMA, "
-			  "inactive queue: %u\n", q);
-		return false;
-	}
-
-	REG_WRITE(ah, AR_Q_TXD, 1 << q);
-
-	for (wait = wait_time; wait != 0; wait--) {
-		if (ath9k_hw_numtxpending(ah, q) == 0)
-			break;
-		udelay(ATH9K_TIME_QUANTUM);
-	}
-
-	if (ath9k_hw_numtxpending(ah, q)) {
-		ath_print(common, ATH_DBG_QUEUE,
-			  "%s: Num of pending TX Frames %d on Q %d\n",
-			  __func__, ath9k_hw_numtxpending(ah, q), q);
-
-		for (j = 0; j < 2; j++) {
-			tsfLow = REG_READ(ah, AR_TSF_L32);
-			REG_WRITE(ah, AR_QUIET2,
-				  SM(10, AR_QUIET2_QUIET_DUR));
-			REG_WRITE(ah, AR_QUIET_PERIOD, 100);
-			REG_WRITE(ah, AR_NEXT_QUIET_TIMER, tsfLow >> 10);
-			REG_SET_BIT(ah, AR_TIMER_MODE,
-				       AR_QUIET_TIMER_EN);
-
-			if ((REG_READ(ah, AR_TSF_L32) >> 10) == (tsfLow >> 10))
-				break;
-
-			ath_print(common, ATH_DBG_QUEUE,
-				  "TSF has moved while trying to set "
-				  "quiet time TSF: 0x%08x\n", tsfLow);
-		}
-
-		REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH);
-
-		udelay(200);
-		REG_CLR_BIT(ah, AR_TIMER_MODE, AR_QUIET_TIMER_EN);
-
-		wait = wait_time;
-		while (ath9k_hw_numtxpending(ah, q)) {
-			if ((--wait) == 0) {
-				ath_print(common, ATH_DBG_FATAL,
-					  "Failed to stop TX DMA in 100 "
-					  "msec after killing last frame\n");
-				break;
-			}
-			udelay(ATH9K_TIME_QUANTUM);
-		}
-
-		REG_CLR_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH);
-	}
-
-	REG_WRITE(ah, AR_Q_TXD, 0);
-	return wait != 0;
-
-#undef ATH9K_TX_STOP_DMA_TIMEOUT
-#undef ATH9K_TIME_QUANTUM
-}
-EXPORT_SYMBOL(ath9k_hw_stoptxdma);
-
-void ath9k_hw_filltxdesc(struct ath_hw *ah, struct ath_desc *ds,
-			 u32 segLen, bool firstSeg,
-			 bool lastSeg, const struct ath_desc *ds0,
-			 dma_addr_t buf_addr)
+static void ar9002_hw_fill_txdesc(struct ath_hw *ah, void *ds, u32 seglen,
+				  bool is_firstseg, bool is_lastseg,
+				  const void *ds0, dma_addr_t buf_addr,
+				  unsigned int qcu)
 {
 	struct ar5416_desc *ads = AR5416DESC(ds);
 
 	ads->ds_data = buf_addr;
 
-	if (firstSeg) {
-		ads->ds_ctl1 |= segLen | (lastSeg ? 0 : AR_TxMore);
-	} else if (lastSeg) {
+	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_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_ctl1 = seglen | AR_TxMore;
 		ads->ds_ctl2 = 0;
 		ads->ds_ctl3 = 0;
 	}
@@ -412,22 +211,9 @@ void ath9k_hw_filltxdesc(struct ath_hw *ah, struct ath_desc *ds,
 	ads->ds_txstatus6 = ads->ds_txstatus7 = 0;
 	ads->ds_txstatus8 = ads->ds_txstatus9 = 0;
 }
-EXPORT_SYMBOL(ath9k_hw_filltxdesc);
 
-void ath9k_hw_cleartxdesc(struct ath_hw *ah, struct ath_desc *ds)
-{
-	struct ar5416_desc *ads = AR5416DESC(ds);
-
-	ads->ds_txstatus0 = ads->ds_txstatus1 = 0;
-	ads->ds_txstatus2 = ads->ds_txstatus3 = 0;
-	ads->ds_txstatus4 = ads->ds_txstatus5 = 0;
-	ads->ds_txstatus6 = ads->ds_txstatus7 = 0;
-	ads->ds_txstatus8 = ads->ds_txstatus9 = 0;
-}
-EXPORT_SYMBOL(ath9k_hw_cleartxdesc);
-
-int ath9k_hw_txprocdesc(struct ath_hw *ah, struct ath_desc *ds,
-			struct ath_tx_status *ts)
+static int ar9002_hw_proc_txdesc(struct ath_hw *ah, void *ds,
+				 struct ath_tx_status *ts)
 {
 	struct ar5416_desc *ads = AR5416DESC(ds);
 
@@ -503,11 +289,11 @@ int ath9k_hw_txprocdesc(struct ath_hw *ah, struct ath_desc *ds,
 
 	return 0;
 }
-EXPORT_SYMBOL(ath9k_hw_txprocdesc);
 
-void ath9k_hw_set11n_txdesc(struct ath_hw *ah, struct ath_desc *ds,
-			    u32 pktLen, enum ath9k_pkt_type type, u32 txPower,
-			    u32 keyIx, enum ath9k_key_type keyType, u32 flags)
+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);
 
@@ -539,14 +325,13 @@ void ath9k_hw_set11n_txdesc(struct ath_hw *ah, struct ath_desc *ds,
 		ads->ds_ctl11 = 0;
 	}
 }
-EXPORT_SYMBOL(ath9k_hw_set11n_txdesc);
-
-void ath9k_hw_set11n_ratescenario(struct ath_hw *ah, struct ath_desc *ds,
-				  struct ath_desc *lastds,
-				  u32 durUpdateEn, u32 rtsctsRate,
-				  u32 rtsctsDuration,
-				  struct ath9k_11n_rate_series series[],
-				  u32 nseries, u32 flags)
+
+static void ar9002_hw_set11n_ratescenario(struct ath_hw *ah, void *ds,
+					  void *lastds,
+					  u32 durUpdateEn, u32 rtsctsRate,
+					  u32 rtsctsDuration,
+					  struct ath9k_11n_rate_series series[],
+					  u32 nseries, u32 flags)
 {
 	struct ar5416_desc *ads = AR5416DESC(ds);
 	struct ar5416_desc *last_ads = AR5416DESC(lastds);
@@ -595,10 +380,9 @@ void ath9k_hw_set11n_ratescenario(struct ath_hw *ah, struct ath_desc *ds,
 	last_ads->ds_ctl2 = ads->ds_ctl2;
 	last_ads->ds_ctl3 = ads->ds_ctl3;
 }
-EXPORT_SYMBOL(ath9k_hw_set11n_ratescenario);
 
-void ath9k_hw_set11n_aggr_first(struct ath_hw *ah, struct ath_desc *ds,
-				u32 aggrLen)
+static void ar9002_hw_set11n_aggr_first(struct ath_hw *ah, void *ds,
+					u32 aggrLen)
 {
 	struct ar5416_desc *ads = AR5416DESC(ds);
 
@@ -606,10 +390,9 @@ void ath9k_hw_set11n_aggr_first(struct ath_hw *ah, struct ath_desc *ds,
 	ads->ds_ctl6 &= ~AR_AggrLen;
 	ads->ds_ctl6 |= SM(aggrLen, AR_AggrLen);
 }
-EXPORT_SYMBOL(ath9k_hw_set11n_aggr_first);
 
-void ath9k_hw_set11n_aggr_middle(struct ath_hw *ah, struct ath_desc *ds,
-				 u32 numDelims)
+static void ar9002_hw_set11n_aggr_middle(struct ath_hw *ah, void *ds,
+					 u32 numDelims)
 {
 	struct ar5416_desc *ads = AR5416DESC(ds);
 	unsigned int ctl6;
@@ -621,9 +404,8 @@ void ath9k_hw_set11n_aggr_middle(struct ath_hw *ah, struct ath_desc *ds,
 	ctl6 |= SM(numDelims, AR_PadDelim);
 	ads->ds_ctl6 = ctl6;
 }
-EXPORT_SYMBOL(ath9k_hw_set11n_aggr_middle);
 
-void ath9k_hw_set11n_aggr_last(struct ath_hw *ah, struct ath_desc *ds)
+static void ar9002_hw_set11n_aggr_last(struct ath_hw *ah, void *ds)
 {
 	struct ar5416_desc *ads = AR5416DESC(ds);
 
@@ -631,28 +413,25 @@ void ath9k_hw_set11n_aggr_last(struct ath_hw *ah, struct ath_desc *ds)
 	ads->ds_ctl1 &= ~AR_MoreAggr;
 	ads->ds_ctl6 &= ~AR_PadDelim;
 }
-EXPORT_SYMBOL(ath9k_hw_set11n_aggr_last);
 
-void ath9k_hw_clr11n_aggr(struct ath_hw *ah, struct ath_desc *ds)
+static void ar9002_hw_clr11n_aggr(struct ath_hw *ah, void *ds)
 {
 	struct ar5416_desc *ads = AR5416DESC(ds);
 
 	ads->ds_ctl1 &= (~AR_IsAggr & ~AR_MoreAggr);
 }
-EXPORT_SYMBOL(ath9k_hw_clr11n_aggr);
 
-void ath9k_hw_set11n_burstduration(struct ath_hw *ah, struct ath_desc *ds,
-				   u32 burstDuration)
+static void ar9002_hw_set11n_burstduration(struct ath_hw *ah, void *ds,
+					   u32 burstDuration)
 {
 	struct ar5416_desc *ads = AR5416DESC(ds);
 
 	ads->ds_ctl2 &= ~AR_BurstDur;
 	ads->ds_ctl2 |= SM(burstDuration, AR_BurstDur);
 }
-EXPORT_SYMBOL(ath9k_hw_set11n_burstduration);
 
-void ath9k_hw_set11n_virtualmorefrag(struct ath_hw *ah, struct ath_desc *ds,
-				     u32 vmf)
+static void ar9002_hw_set11n_virtualmorefrag(struct ath_hw *ah, void *ds,
+					    u32 vmf)
 {
 	struct ar5416_desc *ads = AR5416DESC(ds);
 
@@ -662,6 +441,229 @@ void ath9k_hw_set11n_virtualmorefrag(struct ath_hw *ah, struct ath_desc *ds,
 		ads->ds_ctl0 &= ~AR_VirtMoreFrag;
 }
 
+void ar9002_hw_attach_mac_ops(struct ath_hw *ah)
+{
+	struct ath_hw_ops *ops = ath9k_hw_ops(ah);
+
+	ops->rx_enable = ar9002_hw_rx_enable;
+	ops->set_desc_link = ar9002_hw_set_desc_link;
+	ops->get_desc_link = ar9002_hw_get_desc_link;
+	ops->get_isr = ar9002_hw_get_isr;
+	ops->fill_txdesc = ar9002_hw_fill_txdesc;
+	ops->proc_txdesc = ar9002_hw_proc_txdesc;
+	ops->set11n_txdesc = ar9002_hw_set11n_txdesc;
+	ops->set11n_ratescenario = ar9002_hw_set11n_ratescenario;
+	ops->set11n_aggr_first = ar9002_hw_set11n_aggr_first;
+	ops->set11n_aggr_middle = ar9002_hw_set11n_aggr_middle;
+	ops->set11n_aggr_last = ar9002_hw_set11n_aggr_last;
+	ops->clr11n_aggr = ar9002_hw_clr11n_aggr;
+	ops->set11n_burstduration = ar9002_hw_set11n_burstduration;
+	ops->set11n_virtualmorefrag = ar9002_hw_set11n_virtualmorefrag;
+}
+
+static void ath9k_hw_set_txq_interrupts(struct ath_hw *ah,
+					struct ath9k_tx_queue_info *qi)
+{
+	ath_print(ath9k_hw_common(ah), ATH_DBG_INTERRUPT,
+		  "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);
+
+	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);
+}
+
+u32 ath9k_hw_gettxbuf(struct ath_hw *ah, u32 q)
+{
+	return REG_READ(ah, AR_QTXDP(q));
+}
+EXPORT_SYMBOL(ath9k_hw_gettxbuf);
+
+void ath9k_hw_puttxbuf(struct ath_hw *ah, u32 q, u32 txdp)
+{
+	REG_WRITE(ah, AR_QTXDP(q), txdp);
+}
+EXPORT_SYMBOL(ath9k_hw_puttxbuf);
+
+void ath9k_hw_txstart(struct ath_hw *ah, u32 q)
+{
+	ath_print(ath9k_hw_common(ah), ATH_DBG_QUEUE,
+		  "Enable TXE on queue: %u\n", q);
+	REG_WRITE(ah, AR_Q_TXE, 1 << q);
+}
+EXPORT_SYMBOL(ath9k_hw_txstart);
+
+void ath9k_hw_cleartxdesc(struct ath_hw *ah, void *ds)
+{
+	struct ar5416_desc *ads = AR5416DESC(ds);
+
+	ads->ds_txstatus0 = ads->ds_txstatus1 = 0;
+	ads->ds_txstatus2 = ads->ds_txstatus3 = 0;
+	ads->ds_txstatus4 = ads->ds_txstatus5 = 0;
+	ads->ds_txstatus6 = ads->ds_txstatus7 = 0;
+	ads->ds_txstatus8 = ads->ds_txstatus9 = 0;
+}
+EXPORT_SYMBOL(ath9k_hw_cleartxdesc);
+
+u32 ath9k_hw_numtxpending(struct ath_hw *ah, u32 q)
+{
+	u32 npend;
+
+	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;
+}
+EXPORT_SYMBOL(ath9k_hw_numtxpending);
+
+/**
+ * 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.
+ */
+bool ath9k_hw_updatetxtriglevel(struct ath_hw *ah, bool bIncTrigLevel)
+{
+	u32 txcfg, curLevel, newLevel;
+	enum ath9k_int omask;
+
+	if (ah->tx_trig_level >= ah->config.max_txtrig_level)
+		return false;
+
+	omask = ath9k_hw_set_interrupts(ah, ah->imask & ~ATH9K_INT_GLOBAL);
+
+	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_set_interrupts(ah, omask);
+
+	ah->tx_trig_level = newLevel;
+
+	return newLevel != curLevel;
+}
+EXPORT_SYMBOL(ath9k_hw_updatetxtriglevel);
+
+bool ath9k_hw_stoptxdma(struct ath_hw *ah, u32 q)
+{
+#define ATH9K_TX_STOP_DMA_TIMEOUT	4000    /* usec */
+#define ATH9K_TIME_QUANTUM		100     /* usec */
+	struct ath_common *common = ath9k_hw_common(ah);
+	struct ath9k_hw_capabilities *pCap = &ah->caps;
+	struct ath9k_tx_queue_info *qi;
+	u32 tsfLow, j, wait;
+	u32 wait_time = ATH9K_TX_STOP_DMA_TIMEOUT / ATH9K_TIME_QUANTUM;
+
+	if (q >= pCap->total_queues) {
+		ath_print(common, ATH_DBG_QUEUE, "Stopping TX DMA, "
+			  "invalid queue: %u\n", q);
+		return false;
+	}
+
+	qi = &ah->txq[q];
+	if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
+		ath_print(common, ATH_DBG_QUEUE, "Stopping TX DMA, "
+			  "inactive queue: %u\n", q);
+		return false;
+	}
+
+	REG_WRITE(ah, AR_Q_TXD, 1 << q);
+
+	for (wait = wait_time; wait != 0; wait--) {
+		if (ath9k_hw_numtxpending(ah, q) == 0)
+			break;
+		udelay(ATH9K_TIME_QUANTUM);
+	}
+
+	if (ath9k_hw_numtxpending(ah, q)) {
+		ath_print(common, ATH_DBG_QUEUE,
+			  "%s: Num of pending TX Frames %d on Q %d\n",
+			  __func__, ath9k_hw_numtxpending(ah, q), q);
+
+		for (j = 0; j < 2; j++) {
+			tsfLow = REG_READ(ah, AR_TSF_L32);
+			REG_WRITE(ah, AR_QUIET2,
+				  SM(10, AR_QUIET2_QUIET_DUR));
+			REG_WRITE(ah, AR_QUIET_PERIOD, 100);
+			REG_WRITE(ah, AR_NEXT_QUIET_TIMER, tsfLow >> 10);
+			REG_SET_BIT(ah, AR_TIMER_MODE,
+				       AR_QUIET_TIMER_EN);
+
+			if ((REG_READ(ah, AR_TSF_L32) >> 10) == (tsfLow >> 10))
+				break;
+
+			ath_print(common, ATH_DBG_QUEUE,
+				  "TSF has moved while trying to set "
+				  "quiet time TSF: 0x%08x\n", tsfLow);
+		}
+
+		REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH);
+
+		udelay(200);
+		REG_CLR_BIT(ah, AR_TIMER_MODE, AR_QUIET_TIMER_EN);
+
+		wait = wait_time;
+		while (ath9k_hw_numtxpending(ah, q)) {
+			if ((--wait) == 0) {
+				ath_print(common, ATH_DBG_FATAL,
+					  "Failed to stop TX DMA in 100 "
+					  "msec after killing last frame\n");
+				break;
+			}
+			udelay(ATH9K_TIME_QUANTUM);
+		}
+
+		REG_CLR_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH);
+	}
+
+	REG_WRITE(ah, AR_Q_TXD, 0);
+	return wait != 0;
+
+#undef ATH9K_TX_STOP_DMA_TIMEOUT
+#undef ATH9K_TIME_QUANTUM
+}
+EXPORT_SYMBOL(ath9k_hw_stoptxdma);
+
 void ath9k_hw_gettxintrtxqs(struct ath_hw *ah, u32 *txqs)
 {
 	*txqs &= ah->intr_txqs;
diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h
index 7c0d754..0d49219 100644
--- a/drivers/net/wireless/ath/ath9k/mac.h
+++ b/drivers/net/wireless/ath/ath9k/mac.h
@@ -687,35 +687,10 @@ struct ath9k_channel;
 u32 ath9k_hw_gettxbuf(struct ath_hw *ah, u32 q);
 void ath9k_hw_puttxbuf(struct ath_hw *ah, u32 q, u32 txdp);
 void ath9k_hw_txstart(struct ath_hw *ah, u32 q);
+void ath9k_hw_cleartxdesc(struct ath_hw *ah, void *ds);
 u32 ath9k_hw_numtxpending(struct ath_hw *ah, u32 q);
 bool ath9k_hw_updatetxtriglevel(struct ath_hw *ah, bool bIncTrigLevel);
 bool ath9k_hw_stoptxdma(struct ath_hw *ah, u32 q);
-void ath9k_hw_filltxdesc(struct ath_hw *ah, struct ath_desc *ds,
-			 u32 segLen, bool firstSeg,
-			 bool lastSeg, const struct ath_desc *ds0,
-			 dma_addr_t buf_addr);
-void ath9k_hw_cleartxdesc(struct ath_hw *ah, struct ath_desc *ds);
-int ath9k_hw_txprocdesc(struct ath_hw *ah, struct ath_desc *ds,
-			struct ath_tx_status *ts);
-void ath9k_hw_set11n_txdesc(struct ath_hw *ah, struct ath_desc *ds,
-			    u32 pktLen, enum ath9k_pkt_type type, u32 txPower,
-			    u32 keyIx, enum ath9k_key_type keyType, u32 flags);
-void ath9k_hw_set11n_ratescenario(struct ath_hw *ah, struct ath_desc *ds,
-				  struct ath_desc *lastds,
-				  u32 durUpdateEn, u32 rtsctsRate,
-				  u32 rtsctsDuration,
-				  struct ath9k_11n_rate_series series[],
-				  u32 nseries, u32 flags);
-void ath9k_hw_set11n_aggr_first(struct ath_hw *ah, struct ath_desc *ds,
-				u32 aggrLen);
-void ath9k_hw_set11n_aggr_middle(struct ath_hw *ah, struct ath_desc *ds,
-				 u32 numDelims);
-void ath9k_hw_set11n_aggr_last(struct ath_hw *ah, struct ath_desc *ds);
-void ath9k_hw_clr11n_aggr(struct ath_hw *ah, struct ath_desc *ds);
-void ath9k_hw_set11n_burstduration(struct ath_hw *ah, struct ath_desc *ds,
-				   u32 burstDuration);
-void ath9k_hw_set11n_virtualmorefrag(struct ath_hw *ah, struct ath_desc *ds,
-				     u32 vmf);
 void ath9k_hw_gettxintrtxqs(struct ath_hw *ah, u32 *txqs);
 bool ath9k_hw_set_txq_props(struct ath_hw *ah, int q,
 			    const struct ath9k_tx_queue_info *qinfo);
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 6ab2099..550253f 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -1669,7 +1669,8 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf,
 			    true,	/* first segment */
 			    true,	/* last segment */
 			    ds,		/* first descriptor */
-			    bf->bf_buf_addr);
+			    bf->bf_buf_addr,
+			    txctl->txq->axq_qnum);
 
 	spin_lock_bh(&txctl->txq->axq_lock);
 
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 103+ messages in thread

* [PATCH v3 82/97] ath9k_hw: Add function to configure tx status ring buffer
  2010-04-15 21:38 [PATCH v3 00/97] ath9k: add AR9003 support Luis R. Rodriguez
                   ` (80 preceding siblings ...)
  2010-04-15 21:39 ` [PATCH v3 81/97] ath9k_hw: Define abstraction for tx desc access Luis R. Rodriguez
@ 2010-04-15 21:39 ` Luis R. Rodriguez
  2010-04-15 21:39 ` [PATCH v3 83/97] ath9k_hw: move AR9002 mac ops to its own file Luis R. Rodriguez
                   ` (14 subsequent siblings)
  96 siblings, 0 replies; 103+ messages in thread
From: Luis R. Rodriguez @ 2010-04-15 21:39 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Vasanthakumar Thiagarajan

From: Vasanthakumar Thiagarajan <vasanth@atheros.com>

Also reset tx status ring suring chip reset.

Signed-off-by: Vasanthakumar Thiagarajan <vasanth@atheros.com>
---
 drivers/net/wireless/ath/ath9k/ar9003_mac.c |   30 +++++++++++++++++++++++++++
 drivers/net/wireless/ath/ath9k/ar9003_mac.h |   17 ++++++++++++++-
 drivers/net/wireless/ath/ath9k/hw.c         |    3 ++
 drivers/net/wireless/ath/ath9k/hw.h         |    7 ++++++
 drivers/net/wireless/ath/ath9k/reg.h        |    3 ++
 5 files changed, 59 insertions(+), 1 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.c b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
index c270bbe..81ad09a 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
@@ -347,3 +347,33 @@ int ath9k_hw_process_rxdesc_edma(struct ath_hw *ah, struct ath_rx_status *rxs,
 	return 0;
 }
 EXPORT_SYMBOL(ath9k_hw_process_rxdesc_edma);
+
+void ath9k_hw_reset_txstatus_ring(struct ath_hw *ah)
+{
+	ah->ts_tail = 0;
+
+	memset((void *) ah->ts_ring, 0,
+		ah->ts_size * sizeof(struct ar9003_txs));
+
+	ath_print(ath9k_hw_common(ah), ATH_DBG_XMIT,
+		  "TS Start 0x%x End 0x%x Virt %p, Size %d\n",
+		   ah->ts_paddr_start, ah->ts_paddr_end,
+		   ah->ts_ring, ah->ts_size);
+
+	REG_WRITE(ah, AR_Q_STATUS_RING_START, ah->ts_paddr_start);
+	REG_WRITE(ah, AR_Q_STATUS_RING_END, ah->ts_paddr_end);
+}
+
+void ath9k_hw_setup_statusring(struct ath_hw *ah, void *ts_start,
+			       u32 ts_paddr_start,
+			       u8 size)
+{
+
+	ah->ts_paddr_start = ts_paddr_start;
+	ah->ts_paddr_end = ts_paddr_start + (size * sizeof(struct ar9003_txs));
+	ah->ts_size = size;
+	ah->ts_ring = (struct ar9003_txs *) ts_start;
+
+	ath9k_hw_reset_txstatus_ring(ah);
+}
+EXPORT_SYMBOL(ath9k_hw_setup_statusring);
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.h b/drivers/net/wireless/ath/ath9k/ar9003_mac.h
index 2ba06d7..ef79996 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_mac.h
+++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.h
@@ -73,6 +73,18 @@ struct ar9003_txc {
 	u32 pad[9]; /* pad to cache line (128 bytes/32 dwords) */
 } __packed;
 
+struct ar9003_txs {
+	u32 ds_info;
+	u32 status1;
+	u32 status2;
+	u32 status3;
+	u32 status4;
+	u32 status5;
+	u32 status6;
+	u32 status7;
+	u32 status8;
+} __packed;
+
 void ar9003_hw_attach_mac_ops(struct ath_hw *hw);
 void ath9k_hw_set_rx_bufsize(struct ath_hw *ah, u16 buf_size);
 void ath9k_hw_addrxbuf_edma(struct ath_hw *ah, u32 rxdp,
@@ -81,5 +93,8 @@ void ath9k_hw_addrxbuf_edma(struct ath_hw *ah, u32 rxdp,
 int ath9k_hw_process_rxdesc_edma(struct ath_hw *ah,
 				 struct ath_rx_status *rxs,
 				 void *buf_addr);
-
+void ath9k_hw_reset_txstatus_ring(struct ath_hw *ah);
+void ath9k_hw_setup_statusring(struct ath_hw *ah, void *ts_start,
+			       u32 ts_paddr_start,
+			       u8 size);
 #endif
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 8155e23..bd45d4b 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -896,6 +896,9 @@ static inline void ath9k_hw_set_dma(struct ath_hw *ah)
 		REG_WRITE(ah, AR_PCU_TXBUF_CTRL,
 			  AR_PCU_TXBUF_CTRL_USABLE_SIZE);
 	}
+
+	if (AR_SREV_9300_20_OR_LATER(ah))
+		ath9k_hw_reset_txstatus_ring(ah);
 }
 
 static void ath9k_hw_set_operating_mode(struct ath_hw *ah, int opmode)
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 457d8dd..6dbbab9 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -761,6 +761,13 @@ struct ath_hw {
 	u32 intr_gen_timer_trigger;
 	u32 intr_gen_timer_thresh;
 	struct ath_gen_timer_table hw_gen_timers;
+
+	struct ar9003_txs *ts_ring;
+	void *ts_start;
+	u32 ts_paddr_start;
+	u32 ts_paddr_end;
+	u16 ts_tail;
+	u8 ts_size;
 };
 
 static inline struct ath_common *ath9k_hw_common(struct ath_hw *ah)
diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h
index 2ca478c..ff89140 100644
--- a/drivers/net/wireless/ath/ath9k/reg.h
+++ b/drivers/net/wireless/ath/ath9k/reg.h
@@ -383,6 +383,9 @@
 #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
 
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 103+ messages in thread

* [PATCH v3 83/97] ath9k_hw: move AR9002 mac ops to its own file
  2010-04-15 21:38 [PATCH v3 00/97] ath9k: add AR9003 support Luis R. Rodriguez
                   ` (81 preceding siblings ...)
  2010-04-15 21:39 ` [PATCH v3 82/97] ath9k_hw: Add function to configure tx status ring buffer Luis R. Rodriguez
@ 2010-04-15 21:39 ` Luis R. Rodriguez
  2010-04-15 21:39 ` [PATCH v3 84/97] ath9k_hw: Fill descriptor abstrations for AR9003 Luis R. Rodriguez
                   ` (13 subsequent siblings)
  96 siblings, 0 replies; 103+ messages in thread
From: Luis R. Rodriguez @ 2010-04-15 21:39 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Luis R. Rodriguez, Felix Fietkau

Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
 drivers/net/wireless/ath/ath9k/Makefile     |    1 +
 drivers/net/wireless/ath/ath9k/ar9002_mac.c |  480 +++++++++++++++++++++++++++
 drivers/net/wireless/ath/ath9k/ar9003_hw.c  |    1 +
 drivers/net/wireless/ath/ath9k/ar9003_mac.c |    1 +
 drivers/net/wireless/ath/ath9k/hw.c         |    1 +
 drivers/net/wireless/ath/ath9k/hw.h         |    1 -
 drivers/net/wireless/ath/ath9k/mac.c        |  461 -------------------------
 drivers/net/wireless/ath/ath9k/mac.h        |    2 -
 drivers/net/wireless/ath/ath9k/recv.c       |    1 +
 drivers/net/wireless/ath/ath9k/xmit.c       |    1 +
 10 files changed, 486 insertions(+), 464 deletions(-)
 create mode 100644 drivers/net/wireless/ath/ath9k/ar9002_mac.c

diff --git a/drivers/net/wireless/ath/ath9k/Makefile b/drivers/net/wireless/ath/ath9k/Makefile
index b0702fc..dd112be 100644
--- a/drivers/net/wireless/ath/ath9k/Makefile
+++ b/drivers/net/wireless/ath/ath9k/Makefile
@@ -30,6 +30,7 @@ ath9k_hw-y:=	\
 		ani.o \
 		btcoex.o \
 		mac.o \
+		ar9002_mac.o \
 		ar9003_mac.o \
 		ar9003_eeprom.o
 
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_mac.c b/drivers/net/wireless/ath/ath9k/ar9002_mac.c
new file mode 100644
index 0000000..2be20d2
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/ar9002_mac.c
@@ -0,0 +1,480 @@
+/*
+ * Copyright (c) 2008-2009 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "hw.h"
+
+#define AR_BufLen           0x00000fff
+
+static void ar9002_hw_rx_enable(struct ath_hw *ah)
+{
+	REG_WRITE(ah, AR_CR, AR_CR_RXE);
+}
+
+static void ar9002_hw_set_desc_link(void *ds, u32 ds_link)
+{
+	((struct ath_desc*) ds)->ds_link = ds_link;
+}
+
+static void ar9002_hw_get_desc_link(void *ds, u32 **ds_link)
+{
+	*ds_link = &((struct ath_desc *)ds)->ds_link;
+}
+
+static bool ar9002_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked)
+{
+	u32 isr = 0;
+	u32 mask2 = 0;
+	struct ath9k_hw_capabilities *pCap = &ah->caps;
+	u32 sync_cause = 0;
+	bool fatal_int = false;
+	struct ath_common *common = ath9k_hw_common(ah);
+
+	if (!AR_SREV_9100(ah)) {
+		if (REG_READ(ah, AR_INTR_ASYNC_CAUSE) & AR_INTR_MAC_IRQ) {
+			if ((REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M)
+			    == AR_RTC_STATUS_ON) {
+				isr = REG_READ(ah, AR_ISR);
+			}
+		}
+
+		sync_cause = REG_READ(ah, AR_INTR_SYNC_CAUSE) &
+			AR_INTR_SYNC_DEFAULT;
+
+		*masked = 0;
+
+		if (!isr && !sync_cause)
+			return false;
+	} else {
+		*masked = 0;
+		isr = REG_READ(ah, AR_ISR);
+	}
+
+	if (isr) {
+		if (isr & AR_ISR_BCNMISC) {
+			u32 isr2;
+			isr2 = REG_READ(ah, AR_ISR_S2);
+			if (isr2 & AR_ISR_S2_TIM)
+				mask2 |= ATH9K_INT_TIM;
+			if (isr2 & AR_ISR_S2_DTIM)
+				mask2 |= ATH9K_INT_DTIM;
+			if (isr2 & AR_ISR_S2_DTIMSYNC)
+				mask2 |= ATH9K_INT_DTIMSYNC;
+			if (isr2 & (AR_ISR_S2_CABEND))
+				mask2 |= ATH9K_INT_CABEND;
+			if (isr2 & AR_ISR_S2_GTT)
+				mask2 |= ATH9K_INT_GTT;
+			if (isr2 & AR_ISR_S2_CST)
+				mask2 |= ATH9K_INT_CST;
+			if (isr2 & AR_ISR_S2_TSFOOR)
+				mask2 |= ATH9K_INT_TSFOOR;
+		}
+
+		isr = REG_READ(ah, AR_ISR_RAC);
+		if (isr == 0xffffffff) {
+			*masked = 0;
+			return false;
+		}
+
+		*masked = isr & ATH9K_INT_COMMON;
+
+		if (ah->config.rx_intr_mitigation) {
+			if (isr & (AR_ISR_RXMINTR | AR_ISR_RXINTM))
+				*masked |= ATH9K_INT_RX;
+		}
+
+		if (isr & (AR_ISR_RXOK | AR_ISR_RXERR))
+			*masked |= ATH9K_INT_RX;
+		if (isr &
+		    (AR_ISR_TXOK | AR_ISR_TXDESC | AR_ISR_TXERR |
+		     AR_ISR_TXEOL)) {
+			u32 s0_s, s1_s;
+
+			*masked |= ATH9K_INT_TX;
+
+			s0_s = REG_READ(ah, AR_ISR_S0_S);
+			ah->intr_txqs |= MS(s0_s, AR_ISR_S0_QCU_TXOK);
+			ah->intr_txqs |= MS(s0_s, AR_ISR_S0_QCU_TXDESC);
+
+			s1_s = REG_READ(ah, AR_ISR_S1_S);
+			ah->intr_txqs |= MS(s1_s, AR_ISR_S1_QCU_TXERR);
+			ah->intr_txqs |= MS(s1_s, AR_ISR_S1_QCU_TXEOL);
+		}
+
+		if (isr & AR_ISR_RXORN) {
+			ath_print(common, ATH_DBG_INTERRUPT,
+				  "receive FIFO overrun interrupt\n");
+		}
+
+		if (!AR_SREV_9100(ah)) {
+			if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) {
+				u32 isr5 = REG_READ(ah, AR_ISR_S5_S);
+				if (isr5 & AR_ISR_S5_TIM_TIMER)
+					*masked |= ATH9K_INT_TIM_TIMER;
+			}
+		}
+
+		*masked |= mask2;
+	}
+
+	if (AR_SREV_9100(ah))
+		return true;
+
+	if (isr & AR_ISR_GENTMR) {
+		u32 s5_s;
+
+		s5_s = REG_READ(ah, AR_ISR_S5_S);
+		if (isr & AR_ISR_GENTMR) {
+			ah->intr_gen_timer_trigger =
+				MS(s5_s, AR_ISR_S5_GENTIMER_TRIG);
+
+			ah->intr_gen_timer_thresh =
+				MS(s5_s, AR_ISR_S5_GENTIMER_THRESH);
+
+			if (ah->intr_gen_timer_trigger)
+				*masked |= ATH9K_INT_GENTIMER;
+
+		}
+	}
+
+	if (sync_cause) {
+		fatal_int =
+			(sync_cause &
+			 (AR_INTR_SYNC_HOST1_FATAL | AR_INTR_SYNC_HOST1_PERR))
+			? true : false;
+
+		if (fatal_int) {
+			if (sync_cause & AR_INTR_SYNC_HOST1_FATAL) {
+				ath_print(common, ATH_DBG_ANY,
+					  "received PCI FATAL interrupt\n");
+			}
+			if (sync_cause & AR_INTR_SYNC_HOST1_PERR) {
+				ath_print(common, ATH_DBG_ANY,
+					  "received PCI PERR interrupt\n");
+			}
+			*masked |= ATH9K_INT_FATAL;
+		}
+		if (sync_cause & AR_INTR_SYNC_RADM_CPL_TIMEOUT) {
+			ath_print(common, ATH_DBG_INTERRUPT,
+				  "AR_INTR_SYNC_RADM_CPL_TIMEOUT\n");
+			REG_WRITE(ah, AR_RC, AR_RC_HOSTIF);
+			REG_WRITE(ah, AR_RC, 0);
+			*masked |= ATH9K_INT_FATAL;
+		}
+		if (sync_cause & AR_INTR_SYNC_LOCAL_TIMEOUT) {
+			ath_print(common, ATH_DBG_INTERRUPT,
+				  "AR_INTR_SYNC_LOCAL_TIMEOUT\n");
+		}
+
+		REG_WRITE(ah, AR_INTR_SYNC_CAUSE_CLR, sync_cause);
+		(void) REG_READ(ah, AR_INTR_SYNC_CAUSE_CLR);
+	}
+
+	return true;
+}
+
+static void ar9002_hw_fill_txdesc(struct ath_hw *ah, void *ds, u32 seglen,
+				  bool is_firstseg, bool is_lastseg,
+				  const void *ds0, dma_addr_t buf_addr,
+				  unsigned int qcu)
+{
+	struct ar5416_desc *ads = AR5416DESC(ds);
+
+	ads->ds_data = buf_addr;
+
+	if (is_firstseg) {
+		ads->ds_ctl1 |= seglen | (is_lastseg ? 0 : AR_TxMore);
+	} else if (is_lastseg) {
+		ads->ds_ctl0 = 0;
+		ads->ds_ctl1 = seglen;
+		ads->ds_ctl2 = AR5416DESC_CONST(ds0)->ds_ctl2;
+		ads->ds_ctl3 = AR5416DESC_CONST(ds0)->ds_ctl3;
+	} else {
+		ads->ds_ctl0 = 0;
+		ads->ds_ctl1 = seglen | AR_TxMore;
+		ads->ds_ctl2 = 0;
+		ads->ds_ctl3 = 0;
+	}
+	ads->ds_txstatus0 = ads->ds_txstatus1 = 0;
+	ads->ds_txstatus2 = ads->ds_txstatus3 = 0;
+	ads->ds_txstatus4 = ads->ds_txstatus5 = 0;
+	ads->ds_txstatus6 = ads->ds_txstatus7 = 0;
+	ads->ds_txstatus8 = ads->ds_txstatus9 = 0;
+}
+
+static int ar9002_hw_proc_txdesc(struct ath_hw *ah, void *ds,
+				 struct ath_tx_status *ts)
+{
+	struct ar5416_desc *ads = AR5416DESC(ds);
+
+	if ((ads->ds_txstatus9 & AR_TxDone) == 0)
+		return -EINPROGRESS;
+
+	ts->ts_seqnum = MS(ads->ds_txstatus9, AR_SeqNum);
+	ts->ts_tstamp = ads->AR_SendTimestamp;
+	ts->ts_status = 0;
+	ts->ts_flags = 0;
+
+	if (ads->ds_txstatus1 & AR_FrmXmitOK)
+		ts->ts_status |= ATH9K_TX_ACKED;
+	if (ads->ds_txstatus1 & AR_ExcessiveRetries)
+		ts->ts_status |= ATH9K_TXERR_XRETRY;
+	if (ads->ds_txstatus1 & AR_Filtered)
+		ts->ts_status |= ATH9K_TXERR_FILT;
+	if (ads->ds_txstatus1 & AR_FIFOUnderrun) {
+		ts->ts_status |= ATH9K_TXERR_FIFO;
+		ath9k_hw_updatetxtriglevel(ah, true);
+	}
+	if (ads->ds_txstatus9 & AR_TxOpExceeded)
+		ts->ts_status |= ATH9K_TXERR_XTXOP;
+	if (ads->ds_txstatus1 & AR_TxTimerExpired)
+		ts->ts_status |= ATH9K_TXERR_TIMER_EXPIRED;
+
+	if (ads->ds_txstatus1 & AR_DescCfgErr)
+		ts->ts_flags |= ATH9K_TX_DESC_CFG_ERR;
+	if (ads->ds_txstatus1 & AR_TxDataUnderrun) {
+		ts->ts_flags |= ATH9K_TX_DATA_UNDERRUN;
+		ath9k_hw_updatetxtriglevel(ah, true);
+	}
+	if (ads->ds_txstatus1 & AR_TxDelimUnderrun) {
+		ts->ts_flags |= ATH9K_TX_DELIM_UNDERRUN;
+		ath9k_hw_updatetxtriglevel(ah, true);
+	}
+	if (ads->ds_txstatus0 & AR_TxBaStatus) {
+		ts->ts_flags |= ATH9K_TX_BA;
+		ts->ba_low = ads->AR_BaBitmapLow;
+		ts->ba_high = ads->AR_BaBitmapHigh;
+	}
+
+	ts->ts_rateindex = MS(ads->ds_txstatus9, AR_FinalTxIdx);
+	switch (ts->ts_rateindex) {
+	case 0:
+		ts->ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate0);
+		break;
+	case 1:
+		ts->ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate1);
+		break;
+	case 2:
+		ts->ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate2);
+		break;
+	case 3:
+		ts->ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate3);
+		break;
+	}
+
+	ts->ts_rssi = MS(ads->ds_txstatus5, AR_TxRSSICombined);
+	ts->ts_rssi_ctl0 = MS(ads->ds_txstatus0, AR_TxRSSIAnt00);
+	ts->ts_rssi_ctl1 = MS(ads->ds_txstatus0, AR_TxRSSIAnt01);
+	ts->ts_rssi_ctl2 = MS(ads->ds_txstatus0, AR_TxRSSIAnt02);
+	ts->ts_rssi_ext0 = MS(ads->ds_txstatus5, AR_TxRSSIAnt10);
+	ts->ts_rssi_ext1 = MS(ads->ds_txstatus5, AR_TxRSSIAnt11);
+	ts->ts_rssi_ext2 = MS(ads->ds_txstatus5, AR_TxRSSIAnt12);
+	ts->evm0 = ads->AR_TxEVM0;
+	ts->evm1 = ads->AR_TxEVM1;
+	ts->evm2 = ads->AR_TxEVM2;
+	ts->ts_shortretry = MS(ads->ds_txstatus1, AR_RTSFailCnt);
+	ts->ts_longretry = MS(ads->ds_txstatus1, AR_DataFailCnt);
+	ts->ts_virtcol = MS(ads->ds_txstatus1, AR_VirtRetryCnt);
+	ts->ts_antenna = 0;
+
+	return 0;
+}
+
+static void ar9002_hw_set11n_txdesc(struct ath_hw *ah, void *ds,
+				    u32 pktLen, enum ath9k_pkt_type type,
+				    u32 txPower, u32 keyIx,
+				    enum ath9k_key_type keyType, u32 flags)
+{
+	struct ar5416_desc *ads = AR5416DESC(ds);
+
+	txPower += ah->txpower_indexoffset;
+	if (txPower > 63)
+		txPower = 63;
+
+	ads->ds_ctl0 = (pktLen & AR_FrameLen)
+		| (flags & ATH9K_TXDESC_VMF ? AR_VirtMoreFrag : 0)
+		| SM(txPower, AR_XmitPower)
+		| (flags & ATH9K_TXDESC_VEOL ? AR_VEOL : 0)
+		| (flags & ATH9K_TXDESC_CLRDMASK ? AR_ClrDestMask : 0)
+		| (flags & ATH9K_TXDESC_INTREQ ? AR_TxIntrReq : 0)
+		| (keyIx != ATH9K_TXKEYIX_INVALID ? AR_DestIdxValid : 0);
+
+	ads->ds_ctl1 =
+		(keyIx != ATH9K_TXKEYIX_INVALID ? SM(keyIx, AR_DestIdx) : 0)
+		| SM(type, AR_FrameType)
+		| (flags & ATH9K_TXDESC_NOACK ? AR_NoAck : 0)
+		| (flags & ATH9K_TXDESC_EXT_ONLY ? AR_ExtOnly : 0)
+		| (flags & ATH9K_TXDESC_EXT_AND_CTL ? AR_ExtAndCtl : 0);
+
+	ads->ds_ctl6 = SM(keyType, AR_EncrType);
+
+	if (AR_SREV_9285(ah) || AR_SREV_9271(ah)) {
+		ads->ds_ctl8 = 0;
+		ads->ds_ctl9 = 0;
+		ads->ds_ctl10 = 0;
+		ads->ds_ctl11 = 0;
+	}
+}
+
+static void ar9002_hw_set11n_ratescenario(struct ath_hw *ah, void *ds,
+					  void *lastds,
+					  u32 durUpdateEn, u32 rtsctsRate,
+					  u32 rtsctsDuration,
+					  struct ath9k_11n_rate_series series[],
+					  u32 nseries, u32 flags)
+{
+	struct ar5416_desc *ads = AR5416DESC(ds);
+	struct ar5416_desc *last_ads = AR5416DESC(lastds);
+	u32 ds_ctl0;
+
+	if (flags & (ATH9K_TXDESC_RTSENA | ATH9K_TXDESC_CTSENA)) {
+		ds_ctl0 = ads->ds_ctl0;
+
+		if (flags & ATH9K_TXDESC_RTSENA) {
+			ds_ctl0 &= ~AR_CTSEnable;
+			ds_ctl0 |= AR_RTSEnable;
+		} else {
+			ds_ctl0 &= ~AR_RTSEnable;
+			ds_ctl0 |= AR_CTSEnable;
+		}
+
+		ads->ds_ctl0 = ds_ctl0;
+	} else {
+		ads->ds_ctl0 =
+			(ads->ds_ctl0 & ~(AR_RTSEnable | AR_CTSEnable));
+	}
+
+	ads->ds_ctl2 = set11nTries(series, 0)
+		| set11nTries(series, 1)
+		| set11nTries(series, 2)
+		| set11nTries(series, 3)
+		| (durUpdateEn ? AR_DurUpdateEna : 0)
+		| SM(0, AR_BurstDur);
+
+	ads->ds_ctl3 = set11nRate(series, 0)
+		| set11nRate(series, 1)
+		| set11nRate(series, 2)
+		| set11nRate(series, 3);
+
+	ads->ds_ctl4 = set11nPktDurRTSCTS(series, 0)
+		| set11nPktDurRTSCTS(series, 1);
+
+	ads->ds_ctl5 = set11nPktDurRTSCTS(series, 2)
+		| set11nPktDurRTSCTS(series, 3);
+
+	ads->ds_ctl7 = set11nRateFlags(series, 0)
+		| set11nRateFlags(series, 1)
+		| set11nRateFlags(series, 2)
+		| set11nRateFlags(series, 3)
+		| SM(rtsctsRate, AR_RTSCTSRate);
+	last_ads->ds_ctl2 = ads->ds_ctl2;
+	last_ads->ds_ctl3 = ads->ds_ctl3;
+}
+
+static void ar9002_hw_set11n_aggr_first(struct ath_hw *ah, void *ds,
+					u32 aggrLen)
+{
+	struct ar5416_desc *ads = AR5416DESC(ds);
+
+	ads->ds_ctl1 |= (AR_IsAggr | AR_MoreAggr);
+	ads->ds_ctl6 &= ~AR_AggrLen;
+	ads->ds_ctl6 |= SM(aggrLen, AR_AggrLen);
+}
+
+static void ar9002_hw_set11n_aggr_middle(struct ath_hw *ah, void *ds,
+					 u32 numDelims)
+{
+	struct ar5416_desc *ads = AR5416DESC(ds);
+	unsigned int ctl6;
+
+	ads->ds_ctl1 |= (AR_IsAggr | AR_MoreAggr);
+
+	ctl6 = ads->ds_ctl6;
+	ctl6 &= ~AR_PadDelim;
+	ctl6 |= SM(numDelims, AR_PadDelim);
+	ads->ds_ctl6 = ctl6;
+}
+
+static void ar9002_hw_set11n_aggr_last(struct ath_hw *ah, void *ds)
+{
+	struct ar5416_desc *ads = AR5416DESC(ds);
+
+	ads->ds_ctl1 |= AR_IsAggr;
+	ads->ds_ctl1 &= ~AR_MoreAggr;
+	ads->ds_ctl6 &= ~AR_PadDelim;
+}
+
+static void ar9002_hw_clr11n_aggr(struct ath_hw *ah, void *ds)
+{
+	struct ar5416_desc *ads = AR5416DESC(ds);
+
+	ads->ds_ctl1 &= (~AR_IsAggr & ~AR_MoreAggr);
+}
+
+static void ar9002_hw_set11n_burstduration(struct ath_hw *ah, void *ds,
+					   u32 burstDuration)
+{
+	struct ar5416_desc *ads = AR5416DESC(ds);
+
+	ads->ds_ctl2 &= ~AR_BurstDur;
+	ads->ds_ctl2 |= SM(burstDuration, AR_BurstDur);
+}
+
+static void ar9002_hw_set11n_virtualmorefrag(struct ath_hw *ah, void *ds,
+					    u32 vmf)
+{
+	struct ar5416_desc *ads = AR5416DESC(ds);
+
+	if (vmf)
+		ads->ds_ctl0 |= AR_VirtMoreFrag;
+	else
+		ads->ds_ctl0 &= ~AR_VirtMoreFrag;
+}
+
+void ath9k_hw_setuprxdesc(struct ath_hw *ah, struct ath_desc *ds,
+			  u32 size, u32 flags)
+{
+	struct ar5416_desc *ads = AR5416DESC(ds);
+	struct ath9k_hw_capabilities *pCap = &ah->caps;
+
+	ads->ds_ctl1 = size & AR_BufLen;
+	if (flags & ATH9K_RXDESC_INTREQ)
+		ads->ds_ctl1 |= AR_RxIntrReq;
+
+	ads->ds_rxstatus8 &= ~AR_RxDone;
+	if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP))
+		memset(&(ads->u), 0, sizeof(ads->u));
+}
+EXPORT_SYMBOL(ath9k_hw_setuprxdesc);
+
+void ar9002_hw_attach_mac_ops(struct ath_hw *ah)
+{
+	struct ath_hw_ops *ops = ath9k_hw_ops(ah);
+
+	ops->rx_enable = ar9002_hw_rx_enable;
+	ops->set_desc_link = ar9002_hw_set_desc_link;
+	ops->get_desc_link = ar9002_hw_get_desc_link;
+	ops->get_isr = ar9002_hw_get_isr;
+	ops->fill_txdesc = ar9002_hw_fill_txdesc;
+	ops->proc_txdesc = ar9002_hw_proc_txdesc;
+	ops->set11n_txdesc = ar9002_hw_set11n_txdesc;
+	ops->set11n_ratescenario = ar9002_hw_set11n_ratescenario;
+	ops->set11n_aggr_first = ar9002_hw_set11n_aggr_first;
+	ops->set11n_aggr_middle = ar9002_hw_set11n_aggr_middle;
+	ops->set11n_aggr_last = ar9002_hw_set11n_aggr_last;
+	ops->clr11n_aggr = ar9002_hw_clr11n_aggr;
+	ops->set11n_burstduration = ar9002_hw_set11n_burstduration;
+	ops->set11n_virtualmorefrag = ar9002_hw_set11n_virtualmorefrag;
+}
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_hw.c b/drivers/net/wireless/ath/ath9k/ar9003_hw.c
index f32665d..b15309c 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_hw.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_hw.c
@@ -15,6 +15,7 @@
  */
 
 #include "hw.h"
+#include "ar9003_mac.h"
 #include "ar9003_initvals.h"
 
 /* General hardware code for the AR9003 hadware family */
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.c b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
index 81ad09a..cb93d23 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
@@ -14,6 +14,7 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 #include "hw.h"
+#include "ar9003_mac.h"
 
 static void ar9003_hw_rx_enable(struct ath_hw *hw)
 {
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index bd45d4b..1f06ac0 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -21,6 +21,7 @@
 #include "hw.h"
 #include "hw-ops.h"
 #include "rc.h"
+#include "ar9003_mac.h"
 
 #define ATH9K_CLOCK_RATE_CCK		22
 #define ATH9K_CLOCK_RATE_5GHZ_OFDM	40
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 6dbbab9..b711ec2 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -28,7 +28,6 @@
 #include "reg.h"
 #include "phy.h"
 #include "btcoex.h"
-#include "ar9003_mac.h"
 
 #include "../regd.h"
 #include "../debug.h"
diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c
index 22fa512..0515958 100644
--- a/drivers/net/wireless/ath/ath9k/mac.c
+++ b/drivers/net/wireless/ath/ath9k/mac.c
@@ -16,451 +16,6 @@
 
 #include "hw.h"
 
-static void ar9002_hw_rx_enable(struct ath_hw *ah)
-{
-	REG_WRITE(ah, AR_CR, AR_CR_RXE);
-}
-
-static void ar9002_hw_set_desc_link(void *ds, u32 ds_link)
-{
-	((struct ath_desc *) ds)->ds_link = ds_link;
-}
-
-static void ar9002_hw_get_desc_link(void *ds, u32 **ds_link)
-{
-	*ds_link = &((struct ath_desc *)ds)->ds_link;
-}
-
-static bool ar9002_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked)
-{
-	u32 isr = 0;
-	u32 mask2 = 0;
-	struct ath9k_hw_capabilities *pCap = &ah->caps;
-	u32 sync_cause = 0;
-	bool fatal_int = false;
-	struct ath_common *common = ath9k_hw_common(ah);
-
-	if (!AR_SREV_9100(ah)) {
-		if (REG_READ(ah, AR_INTR_ASYNC_CAUSE) & AR_INTR_MAC_IRQ) {
-			if ((REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M)
-			    == AR_RTC_STATUS_ON) {
-				isr = REG_READ(ah, AR_ISR);
-			}
-		}
-
-		sync_cause = REG_READ(ah, AR_INTR_SYNC_CAUSE) &
-			AR_INTR_SYNC_DEFAULT;
-
-		*masked = 0;
-
-		if (!isr && !sync_cause)
-			return false;
-	} else {
-		*masked = 0;
-		isr = REG_READ(ah, AR_ISR);
-	}
-
-	if (isr) {
-		if (isr & AR_ISR_BCNMISC) {
-			u32 isr2;
-			isr2 = REG_READ(ah, AR_ISR_S2);
-			if (isr2 & AR_ISR_S2_TIM)
-				mask2 |= ATH9K_INT_TIM;
-			if (isr2 & AR_ISR_S2_DTIM)
-				mask2 |= ATH9K_INT_DTIM;
-			if (isr2 & AR_ISR_S2_DTIMSYNC)
-				mask2 |= ATH9K_INT_DTIMSYNC;
-			if (isr2 & (AR_ISR_S2_CABEND))
-				mask2 |= ATH9K_INT_CABEND;
-			if (isr2 & AR_ISR_S2_GTT)
-				mask2 |= ATH9K_INT_GTT;
-			if (isr2 & AR_ISR_S2_CST)
-				mask2 |= ATH9K_INT_CST;
-			if (isr2 & AR_ISR_S2_TSFOOR)
-				mask2 |= ATH9K_INT_TSFOOR;
-		}
-
-		isr = REG_READ(ah, AR_ISR_RAC);
-		if (isr == 0xffffffff) {
-			*masked = 0;
-			return false;
-		}
-
-		*masked = isr & ATH9K_INT_COMMON;
-
-		if (ah->config.rx_intr_mitigation) {
-			if (isr & (AR_ISR_RXMINTR | AR_ISR_RXINTM))
-				*masked |= ATH9K_INT_RX;
-		}
-
-		if (isr & (AR_ISR_RXOK | AR_ISR_RXERR))
-			*masked |= ATH9K_INT_RX;
-		if (isr &
-		    (AR_ISR_TXOK | AR_ISR_TXDESC | AR_ISR_TXERR |
-		     AR_ISR_TXEOL)) {
-			u32 s0_s, s1_s;
-
-			*masked |= ATH9K_INT_TX;
-
-			s0_s = REG_READ(ah, AR_ISR_S0_S);
-			ah->intr_txqs |= MS(s0_s, AR_ISR_S0_QCU_TXOK);
-			ah->intr_txqs |= MS(s0_s, AR_ISR_S0_QCU_TXDESC);
-
-			s1_s = REG_READ(ah, AR_ISR_S1_S);
-			ah->intr_txqs |= MS(s1_s, AR_ISR_S1_QCU_TXERR);
-			ah->intr_txqs |= MS(s1_s, AR_ISR_S1_QCU_TXEOL);
-		}
-
-		if (isr & AR_ISR_RXORN) {
-			ath_print(common, ATH_DBG_INTERRUPT,
-				  "receive FIFO overrun interrupt\n");
-		}
-
-		if (!AR_SREV_9100(ah)) {
-			if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) {
-				u32 isr5 = REG_READ(ah, AR_ISR_S5_S);
-				if (isr5 & AR_ISR_S5_TIM_TIMER)
-					*masked |= ATH9K_INT_TIM_TIMER;
-			}
-		}
-
-		*masked |= mask2;
-	}
-
-	if (AR_SREV_9100(ah))
-		return true;
-
-	if (isr & AR_ISR_GENTMR) {
-		u32 s5_s;
-
-		s5_s = REG_READ(ah, AR_ISR_S5_S);
-		if (isr & AR_ISR_GENTMR) {
-			ah->intr_gen_timer_trigger =
-				MS(s5_s, AR_ISR_S5_GENTIMER_TRIG);
-
-			ah->intr_gen_timer_thresh =
-				MS(s5_s, AR_ISR_S5_GENTIMER_THRESH);
-
-			if (ah->intr_gen_timer_trigger)
-				*masked |= ATH9K_INT_GENTIMER;
-
-		}
-	}
-
-	if (sync_cause) {
-		fatal_int =
-			(sync_cause &
-			 (AR_INTR_SYNC_HOST1_FATAL | AR_INTR_SYNC_HOST1_PERR))
-			? true : false;
-
-		if (fatal_int) {
-			if (sync_cause & AR_INTR_SYNC_HOST1_FATAL) {
-				ath_print(common, ATH_DBG_ANY,
-					  "received PCI FATAL interrupt\n");
-			}
-			if (sync_cause & AR_INTR_SYNC_HOST1_PERR) {
-				ath_print(common, ATH_DBG_ANY,
-					  "received PCI PERR interrupt\n");
-			}
-			*masked |= ATH9K_INT_FATAL;
-		}
-		if (sync_cause & AR_INTR_SYNC_RADM_CPL_TIMEOUT) {
-			ath_print(common, ATH_DBG_INTERRUPT,
-				  "AR_INTR_SYNC_RADM_CPL_TIMEOUT\n");
-			REG_WRITE(ah, AR_RC, AR_RC_HOSTIF);
-			REG_WRITE(ah, AR_RC, 0);
-			*masked |= ATH9K_INT_FATAL;
-		}
-		if (sync_cause & AR_INTR_SYNC_LOCAL_TIMEOUT) {
-			ath_print(common, ATH_DBG_INTERRUPT,
-				  "AR_INTR_SYNC_LOCAL_TIMEOUT\n");
-		}
-
-		REG_WRITE(ah, AR_INTR_SYNC_CAUSE_CLR, sync_cause);
-		(void) REG_READ(ah, AR_INTR_SYNC_CAUSE_CLR);
-	}
-
-	return true;
-}
-
-static void ar9002_hw_fill_txdesc(struct ath_hw *ah, void *ds, u32 seglen,
-				  bool is_firstseg, bool is_lastseg,
-				  const void *ds0, dma_addr_t buf_addr,
-				  unsigned int qcu)
-{
-	struct ar5416_desc *ads = AR5416DESC(ds);
-
-	ads->ds_data = buf_addr;
-
-	if (is_firstseg) {
-		ads->ds_ctl1 |= seglen | (is_lastseg ? 0 : AR_TxMore);
-	} else if (is_lastseg) {
-		ads->ds_ctl0 = 0;
-		ads->ds_ctl1 = seglen;
-		ads->ds_ctl2 = AR5416DESC_CONST(ds0)->ds_ctl2;
-		ads->ds_ctl3 = AR5416DESC_CONST(ds0)->ds_ctl3;
-	} else {
-		ads->ds_ctl0 = 0;
-		ads->ds_ctl1 = seglen | AR_TxMore;
-		ads->ds_ctl2 = 0;
-		ads->ds_ctl3 = 0;
-	}
-	ads->ds_txstatus0 = ads->ds_txstatus1 = 0;
-	ads->ds_txstatus2 = ads->ds_txstatus3 = 0;
-	ads->ds_txstatus4 = ads->ds_txstatus5 = 0;
-	ads->ds_txstatus6 = ads->ds_txstatus7 = 0;
-	ads->ds_txstatus8 = ads->ds_txstatus9 = 0;
-}
-
-static int ar9002_hw_proc_txdesc(struct ath_hw *ah, void *ds,
-				 struct ath_tx_status *ts)
-{
-	struct ar5416_desc *ads = AR5416DESC(ds);
-
-	if ((ads->ds_txstatus9 & AR_TxDone) == 0)
-		return -EINPROGRESS;
-
-	ts->ts_seqnum = MS(ads->ds_txstatus9, AR_SeqNum);
-	ts->ts_tstamp = ads->AR_SendTimestamp;
-	ts->ts_status = 0;
-	ts->ts_flags = 0;
-
-	if (ads->ds_txstatus1 & AR_FrmXmitOK)
-		ts->ts_status |= ATH9K_TX_ACKED;
-	if (ads->ds_txstatus1 & AR_ExcessiveRetries)
-		ts->ts_status |= ATH9K_TXERR_XRETRY;
-	if (ads->ds_txstatus1 & AR_Filtered)
-		ts->ts_status |= ATH9K_TXERR_FILT;
-	if (ads->ds_txstatus1 & AR_FIFOUnderrun) {
-		ts->ts_status |= ATH9K_TXERR_FIFO;
-		ath9k_hw_updatetxtriglevel(ah, true);
-	}
-	if (ads->ds_txstatus9 & AR_TxOpExceeded)
-		ts->ts_status |= ATH9K_TXERR_XTXOP;
-	if (ads->ds_txstatus1 & AR_TxTimerExpired)
-		ts->ts_status |= ATH9K_TXERR_TIMER_EXPIRED;
-
-	if (ads->ds_txstatus1 & AR_DescCfgErr)
-		ts->ts_flags |= ATH9K_TX_DESC_CFG_ERR;
-	if (ads->ds_txstatus1 & AR_TxDataUnderrun) {
-		ts->ts_flags |= ATH9K_TX_DATA_UNDERRUN;
-		ath9k_hw_updatetxtriglevel(ah, true);
-	}
-	if (ads->ds_txstatus1 & AR_TxDelimUnderrun) {
-		ts->ts_flags |= ATH9K_TX_DELIM_UNDERRUN;
-		ath9k_hw_updatetxtriglevel(ah, true);
-	}
-	if (ads->ds_txstatus0 & AR_TxBaStatus) {
-		ts->ts_flags |= ATH9K_TX_BA;
-		ts->ba_low = ads->AR_BaBitmapLow;
-		ts->ba_high = ads->AR_BaBitmapHigh;
-	}
-
-	ts->ts_rateindex = MS(ads->ds_txstatus9, AR_FinalTxIdx);
-	switch (ts->ts_rateindex) {
-	case 0:
-		ts->ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate0);
-		break;
-	case 1:
-		ts->ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate1);
-		break;
-	case 2:
-		ts->ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate2);
-		break;
-	case 3:
-		ts->ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate3);
-		break;
-	}
-
-	ts->ts_rssi = MS(ads->ds_txstatus5, AR_TxRSSICombined);
-	ts->ts_rssi_ctl0 = MS(ads->ds_txstatus0, AR_TxRSSIAnt00);
-	ts->ts_rssi_ctl1 = MS(ads->ds_txstatus0, AR_TxRSSIAnt01);
-	ts->ts_rssi_ctl2 = MS(ads->ds_txstatus0, AR_TxRSSIAnt02);
-	ts->ts_rssi_ext0 = MS(ads->ds_txstatus5, AR_TxRSSIAnt10);
-	ts->ts_rssi_ext1 = MS(ads->ds_txstatus5, AR_TxRSSIAnt11);
-	ts->ts_rssi_ext2 = MS(ads->ds_txstatus5, AR_TxRSSIAnt12);
-	ts->evm0 = ads->AR_TxEVM0;
-	ts->evm1 = ads->AR_TxEVM1;
-	ts->evm2 = ads->AR_TxEVM2;
-	ts->ts_shortretry = MS(ads->ds_txstatus1, AR_RTSFailCnt);
-	ts->ts_longretry = MS(ads->ds_txstatus1, AR_DataFailCnt);
-	ts->ts_virtcol = MS(ads->ds_txstatus1, AR_VirtRetryCnt);
-	ts->ts_antenna = 0;
-
-	return 0;
-}
-
-static void ar9002_hw_set11n_txdesc(struct ath_hw *ah, void *ds,
-				    u32 pktLen, enum ath9k_pkt_type type,
-				    u32 txPower, u32 keyIx,
-				    enum ath9k_key_type keyType, u32 flags)
-{
-	struct ar5416_desc *ads = AR5416DESC(ds);
-
-	txPower += ah->txpower_indexoffset;
-	if (txPower > 63)
-		txPower = 63;
-
-	ads->ds_ctl0 = (pktLen & AR_FrameLen)
-		| (flags & ATH9K_TXDESC_VMF ? AR_VirtMoreFrag : 0)
-		| SM(txPower, AR_XmitPower)
-		| (flags & ATH9K_TXDESC_VEOL ? AR_VEOL : 0)
-		| (flags & ATH9K_TXDESC_CLRDMASK ? AR_ClrDestMask : 0)
-		| (flags & ATH9K_TXDESC_INTREQ ? AR_TxIntrReq : 0)
-		| (keyIx != ATH9K_TXKEYIX_INVALID ? AR_DestIdxValid : 0);
-
-	ads->ds_ctl1 =
-		(keyIx != ATH9K_TXKEYIX_INVALID ? SM(keyIx, AR_DestIdx) : 0)
-		| SM(type, AR_FrameType)
-		| (flags & ATH9K_TXDESC_NOACK ? AR_NoAck : 0)
-		| (flags & ATH9K_TXDESC_EXT_ONLY ? AR_ExtOnly : 0)
-		| (flags & ATH9K_TXDESC_EXT_AND_CTL ? AR_ExtAndCtl : 0);
-
-	ads->ds_ctl6 = SM(keyType, AR_EncrType);
-
-	if (AR_SREV_9285(ah) || AR_SREV_9271(ah)) {
-		ads->ds_ctl8 = 0;
-		ads->ds_ctl9 = 0;
-		ads->ds_ctl10 = 0;
-		ads->ds_ctl11 = 0;
-	}
-}
-
-static void ar9002_hw_set11n_ratescenario(struct ath_hw *ah, void *ds,
-					  void *lastds,
-					  u32 durUpdateEn, u32 rtsctsRate,
-					  u32 rtsctsDuration,
-					  struct ath9k_11n_rate_series series[],
-					  u32 nseries, u32 flags)
-{
-	struct ar5416_desc *ads = AR5416DESC(ds);
-	struct ar5416_desc *last_ads = AR5416DESC(lastds);
-	u32 ds_ctl0;
-
-	if (flags & (ATH9K_TXDESC_RTSENA | ATH9K_TXDESC_CTSENA)) {
-		ds_ctl0 = ads->ds_ctl0;
-
-		if (flags & ATH9K_TXDESC_RTSENA) {
-			ds_ctl0 &= ~AR_CTSEnable;
-			ds_ctl0 |= AR_RTSEnable;
-		} else {
-			ds_ctl0 &= ~AR_RTSEnable;
-			ds_ctl0 |= AR_CTSEnable;
-		}
-
-		ads->ds_ctl0 = ds_ctl0;
-	} else {
-		ads->ds_ctl0 =
-			(ads->ds_ctl0 & ~(AR_RTSEnable | AR_CTSEnable));
-	}
-
-	ads->ds_ctl2 = set11nTries(series, 0)
-		| set11nTries(series, 1)
-		| set11nTries(series, 2)
-		| set11nTries(series, 3)
-		| (durUpdateEn ? AR_DurUpdateEna : 0)
-		| SM(0, AR_BurstDur);
-
-	ads->ds_ctl3 = set11nRate(series, 0)
-		| set11nRate(series, 1)
-		| set11nRate(series, 2)
-		| set11nRate(series, 3);
-
-	ads->ds_ctl4 = set11nPktDurRTSCTS(series, 0)
-		| set11nPktDurRTSCTS(series, 1);
-
-	ads->ds_ctl5 = set11nPktDurRTSCTS(series, 2)
-		| set11nPktDurRTSCTS(series, 3);
-
-	ads->ds_ctl7 = set11nRateFlags(series, 0)
-		| set11nRateFlags(series, 1)
-		| set11nRateFlags(series, 2)
-		| set11nRateFlags(series, 3)
-		| SM(rtsctsRate, AR_RTSCTSRate);
-	last_ads->ds_ctl2 = ads->ds_ctl2;
-	last_ads->ds_ctl3 = ads->ds_ctl3;
-}
-
-static void ar9002_hw_set11n_aggr_first(struct ath_hw *ah, void *ds,
-					u32 aggrLen)
-{
-	struct ar5416_desc *ads = AR5416DESC(ds);
-
-	ads->ds_ctl1 |= (AR_IsAggr | AR_MoreAggr);
-	ads->ds_ctl6 &= ~AR_AggrLen;
-	ads->ds_ctl6 |= SM(aggrLen, AR_AggrLen);
-}
-
-static void ar9002_hw_set11n_aggr_middle(struct ath_hw *ah, void *ds,
-					 u32 numDelims)
-{
-	struct ar5416_desc *ads = AR5416DESC(ds);
-	unsigned int ctl6;
-
-	ads->ds_ctl1 |= (AR_IsAggr | AR_MoreAggr);
-
-	ctl6 = ads->ds_ctl6;
-	ctl6 &= ~AR_PadDelim;
-	ctl6 |= SM(numDelims, AR_PadDelim);
-	ads->ds_ctl6 = ctl6;
-}
-
-static void ar9002_hw_set11n_aggr_last(struct ath_hw *ah, void *ds)
-{
-	struct ar5416_desc *ads = AR5416DESC(ds);
-
-	ads->ds_ctl1 |= AR_IsAggr;
-	ads->ds_ctl1 &= ~AR_MoreAggr;
-	ads->ds_ctl6 &= ~AR_PadDelim;
-}
-
-static void ar9002_hw_clr11n_aggr(struct ath_hw *ah, void *ds)
-{
-	struct ar5416_desc *ads = AR5416DESC(ds);
-
-	ads->ds_ctl1 &= (~AR_IsAggr & ~AR_MoreAggr);
-}
-
-static void ar9002_hw_set11n_burstduration(struct ath_hw *ah, void *ds,
-					   u32 burstDuration)
-{
-	struct ar5416_desc *ads = AR5416DESC(ds);
-
-	ads->ds_ctl2 &= ~AR_BurstDur;
-	ads->ds_ctl2 |= SM(burstDuration, AR_BurstDur);
-}
-
-static void ar9002_hw_set11n_virtualmorefrag(struct ath_hw *ah, void *ds,
-					    u32 vmf)
-{
-	struct ar5416_desc *ads = AR5416DESC(ds);
-
-	if (vmf)
-		ads->ds_ctl0 |= AR_VirtMoreFrag;
-	else
-		ads->ds_ctl0 &= ~AR_VirtMoreFrag;
-}
-
-void ar9002_hw_attach_mac_ops(struct ath_hw *ah)
-{
-	struct ath_hw_ops *ops = ath9k_hw_ops(ah);
-
-	ops->rx_enable = ar9002_hw_rx_enable;
-	ops->set_desc_link = ar9002_hw_set_desc_link;
-	ops->get_desc_link = ar9002_hw_get_desc_link;
-	ops->get_isr = ar9002_hw_get_isr;
-	ops->fill_txdesc = ar9002_hw_fill_txdesc;
-	ops->proc_txdesc = ar9002_hw_proc_txdesc;
-	ops->set11n_txdesc = ar9002_hw_set11n_txdesc;
-	ops->set11n_ratescenario = ar9002_hw_set11n_ratescenario;
-	ops->set11n_aggr_first = ar9002_hw_set11n_aggr_first;
-	ops->set11n_aggr_middle = ar9002_hw_set11n_aggr_middle;
-	ops->set11n_aggr_last = ar9002_hw_set11n_aggr_last;
-	ops->clr11n_aggr = ar9002_hw_clr11n_aggr;
-	ops->set11n_burstduration = ar9002_hw_set11n_burstduration;
-	ops->set11n_virtualmorefrag = ar9002_hw_set11n_virtualmorefrag;
-}
-
 static void ath9k_hw_set_txq_interrupts(struct ath_hw *ah,
 					struct ath9k_tx_queue_info *qi)
 {
@@ -1122,22 +677,6 @@ int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds,
 }
 EXPORT_SYMBOL(ath9k_hw_rxprocdesc);
 
-void ath9k_hw_setuprxdesc(struct ath_hw *ah, struct ath_desc *ds,
-			  u32 size, u32 flags)
-{
-	struct ar5416_desc *ads = AR5416DESC(ds);
-	struct ath9k_hw_capabilities *pCap = &ah->caps;
-
-	ads->ds_ctl1 = size & AR_BufLen;
-	if (flags & ATH9K_RXDESC_INTREQ)
-		ads->ds_ctl1 |= AR_RxIntrReq;
-
-	ads->ds_rxstatus8 &= ~AR_RxDone;
-	if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP))
-		memset(&(ads->u), 0, sizeof(ads->u));
-}
-EXPORT_SYMBOL(ath9k_hw_setuprxdesc);
-
 /*
  * This can stop or re-enables RX.
  *
diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h
index 0d49219..eb430c4 100644
--- a/drivers/net/wireless/ath/ath9k/mac.h
+++ b/drivers/net/wireless/ath/ath9k/mac.h
@@ -354,7 +354,6 @@ struct ar5416_desc {
 #define AR_DestIdxValid     0x40000000
 #define AR_CTSEnable        0x80000000
 
-#define AR_BufLen           0x00000fff
 #define AR_TxMore           0x00001000
 #define AR_DestIdx          0x000fe000
 #define AR_DestIdx_S        13
@@ -494,7 +493,6 @@ struct ar5416_desc {
 
 #define AR_RxCTLRsvd00  0xffffffff
 
-#define AR_BufLen       0x00000fff
 #define AR_RxCtlRsvd00  0x00001000
 #define AR_RxIntrReq    0x00002000
 #define AR_RxCtlRsvd01  0xffffc000
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index ffb599c..cb4995c 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -15,6 +15,7 @@
  */
 
 #include "ath9k.h"
+#include "ar9003_mac.h"
 
 #define SKB_CB_ATHBUF(__skb)	(*((struct ath_buf **)__skb->cb))
 
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 550253f..7dae199 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -15,6 +15,7 @@
  */
 
 #include "ath9k.h"
+#include "ar9003_mac.h"
 
 #define BITS_PER_BYTE           8
 #define OFDM_PLCP_BITS          22
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 103+ messages in thread

* [PATCH v3 84/97] ath9k_hw: Fill descriptor abstrations for AR9003
  2010-04-15 21:38 [PATCH v3 00/97] ath9k: add AR9003 support Luis R. Rodriguez
                   ` (82 preceding siblings ...)
  2010-04-15 21:39 ` [PATCH v3 83/97] ath9k_hw: move AR9002 mac ops to its own file Luis R. Rodriguez
@ 2010-04-15 21:39 ` Luis R. Rodriguez
  2010-04-15 21:39 ` [PATCH v3 85/97] ath9k: add RXLP and RXHP to debugfs counters Luis R. Rodriguez
                   ` (12 subsequent siblings)
  96 siblings, 0 replies; 103+ messages in thread
From: Luis R. Rodriguez @ 2010-04-15 21:39 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Vasanthakumar Thiagarajan, Felix Fietkau

From: Vasanthakumar Thiagarajan <vasanth@atheros.com>

Signed-off-by: Vasanthakumar Thiagarajan <vasanth@atheros.com>
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
 drivers/net/wireless/ath/ath9k/ar9003_mac.c |  234 ++++++++++++++++++++++++++-
 drivers/net/wireless/ath/ath9k/ar9003_mac.h |   20 +++
 drivers/net/wireless/ath/ath9k/mac.h        |    7 +-
 3 files changed, 254 insertions(+), 7 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.c b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
index cb93d23..1a8c1ba 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
@@ -168,23 +168,169 @@ static bool ar9003_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked)
 	return true;
 }
 
+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_fill_txdesc(struct ath_hw *ah, void *ds, u32 seglen,
 				  bool is_firstseg, bool is_lastseg,
 				  const void *ds0, dma_addr_t buf_addr,
 				  unsigned int qcu)
 {
+	struct ar9003_txc *ads = (struct ar9003_txc *) ds;
+	unsigned int descid = 0;
+
+	ads->info = (ATHEROS_VENDOR_ID << AR_DescId_S) |
+				     (1 << AR_TxRxDesc_S) |
+				     (1 << AR_CtrlStat_S) |
+				     (qcu << AR_TxQcuNum_S) | 0x17;
+
+	ads->data0 = buf_addr;
+	ads->data1 = 0;
+	ads->data2 = 0;
+	ads->data3 = 0;
+
+	ads->ctl3 = (seglen << AR_BufLen_S);
+	ads->ctl3 &= AR_BufLen;
+
+	/* Fill in pointer checksum and descriptor id */
+	ads->ctl10 = ar9003_calc_ptr_chksum(ads);
+	ads->ctl10 |= (descid << AR_TxDescId_S);
+
+	if (is_firstseg) {
+		ads->ctl12 |= (is_lastseg ? 0 : AR_TxMore);
+	} else if (is_lastseg) {
+		ads->ctl11 = 0;
+		ads->ctl12 = 0;
+		ads->ctl13 = AR9003TXC_CONST(ds0)->ctl13;
+		ads->ctl14 = AR9003TXC_CONST(ds0)->ctl14;
+	} else {
+		/* XXX Intermediate descriptor in a multi-descriptor frame.*/
+		ads->ctl11 = 0;
+		ads->ctl12 = AR_TxMore;
+		ads->ctl13 = 0;
+		ads->ctl14 = 0;
+	}
 }
 
 static int ar9003_hw_proc_txdesc(struct ath_hw *ah, void *ds,
 				 struct ath_tx_status *ts)
 {
+	struct ar9003_txs *ads;
+
+	ads = &ah->ts_ring[ah->ts_tail];
+
+	if ((ads->status8 & AR_TxDone) == 0)
+		return -EINPROGRESS;
+
+	ah->ts_tail = (ah->ts_tail + 1) % ah->ts_size;
+
+	if ((MS(ads->ds_info, AR_DescId) != ATHEROS_VENDOR_ID) ||
+	    (MS(ads->ds_info, AR_TxRxDesc) != 1)) {
+		ath_print(ath9k_hw_common(ah), ATH_DBG_XMIT,
+			  "Tx Descriptor error %x\n", ads->ds_info);
+		memset(ads, 0, sizeof(*ads));
+		return -EIO;
+	}
+
+	ts->qid = MS(ads->ds_info, AR_TxQcuNum);
+	ts->desc_id = MS(ads->status1, AR_TxDescId);
+	ts->ts_seqnum = MS(ads->status8, AR_SeqNum);
+	ts->ts_tstamp = ads->status4;
+	ts->ts_status = 0;
+	ts->ts_flags  = 0;
+
+	if (ads->status3 & AR_ExcessiveRetries)
+		ts->ts_status |= ATH9K_TXERR_XRETRY;
+	if (ads->status3 & AR_Filtered)
+		ts->ts_status |= ATH9K_TXERR_FILT;
+	if (ads->status3 & AR_FIFOUnderrun) {
+		ts->ts_status |= ATH9K_TXERR_FIFO;
+		ath9k_hw_updatetxtriglevel(ah, true);
+	}
+	if (ads->status8 & AR_TxOpExceeded)
+		ts->ts_status |= ATH9K_TXERR_XTXOP;
+	if (ads->status3 & AR_TxTimerExpired)
+		ts->ts_status |= ATH9K_TXERR_TIMER_EXPIRED;
+
+	if (ads->status3 & AR_DescCfgErr)
+		ts->ts_flags |= ATH9K_TX_DESC_CFG_ERR;
+	if (ads->status3 & AR_TxDataUnderrun) {
+		ts->ts_flags |= ATH9K_TX_DATA_UNDERRUN;
+		ath9k_hw_updatetxtriglevel(ah, true);
+	}
+	if (ads->status3 & AR_TxDelimUnderrun) {
+		ts->ts_flags |= ATH9K_TX_DELIM_UNDERRUN;
+		ath9k_hw_updatetxtriglevel(ah, true);
+	}
+	if (ads->status2 & AR_TxBaStatus) {
+		ts->ts_flags |= ATH9K_TX_BA;
+		ts->ba_low = ads->status5;
+		ts->ba_high = ads->status6;
+	}
+
+	ts->ts_rateindex = MS(ads->status8, AR_FinalTxIdx);
+
+	ts->ts_rssi = MS(ads->status7, AR_TxRSSICombined);
+	ts->ts_rssi_ctl0 = MS(ads->status2, AR_TxRSSIAnt00);
+	ts->ts_rssi_ctl1 = MS(ads->status2, AR_TxRSSIAnt01);
+	ts->ts_rssi_ctl2 = MS(ads->status2, AR_TxRSSIAnt02);
+	ts->ts_rssi_ext0 = MS(ads->status7, AR_TxRSSIAnt10);
+	ts->ts_rssi_ext1 = MS(ads->status7, AR_TxRSSIAnt11);
+	ts->ts_rssi_ext2 = MS(ads->status7, AR_TxRSSIAnt12);
+	ts->ts_shortretry = MS(ads->status3, AR_RTSFailCnt);
+	ts->ts_longretry = MS(ads->status3, AR_DataFailCnt);
+	ts->ts_virtcol = MS(ads->status3, AR_VirtRetryCnt);
+	ts->ts_antenna = 0;
+
+	ts->tid = MS(ads->status8, AR_TxTid);
+
+	memset(ads, 0, sizeof(*ads));
+
 	return 0;
 }
+
 static void ar9003_hw_set11n_txdesc(struct ath_hw *ah, void *ds,
-			    u32 pktLen, enum ath9k_pkt_type type, u32 txPower,
-			    u32 keyIx, enum ath9k_key_type keyType, u32 flags)
+		u32 pktlen, enum ath9k_pkt_type type, u32 txpower,
+		u32 keyIx, enum ath9k_key_type keyType, u32 flags)
 {
-
+	struct ar9003_txc *ads = (struct ar9003_txc *) ds;
+
+	txpower += ah->txpower_indexoffset;
+	if (txpower > 63)
+		txpower = 63;
+
+	ads->ctl11 = (pktlen & AR_FrameLen)
+		| (flags & ATH9K_TXDESC_VMF ? AR_VirtMoreFrag : 0)
+		| SM(txpower, AR_XmitPower)
+		| (flags & ATH9K_TXDESC_VEOL ? AR_VEOL : 0)
+		| (flags & ATH9K_TXDESC_CLRDMASK ? AR_ClrDestMask : 0)
+		| (keyIx != ATH9K_TXKEYIX_INVALID ? AR_DestIdxValid : 0)
+		| (flags & ATH9K_TXDESC_LOWRXCHAIN ? AR_LowRxChain : 0);
+
+	ads->ctl12 =
+		(keyIx != ATH9K_TXKEYIX_INVALID ? SM(keyIx, AR_DestIdx) : 0)
+		| SM(type, AR_FrameType)
+		| (flags & ATH9K_TXDESC_NOACK ? AR_NoAck : 0)
+		| (flags & ATH9K_TXDESC_EXT_ONLY ? AR_ExtOnly : 0)
+		| (flags & ATH9K_TXDESC_EXT_AND_CTL ? AR_ExtAndCtl : 0);
+
+	ads->ctl17 = SM(keyType, AR_EncrType);
+	ads->ctl18 = 0;
+	ads->ctl19 = AR_Not_Sounding;
+
+	ads->ctl20 = 0;
+	ads->ctl21 = 0;
+	ads->ctl22 = 0;
 }
 
 static void ar9003_hw_set11n_ratescenario(struct ath_hw *ah, void *ds,
@@ -194,41 +340,119 @@ static void ar9003_hw_set11n_ratescenario(struct ath_hw *ah, void *ds,
 					  struct ath9k_11n_rate_series series[],
 					  u32 nseries, u32 flags)
 {
+	struct ar9003_txc *ads = (struct ar9003_txc *) ds;
+	struct ar9003_txc *last_ads = (struct ar9003_txc *) lastds;
+	u_int32_t ctl11;
+
+	if (flags & (ATH9K_TXDESC_RTSENA | ATH9K_TXDESC_CTSENA)) {
+		ctl11 = ads->ctl11;
+
+		if (flags & ATH9K_TXDESC_RTSENA) {
+			ctl11 &= ~AR_CTSEnable;
+			ctl11 |= AR_RTSEnable;
+		} else {
+			ctl11 &= ~AR_RTSEnable;
+			ctl11 |= AR_CTSEnable;
+		}
+
+		ads->ctl11 = ctl11;
+	} else {
+		ads->ctl11 = (ads->ctl11 & ~(AR_RTSEnable | AR_CTSEnable));
+	}
 
+	ads->ctl13 = set11nTries(series, 0)
+		|  set11nTries(series, 1)
+		|  set11nTries(series, 2)
+		|  set11nTries(series, 3)
+		|  (durUpdateEn ? AR_DurUpdateEna : 0)
+		|  SM(0, AR_BurstDur);
+
+	ads->ctl14 = set11nRate(series, 0)
+		|  set11nRate(series, 1)
+		|  set11nRate(series, 2)
+		|  set11nRate(series, 3);
+
+	ads->ctl15 = set11nPktDurRTSCTS(series, 0)
+		|  set11nPktDurRTSCTS(series, 1);
+
+	ads->ctl16 = set11nPktDurRTSCTS(series, 2)
+		|  set11nPktDurRTSCTS(series, 3);
+
+	ads->ctl18 = set11nRateFlags(series, 0)
+		|  set11nRateFlags(series, 1)
+		|  set11nRateFlags(series, 2)
+		|  set11nRateFlags(series, 3)
+		| SM(rtsctsRate, AR_RTSCTSRate);
+	ads->ctl19 = AR_Not_Sounding;
+
+	last_ads->ctl13 = ads->ctl13;
+	last_ads->ctl14 = ads->ctl14;
 }
 
 static void ar9003_hw_set11n_aggr_first(struct ath_hw *ah, void *ds,
 					u32 aggrLen)
 {
+	struct ar9003_txc *ads = (struct ar9003_txc *) ds;
+
+	ads->ctl12 |= (AR_IsAggr | AR_MoreAggr);
 
+	ads->ctl17 &= ~AR_AggrLen;
+	ads->ctl17 |= SM(aggrLen, AR_AggrLen);
 }
 
 static void ar9003_hw_set11n_aggr_middle(struct ath_hw *ah, void *ds,
 					 u32 numDelims)
 {
-
+	struct ar9003_txc *ads = (struct ar9003_txc *) ds;
+	unsigned int ctl17;
+
+	ads->ctl12 |= (AR_IsAggr | AR_MoreAggr);
+
+	/*
+	 * We use a stack variable to manipulate ctl6 to reduce uncached
+	 * read modify, modfiy, write.
+	 */
+	ctl17 = ads->ctl17;
+	ctl17 &= ~AR_PadDelim;
+	ctl17 |= SM(numDelims, AR_PadDelim);
+	ads->ctl17 = ctl17;
 }
 
 static void ar9003_hw_set11n_aggr_last(struct ath_hw *ah, void *ds)
 {
+	struct ar9003_txc *ads = (struct ar9003_txc *) ds;
 
+	ads->ctl12 |= AR_IsAggr;
+	ads->ctl12 &= ~AR_MoreAggr;
+	ads->ctl17 &= ~AR_PadDelim;
 }
 
 static void ar9003_hw_clr11n_aggr(struct ath_hw *ah, void *ds)
 {
+	struct ar9003_txc *ads = (struct ar9003_txc *) ds;
 
+	ads->ctl12 &= (~AR_IsAggr & ~AR_MoreAggr);
 }
 
 static void ar9003_hw_set11n_burstduration(struct ath_hw *ah, void *ds,
 					   u32 burstDuration)
 {
+	struct ar9003_txc *ads = (struct ar9003_txc *) ds;
+
+	ads->ctl13 &= ~AR_BurstDur;
+	ads->ctl13 |= SM(burstDuration, AR_BurstDur);
 
 }
 
 static void ar9003_hw_set11n_virtualmorefrag(struct ath_hw *ah, void *ds,
-					    u32 vmf)
+					     u32 vmf)
 {
+	struct ar9003_txc *ads = (struct ar9003_txc *) ds;
 
+	if (vmf)
+		ads->ctl11 |=  AR_VirtMoreFrag;
+	else
+		ads->ctl11 &= ~AR_VirtMoreFrag;
 }
 
 void ar9003_hw_attach_mac_ops(struct ath_hw *hw)
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.h b/drivers/net/wireless/ath/ath9k/ar9003_mac.h
index ef79996..f17558b 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_mac.h
+++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.h
@@ -20,7 +20,25 @@
 #define AR_DescId	0xffff0000
 #define AR_DescId_S	16
 #define AR_CtrlStat	0x00004000
+#define AR_CtrlStat_S	14
 #define AR_TxRxDesc	0x00008000
+#define AR_TxRxDesc_S	15
+#define AR_TxQcuNum	0x00000f00
+#define AR_TxQcuNum_S	8
+
+#define AR_BufLen	0x0fff0000
+#define AR_BufLen_S	16
+
+#define AR_TxDescId	0xffff0000
+#define AR_TxDescId_S	16
+#define AR_TxPtrChkSum	0x0000ffff
+
+#define AR_TxTid	0xf0000000
+#define AR_TxTid_S	28
+
+#define AR_LowRxChain	0x00004000
+
+#define AR_Not_Sounding	0x20000000
 
 #define MAP_ISR_S2_CST          6
 #define MAP_ISR_S2_GTT          6
@@ -30,6 +48,8 @@
 #define MAP_ISR_S2_DTIM         7
 #define MAP_ISR_S2_TSFOOR       4
 
+#define AR9003TXC_CONST(_ds) ((const struct ar9003_txc *) _ds)
+
 struct ar9003_rxs {
 	u32 ds_info;
 	u32 status1;
diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h
index eb430c4..b591dc2 100644
--- a/drivers/net/wireless/ath/ath9k/mac.h
+++ b/drivers/net/wireless/ath/ath9k/mac.h
@@ -116,7 +116,10 @@ struct ath_tx_status {
 	int8_t ts_rssi_ext0;
 	int8_t ts_rssi_ext1;
 	int8_t ts_rssi_ext2;
-	u8 pad[3];
+	u8 qid;
+	u16 desc_id;
+	u8 tid;
+	u8 pad[2];
 	u32 ba_low;
 	u32 ba_high;
 	u32 evm0;
@@ -260,7 +263,7 @@ struct ath_desc {
 #define ATH9K_TXDESC_EXT_AND_CTL	0x0080
 #define ATH9K_TXDESC_VMF		0x0100
 #define ATH9K_TXDESC_FRAG_IS_ON 	0x0200
-#define ATH9K_TXDESC_CAB		0x0400
+#define ATH9K_TXDESC_LOWRXCHAIN		0x0400
 
 #define ATH9K_RXDESC_INTREQ		0x0020
 
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 103+ messages in thread

* [PATCH v3 85/97] ath9k: add RXLP and RXHP to debugfs counters
  2010-04-15 21:38 [PATCH v3 00/97] ath9k: add AR9003 support Luis R. Rodriguez
                   ` (83 preceding siblings ...)
  2010-04-15 21:39 ` [PATCH v3 84/97] ath9k_hw: Fill descriptor abstrations for AR9003 Luis R. Rodriguez
@ 2010-04-15 21:39 ` Luis R. Rodriguez
  2010-04-15 21:39 ` [PATCH v3 86/97] ath9k_hw: enable CRC check of descriptors for AR9003 Luis R. Rodriguez
                   ` (11 subsequent siblings)
  96 siblings, 0 replies; 103+ messages in thread
From: Luis R. Rodriguez @ 2010-04-15 21:39 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Luis R. Rodriguez, Felix Fietkau

Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
 drivers/net/wireless/ath/ath9k/debug.c |   22 ++++++++++++++++++----
 drivers/net/wireless/ath/ath9k/debug.h |    4 ++++
 2 files changed, 22 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c
index 9a8e419..64e30cd 100644
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -180,8 +180,15 @@ void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status)
 {
 	if (status)
 		sc->debug.stats.istats.total++;
-	if (status & ATH9K_INT_RX)
-		sc->debug.stats.istats.rxok++;
+	if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
+		if (status & ATH9K_INT_RXLP)
+			sc->debug.stats.istats.rxlp++;
+		if (status & ATH9K_INT_RXHP)
+			sc->debug.stats.istats.rxhp++;
+	} else {
+		if (status & ATH9K_INT_RX)
+			sc->debug.stats.istats.rxok++;
+	}
 	if (status & ATH9K_INT_RXEOL)
 		sc->debug.stats.istats.rxeol++;
 	if (status & ATH9K_INT_RXORN)
@@ -223,8 +230,15 @@ static ssize_t read_file_interrupt(struct file *file, char __user *user_buf,
 	char buf[512];
 	unsigned int len = 0;
 
-	len += snprintf(buf + len, sizeof(buf) - len,
-		"%8s: %10u\n", "RX", sc->debug.stats.istats.rxok);
+	if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
+		len += snprintf(buf + len, sizeof(buf) - len,
+			"%8s: %10u\n", "RXLP", sc->debug.stats.istats.rxlp);
+		len += snprintf(buf + len, sizeof(buf) - len,
+			"%8s: %10u\n", "RXHP", sc->debug.stats.istats.rxhp);
+	} else {
+		len += snprintf(buf + len, sizeof(buf) - len,
+			"%8s: %10u\n", "RX", sc->debug.stats.istats.rxok);
+	}
 	len += snprintf(buf + len, sizeof(buf) - len,
 		"%8s: %10u\n", "RXEOL", sc->debug.stats.istats.rxeol);
 	len += snprintf(buf + len, sizeof(buf) - len,
diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h
index b2af9de..c545960 100644
--- a/drivers/net/wireless/ath/ath9k/debug.h
+++ b/drivers/net/wireless/ath/ath9k/debug.h
@@ -35,6 +35,8 @@ struct ath_buf;
  * struct ath_interrupt_stats - Contains statistics about interrupts
  * @total: Total no. of interrupts generated so far
  * @rxok: RX with no errors
+ * @rxlp: RX with low priority RX
+ * @rxhp: RX with high priority, uapsd only
  * @rxeol: RX with no more RXDESC available
  * @rxorn: RX FIFO overrun
  * @txok: TX completed at the requested rate
@@ -55,6 +57,8 @@ struct ath_buf;
 struct ath_interrupt_stats {
 	u32 total;
 	u32 rxok;
+	u32 rxlp;
+	u32 rxhp;
 	u32 rxeol;
 	u32 rxorn;
 	u32 txok;
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 103+ messages in thread

* [PATCH v3 86/97] ath9k_hw: enable CRC check of descriptors for AR9003
  2010-04-15 21:38 [PATCH v3 00/97] ath9k: add AR9003 support Luis R. Rodriguez
                   ` (84 preceding siblings ...)
  2010-04-15 21:39 ` [PATCH v3 85/97] ath9k: add RXLP and RXHP to debugfs counters Luis R. Rodriguez
@ 2010-04-15 21:39 ` Luis R. Rodriguez
  2010-04-15 21:39 ` [PATCH v3 87/97] ath9k_hw: set cwmin and cwmax to 0 for for AR9003 upon txq reset Luis R. Rodriguez
                   ` (10 subsequent siblings)
  96 siblings, 0 replies; 103+ messages in thread
From: Luis R. Rodriguez @ 2010-04-15 21:39 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Luis R. Rodriguez

Enable CRC check on the descriptor fetched from host on AR9003
upon reseting the TX queue.

Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/mac.c |    3 +++
 drivers/net/wireless/ath/ath9k/reg.h |    4 ++++
 2 files changed, 7 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c
index 0515958..44ea43a 100644
--- a/drivers/net/wireless/ath/ath9k/mac.c
+++ b/drivers/net/wireless/ath/ath9k/mac.c
@@ -569,6 +569,9 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
 			  AR_D_MISC_POST_FR_BKOFF_DIS);
 	}
 
+	if (AR_SREV_9300_20_OR_LATER(ah))
+		REG_WRITE(ah, AR_Q_DESC_CRCCHK, AR_Q_DESC_CRCCHK_EN);
+
 	if (qi->tqi_qflags & TXQ_FLAG_TXOKINT_ENABLE)
 		ah->txok_interrupt_mask |= 1 << q;
 	else
diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h
index ff89140..d4371a4 100644
--- a/drivers/net/wireless/ath/ath9k/reg.h
+++ b/drivers/net/wireless/ath/ath9k/reg.h
@@ -478,6 +478,10 @@
 #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
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 103+ messages in thread

* [PATCH v3 87/97] ath9k_hw: set cwmin and cwmax to 0 for for AR9003 upon txq reset
  2010-04-15 21:38 [PATCH v3 00/97] ath9k: add AR9003 support Luis R. Rodriguez
                   ` (85 preceding siblings ...)
  2010-04-15 21:39 ` [PATCH v3 86/97] ath9k_hw: enable CRC check of descriptors for AR9003 Luis R. Rodriguez
@ 2010-04-15 21:39 ` Luis R. Rodriguez
  2010-04-15 21:39 ` [PATCH v3 88/97] ath9k: Setup appropriate tx desc for regular dma and edma Luis R. Rodriguez
                   ` (9 subsequent siblings)
  96 siblings, 0 replies; 103+ messages in thread
From: Luis R. Rodriguez @ 2010-04-15 21:39 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Luis R. Rodriguez

Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/mac.c |    6 ++++++
 1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c
index 44ea43a..c003baf 100644
--- a/drivers/net/wireless/ath/ath9k/mac.c
+++ b/drivers/net/wireless/ath/ath9k/mac.c
@@ -533,6 +533,12 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
 			     AR_D_MISC_ARB_LOCKOUT_CNTRL_S)
 			  | AR_D_MISC_BEACON_USE
 			  | AR_D_MISC_POST_FR_BKOFF_DIS);
+		/* cwmin and cwmax should be 0 for beacon queue */
+		if (AR_SREV_9300_20_OR_LATER(ah)) {
+			REG_WRITE(ah, AR_DLCL_IFS(q), SM(0, AR_D_LCL_IFS_CWMIN)
+				  | SM(0, AR_D_LCL_IFS_CWMAX)
+				  | SM(qi->tqi_aifs, AR_D_LCL_IFS_AIFS));
+		}
 		break;
 	case ATH9K_TX_QUEUE_CAB:
 		REG_WRITE(ah, AR_QMISC(q), REG_READ(ah, AR_QMISC(q))
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 103+ messages in thread

* [PATCH v3 88/97] ath9k: Setup appropriate tx desc for regular dma and edma
  2010-04-15 21:38 [PATCH v3 00/97] ath9k: add AR9003 support Luis R. Rodriguez
                   ` (86 preceding siblings ...)
  2010-04-15 21:39 ` [PATCH v3 87/97] ath9k_hw: set cwmin and cwmax to 0 for for AR9003 upon txq reset Luis R. Rodriguez
@ 2010-04-15 21:39 ` Luis R. Rodriguez
  2010-04-15 21:39 ` [PATCH v3 89/97] ath9k: Initialize and configure tx status for EDMA Luis R. Rodriguez
                   ` (8 subsequent siblings)
  96 siblings, 0 replies; 103+ messages in thread
From: Luis R. Rodriguez @ 2010-04-15 21:39 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Vasanthakumar Thiagarajan

From: Vasanthakumar Thiagarajan <vasanth@atheros.com>

Signed-off-by: Vasanthakumar Thiagarajan <vasanth@atheros.com>
---
 drivers/net/wireless/ath/ath9k/ath9k.h |    2 +-
 drivers/net/wireless/ath/ath9k/init.c  |   26 ++++++++++++++++----------
 drivers/net/wireless/ath/ath9k/recv.c  |    2 +-
 drivers/net/wireless/ath/ath9k/xmit.c  |    4 ++--
 4 files changed, 20 insertions(+), 14 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index a11d830..f67be52 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -123,7 +123,7 @@ struct ath_descdma {
 
 int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
 		      struct list_head *head, const char *name,
-		      int nbuf, int ndesc);
+		      int nbuf, int ndesc, bool is_tx);
 void ath_descdma_cleanup(struct ath_softc *sc, struct ath_descdma *dd,
 			 struct list_head *head);
 
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index 9779646..299ec05 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -235,31 +235,37 @@ static int ath9k_reg_notifier(struct wiphy *wiphy,
 */
 int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
 		      struct list_head *head, const char *name,
-		      int nbuf, int ndesc)
+		      int nbuf, int ndesc, bool is_tx)
 {
 #define	DS2PHYS(_dd, _ds)						\
 	((_dd)->dd_desc_paddr + ((caddr_t)(_ds) - (caddr_t)(_dd)->dd_desc))
 #define ATH_DESC_4KB_BOUND_CHECK(_daddr) ((((_daddr) & 0xFFF) > 0xF7F) ? 1 : 0)
 #define ATH_DESC_4KB_BOUND_NUM_SKIPPED(_len) ((_len) / 4096)
 	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
-	struct ath_desc *ds;
+	u8 *ds;
 	struct ath_buf *bf;
-	int i, bsize, error;
+	int i, bsize, error, desc_len;
 
 	ath_print(common, ATH_DBG_CONFIG, "%s DMA: %u buffers %u desc/buf\n",
 		  name, nbuf, ndesc);
 
 	INIT_LIST_HEAD(head);
+
+	if (is_tx)
+		desc_len = sc->sc_ah->caps.tx_desc_len;
+	else
+		desc_len = sizeof(struct ath_desc);
+
 	/* ath_desc must be a multiple of DWORDs */
-	if ((sizeof(struct ath_desc) % 4) != 0) {
+	if ((desc_len % 4) != 0) {
 		ath_print(common, ATH_DBG_FATAL,
 			  "ath_desc not DWORD aligned\n");
-		BUG_ON((sizeof(struct ath_desc) % 4) != 0);
+		BUG_ON((desc_len % 4) != 0);
 		error = -ENOMEM;
 		goto fail;
 	}
 
-	dd->dd_desc_len = sizeof(struct ath_desc) * nbuf * ndesc;
+	dd->dd_desc_len = desc_len * nbuf * ndesc;
 
 	/*
 	 * Need additional DMA memory because we can't use
@@ -272,7 +278,7 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
 		u32 dma_len;
 
 		while (ndesc_skipped) {
-			dma_len = ndesc_skipped * sizeof(struct ath_desc);
+			dma_len = ndesc_skipped * desc_len;
 			dd->dd_desc_len += dma_len;
 
 			ndesc_skipped = ATH_DESC_4KB_BOUND_NUM_SKIPPED(dma_len);
@@ -286,7 +292,7 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
 		error = -ENOMEM;
 		goto fail;
 	}
-	ds = dd->dd_desc;
+	ds = (u8 *) dd->dd_desc;
 	ath_print(common, ATH_DBG_CONFIG, "%s DMA map: %p (%u) -> %llx (%u)\n",
 		  name, ds, (u32) dd->dd_desc_len,
 		  ito64(dd->dd_desc_paddr), /*XXX*/(u32) dd->dd_desc_len);
@@ -300,7 +306,7 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
 	}
 	dd->dd_bufptr = bf;
 
-	for (i = 0; i < nbuf; i++, bf++, ds += ndesc) {
+	for (i = 0; i < nbuf; i++, bf++, ds += (desc_len * ndesc)) {
 		bf->bf_desc = ds;
 		bf->bf_daddr = DS2PHYS(dd, ds);
 
@@ -316,7 +322,7 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
 				       ((caddr_t) dd->dd_desc +
 					dd->dd_desc_len));
 
-				ds += ndesc;
+				ds += (desc_len * ndesc);
 				bf->bf_desc = ds;
 				bf->bf_daddr = DS2PHYS(dd, ds);
 			}
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index cb4995c..ac60c4e 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -325,7 +325,7 @@ int ath_rx_init(struct ath_softc *sc, int nbufs)
 		/* Initialize rx descriptors */
 
 		error = ath_descdma_setup(sc, &sc->rx.rxdma, &sc->rx.rxbuf,
-				"rx", nbufs, 1);
+				"rx", nbufs, 1, 0);
 		if (error != 0) {
 			ath_print(common, ATH_DBG_FATAL,
 				  "failed to allocate rx descriptors: %d\n",
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 7dae199..c32da05 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -2152,7 +2152,7 @@ int ath_tx_init(struct ath_softc *sc, int nbufs)
 	spin_lock_init(&sc->tx.txbuflock);
 
 	error = ath_descdma_setup(sc, &sc->tx.txdma, &sc->tx.txbuf,
-				  "tx", nbufs, 1);
+				  "tx", nbufs, 1, 1);
 	if (error != 0) {
 		ath_print(common, ATH_DBG_FATAL,
 			  "Failed to allocate tx descriptors: %d\n", error);
@@ -2160,7 +2160,7 @@ int ath_tx_init(struct ath_softc *sc, int nbufs)
 	}
 
 	error = ath_descdma_setup(sc, &sc->beacon.bdma, &sc->beacon.bbuf,
-				  "beacon", ATH_BCBUF, 1);
+				  "beacon", ATH_BCBUF, 1, 0);
 	if (error != 0) {
 		ath_print(common, ATH_DBG_FATAL,
 			  "Failed to allocate beacon descriptors: %d\n", error);
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 103+ messages in thread

* [PATCH v3 89/97] ath9k: Initialize and configure tx status for EDMA
  2010-04-15 21:38 [PATCH v3 00/97] ath9k: add AR9003 support Luis R. Rodriguez
                   ` (87 preceding siblings ...)
  2010-04-15 21:39 ` [PATCH v3 88/97] ath9k: Setup appropriate tx desc for regular dma and edma Luis R. Rodriguez
@ 2010-04-15 21:39 ` Luis R. Rodriguez
  2010-04-15 21:39 ` [PATCH v3 90/97] ath9k_hw: Compute pointer checksum over the link descriptor Luis R. Rodriguez
                   ` (7 subsequent siblings)
  96 siblings, 0 replies; 103+ messages in thread
From: Luis R. Rodriguez @ 2010-04-15 21:39 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Vasanthakumar Thiagarajan

From: Vasanthakumar Thiagarajan <vasanth@atheros.com>

Also add a function to clean up tx status ring.

Signed-off-by: Vasanthakumar Thiagarajan <vasanth@atheros.com>
---
 drivers/net/wireless/ath/ath9k/ath9k.h |    6 +++-
 drivers/net/wireless/ath/ath9k/hw.c    |    1 +
 drivers/net/wireless/ath/ath9k/hw.h    |    1 +
 drivers/net/wireless/ath/ath9k/xmit.c  |   46 +++++++++++++++++++++++++++++++-
 4 files changed, 52 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index f67be52..2d3e42a 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -114,8 +114,10 @@ enum buffer_type {
 #define bf_isretried(bf)	(bf->bf_state.bf_type & BUF_RETRY)
 #define bf_isxretried(bf)	(bf->bf_state.bf_type & BUF_XRETRY)
 
+#define ATH_TXSTATUS_RING_SIZE 64
+
 struct ath_descdma {
-	struct ath_desc *dd_desc;
+	void *dd_desc;
 	dma_addr_t dd_desc_paddr;
 	u32 dd_desc_len;
 	struct ath_buf *dd_bufptr;
@@ -515,6 +517,8 @@ struct ath_softc {
 	struct ath_beacon_config cur_beacon_conf;
 	struct delayed_work tx_complete_work;
 	struct ath_btcoex btcoex;
+
+	struct ath_descdma txsdma;
 };
 
 struct ath_wiphy {
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 1f06ac0..4092090 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -2094,6 +2094,7 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
 		pCap->rx_lp_qdepth = ATH9K_HW_RX_LP_QDEPTH;
 		pCap->rx_status_len = sizeof(struct ar9003_rxs);
 		pCap->tx_desc_len = sizeof(struct ar9003_txc);
+		pCap->txs_len = sizeof(struct ar9003_txs);
 	} else {
 		pCap->tx_desc_len = sizeof(struct ath_desc);
 	}
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index b711ec2..9d3796a 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -209,6 +209,7 @@ struct ath9k_hw_capabilities {
 	u8 rx_lp_qdepth;
 	u8 rx_status_len;
 	u8 tx_desc_len;
+	u8 txs_len;
 };
 
 struct ath9k_ops_config {
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index c32da05..f9f7445 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -2144,6 +2144,41 @@ void ath_tx_tasklet(struct ath_softc *sc)
 /* Init, Cleanup */
 /*****************/
 
+static int ath_txstatus_setup(struct ath_softc *sc, int size)
+{
+	struct ath_descdma *dd = &sc->txsdma;
+	u8 txs_len = sc->sc_ah->caps.txs_len;
+
+	dd->dd_desc_len = size * txs_len;
+	dd->dd_desc = dma_alloc_coherent(sc->dev, dd->dd_desc_len,
+					 &dd->dd_desc_paddr, GFP_KERNEL);
+	if (!dd->dd_desc)
+		return -ENOMEM;
+
+	return 0;
+}
+
+static int ath_tx_edma_init(struct ath_softc *sc)
+{
+	int err;
+
+	err = ath_txstatus_setup(sc, ATH_TXSTATUS_RING_SIZE);
+	if (!err)
+		ath9k_hw_setup_statusring(sc->sc_ah, sc->txsdma.dd_desc,
+					  sc->txsdma.dd_desc_paddr,
+					  ATH_TXSTATUS_RING_SIZE);
+
+	return err;
+}
+
+static void ath_tx_edma_cleanup(struct ath_softc *sc)
+{
+	struct ath_descdma *dd = &sc->txsdma;
+
+	dma_free_coherent(sc->dev, dd->dd_desc_len, dd->dd_desc,
+			  dd->dd_desc_paddr);
+}
+
 int ath_tx_init(struct ath_softc *sc, int nbufs)
 {
 	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
@@ -2160,7 +2195,7 @@ int ath_tx_init(struct ath_softc *sc, int nbufs)
 	}
 
 	error = ath_descdma_setup(sc, &sc->beacon.bdma, &sc->beacon.bbuf,
-				  "beacon", ATH_BCBUF, 1, 0);
+				  "beacon", ATH_BCBUF, 1, 1);
 	if (error != 0) {
 		ath_print(common, ATH_DBG_FATAL,
 			  "Failed to allocate beacon descriptors: %d\n", error);
@@ -2169,6 +2204,12 @@ int ath_tx_init(struct ath_softc *sc, int nbufs)
 
 	INIT_DELAYED_WORK(&sc->tx_complete_work, ath_tx_complete_poll_work);
 
+	if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
+		error = ath_tx_edma_init(sc);
+		if (error)
+			goto err;
+	}
+
 err:
 	if (error != 0)
 		ath_tx_cleanup(sc);
@@ -2183,6 +2224,9 @@ void ath_tx_cleanup(struct ath_softc *sc)
 
 	if (sc->tx.txdma.dd_desc_len != 0)
 		ath_descdma_cleanup(sc, &sc->tx.txdma, &sc->tx.txbuf);
+
+	if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
+		ath_tx_edma_cleanup(sc);
 }
 
 void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an)
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 103+ messages in thread

* [PATCH v3 90/97] ath9k_hw: Compute pointer checksum over the link descriptor
  2010-04-15 21:38 [PATCH v3 00/97] ath9k: add AR9003 support Luis R. Rodriguez
                   ` (88 preceding siblings ...)
  2010-04-15 21:39 ` [PATCH v3 89/97] ath9k: Initialize and configure tx status for EDMA Luis R. Rodriguez
@ 2010-04-15 21:39 ` Luis R. Rodriguez
  2010-04-15 21:39 ` [PATCH v3 91/97] ath9k: Add Tx EDMA support Luis R. Rodriguez
                   ` (6 subsequent siblings)
  96 siblings, 0 replies; 103+ messages in thread
From: Luis R. Rodriguez @ 2010-04-15 21:39 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Vasanthakumar Thiagarajan, Felix Fietkau

From: Vasanthakumar Thiagarajan <vasanth@atheros.com>

Signed-off-by: Vasanthakumar Thiagarajan <vasanth@atheros.com>
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
 drivers/net/wireless/ath/ath9k/ar9003_mac.c |   36 +++++++++++++++-----------
 1 files changed, 21 insertions(+), 15 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.c b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
index 1a8c1ba..582c880 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
@@ -21,14 +21,33 @@ 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 *) ds)->link = 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)
 {
-	*ds_link = &((struct ar9003_txc *) ds)->link;
+	struct ar9003_txc *ads = ds;
+
+	*ds_link = &ads->link;
 }
 
 static bool ar9003_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked)
@@ -168,19 +187,6 @@ static bool ar9003_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked)
 	return true;
 }
 
-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_fill_txdesc(struct ath_hw *ah, void *ds, u32 seglen,
 				  bool is_firstseg, bool is_lastseg,
 				  const void *ds0, dma_addr_t buf_addr,
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 103+ messages in thread

* [PATCH v3 91/97] ath9k: Add Tx EDMA support
  2010-04-15 21:38 [PATCH v3 00/97] ath9k: add AR9003 support Luis R. Rodriguez
                   ` (89 preceding siblings ...)
  2010-04-15 21:39 ` [PATCH v3 90/97] ath9k_hw: Compute pointer checksum over the link descriptor Luis R. Rodriguez
@ 2010-04-15 21:39 ` Luis R. Rodriguez
  2010-04-15 21:39 ` [PATCH v3 92/97] mac80211: add LDPC control flag Luis R. Rodriguez
                   ` (5 subsequent siblings)
  96 siblings, 0 replies; 103+ messages in thread
From: Luis R. Rodriguez @ 2010-04-15 21:39 UTC (permalink / raw)
  To: linville
  Cc: linux-wireless, Vasanthakumar Thiagarajan, Luis R. Rodriguez,
	Felix Fietkau

From: Vasanthakumar Thiagarajan <vasanth@atheros.com>

Signed-off-by: Vasanthakumar Thiagarajan <vasanth@atheros.com>
Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
 drivers/net/wireless/ath/ath9k/ath9k.h |    6 +
 drivers/net/wireless/ath/ath9k/main.c  |    8 +-
 drivers/net/wireless/ath/ath9k/xmit.c  |  264 +++++++++++++++++++++++++-------
 3 files changed, 218 insertions(+), 60 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 2d3e42a..fbb7dec 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -190,6 +190,7 @@ enum ATH_AGGR_STATUS {
 	ATH_AGGR_LIMITED,
 };
 
+#define ATH_TXFIFO_DEPTH 8
 struct ath_txq {
 	u32 axq_qnum;
 	u32 *axq_link;
@@ -199,6 +200,10 @@ struct ath_txq {
 	bool stopped;
 	bool axq_tx_inprogress;
 	struct list_head axq_acq;
+	struct list_head txq_fifo[ATH_TXFIFO_DEPTH];
+	struct list_head txq_fifo_pending;
+	u8 txq_headidx;
+	u8 txq_tailidx;
 };
 
 #define AGGR_CLEANUP         BIT(1)
@@ -268,6 +273,7 @@ int ath_txq_update(struct ath_softc *sc, int qnum,
 int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
 		 struct ath_tx_control *txctl);
 void ath_tx_tasklet(struct ath_softc *sc);
+void ath_tx_edma_tasklet(struct ath_softc *sc);
 void ath_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb);
 bool ath_tx_aggr_check(struct ath_softc *sc, struct ath_node *an, u8 tidno);
 void ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta,
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 92f6fdc..1f4ea74 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -429,8 +429,12 @@ void ath9k_tasklet(unsigned long data)
 		spin_unlock_bh(&sc->rx.rxflushlock);
 	}
 
-	if (status & ATH9K_INT_TX)
-		ath_tx_tasklet(sc);
+	if (status & ATH9K_INT_TX) {
+		if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
+			ath_tx_edma_tasklet(sc);
+		else
+			ath_tx_tasklet(sc);
+	}
 
 	if ((status & ATH9K_INT_TSFOOR) && sc->ps_enabled) {
 		/*
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index f9f7445..c2b4503 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -92,7 +92,6 @@ static int ath_max_4ms_framelen[3][16] = {
 	}
 };
 
-
 /*********************/
 /* Aggregation logic */
 /*********************/
@@ -379,7 +378,8 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
 			}
 		}
 
-		if (bf_next == NULL) {
+		if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) &&
+		    bf_next == NULL) {
 			/*
 			 * Make sure the last desc is reclaimed if it
 			 * not a holding desc.
@@ -413,36 +413,43 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
 				!txfail, sendbar);
 		} else {
 			/* retry the un-acked ones */
-			if (bf->bf_next == NULL && bf_last->bf_stale) {
-				struct ath_buf *tbf;
-
-				tbf = ath_clone_txbuf(sc, bf_last);
-				/*
-				 * Update tx baw and complete the frame with
-				 * failed status if we run out of tx buf
-				 */
-				if (!tbf) {
-					spin_lock_bh(&txq->axq_lock);
-					ath_tx_update_baw(sc, tid,
-							  bf->bf_seqno);
-					spin_unlock_bh(&txq->axq_lock);
-
-					bf->bf_state.bf_type |= BUF_XRETRY;
-					ath_tx_rc_status(bf, ts, nbad,
-							 0, false);
-					ath_tx_complete_buf(sc, bf, txq,
-							    &bf_head, ts, 0, 0);
-					break;
+			if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)) {
+				if (bf->bf_next == NULL && bf_last->bf_stale) {
+					struct ath_buf *tbf;
+
+					tbf = ath_clone_txbuf(sc, bf_last);
+					/*
+					 * Update tx baw and complete the
+					 * frame with failed status if we
+					 * run out of tx buf.
+					 */
+					if (!tbf) {
+						spin_lock_bh(&txq->axq_lock);
+						ath_tx_update_baw(sc, tid,
+								bf->bf_seqno);
+						spin_unlock_bh(&txq->axq_lock);
+
+						bf->bf_state.bf_type |=
+							BUF_XRETRY;
+						ath_tx_rc_status(bf, ts, nbad,
+								0, false);
+						ath_tx_complete_buf(sc, bf, txq,
+								    &bf_head,
+								    ts, 0, 0);
+						break;
+					}
+
+					ath9k_hw_cleartxdesc(sc->sc_ah,
+							     tbf->bf_desc);
+					list_add_tail(&tbf->list, &bf_head);
+				} else {
+					/*
+					 * Clear descriptor status words for
+					 * software retry
+					 */
+					ath9k_hw_cleartxdesc(sc->sc_ah,
+							     bf->bf_desc);
 				}
-
-				ath9k_hw_cleartxdesc(sc->sc_ah, tbf->bf_desc);
-				list_add_tail(&tbf->list, &bf_head);
-			} else {
-				/*
-				 * Clear descriptor status words for
-				 * software retry
-				 */
-				ath9k_hw_cleartxdesc(sc->sc_ah, bf->bf_desc);
 			}
 
 			/*
@@ -855,7 +862,7 @@ struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype)
 	struct ath_hw *ah = sc->sc_ah;
 	struct ath_common *common = ath9k_hw_common(ah);
 	struct ath9k_tx_queue_info qi;
-	int qnum;
+	int qnum, i;
 
 	memset(&qi, 0, sizeof(qi));
 	qi.tqi_subtype = subtype;
@@ -910,6 +917,11 @@ struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype)
 		txq->axq_depth = 0;
 		txq->axq_tx_inprogress = false;
 		sc->tx.txqsetup |= 1<<qnum;
+
+		txq->txq_headidx = txq->txq_tailidx = 0;
+		for (i = 0; i < ATH_TXFIFO_DEPTH; i++)
+			INIT_LIST_HEAD(&txq->txq_fifo[i]);
+		INIT_LIST_HEAD(&txq->txq_fifo_pending);
 	}
 	return &sc->tx.txq[qnum];
 }
@@ -1042,30 +1054,49 @@ void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx)
 	for (;;) {
 		spin_lock_bh(&txq->axq_lock);
 
-		if (list_empty(&txq->axq_q)) {
-			txq->axq_link = NULL;
-			spin_unlock_bh(&txq->axq_lock);
-			break;
-		}
-
-		bf = list_first_entry(&txq->axq_q, struct ath_buf, list);
+		if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
+			if (list_empty(&txq->txq_fifo[txq->txq_tailidx])) {
+				txq->txq_headidx = txq->txq_tailidx = 0;
+				spin_unlock_bh(&txq->axq_lock);
+				break;
+			} else {
+				bf = list_first_entry(&txq->txq_fifo[txq->txq_tailidx],
+						      struct ath_buf, list);
+			}
+		} else {
+			if (list_empty(&txq->axq_q)) {
+				txq->axq_link = NULL;
+				spin_unlock_bh(&txq->axq_lock);
+				break;
+			}
+			bf = list_first_entry(&txq->axq_q, struct ath_buf,
+					      list);
 
-		if (bf->bf_stale) {
-			list_del(&bf->list);
-			spin_unlock_bh(&txq->axq_lock);
+			if (bf->bf_stale) {
+				list_del(&bf->list);
+				spin_unlock_bh(&txq->axq_lock);
 
-			spin_lock_bh(&sc->tx.txbuflock);
-			list_add_tail(&bf->list, &sc->tx.txbuf);
-			spin_unlock_bh(&sc->tx.txbuflock);
-			continue;
+				spin_lock_bh(&sc->tx.txbuflock);
+				list_add_tail(&bf->list, &sc->tx.txbuf);
+				spin_unlock_bh(&sc->tx.txbuflock);
+				continue;
+			}
 		}
 
 		lastbf = bf->bf_lastbf;
 		if (!retry_tx)
 			lastbf->bf_tx_aborted = true;
 
-		/* remove ath_buf's of the same mpdu from txq */
-		list_cut_position(&bf_head, &txq->axq_q, &lastbf->list);
+		if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
+			list_cut_position(&bf_head,
+					  &txq->txq_fifo[txq->txq_tailidx],
+					  &lastbf->list);
+			INCR(txq->txq_tailidx, ATH_TXFIFO_DEPTH);
+		} else {
+			/* remove ath_buf's of the same mpdu from txq */
+			list_cut_position(&bf_head, &txq->axq_q, &lastbf->list);
+		}
+
 		txq->axq_depth--;
 
 		spin_unlock_bh(&txq->axq_lock);
@@ -1088,6 +1119,27 @@ void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx)
 			spin_unlock_bh(&txq->axq_lock);
 		}
 	}
+
+	if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
+		spin_lock_bh(&txq->axq_lock);
+		while (!list_empty(&txq->txq_fifo_pending)) {
+			bf = list_first_entry(&txq->txq_fifo_pending,
+					      struct ath_buf, list);
+			list_cut_position(&bf_head,
+					  &txq->txq_fifo_pending,
+					  &bf->bf_lastbf->list);
+			spin_unlock_bh(&txq->axq_lock);
+
+			if (bf_isampdu(bf))
+				ath_tx_complete_aggr(sc, txq, bf, &bf_head,
+						     &ts, 0);
+			else
+				ath_tx_complete_buf(sc, bf, txq, &bf_head,
+						    &ts, 0, 0);
+			spin_lock_bh(&txq->axq_lock);
+		}
+		spin_unlock_bh(&txq->axq_lock);
+	}
 }
 
 void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx)
@@ -1225,25 +1277,47 @@ static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq,
 
 	bf = list_first_entry(head, struct ath_buf, list);
 
-	list_splice_tail_init(head, &txq->axq_q);
-	txq->axq_depth++;
-
 	ath_print(common, ATH_DBG_QUEUE,
 		  "qnum: %d, txq depth: %d\n", txq->axq_qnum, txq->axq_depth);
 
-	if (txq->axq_link == NULL) {
+	if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
+		if (txq->axq_depth >= ATH_TXFIFO_DEPTH) {
+			list_splice_tail_init(head, &txq->txq_fifo_pending);
+			return;
+		}
+		if (!list_empty(&txq->txq_fifo[txq->txq_headidx]))
+			ath_print(common, ATH_DBG_XMIT,
+				  "Initializing tx fifo %d which "
+				  "is non-empty\n",
+				  txq->txq_headidx);
+		INIT_LIST_HEAD(&txq->txq_fifo[txq->txq_headidx]);
+		list_splice_init(head, &txq->txq_fifo[txq->txq_headidx]);
+		INCR(txq->txq_headidx, ATH_TXFIFO_DEPTH);
 		ath9k_hw_puttxbuf(ah, txq->axq_qnum, bf->bf_daddr);
 		ath_print(common, ATH_DBG_XMIT,
 			  "TXDP[%u] = %llx (%p)\n",
 			  txq->axq_qnum, ito64(bf->bf_daddr), bf->bf_desc);
 	} else {
-		*txq->axq_link = bf->bf_daddr;
-		ath_print(common, ATH_DBG_XMIT, "link[%u] (%p)=%llx (%p)\n",
-			  txq->axq_qnum, txq->axq_link,
-			  ito64(bf->bf_daddr), bf->bf_desc);
+		list_splice_tail_init(head, &txq->axq_q);
+
+		if (txq->axq_link == NULL) {
+			ath9k_hw_puttxbuf(ah, txq->axq_qnum, bf->bf_daddr);
+			ath_print(common, ATH_DBG_XMIT,
+					"TXDP[%u] = %llx (%p)\n",
+					txq->axq_qnum, ito64(bf->bf_daddr),
+					bf->bf_desc);
+		} else {
+			*txq->axq_link = bf->bf_daddr;
+			ath_print(common, ATH_DBG_XMIT,
+					"link[%u] (%p)=%llx (%p)\n",
+					txq->axq_qnum, txq->axq_link,
+					ito64(bf->bf_daddr), bf->bf_desc);
+		}
+		ath9k_hw_get_desc_link(ah, bf->bf_lastbf->bf_desc,
+				       &txq->axq_link);
+		ath9k_hw_txstart(ah, txq->axq_qnum);
 	}
-	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 struct ath_buf *ath_tx_get_buffer(struct ath_softc *sc)
@@ -2140,6 +2214,80 @@ void ath_tx_tasklet(struct ath_softc *sc)
 	}
 }
 
+void ath_tx_edma_tasklet(struct ath_softc *sc)
+{
+	struct ath_tx_status txs;
+	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
+	struct ath_hw *ah = sc->sc_ah;
+	struct ath_txq *txq;
+	struct ath_buf *bf, *lastbf;
+	struct list_head bf_head;
+	int status;
+	int txok;
+
+	for (;;) {
+		status = ath9k_hw_txprocdesc(ah, NULL, (void *)&txs);
+		if (status == -EINPROGRESS)
+			break;
+		if (status == -EIO) {
+			ath_print(common, ATH_DBG_XMIT,
+				  "Error processing tx status\n");
+			break;
+		}
+
+		/* Skip beacon completions */
+		if (txs.qid == sc->beacon.beaconq)
+			continue;
+
+		txq = &sc->tx.txq[txs.qid];
+
+		spin_lock_bh(&txq->axq_lock);
+		if (list_empty(&txq->txq_fifo[txq->txq_tailidx])) {
+			spin_unlock_bh(&txq->axq_lock);
+			return;
+		}
+
+		bf = list_first_entry(&txq->txq_fifo[txq->txq_tailidx],
+				      struct ath_buf, list);
+		lastbf = bf->bf_lastbf;
+
+		INIT_LIST_HEAD(&bf_head);
+		list_cut_position(&bf_head, &txq->txq_fifo[txq->txq_tailidx],
+				  &lastbf->list);
+		INCR(txq->txq_tailidx, ATH_TXFIFO_DEPTH);
+		txq->axq_depth--;
+		txq->axq_tx_inprogress = false;
+		spin_unlock_bh(&txq->axq_lock);
+
+		txok = !(txs.ts_status & ATH9K_TXERR_MASK);
+
+		if (!bf_isampdu(bf)) {
+			bf->bf_retries = txs.ts_longretry;
+			if (txs.ts_status & ATH9K_TXERR_XRETRY)
+				bf->bf_state.bf_type |= BUF_XRETRY;
+			ath_tx_rc_status(bf, &txs, 0, txok, true);
+		}
+
+		if (bf_isampdu(bf))
+			ath_tx_complete_aggr(sc, txq, bf, &bf_head, &txs, txok);
+		else
+			ath_tx_complete_buf(sc, bf, txq, &bf_head,
+					    &txs, txok, 0);
+
+		spin_lock_bh(&txq->axq_lock);
+		if (!list_empty(&txq->txq_fifo_pending)) {
+			INIT_LIST_HEAD(&bf_head);
+			bf = list_first_entry(&txq->txq_fifo_pending,
+				struct ath_buf, list);
+			list_cut_position(&bf_head, &txq->txq_fifo_pending,
+				&bf->bf_lastbf->list);
+			ath_tx_txqaddbuf(sc, txq, &bf_head);
+		} else if (sc->sc_flags & SC_OP_TXAGGR)
+			ath_txq_schedule(sc, txq);
+		spin_unlock_bh(&txq->axq_lock);
+	}
+}
+
 /*****************/
 /* Init, Cleanup */
 /*****************/
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 103+ messages in thread

* [PATCH v3 92/97] mac80211: add LDPC control flag
  2010-04-15 21:38 [PATCH v3 00/97] ath9k: add AR9003 support Luis R. Rodriguez
                   ` (90 preceding siblings ...)
  2010-04-15 21:39 ` [PATCH v3 91/97] ath9k: Add Tx EDMA support Luis R. Rodriguez
@ 2010-04-15 21:39 ` Luis R. Rodriguez
  2010-04-15 21:39 ` [PATCH v3 93/97] ath9k_hw: add LDPC support for AR9003 Luis R. Rodriguez
                   ` (4 subsequent siblings)
  96 siblings, 0 replies; 103+ messages in thread
From: Luis R. Rodriguez @ 2010-04-15 21:39 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Luis R. Rodriguez

LDPC will be enabled through the rate control algorithm
for each buffer the the tx_info flags.

Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 include/net/mac80211.h |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index dcf3c5f..75056dd 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -274,6 +274,7 @@ struct ieee80211_bss_conf {
  * @IEEE80211_TX_INTFL_NL80211_FRAME_TX: Frame was requested through nl80211
  *	MLME command (internal to mac80211 to figure out whether to send TX
  *	status to user space)
+ * @IEEE80211_TX_CTL_LDPC: tells the driver to use LDPC for this frame
  */
 enum mac80211_tx_control_flags {
 	IEEE80211_TX_CTL_REQ_TX_STATUS		= BIT(0),
@@ -297,6 +298,7 @@ enum mac80211_tx_control_flags {
 	IEEE80211_TX_INTFL_RETRANSMISSION	= BIT(19),
 	IEEE80211_TX_INTFL_HAS_RADIOTAP		= BIT(20),
 	IEEE80211_TX_INTFL_NL80211_FRAME_TX	= BIT(21),
+	IEEE80211_TX_CTL_LDPC			= BIT(22),
 };
 
 /**
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 103+ messages in thread

* [PATCH v3 93/97] ath9k_hw: add LDPC support for AR9003
  2010-04-15 21:38 [PATCH v3 00/97] ath9k: add AR9003 support Luis R. Rodriguez
                   ` (91 preceding siblings ...)
  2010-04-15 21:39 ` [PATCH v3 92/97] mac80211: add LDPC control flag Luis R. Rodriguez
@ 2010-04-15 21:39 ` Luis R. Rodriguez
  2010-04-15 21:39 ` [PATCH v3 94/97] ath9k: add LDPC support Luis R. Rodriguez
                   ` (3 subsequent siblings)
  96 siblings, 0 replies; 103+ messages in thread
From: Luis R. Rodriguez @ 2010-04-15 21:39 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Luis R. Rodriguez

Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/ar9003_mac.c |    3 ++-
 drivers/net/wireless/ath/ath9k/hw.c         |    2 +-
 drivers/net/wireless/ath/ath9k/hw.h         |    1 +
 drivers/net/wireless/ath/ath9k/mac.h        |    2 ++
 4 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.c b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
index 582c880..7d111fb 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
@@ -330,7 +330,8 @@ static void ar9003_hw_set11n_txdesc(struct ath_hw *ah, void *ds,
 		| (flags & ATH9K_TXDESC_EXT_ONLY ? AR_ExtOnly : 0)
 		| (flags & ATH9K_TXDESC_EXT_AND_CTL ? AR_ExtAndCtl : 0);
 
-	ads->ctl17 = SM(keyType, AR_EncrType);
+	ads->ctl17 = SM(keyType, AR_EncrType) |
+		     (flags & ATH9K_TXDESC_LDPC ? AR_LDPC : 0);
 	ads->ctl18 = 0;
 	ads->ctl19 = AR_Not_Sounding;
 
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 4092090..44077cb 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -2089,7 +2089,7 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
 	}
 
 	if (AR_SREV_9300_20_OR_LATER(ah)) {
-		pCap->hw_caps |= ATH9K_HW_CAP_EDMA;
+		pCap->hw_caps |= ATH9K_HW_CAP_EDMA | ATH9K_HW_CAP_LDPC;
 		pCap->rx_hp_qdepth = ATH9K_HW_RX_HP_QDEPTH;
 		pCap->rx_lp_qdepth = ATH9K_HW_RX_LP_QDEPTH;
 		pCap->rx_status_len = sizeof(struct ar9003_rxs);
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 9d3796a..7ce5420 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -179,6 +179,7 @@ enum ath9k_hw_caps {
 	ATH9K_HW_CAP_4KB_SPLITTRANS             = BIT(16),
 	ATH9K_HW_CAP_EDMA			= BIT(17),
 	ATH9K_HW_CAP_RAC_SUPPORTED		= BIT(18),
+	ATH9K_HW_CAP_LDPC			= BIT(19),
 };
 
 enum ath9k_capability_type {
diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h
index b591dc2..346d84a 100644
--- a/drivers/net/wireless/ath/ath9k/mac.h
+++ b/drivers/net/wireless/ath/ath9k/mac.h
@@ -264,6 +264,7 @@ struct ath_desc {
 #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
 
@@ -413,6 +414,7 @@ struct ar5416_desc {
 #define AR_EncrType         0x0c000000
 #define AR_EncrType_S       26
 #define AR_TxCtlRsvd61      0xf0000000
+#define AR_LDPC             0x80000000
 
 #define AR_2040_0           0x00000001
 #define AR_GI0              0x00000002
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 103+ messages in thread

* [PATCH v3 94/97] ath9k: add LDPC support
  2010-04-15 21:38 [PATCH v3 00/97] ath9k: add AR9003 support Luis R. Rodriguez
                   ` (92 preceding siblings ...)
  2010-04-15 21:39 ` [PATCH v3 93/97] ath9k_hw: add LDPC support for AR9003 Luis R. Rodriguez
@ 2010-04-15 21:39 ` Luis R. Rodriguez
  2010-04-15 21:39 ` [PATCH v3 95/97] ath9k: Enable TXOK and TXERR interrupts for TX EDMA Luis R. Rodriguez
                   ` (2 subsequent siblings)
  96 siblings, 0 replies; 103+ messages in thread
From: Luis R. Rodriguez @ 2010-04-15 21:39 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Luis R. Rodriguez

LDPC is enabled by the rate control if the its determined
that the target peer supports LDPC. We would have already
intersected the HT capabilities so if our peer supports
LDPC so do we.

Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/init.c |    3 +++
 drivers/net/wireless/ath/ath9k/rc.c   |    9 +++++++++
 drivers/net/wireless/ath/ath9k/xmit.c |   14 ++++++++++----
 3 files changed, 22 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index 299ec05..ca6e781 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -191,6 +191,9 @@ static void setup_ht_cap(struct ath_softc *sc,
 		       IEEE80211_HT_CAP_SGI_40 |
 		       IEEE80211_HT_CAP_DSSSCCK40;
 
+	if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_LDPC)
+		ht_info->cap |= IEEE80211_HT_CAP_LDPC_CODING;
+
 	ht_info->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
 	ht_info->ampdu_density = IEEE80211_HT_MPDU_DENSITY_8;
 
diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c
index ee81291..bf3ad7a 100644
--- a/drivers/net/wireless/ath/ath9k/rc.c
+++ b/drivers/net/wireless/ath/ath9k/rc.c
@@ -691,6 +691,15 @@ static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
 	rate_table = sc->cur_rate_table;
 	rix = ath_rc_get_highest_rix(sc, ath_rc_priv, rate_table, &is_probe);
 
+	/*
+	 * If we're in HT mode and both us and our peer supports LDPC.
+	 * We don't need to check our own device's capabilities as our own
+	 * ht capabilities would have already been intersected with our peer's.
+	 */
+	if (conf_is_ht(&sc->hw->conf) &&
+	    (sta->ht_cap.cap & IEEE80211_HT_CAP_LDPC_CODING))
+		tx_info->flags |= IEEE80211_TX_CTL_LDPC;
+
 	if (is_probe) {
 		/* set one try for probe rates. For the
 		 * probes don't enable rts */
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index c2b4503..90e629f 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -1483,8 +1483,7 @@ static void assign_aggr_tid_seqno(struct sk_buff *skb,
 	INCR(tid->seq_next, IEEE80211_SEQ_MAX);
 }
 
-static int setup_tx_flags(struct ath_softc *sc, struct sk_buff *skb,
-			  struct ath_txq *txq)
+static int setup_tx_flags(struct sk_buff *skb, bool use_ldpc)
 {
 	struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
 	int flags = 0;
@@ -1495,6 +1494,9 @@ static int setup_tx_flags(struct ath_softc *sc, struct sk_buff *skb,
 	if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK)
 		flags |= ATH9K_TXDESC_NOACK;
 
+	if (use_ldpc)
+		flags |= ATH9K_TXDESC_LDPC;
+
 	return flags;
 }
 
@@ -1646,6 +1648,7 @@ static int ath_tx_setup_buffer(struct ieee80211_hw *hw, struct ath_buf *bf,
 	int hdrlen;
 	__le16 fc;
 	int padpos, padsize;
+	bool use_ldpc = false;
 
 	tx_info->pad[0] = 0;
 	switch (txctl->frame_type) {
@@ -1672,10 +1675,13 @@ static int ath_tx_setup_buffer(struct ieee80211_hw *hw, struct ath_buf *bf,
 		bf->bf_frmlen -= padsize;
 	}
 
-	if (conf_is_ht(&hw->conf))
+	if (conf_is_ht(&hw->conf)) {
 		bf->bf_state.bf_type |= BUF_HT;
+		if (tx_info->flags & IEEE80211_TX_CTL_LDPC)
+			use_ldpc = true;
+	}
 
-	bf->bf_flags = setup_tx_flags(sc, skb, txctl->txq);
+	bf->bf_flags = setup_tx_flags(skb, use_ldpc);
 
 	bf->bf_keytype = get_hw_crypto_keytype(skb);
 	if (bf->bf_keytype != ATH9K_KEY_TYPE_CLEAR) {
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 103+ messages in thread

* [PATCH v3 95/97] ath9k: Enable TXOK and TXERR interrupts for TX EDMA
  2010-04-15 21:38 [PATCH v3 00/97] ath9k: add AR9003 support Luis R. Rodriguez
                   ` (93 preceding siblings ...)
  2010-04-15 21:39 ` [PATCH v3 94/97] ath9k: add LDPC support Luis R. Rodriguez
@ 2010-04-15 21:39 ` Luis R. Rodriguez
  2010-04-15 21:39 ` [PATCH v3 96/97] ath9k_hw: Abort rx if hw is not coming out of full sleep in reset Luis R. Rodriguez
  2010-04-15 21:39 ` [PATCH v3 97/97] ath9k_hw: add the PCI ID for the first AR9300 device Luis R. Rodriguez
  96 siblings, 0 replies; 103+ messages in thread
From: Luis R. Rodriguez @ 2010-04-15 21:39 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Vasanthakumar Thiagarajan

From: Vasanthakumar Thiagarajan <vasanth@atheros.com>

Signed-off-by: Vasanthakumar Thiagarajan <vasanth@atheros.com>
---
 drivers/net/wireless/ath/ath9k/xmit.c |   15 ++++++++++-----
 1 files changed, 10 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 90e629f..cac178a 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -886,11 +886,16 @@ struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype)
 	 * The UAPSD queue is an exception, since we take a desc-
 	 * based intr on the EOSP frames.
 	 */
-	if (qtype == ATH9K_TX_QUEUE_UAPSD)
-		qi.tqi_qflags = TXQ_FLAG_TXDESCINT_ENABLE;
-	else
-		qi.tqi_qflags = TXQ_FLAG_TXEOLINT_ENABLE |
-			TXQ_FLAG_TXDESCINT_ENABLE;
+	if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
+		qi.tqi_qflags = TXQ_FLAG_TXOKINT_ENABLE |
+				TXQ_FLAG_TXERRINT_ENABLE;
+	} else {
+		if (qtype == ATH9K_TX_QUEUE_UAPSD)
+			qi.tqi_qflags = TXQ_FLAG_TXDESCINT_ENABLE;
+		else
+			qi.tqi_qflags = TXQ_FLAG_TXEOLINT_ENABLE |
+					TXQ_FLAG_TXDESCINT_ENABLE;
+	}
 	qnum = ath9k_hw_setuptxqueue(ah, qtype, &qi);
 	if (qnum == -1) {
 		/*
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 103+ messages in thread

* [PATCH v3 96/97] ath9k_hw: Abort rx if hw is not coming out of full sleep in reset
  2010-04-15 21:38 [PATCH v3 00/97] ath9k: add AR9003 support Luis R. Rodriguez
                   ` (94 preceding siblings ...)
  2010-04-15 21:39 ` [PATCH v3 95/97] ath9k: Enable TXOK and TXERR interrupts for TX EDMA Luis R. Rodriguez
@ 2010-04-15 21:39 ` Luis R. Rodriguez
  2010-04-15 21:39 ` [PATCH v3 97/97] ath9k_hw: add the PCI ID for the first AR9300 device Luis R. Rodriguez
  96 siblings, 0 replies; 103+ messages in thread
From: Luis R. Rodriguez @ 2010-04-15 21:39 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Vasanthakumar Thiagarajan

From: Vasanthakumar Thiagarajan <vasanth@atheros.com>

Signed-off-by: Vasanthakumar Thiagarajan <vasanth@atheros.com>
---
 drivers/net/wireless/ath/ath9k/hw.c  |    7 +++++++
 drivers/net/wireless/ath/ath9k/mac.c |    8 ++++++++
 drivers/net/wireless/ath/ath9k/mac.h |    1 +
 3 files changed, 16 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 44077cb..b9921e9 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -1138,6 +1138,13 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
 	ah->txchainmask = common->tx_chainmask;
 	ah->rxchainmask = common->rx_chainmask;
 
+	if (!ah->chip_fullsleep) {
+		ath9k_hw_abortpcurecv(ah);
+		if (!ath9k_hw_stopdmarecv(ah))
+			ath_print(common, ATH_DBG_XMIT,
+				"Failed to stop receive dma\n");
+	}
+
 	if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
 		return -EIO;
 
diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c
index c003baf..b54e857 100644
--- a/drivers/net/wireless/ath/ath9k/mac.c
+++ b/drivers/net/wireless/ath/ath9k/mac.c
@@ -747,6 +747,14 @@ void ath9k_hw_stoppcurecv(struct ath_hw *ah)
 }
 EXPORT_SYMBOL(ath9k_hw_stoppcurecv);
 
+void ath9k_hw_abortpcurecv(struct ath_hw *ah)
+{
+	REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_ABORT | AR_DIAG_RX_DIS);
+
+	ath9k_hw_disable_mib_counters(ah);
+}
+EXPORT_SYMBOL(ath9k_hw_abortpcurecv);
+
 bool ath9k_hw_stopdmarecv(struct ath_hw *ah)
 {
 #define AH_RX_STOP_DMA_TIMEOUT 10000   /* usec */
diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h
index 346d84a..68eb8d0 100644
--- a/drivers/net/wireless/ath/ath9k/mac.h
+++ b/drivers/net/wireless/ath/ath9k/mac.h
@@ -711,6 +711,7 @@ bool ath9k_hw_setrxabort(struct ath_hw *ah, bool set);
 void ath9k_hw_putrxbuf(struct ath_hw *ah, u32 rxdp);
 void ath9k_hw_startpcureceive(struct ath_hw *ah);
 void ath9k_hw_stoppcurecv(struct ath_hw *ah);
+void ath9k_hw_abortpcurecv(struct ath_hw *ah);
 bool ath9k_hw_stopdmarecv(struct ath_hw *ah);
 int ath9k_hw_beaconq_setup(struct ath_hw *ah);
 
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 103+ messages in thread

* [PATCH v3 97/97] ath9k_hw: add the PCI ID for the first AR9300 device
  2010-04-15 21:38 [PATCH v3 00/97] ath9k: add AR9003 support Luis R. Rodriguez
                   ` (95 preceding siblings ...)
  2010-04-15 21:39 ` [PATCH v3 96/97] ath9k_hw: Abort rx if hw is not coming out of full sleep in reset Luis R. Rodriguez
@ 2010-04-15 21:39 ` Luis R. Rodriguez
  96 siblings, 0 replies; 103+ messages in thread
From: Luis R. Rodriguez @ 2010-04-15 21:39 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Luis R. Rodriguez

The first AR9003 hardware family device supported is the
AR9300, which has the vendor:device id 168c:0030

Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/pci.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c
index 1ec836c..257b10b 100644
--- a/drivers/net/wireless/ath/ath9k/pci.c
+++ b/drivers/net/wireless/ath/ath9k/pci.c
@@ -28,6 +28,7 @@ static DEFINE_PCI_DEVICE_TABLE(ath_pci_id_table) = {
 	{ PCI_VDEVICE(ATHEROS, 0x002C) }, /* PCI-E 802.11n bonded out */
 	{ PCI_VDEVICE(ATHEROS, 0x002D) }, /* PCI   */
 	{ PCI_VDEVICE(ATHEROS, 0x002E) }, /* PCI-E */
+	{ PCI_VDEVICE(ATHEROS, 0x0030) }, /* PCI-E  AR9300 */
 	{ 0 }
 };
 
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 103+ messages in thread

* Re: [PATCH v3 09/97] ath9k_hw: Move some RF ops to the private callbacks
  2010-04-15 21:38 ` [PATCH v3 09/97] ath9k_hw: Move some RF ops to the private callbacks Luis R. Rodriguez
@ 2010-04-16 19:43   ` John W. Linville
  2010-04-16 19:56     ` Luis R. Rodriguez
  0 siblings, 1 reply; 103+ messages in thread
From: John W. Linville @ 2010-04-16 19:43 UTC (permalink / raw)
  To: Luis R. Rodriguez; +Cc: linux-wireless, Felix Fietkau

On Thu, Apr 15, 2010 at 05:38:14PM -0400, Luis R. Rodriguez wrote:
> The PHY split is easier done in a few steps. First move
> the RF ops to the private ops and rename them accordingly.
> We split PHY stuff up first for the AR5008 and AR9002
> families. There are some callbacks that AR9002 share
> with the AR5008 familiy so we set those first, if AR9002
> has some different callbacks it will override them upon
> hardware init.
> 
> Signed-off-by: Felix Fietkau <nbd@openwrt.org>
> Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
> ---
>  drivers/net/wireless/ath/ath9k/Makefile            |    3 +-
>  drivers/net/wireless/ath/ath9k/ani.c               |    1 +
>  .../net/wireless/ath/ath9k/{phy.c => ar5008_phy.c} |  884 ++++++++++----------

In general, it is better to do renames in a separate patch -- the
fixups are easier in cases where something else hit that file before
your patch is applied.  It might also help if you based big patches
(or big series) on wireless-next-2.6 instead of wireless-testing, as I
need to apply them to wireless-next-2.6 before I can send them to Dave.

In this case, a patch that wireless-testing picked-up from linux-2.6
and which isn't in wireless-next-2.6 (and probably not net-next-2.6
either) causes this patch to fail to apply to wirless-next-2.6.
I'll fix it up, in the interest of putting this series behind us...

John
-- 
John W. Linville		Someday the world will need a hero, and you
linville@tuxdriver.com			might be all we have.  Be ready.

^ permalink raw reply	[flat|nested] 103+ messages in thread

* Re: [PATCH v3 09/97] ath9k_hw: Move some RF ops to the private callbacks
  2010-04-16 19:43   ` John W. Linville
@ 2010-04-16 19:56     ` Luis R. Rodriguez
  0 siblings, 0 replies; 103+ messages in thread
From: Luis R. Rodriguez @ 2010-04-16 19:56 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, Felix Fietkau

On Fri, Apr 16, 2010 at 12:43 PM, John W. Linville
<linville@tuxdriver.com> wrote:
> On Thu, Apr 15, 2010 at 05:38:14PM -0400, Luis R. Rodriguez wrote:
>> The PHY split is easier done in a few steps. First move
>> the RF ops to the private ops and rename them accordingly.
>> We split PHY stuff up first for the AR5008 and AR9002
>> families. There are some callbacks that AR9002 share
>> with the AR5008 familiy so we set those first, if AR9002
>> has some different callbacks it will override them upon
>> hardware init.
>>
>> Signed-off-by: Felix Fietkau <nbd@openwrt.org>
>> Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
>> ---
>>  drivers/net/wireless/ath/ath9k/Makefile            |    3 +-
>>  drivers/net/wireless/ath/ath9k/ani.c               |    1 +
>>  .../net/wireless/ath/ath9k/{phy.c => ar5008_phy.c} |  884 ++++++++++----------
>
> In general, it is better to do renames in a separate patch -- the
> fixups are easier in cases where something else hit that file before
> your patch is applied.  It might also help if you based big patches
> (or big series) on wireless-next-2.6 instead of wireless-testing, as I
> need to apply them to wireless-next-2.6 before I can send them to Dave.
>
> In this case, a patch that wireless-testing picked-up from linux-2.6
> and which isn't in wireless-next-2.6 (and probably not net-next-2.6
> either) causes this patch to fail to apply to wirless-next-2.6.
> I'll fix it up, in the interest of putting this series behind us...

Thanks for addressing it on your end this time, next time we'll rebase
on top of wireless-next-2.6 when doing a larger series. I don't expect
this to happen quite often though. This was just a new hardware
family, which happens so far about every what, 4-5 years?

Thanks!!!

  Luis

^ permalink raw reply	[flat|nested] 103+ messages in thread

* Re: [PATCH v3 42/97] ath9k: Make bf_desc of ath_buf opaque
  2010-04-15 21:38 ` [PATCH v3 42/97] ath9k: Make bf_desc of ath_buf opaque Luis R. Rodriguez
@ 2010-04-16 22:00   ` Pavel Roskin
  2010-04-16 22:09     ` Felix Fietkau
  0 siblings, 1 reply; 103+ messages in thread
From: Pavel Roskin @ 2010-04-16 22:00 UTC (permalink / raw)
  To: Luis R. Rodriguez; +Cc: linville, linux-wireless, Vasanthakumar Thiagarajan

On Thu, 2010-04-15 at 17:38 -0400, Luis R. Rodriguez wrote:
> From: Vasanthakumar Thiagarajan <vasanth@atheros.com>
> 
> Signed-off-by: Vasanthakumar Thiagarajan <vasanth@atheros.com>

> -	struct ath_desc *bf_desc;	/* virtual addr of desc */
> +	void *bf_desc;			/* virtual addr of desc */

Why?

The obvious downside is that bf_desc becomes compatible with pointers of
any type.

The only upside I can think of is that bf_desc won't be dereferenced by
accident.  The same could be done by using a scalar type or
__attribute__((noderef)).

I believe the downside outweighs the upside in absence of any
explanation.

-- 
Regards,
Pavel Roskin

^ permalink raw reply	[flat|nested] 103+ messages in thread

* Re: [PATCH v3 42/97] ath9k: Make bf_desc of ath_buf opaque
  2010-04-16 22:00   ` Pavel Roskin
@ 2010-04-16 22:09     ` Felix Fietkau
  2010-04-19 15:53       ` Pavel Roskin
  0 siblings, 1 reply; 103+ messages in thread
From: Felix Fietkau @ 2010-04-16 22:09 UTC (permalink / raw)
  To: Pavel Roskin
  Cc: Luis R. Rodriguez, linville, linux-wireless, Vasanthakumar Thiagarajan

On 2010-04-17 12:00 AM, Pavel Roskin wrote:
> On Thu, 2010-04-15 at 17:38 -0400, Luis R. Rodriguez wrote:
>> From: Vasanthakumar Thiagarajan <vasanth@atheros.com>
>> 
>> Signed-off-by: Vasanthakumar Thiagarajan <vasanth@atheros.com>
> 
>> -	struct ath_desc *bf_desc;	/* virtual addr of desc */
>> +	void *bf_desc;			/* virtual addr of desc */
> 
> Why?
> 
> The obvious downside is that bf_desc becomes compatible with pointers of
> any type.
Because on AR9300 where it's used, it points to a struct ar9003_txc instead.

> The only upside I can think of is that bf_desc won't be dereferenced by
> accident.  The same could be done by using a scalar type or
> __attribute__((noderef)).
I don't think a scalar type makes any sense for this, because it is a
pointer, and it does get passed to functions that dereference it.
In cases where struct ar9003_txc is used, it'd have to pass through
either an explicit cast or an implicit one going through void* anyway,
so we might as well make it clear that while bf_desc is a valid pointer,
it does not always point to struct ath_desc

- Felix

^ permalink raw reply	[flat|nested] 103+ messages in thread

* Re: [PATCH v3 42/97] ath9k: Make bf_desc of ath_buf opaque
  2010-04-16 22:09     ` Felix Fietkau
@ 2010-04-19 15:53       ` Pavel Roskin
  0 siblings, 0 replies; 103+ messages in thread
From: Pavel Roskin @ 2010-04-19 15:53 UTC (permalink / raw)
  To: Felix Fietkau
  Cc: Luis R. Rodriguez, linville, linux-wireless, Vasanthakumar Thiagarajan

On Sat, 2010-04-17 at 00:09 +0200, Felix Fietkau wrote:

> > The obvious downside is that bf_desc becomes compatible with pointers of
> > any type.
> Because on AR9300 where it's used, it points to a struct ar9003_txc instead.

OK, fair enough.

-- 
Regards,
Pavel Roskin

^ permalink raw reply	[flat|nested] 103+ messages in thread

end of thread, other threads:[~2010-04-19 15:53 UTC | newest]

Thread overview: 103+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-04-15 21:38 [PATCH v3 00/97] ath9k: add AR9003 support Luis R. Rodriguez
2010-04-15 21:38 ` [PATCH v3 01/97] ath9k_hw: start building an abstraction layer for hardware routines Luis R. Rodriguez
2010-04-15 21:38 ` [PATCH v3 02/97] ath9k_hw: add silicon revision macros for AR9300 Luis R. Rodriguez
2010-04-15 21:38 ` [PATCH v3 03/97] ath9k_hw: add a macro for abstracting generic timer access Luis R. Rodriguez
2010-04-15 21:38 ` [PATCH v3 04/97] ath9k_hw: fix a missing hex prefix for a register mask Luis R. Rodriguez
2010-04-15 21:38 ` [PATCH v3 05/97] ath9k_hw: add simple register abstraction for some AR9300 registers Luis R. Rodriguez
2010-04-15 21:38 ` [PATCH v3 06/97] ath9k_hw: add support for GPIO differences on AR9003 Luis R. Rodriguez
2010-04-15 21:38 ` [PATCH v3 07/97] ath9k_hw: AR9003 does not have AR_RC_AHB skip its setting Luis R. Rodriguez
2010-04-15 21:38 ` [PATCH v3 08/97] ath9k_hw: remove wrapper ath9k_hw_write_regs() Luis R. Rodriguez
2010-04-15 21:38 ` [PATCH v3 09/97] ath9k_hw: Move some RF ops to the private callbacks Luis R. Rodriguez
2010-04-16 19:43   ` John W. Linville
2010-04-16 19:56     ` Luis R. Rodriguez
2010-04-15 21:38 ` [PATCH v3 10/97] ath9k_hw: skip PLL initialization on AR9003 on Power-On-Reset Luis R. Rodriguez
2010-04-15 21:38 ` [PATCH v3 11/97] ath9k_hw: add some comments for ath9k_set_power_network_sleep() Luis R. Rodriguez
2010-04-15 21:38 ` [PATCH v3 12/97] ath9k_hw: add a private callback for PLL control computation Luis R. Rodriguez
2010-04-15 21:38 ` [PATCH v3 13/97] ath9k_hw: Add the PCI IDs for AR9300 and fill up the pci_id_tables Luis R. Rodriguez
2010-04-15 21:38 ` [PATCH v3 14/97] ath9k_hw: Add AR9003 PHY support Luis R. Rodriguez
2010-04-15 21:38 ` [PATCH v3 15/97] ath9k_hw: move init config and default after chip is up Luis R. Rodriguez
2010-04-15 21:38 ` [PATCH v3 16/97] ath9k_hw: add the AR9003 ar9003_hw_macversion_supported() Luis R. Rodriguez
2010-04-15 21:38 ` [PATCH v3 17/97] ath9k_hw: disable ANI for AR9003 Luis R. Rodriguez
2010-04-15 21:38 ` [PATCH v3 18/97] ath9k: disable the MIB interrupt if ANI is disabled Luis R. Rodriguez
2010-04-15 21:38 ` [PATCH v3 19/97] ath9k_hw: Add hw cap flag for EDMA for the AR9003 family Luis R. Rodriguez
2010-04-15 21:38 ` [PATCH v3 20/97] ath9k_hw: Fill few hw cap for edma Luis R. Rodriguez
2010-04-15 21:38 ` [PATCH v3 21/97] ath9k_hw: Add abstraction for rx enable Luis R. Rodriguez
2010-04-15 21:38 ` [PATCH v3 22/97] ath9k_hw: Fill rx_enable() for the AR9003 hardware family Luis R. Rodriguez
2010-04-15 21:38 ` [PATCH v3 23/97] ath9k_hw: Add few routines for rx edma support Luis R. Rodriguez
2010-04-15 21:38 ` [PATCH v3 24/97] ath9k_hw: update the chip tests for AR9003 Luis R. Rodriguez
2010-04-15 21:38 ` [PATCH v3 25/97] ath9k_hw: prevent reset control register zeroing on AR9003 reset Luis R. Rodriguez
2010-04-15 21:38 ` [PATCH v3 26/97] ath9k_hw: Add AR9003 PHY register definitions Luis R. Rodriguez
2010-04-15 21:38 ` [PATCH v3 27/97] ath9k_hw: add common channel select helpers for ar900[23] Luis R. Rodriguez
2010-04-15 21:38 ` [PATCH v3 28/97] ath9k_hw: Set the channel on AR9003 Luis R. Rodriguez
2010-04-15 21:38 ` [PATCH v3 29/97] ath9k_hw: Implement PLL control " Luis R. Rodriguez
2010-04-15 21:38 ` [PATCH v3 30/97] ath9k_hw: Implement spur mitigation " Luis R. Rodriguez
2010-04-15 21:38 ` [PATCH v3 31/97] ath9k_hw: split initvals.h by hardware family Luis R. Rodriguez
2010-04-15 21:38 ` [PATCH v3 32/97] ath9k_hw: add initvals for the AR9003 " Luis R. Rodriguez
2010-04-15 21:38 ` [PATCH v3 33/97] ath9k_hw: add helpers for processing the AR9003 INI Luis R. Rodriguez
2010-04-15 21:38 ` [PATCH v3 34/97] ath9k_hw: Split off ANI control to the PHY ops Luis R. Rodriguez
2010-04-15 21:38 ` [PATCH v3 35/97] ath9k_hw: add all the AR9003 PHY callbacks Luis R. Rodriguez
2010-04-15 21:38 ` [PATCH v3 36/97] ath9k_hw: Define tx control struct for AR9003 Luis R. Rodriguez
2010-04-15 21:38 ` [PATCH v3 37/97] ath9k_hw: Move code which populates ds_data to ath9k_hw Luis R. Rodriguez
2010-04-15 21:38 ` [PATCH v3 38/97] ath9k_hw: Add abstraction to set/get link pointer Luis R. Rodriguez
2010-04-15 21:38 ` [PATCH v3 39/97] ath9k: Use abstraction to get " Luis R. Rodriguez
2010-04-15 21:38 ` [PATCH v3 40/97] ath9k: Use memcpy in ath_clone_txbuf() Luis R. Rodriguez
2010-04-15 21:38 ` [PATCH v3 41/97] ath9k: Remove ATH9K_TX_SW_ABORTED and introduce a bool for this purpose Luis R. Rodriguez
2010-04-15 21:38 ` [PATCH v3 42/97] ath9k: Make bf_desc of ath_buf opaque Luis R. Rodriguez
2010-04-16 22:00   ` Pavel Roskin
2010-04-16 22:09     ` Felix Fietkau
2010-04-19 15:53       ` Pavel Roskin
2010-04-15 21:38 ` [PATCH v3 43/97] ath9k: Add Rx EDMA support Luis R. Rodriguez
2010-04-15 21:38 ` [PATCH v3 44/97] ath9k_hw: Split out the function for reading the noise floor Luis R. Rodriguez
2010-04-15 21:38 ` [PATCH v3 45/97] ath9k_hw: the eep_map is used only for AR9280 PCI card ini fixup Luis R. Rodriguez
2010-04-15 21:38 ` [PATCH v3 46/97] ath9k_hw: add a helper for Power Amplifier calibration for AR9002 Luis R. Rodriguez
2010-04-15 21:38 ` [PATCH v3 47/97] ath9k_hw: add a helper for the OLC tem compensation " Luis R. Rodriguez
2010-04-15 21:38 ` [PATCH v3 48/97] ath9k_hw: rename PA calib for AR9287 Luis R. Rodriguez
2010-04-15 21:38 ` [PATCH v3 49/97] ath9k_hw: shift code for AR9280 OLC temp comp Luis R. Rodriguez
2010-04-15 21:38 ` [PATCH v3 50/97] ath9k_hw: move the AR9280 OLC temp comp to its own helper Luis R. Rodriguez
2010-04-15 21:38 ` [PATCH v3 51/97] ath9k_hw: simplify OLC temp compensation for AR9002 Luis R. Rodriguez
2010-04-15 21:38 ` [PATCH v3 52/97] ath9k_hw: rename the PA calib routines to match their families Luis R. Rodriguez
2010-04-15 21:38 ` [PATCH v3 53/97] ath9k_hw: rename getNoiseFloorThresh() to ath9k_hw_loadnf() Luis R. Rodriguez
2010-04-15 21:38 ` [PATCH v3 54/97] ath9k_hw: move the cal AR9100 calibration settings Luis R. Rodriguez
2010-04-15 21:39 ` [PATCH v3 55/97] ath9k_hw: split calib code by hardware families Luis R. Rodriguez
2010-04-15 21:39 ` [PATCH v3 56/97] ath9k_hw: add the AR9003 ar9003_hw_init_cal callback Luis R. Rodriguez
2010-04-15 21:39 ` [PATCH v3 57/97] ath9k_hw: add the config_pci_powersave AR9003 callback Luis R. Rodriguez
2010-04-15 21:39 ` [PATCH v3 58/97] ath9k_hw: split the generic hardware code by hardware family Luis R. Rodriguez
2010-04-15 21:39 ` [PATCH v3 59/97] ath9k_hw: move the cck channel 14 INI to the AR9002 hw code Luis R. Rodriguez
2010-04-15 21:39 ` [PATCH v3 60/97] ath9k_hw: move TX/RX gain INI stuff to its own hardware family code Luis R. Rodriguez
2010-04-15 21:39 ` [PATCH v3 61/97] ath9k_hw: Abstract the routine which returns interrupt status Luis R. Rodriguez
2010-04-15 21:39 ` [PATCH v3 62/97] ath9k_hw: Initialize interrupt mask for AR9003 Luis R. Rodriguez
2010-04-15 21:39 ` [PATCH v3 63/97] ath9k_hw: abstract the AR_PHY_AGC_CONTROL register access Luis R. Rodriguez
2010-04-15 21:39 ` [PATCH v3 64/97] ath9k_hw: abstract loading noisefloor Luis R. Rodriguez
2010-04-15 21:39 ` [PATCH v3 65/97] ath9k_hw: fill in the callbacks for calibration for AR9003 Luis R. Rodriguez
2010-04-15 21:39 ` [PATCH v3 66/97] ath9k_hw: complete AR9003 calibration Luis R. Rodriguez
2010-04-15 21:39 ` [PATCH v3 67/97] ath9k_hw: rename eep_AR9287_ops to eep_ar9287_ops Luis R. Rodriguez
2010-04-15 21:39 ` [PATCH v3 68/97] ath9k_hw: restore mac address reading logic Luis R. Rodriguez
2010-04-15 21:39 ` [PATCH v3 69/97] ath9k_hw: Implement AR9003 eeprom callbacks Luis R. Rodriguez
2010-04-15 21:39 ` [PATCH v3 70/97] ath9k_hw: add OFDM spur mitigation for AR9003 Luis R. Rodriguez
2010-04-15 21:39 ` [PATCH v3 71/97] ath9k_hw: Fill get_isr() " Luis R. Rodriguez
2010-04-15 21:39 ` [PATCH v3 72/97] ath9k_hw: move AR9280 PCI EEPROM fix to eeprom_def.c Luis R. Rodriguez
2010-04-15 21:39 ` [PATCH v3 73/97] ath9k_hw: move the RF claim stuff to AR9002 hardware family Luis R. Rodriguez
2010-04-15 21:39 ` [PATCH v3 74/97] ath9k_hw: Configure Tx interrupt mitigation timer Luis R. Rodriguez
2010-04-15 21:39 ` [PATCH v3 75/97] ath9k_hw: add the AR9300 SREV hw name print Luis R. Rodriguez
2010-04-15 21:39 ` [PATCH v3 76/97] ath9k_hw: add TX/RX gain register initialization for AR9003 Luis R. Rodriguez
2010-04-15 21:39 ` [PATCH v3 77/97] ath9k_hw: Update ath9k_hw_set_dma for AR9300 Luis R. Rodriguez
2010-04-15 21:39 ` [PATCH v3 78/97] ath9k_hw: skip asynch fifo enablement to AR9003 Luis R. Rodriguez
2010-04-15 21:39 ` [PATCH v3 79/97] ath9k_hw: skip WEP aggregation enable code for AR9003 Luis R. Rodriguez
2010-04-15 21:39 ` [PATCH v3 80/97] ath9k: Load SW filtered NF values and start NF cal during full reset " Luis R. Rodriguez
2010-04-15 21:39 ` [PATCH v3 81/97] ath9k_hw: Define abstraction for tx desc access Luis R. Rodriguez
2010-04-15 21:39 ` [PATCH v3 82/97] ath9k_hw: Add function to configure tx status ring buffer Luis R. Rodriguez
2010-04-15 21:39 ` [PATCH v3 83/97] ath9k_hw: move AR9002 mac ops to its own file Luis R. Rodriguez
2010-04-15 21:39 ` [PATCH v3 84/97] ath9k_hw: Fill descriptor abstrations for AR9003 Luis R. Rodriguez
2010-04-15 21:39 ` [PATCH v3 85/97] ath9k: add RXLP and RXHP to debugfs counters Luis R. Rodriguez
2010-04-15 21:39 ` [PATCH v3 86/97] ath9k_hw: enable CRC check of descriptors for AR9003 Luis R. Rodriguez
2010-04-15 21:39 ` [PATCH v3 87/97] ath9k_hw: set cwmin and cwmax to 0 for for AR9003 upon txq reset Luis R. Rodriguez
2010-04-15 21:39 ` [PATCH v3 88/97] ath9k: Setup appropriate tx desc for regular dma and edma Luis R. Rodriguez
2010-04-15 21:39 ` [PATCH v3 89/97] ath9k: Initialize and configure tx status for EDMA Luis R. Rodriguez
2010-04-15 21:39 ` [PATCH v3 90/97] ath9k_hw: Compute pointer checksum over the link descriptor Luis R. Rodriguez
2010-04-15 21:39 ` [PATCH v3 91/97] ath9k: Add Tx EDMA support Luis R. Rodriguez
2010-04-15 21:39 ` [PATCH v3 92/97] mac80211: add LDPC control flag Luis R. Rodriguez
2010-04-15 21:39 ` [PATCH v3 93/97] ath9k_hw: add LDPC support for AR9003 Luis R. Rodriguez
2010-04-15 21:39 ` [PATCH v3 94/97] ath9k: add LDPC support Luis R. Rodriguez
2010-04-15 21:39 ` [PATCH v3 95/97] ath9k: Enable TXOK and TXERR interrupts for TX EDMA Luis R. Rodriguez
2010-04-15 21:39 ` [PATCH v3 96/97] ath9k_hw: Abort rx if hw is not coming out of full sleep in reset Luis R. Rodriguez
2010-04-15 21:39 ` [PATCH v3 97/97] ath9k_hw: add the PCI ID for the first AR9300 device Luis R. Rodriguez

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).