summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--MAINTAINERS3
-rw-r--r--drivers/net/wireless/Kconfig1
-rw-r--r--drivers/net/wireless/Makefile1
-rw-r--r--drivers/net/wireless/at76c50x-usb.c3
-rw-r--r--drivers/net/wireless/ath/ath.h16
-rw-r--r--drivers/net/wireless/ath/ath5k/ani.c41
-rw-r--r--drivers/net/wireless/ath/ath5k/ani.h5
-rw-r--r--drivers/net/wireless/ath/ath5k/ath5k.h2
-rw-r--r--drivers/net/wireless/ath/ath5k/base.c71
-rw-r--r--drivers/net/wireless/ath/ath5k/debug.c49
-rw-r--r--drivers/net/wireless/ath/ath5k/debug.h12
-rw-r--r--drivers/net/wireless/ath/ath5k/pcu.c13
-rw-r--r--drivers/net/wireless/ath/ath5k/phy.c1
-rw-r--r--drivers/net/wireless/ath/ath9k/ani.c101
-rw-r--r--drivers/net/wireless/ath/ath9k/ani.h8
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_2p0_initvals.h1784
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_hw.c162
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_phy.c7
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h7
-rw-r--r--drivers/net/wireless/ath/ath9k/beacon.c21
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.c93
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.h21
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_init.c12
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_main.c1
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_txrx.c3
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c66
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.h21
-rw-r--r--drivers/net/wireless/ath/ath9k/init.c16
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c179
-rw-r--r--drivers/net/wireless/ath/ath9k/rc.c184
-rw-r--r--drivers/net/wireless/ath/ath9k/rc.h26
-rw-r--r--drivers/net/wireless/ath/ath9k/recv.c10
-rw-r--r--drivers/net/wireless/ath/ath9k/reg.h14
-rw-r--r--drivers/net/wireless/ath/ath9k/xmit.c38
-rw-r--r--drivers/net/wireless/ath/carl9170/rx.c89
-rw-r--r--drivers/net/wireless/ath/carl9170/wlan.h14
-rw-r--r--drivers/net/wireless/ath/debug.c29
-rw-r--r--drivers/net/wireless/ath/debug.h10
-rw-r--r--drivers/net/wireless/ath/hw.c59
-rw-r--r--drivers/net/wireless/ath/reg.h11
-rw-r--r--drivers/net/wireless/b43/Makefile2
-rw-r--r--drivers/net/wireless/b43/phy_common.h5
-rw-r--r--drivers/net/wireless/b43/phy_n.c128
-rw-r--r--drivers/net/wireless/b43/phy_n.h218
-rw-r--r--drivers/net/wireless/b43/radio_2055.c1332
-rw-r--r--drivers/net/wireless/b43/radio_2055.h254
-rw-r--r--drivers/net/wireless/b43/radio_2056.c43
-rw-r--r--drivers/net/wireless/b43/radio_2056.h42
-rw-r--r--drivers/net/wireless/b43/tables_nphy.c1311
-rw-r--r--drivers/net/wireless/b43/tables_nphy.h59
-rw-r--r--drivers/net/wireless/iwlwifi/Makefile2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-1000.c7
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.c76
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.h9
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.c27
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000.c14
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-6000.c62
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-calib.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-calib.h (renamed from drivers/net/wireless/iwlwifi/iwl-calib.h)4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c454
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c9
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-lib.c372
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rs.c69
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rs.h10
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rx.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-sta.c716
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-tt.c5
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-tx.c40
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-ucode.c28
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c106
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.h71
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-commands.h13
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c531
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h49
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-debugfs.c1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h16
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom.c381
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom.h8
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-helpers.h5
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-rx.c1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-scan.c12
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-sta.c725
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-sta.h35
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-tx.c38
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c97
-rw-r--r--drivers/net/wireless/libertas/if_usb.c4
-rw-r--r--drivers/net/wireless/p54/eeprom.c4
-rw-r--r--drivers/net/wireless/rt2x00/rt2400pci.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt2500pci.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt2800lib.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt2800pci.c4
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00.h18
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00dev.c85
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00lib.h11
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00link.c12
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00pci.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.c56
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00usb.c54
-rw-r--r--drivers/net/wireless/wl1251/Kconfig33
-rw-r--r--drivers/net/wireless/wl1251/Makefile6
-rw-r--r--drivers/net/wireless/wl1251/acx.c (renamed from drivers/net/wireless/wl12xx/wl1251_acx.c)8
-rw-r--r--drivers/net/wireless/wl1251/acx.h (renamed from drivers/net/wireless/wl12xx/wl1251_acx.h)2
-rw-r--r--drivers/net/wireless/wl1251/boot.c (renamed from drivers/net/wireless/wl12xx/wl1251_boot.c)12
-rw-r--r--drivers/net/wireless/wl1251/boot.h (renamed from drivers/net/wireless/wl12xx/wl1251_boot.h)0
-rw-r--r--drivers/net/wireless/wl1251/cmd.c (renamed from drivers/net/wireless/wl12xx/wl1251_cmd.c)10
-rw-r--r--drivers/net/wireless/wl1251/cmd.h (renamed from drivers/net/wireless/wl12xx/wl1251_cmd.h)0
-rw-r--r--drivers/net/wireless/wl1251/debugfs.c (renamed from drivers/net/wireless/wl12xx/wl1251_debugfs.c)6
-rw-r--r--drivers/net/wireless/wl1251/debugfs.h (renamed from drivers/net/wireless/wl12xx/wl1251_debugfs.h)0
-rw-r--r--drivers/net/wireless/wl1251/event.c (renamed from drivers/net/wireless/wl12xx/wl1251_event.c)8
-rw-r--r--drivers/net/wireless/wl1251/event.h (renamed from drivers/net/wireless/wl12xx/wl1251_event.h)0
-rw-r--r--drivers/net/wireless/wl1251/init.c (renamed from drivers/net/wireless/wl12xx/wl1251_init.c)8
-rw-r--r--drivers/net/wireless/wl1251/init.h (renamed from drivers/net/wireless/wl12xx/wl1251_init.h)0
-rw-r--r--drivers/net/wireless/wl1251/io.c (renamed from drivers/net/wireless/wl12xx/wl1251_io.c)4
-rw-r--r--drivers/net/wireless/wl1251/io.h (renamed from drivers/net/wireless/wl12xx/wl1251_io.h)0
-rw-r--r--drivers/net/wireless/wl1251/main.c (renamed from drivers/net/wireless/wl12xx/wl1251_main.c)20
-rw-r--r--drivers/net/wireless/wl1251/ps.c (renamed from drivers/net/wireless/wl12xx/wl1251_ps.c)8
-rw-r--r--drivers/net/wireless/wl1251/ps.h (renamed from drivers/net/wireless/wl12xx/wl1251_ps.h)2
-rw-r--r--drivers/net/wireless/wl1251/reg.h (renamed from drivers/net/wireless/wl12xx/wl1251_reg.h)0
-rw-r--r--drivers/net/wireless/wl1251/rx.c (renamed from drivers/net/wireless/wl12xx/wl1251_rx.c)10
-rw-r--r--drivers/net/wireless/wl1251/rx.h (renamed from drivers/net/wireless/wl12xx/wl1251_rx.h)0
-rw-r--r--drivers/net/wireless/wl1251/sdio.c (renamed from drivers/net/wireless/wl12xx/wl1251_sdio.c)0
-rw-r--r--drivers/net/wireless/wl1251/spi.c (renamed from drivers/net/wireless/wl12xx/wl1251_spi.c)4
-rw-r--r--drivers/net/wireless/wl1251/spi.h (renamed from drivers/net/wireless/wl12xx/wl1251_spi.h)6
-rw-r--r--drivers/net/wireless/wl1251/tx.c (renamed from drivers/net/wireless/wl12xx/wl1251_tx.c)8
-rw-r--r--drivers/net/wireless/wl1251/tx.h (renamed from drivers/net/wireless/wl12xx/wl1251_tx.h)2
-rw-r--r--drivers/net/wireless/wl1251/wl1251.h (renamed from drivers/net/wireless/wl12xx/wl1251.h)0
-rw-r--r--drivers/net/wireless/wl1251/wl12xx_80211.h156
-rw-r--r--drivers/net/wireless/wl12xx/Kconfig34
-rw-r--r--drivers/net/wireless/wl12xx/Makefile9
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_sdio.c43
-rw-r--r--include/linux/ieee80211.h71
-rw-r--r--include/linux/nl80211.h15
-rw-r--r--include/linux/wireless.h2
-rw-r--r--include/net/cfg80211.h31
-rw-r--r--include/net/mac80211.h9
-rw-r--r--net/mac80211/cfg.c22
-rw-r--r--net/mac80211/ht.c2
-rw-r--r--net/mac80211/ieee80211_i.h4
-rw-r--r--net/mac80211/iface.c9
-rw-r--r--net/mac80211/main.c3
-rw-r--r--net/mac80211/mesh_plink.c17
-rw-r--r--net/mac80211/mlme.c18
-rw-r--r--net/mac80211/rc80211_minstrel_ht.c7
-rw-r--r--net/mac80211/rx.c24
-rw-r--r--net/mac80211/wep.c8
-rw-r--r--net/wireless/core.c54
-rw-r--r--net/wireless/mlme.c23
-rw-r--r--net/wireless/nl80211.c15
-rw-r--r--net/wireless/radiotap.c58
-rw-r--r--net/wireless/sysfs.c9
-rw-r--r--net/wireless/wext-compat.c4
151 files changed, 5272 insertions, 6383 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index c539910b1f76..476fb3a123ca 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -6461,8 +6461,7 @@ L:	linux-wireless@vger.kernel.org
 W:	http://wireless.kernel.org
 T:	git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-testing.git
 S:	Maintained
-F:	drivers/net/wireless/wl12xx/*
-X:	drivers/net/wireless/wl12xx/wl1271*
+F:	drivers/net/wireless/wl1251/*
 
 WL1271 WIRELESS DRIVER
 M:	Luciano Coelho <luciano.coelho@nokia.com>
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
index 174e3442d519..4de4410cd38e 100644
--- a/drivers/net/wireless/Kconfig
+++ b/drivers/net/wireless/Kconfig
@@ -279,6 +279,7 @@ source "drivers/net/wireless/libertas/Kconfig"
 source "drivers/net/wireless/orinoco/Kconfig"
 source "drivers/net/wireless/p54/Kconfig"
 source "drivers/net/wireless/rt2x00/Kconfig"
+source "drivers/net/wireless/wl1251/Kconfig"
 source "drivers/net/wireless/wl12xx/Kconfig"
 source "drivers/net/wireless/zd1211rw/Kconfig"
 
diff --git a/drivers/net/wireless/Makefile b/drivers/net/wireless/Makefile
index a13a602edb13..06f8ca26c5c1 100644
--- a/drivers/net/wireless/Makefile
+++ b/drivers/net/wireless/Makefile
@@ -49,6 +49,7 @@ obj-$(CONFIG_ATH_COMMON)	+= ath/
 
 obj-$(CONFIG_MAC80211_HWSIM)	+= mac80211_hwsim.o
 
+obj-$(CONFIG_WL1251)	+= wl1251/
 obj-$(CONFIG_WL12XX)	+= wl12xx/
 obj-$(CONFIG_WL12XX_PLATFORM_DATA)	+= wl12xx/
 
diff --git a/drivers/net/wireless/at76c50x-usb.c b/drivers/net/wireless/at76c50x-usb.c
index 91c5f73b5ba3..1476314afa8a 100644
--- a/drivers/net/wireless/at76c50x-usb.c
+++ b/drivers/net/wireless/at76c50x-usb.c
@@ -1525,8 +1525,7 @@ static void at76_rx_tasklet(unsigned long param)
 
 	if (priv->device_unplugged) {
 		at76_dbg(DBG_DEVSTART, "device unplugged");
-		if (urb)
-			at76_dbg(DBG_DEVSTART, "urb status %d", urb->status);
+		at76_dbg(DBG_DEVSTART, "urb status %d", urb->status);
 		return;
 	}
 
diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h
index cee0191704f5..501050c0296f 100644
--- a/drivers/net/wireless/ath/ath.h
+++ b/drivers/net/wireless/ath/ath.h
@@ -19,6 +19,7 @@
 
 #include <linux/skbuff.h>
 #include <linux/if_ether.h>
+#include <linux/spinlock.h>
 #include <net/mac80211.h>
 
 /*
@@ -42,6 +43,13 @@ struct ath_ani {
 	struct timer_list timer;
 };
 
+struct ath_cycle_counters {
+	u32 cycles;
+	u32 rx_busy;
+	u32 rx_frame;
+	u32 tx_frame;
+};
+
 enum ath_device_state {
 	ATH_HW_UNAVAILABLE,
 	ATH_HW_INITIALIZED,
@@ -145,6 +153,12 @@ struct ath_common {
 	DECLARE_BITMAP(tkip_keymap, ATH_KEYMAX);
 	enum ath_crypt_caps crypt_caps;
 
+	unsigned int clockrate;
+
+	spinlock_t cc_lock;
+	struct ath_cycle_counters cc_ani;
+	struct ath_cycle_counters cc_survey;
+
 	struct ath_regulatory regulatory;
 	const struct ath_ops *ops;
 	const struct ath_bus_ops *bus_ops;
@@ -161,5 +175,7 @@ int ath_key_config(struct ath_common *common,
 			  struct ieee80211_sta *sta,
 			  struct ieee80211_key_conf *key);
 bool ath_hw_keyreset(struct ath_common *common, u16 entry);
+void ath_hw_cycle_counters_update(struct ath_common *common);
+int32_t ath_hw_get_listen_time(struct ath_common *common);
 
 #endif /* ATH_H */
diff --git a/drivers/net/wireless/ath/ath5k/ani.c b/drivers/net/wireless/ath/ath5k/ani.c
index e4a5f046bba4..f1419198a479 100644
--- a/drivers/net/wireless/ath/ath5k/ani.c
+++ b/drivers/net/wireless/ath/ath5k/ani.c
@@ -355,41 +355,28 @@ ath5k_ani_lower_immunity(struct ath5k_hw *ah, struct ath5k_ani_state *as)
 
 
 /**
- * ath5k_hw_ani_get_listen_time() - Calculate time spent listening
+ * ath5k_hw_ani_get_listen_time() - Update counters and return listening time
  *
  * Return an approximation of the time spent "listening" in milliseconds (ms)
- * since the last call of this function by deducting the cycles spent
- * transmitting and receiving from the total cycle count.
- * Save profile count values for debugging/statistics and because we might want
- * to use them later.
- *
- * We assume no one else clears these registers!
+ * since the last call of this function.
+ * Save a snapshot of the counter values for debugging/statistics.
  */
 static int
 ath5k_hw_ani_get_listen_time(struct ath5k_hw *ah, struct ath5k_ani_state *as)
 {
+	struct ath_common *common = ath5k_hw_common(ah);
 	int listen;
 
-	/* freeze */
-	ath5k_hw_reg_write(ah, AR5K_MIBC_FMC, AR5K_MIBC);
-	/* read */
-	as->pfc_cycles = ath5k_hw_reg_read(ah, AR5K_PROFCNT_CYCLE);
-	as->pfc_busy = ath5k_hw_reg_read(ah, AR5K_PROFCNT_RXCLR);
-	as->pfc_tx = ath5k_hw_reg_read(ah, AR5K_PROFCNT_TX);
-	as->pfc_rx = ath5k_hw_reg_read(ah, AR5K_PROFCNT_RX);
-	/* clear */
-	ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_TX);
-	ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_RX);
-	ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_RXCLR);
-	ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_CYCLE);
-	/* un-freeze */
-	ath5k_hw_reg_write(ah, 0, AR5K_MIBC);
-
-	/* TODO: where does 44000 come from? (11g clock rate?) */
-	listen = (as->pfc_cycles - as->pfc_rx - as->pfc_tx) / 44000;
-
-	if (as->pfc_cycles == 0 || listen < 0)
-		return 0;
+	spin_lock_bh(&common->cc_lock);
+
+	ath_hw_cycle_counters_update(common);
+	memcpy(&as->last_cc, &common->cc_ani, sizeof(as->last_cc));
+
+	/* clears common->cc_ani */
+	listen = ath_hw_get_listen_time(common);
+
+	spin_unlock_bh(&common->cc_lock);
+
 	return listen;
 }
 
diff --git a/drivers/net/wireless/ath/ath5k/ani.h b/drivers/net/wireless/ath/ath5k/ani.h
index 55cf26d8522c..d0a664039c87 100644
--- a/drivers/net/wireless/ath/ath5k/ani.h
+++ b/drivers/net/wireless/ath/ath5k/ani.h
@@ -75,10 +75,7 @@ struct ath5k_ani_state {
 	unsigned int		cck_errors;
 
 	/* debug/statistics only: numbers from last ANI calibration */
-	unsigned int		pfc_tx;
-	unsigned int		pfc_rx;
-	unsigned int		pfc_busy;
-	unsigned int		pfc_cycles;
+	struct ath_cycle_counters last_cc;
 	unsigned int		last_listen;
 	unsigned int		last_ofdm_errors;
 	unsigned int		last_cck_errors;
diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h
index 0cba2e315d9a..4a367cdb3eb9 100644
--- a/drivers/net/wireless/ath/ath5k/ath5k.h
+++ b/drivers/net/wireless/ath/ath5k/ath5k.h
@@ -1201,7 +1201,7 @@ void ath5k_hw_set_ack_bitrate_high(struct ath5k_hw *ah, bool high);
 /* Clock rate related functions */
 unsigned int ath5k_hw_htoclock(struct ath5k_hw *ah, unsigned int usec);
 unsigned int ath5k_hw_clocktoh(struct ath5k_hw *ah, unsigned int clock);
-unsigned int ath5k_hw_get_clockrate(struct ath5k_hw *ah);
+void ath5k_hw_set_clockrate(struct ath5k_hw *ah);
 
 /* Queue Control Unit, DFS Control Unit Functions */
 int ath5k_hw_get_tx_queueprops(struct ath5k_hw *ah, int queue,
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index dad726585637..f1ae75d35d5d 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -62,6 +62,7 @@
 #include "reg.h"
 #include "debug.h"
 #include "ani.h"
+#include "../debug.h"
 
 static int modparam_nohwcrypt;
 module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO);
@@ -517,12 +518,14 @@ struct ath_vif_iter_data {
 	bool		need_set_hw_addr;
 	bool		found_active;
 	bool		any_assoc;
+	enum nl80211_iftype opmode;
 };
 
 static void ath_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
 {
 	struct ath_vif_iter_data *iter_data = data;
 	int i;
+	struct ath5k_vif *avf = (void *)vif->drv_priv;
 
 	if (iter_data->hw_macaddr)
 		for (i = 0; i < ETH_ALEN; i++)
@@ -539,13 +542,32 @@ static void ath_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
 			iter_data->need_set_hw_addr = false;
 
 	if (!iter_data->any_assoc) {
-		struct ath5k_vif *avf = (void *)vif->drv_priv;
 		if (avf->assoc)
 			iter_data->any_assoc = true;
 	}
+
+	/* Calculate combined mode - when APs are active, operate in AP mode.
+	 * Otherwise use the mode of the new interface. This can currently
+	 * only deal with combinations of APs and STAs. Only one ad-hoc
+	 * interfaces is allowed above.
+	 */
+	if (avf->opmode == NL80211_IFTYPE_AP)
+		iter_data->opmode = NL80211_IFTYPE_AP;
+	else
+		if (iter_data->opmode == NL80211_IFTYPE_UNSPECIFIED)
+			iter_data->opmode = avf->opmode;
 }
 
-void ath5k_update_bssid_mask(struct ath5k_softc *sc, struct ieee80211_vif *vif)
+static void ath_do_set_opmode(struct ath5k_softc *sc)
+{
+	struct ath5k_hw *ah = sc->ah;
+	ath5k_hw_set_opmode(ah, sc->opmode);
+	ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "mode setup opmode %d (%s)\n",
+		  sc->opmode, ath_opmode_to_string(sc->opmode));
+}
+
+void ath5k_update_bssid_mask_and_opmode(struct ath5k_softc *sc,
+					struct ieee80211_vif *vif)
 {
 	struct ath_common *common = ath5k_hw_common(sc->ah);
 	struct ath_vif_iter_data iter_data;
@@ -558,6 +580,7 @@ void ath5k_update_bssid_mask(struct ath5k_softc *sc, struct ieee80211_vif *vif)
 	memset(&iter_data.mask, 0xff, ETH_ALEN);
 	iter_data.found_active = false;
 	iter_data.need_set_hw_addr = true;
+	iter_data.opmode = NL80211_IFTYPE_UNSPECIFIED;
 
 	if (vif)
 		ath_vif_iter(&iter_data, vif->addr, vif);
@@ -567,10 +590,18 @@ void ath5k_update_bssid_mask(struct ath5k_softc *sc, struct ieee80211_vif *vif)
 						   &iter_data);
 	memcpy(sc->bssidmask, iter_data.mask, ETH_ALEN);
 
+	sc->opmode = iter_data.opmode;
+	if (sc->opmode == NL80211_IFTYPE_UNSPECIFIED)
+		/* Nothing active, default to station mode */
+		sc->opmode = NL80211_IFTYPE_STATION;
+
+	ath_do_set_opmode(sc);
+
 	if (iter_data.need_set_hw_addr && iter_data.found_active)
 		ath5k_hw_set_lladdr(sc->ah, iter_data.active_mac);
 
-	ath5k_hw_set_bssid_mask(sc->ah, sc->bssidmask);
+	if (ath5k_hw_hasbssidmask(sc->ah))
+		ath5k_hw_set_bssid_mask(sc->ah, sc->bssidmask);
 }
 
 static void
@@ -582,15 +613,9 @@ ath5k_mode_setup(struct ath5k_softc *sc, struct ieee80211_vif *vif)
 	/* configure rx filter */
 	rfilt = sc->filter_flags;
 	ath5k_hw_set_rx_filter(ah, rfilt);
-
-	if (ath5k_hw_hasbssidmask(ah))
-		ath5k_update_bssid_mask(sc, vif);
-
-	/* configure operational mode */
-	ath5k_hw_set_opmode(ah, sc->opmode);
-
-	ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "mode setup opmode %d\n", sc->opmode);
 	ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "RX filter 0x%x\n", rfilt);
+
+	ath5k_update_bssid_mask_and_opmode(sc, vif);
 }
 
 static inline int
@@ -2688,7 +2713,7 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw)
 	SET_IEEE80211_PERM_ADDR(hw, mac);
 	memcpy(&sc->lladdr, mac, ETH_ALEN);
 	/* All MAC address bits matter for ACKs */
-	ath5k_update_bssid_mask(sc, NULL);
+	ath5k_update_bssid_mask_and_opmode(sc, NULL);
 
 	regulatory->current_rd = ah->ah_capabilities.cap_eeprom.ee_regdomain;
 	ret = ath_regd_init(regulatory, hw->wiphy, ath5k_reg_notifier);
@@ -2786,7 +2811,6 @@ static int ath5k_add_interface(struct ieee80211_hw *hw,
 {
 	struct ath5k_softc *sc = hw->priv;
 	int ret;
-	struct ath5k_hw *ah = sc->ah;
 	struct ath5k_vif *avf = (void *)vif->drv_priv;
 
 	mutex_lock(&sc->lock);
@@ -2850,18 +2874,6 @@ static int ath5k_add_interface(struct ieee80211_hw *hw,
 			sc->num_adhoc_vifs++;
 	}
 
-	/* Set combined mode - when APs are configured, operate in AP mode.
-	 * Otherwise use the mode of the new interface. This can currently
-	 * only deal with combinations of APs and STAs. Only one ad-hoc
-	 * interfaces is allowed above.
-	 */
-	if (sc->num_ap_vifs)
-		sc->opmode = NL80211_IFTYPE_AP;
-	else
-		sc->opmode = vif->type;
-
-	ath5k_hw_set_opmode(ah, sc->opmode);
-
 	/* Any MAC address is fine, all others are included through the
 	 * filter.
 	 */
@@ -2905,7 +2917,7 @@ ath5k_remove_interface(struct ieee80211_hw *hw,
 	else if (avf->opmode == NL80211_IFTYPE_ADHOC)
 		sc->num_adhoc_vifs--;
 
-	ath5k_update_bssid_mask(sc, NULL);
+	ath5k_update_bssid_mask_and_opmode(sc, NULL);
 	mutex_unlock(&sc->lock);
 }
 
@@ -3529,8 +3541,6 @@ ath5k_pci_probe(struct pci_dev *pdev,
 	sc->hw = hw;
 	sc->pdev = pdev;
 
-	ath5k_debug_init_device(sc);
-
 	/*
 	 * Mark the device as detached to avoid processing
 	 * interrupts until setup is complete.
@@ -3638,6 +3648,7 @@ ath5k_pci_probe(struct pci_dev *pdev,
 		}
 	}
 
+	ath5k_debug_init_device(sc);
 
 	/* ready to process interrupts */
 	__clear_bit(ATH_STAT_INVALID, sc->status);
@@ -3724,8 +3735,6 @@ init_ath5k_pci(void)
 {
 	int ret;
 
-	ath5k_debug_init();
-
 	ret = pci_register_driver(&ath5k_pci_driver);
 	if (ret) {
 		printk(KERN_ERR "ath5k_pci: can't register pci driver\n");
@@ -3739,8 +3748,6 @@ static void __exit
 exit_ath5k_pci(void)
 {
 	pci_unregister_driver(&ath5k_pci_driver);
-
-	ath5k_debug_finish();
 }
 
 module_init(init_ath5k_pci);
diff --git a/drivers/net/wireless/ath/ath5k/debug.c b/drivers/net/wireless/ath/ath5k/debug.c
index c2d549f871f9..42ea5b1bdb12 100644
--- a/drivers/net/wireless/ath/ath5k/debug.c
+++ b/drivers/net/wireless/ath/ath5k/debug.c
@@ -60,6 +60,7 @@
 
 #include "base.h"
 #include "debug.h"
+#include "../debug.h"
 
 static unsigned int ath5k_debug;
 module_param_named(debug, ath5k_debug, uint, 0);
@@ -71,8 +72,6 @@ module_param_named(debug, ath5k_debug, uint, 0);
 #include "reg.h"
 #include "ani.h"
 
-static struct dentry *ath5k_global_debugfs;
-
 static int ath5k_debugfs_open(struct inode *inode, struct file *file)
 {
 	file->private_data = inode->i_private;
@@ -520,9 +519,10 @@ static ssize_t read_file_misc(struct file *file, char __user *user_buf,
 	if (filt & AR5K_RX_FILTER_PHYERR_5211)
 		snprintf(buf+len, sizeof(buf)-len, " PHYERR-5211");
 	if (filt & AR5K_RX_FILTER_RADARERR_5211)
-		len += snprintf(buf+len, sizeof(buf)-len, " RADARERR-5211\n");
-	else
-		len += snprintf(buf+len, sizeof(buf)-len, "\n");
+		len += snprintf(buf+len, sizeof(buf)-len, " RADARERR-5211");
+
+	len += snprintf(buf+len, sizeof(buf)-len, "\nopmode: %s (%d)\n",
+			ath_opmode_to_string(sc->opmode), sc->opmode);
 
 	if (len > sizeof(buf))
 		len = sizeof(buf);
@@ -715,20 +715,21 @@ static ssize_t read_file_ani(struct file *file, char __user *user_buf,
 	len += snprintf(buf+len, sizeof(buf)-len,
 			"beacon RSSI average:\t%d\n",
 			sc->ah->ah_beacon_rssi_avg.avg);
+
+#define CC_PRINT(_struct, _field) \
+	_struct._field, \
+	_struct.cycles > 0 ? \
+	_struct._field*100/_struct.cycles : 0
+
 	len += snprintf(buf+len, sizeof(buf)-len, "profcnt tx\t\t%u\t(%d%%)\n",
-			as->pfc_tx,
-			as->pfc_cycles > 0 ?
-			as->pfc_tx*100/as->pfc_cycles : 0);
+			CC_PRINT(as->last_cc, tx_frame));
 	len += snprintf(buf+len, sizeof(buf)-len, "profcnt rx\t\t%u\t(%d%%)\n",
-			as->pfc_rx,
-			as->pfc_cycles > 0 ?
-			as->pfc_rx*100/as->pfc_cycles : 0);
+			CC_PRINT(as->last_cc, rx_frame));
 	len += snprintf(buf+len, sizeof(buf)-len, "profcnt busy\t\t%u\t(%d%%)\n",
-			as->pfc_busy,
-			as->pfc_cycles > 0 ?
-			as->pfc_busy*100/as->pfc_cycles : 0);
+			CC_PRINT(as->last_cc, rx_busy));
+#undef CC_PRINT
 	len += snprintf(buf+len, sizeof(buf)-len, "profcnt cycles\t\t%u\n",
-			as->pfc_cycles);
+			as->last_cc.cycles);
 	len += snprintf(buf+len, sizeof(buf)-len,
 			"listen time\t\t%d\tlast: %d\n",
 			as->listen_time, as->last_listen);
@@ -879,21 +880,13 @@ static const struct file_operations fops_queue = {
 };
 
 
-/* init */
-
-void
-ath5k_debug_init(void)
-{
-	ath5k_global_debugfs = debugfs_create_dir("ath5k", NULL);
-}
-
 void
 ath5k_debug_init_device(struct ath5k_softc *sc)
 {
 	sc->debug.level = ath5k_debug;
 
-	sc->debug.debugfs_phydir = debugfs_create_dir(wiphy_name(sc->hw->wiphy),
-				ath5k_global_debugfs);
+	sc->debug.debugfs_phydir = debugfs_create_dir("ath5k",
+				sc->hw->wiphy->debugfsdir);
 
 	sc->debug.debugfs_debug = debugfs_create_file("debug",
 				S_IWUSR | S_IRUSR,
@@ -934,12 +927,6 @@ ath5k_debug_init_device(struct ath5k_softc *sc)
 }
 
 void
-ath5k_debug_finish(void)
-{
-	debugfs_remove(ath5k_global_debugfs);
-}
-
-void
 ath5k_debug_finish_device(struct ath5k_softc *sc)
 {
 	debugfs_remove(sc->debug.debugfs_debug);
diff --git a/drivers/net/wireless/ath/ath5k/debug.h b/drivers/net/wireless/ath/ath5k/debug.h
index 4f078b134015..236edbd2507d 100644
--- a/drivers/net/wireless/ath/ath5k/debug.h
+++ b/drivers/net/wireless/ath/ath5k/debug.h
@@ -138,15 +138,9 @@ enum ath5k_debug_level {
 	} while (0)
 
 void
-ath5k_debug_init(void);
-
-void
 ath5k_debug_init_device(struct ath5k_softc *sc);
 
 void
-ath5k_debug_finish(void);
-
-void
 ath5k_debug_finish_device(struct ath5k_softc *sc);
 
 void
@@ -174,15 +168,9 @@ ATH5K_DBG_UNLIMIT(struct ath5k_softc *sc, unsigned int m, const char *fmt, ...)
 {}
 
 static inline void
-ath5k_debug_init(void) {}
-
-static inline void
 ath5k_debug_init_device(struct ath5k_softc *sc) {}
 
 static inline void
-ath5k_debug_finish(void) {}
-
-static inline void
 ath5k_debug_finish_device(struct ath5k_softc *sc) {}
 
 static inline void
diff --git a/drivers/net/wireless/ath/ath5k/pcu.c b/drivers/net/wireless/ath/ath5k/pcu.c
index 095d30b50ec7..074b4c644399 100644
--- a/drivers/net/wireless/ath/ath5k/pcu.c
+++ b/drivers/net/wireless/ath/ath5k/pcu.c
@@ -207,7 +207,8 @@ static int ath5k_hw_set_cts_timeout(struct ath5k_hw *ah, unsigned int timeout)
  */
 unsigned int ath5k_hw_htoclock(struct ath5k_hw *ah, unsigned int usec)
 {
-	return usec * ath5k_hw_get_clockrate(ah);
+	struct ath_common *common = ath5k_hw_common(ah);
+	return usec * common->clockrate;
 }
 
 /**
@@ -216,17 +217,19 @@ unsigned int ath5k_hw_htoclock(struct ath5k_hw *ah, unsigned int usec)
  */
 unsigned int ath5k_hw_clocktoh(struct ath5k_hw *ah, unsigned int clock)
 {
-	return clock / ath5k_hw_get_clockrate(ah);
+	struct ath_common *common = ath5k_hw_common(ah);
+	return clock / common->clockrate;
 }
 
 /**
- * ath5k_hw_get_clockrate - Get the clock rate for current mode
+ * ath5k_hw_set_clockrate - Set common->clockrate for the current channel
  *
  * @ah: The &struct ath5k_hw
  */
-unsigned int ath5k_hw_get_clockrate(struct ath5k_hw *ah)
+void ath5k_hw_set_clockrate(struct ath5k_hw *ah)
 {
 	struct ieee80211_channel *channel = ah->ah_current_channel;
+	struct ath_common *common = ath5k_hw_common(ah);
 	int clock;
 
 	if (channel->hw_value & CHANNEL_5GHZ)
@@ -240,7 +243,7 @@ unsigned int ath5k_hw_get_clockrate(struct ath5k_hw *ah)
 	if (channel->hw_value & CHANNEL_TURBO)
 		clock *= 2;
 
-	return clock;
+	common->clockrate = clock;
 }
 
 /**
diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c
index 61da913e7c8f..219367884e64 100644
--- a/drivers/net/wireless/ath/ath5k/phy.c
+++ b/drivers/net/wireless/ath/ath5k/phy.c
@@ -1093,6 +1093,7 @@ int ath5k_hw_channel(struct ath5k_hw *ah, struct ieee80211_channel *channel)
 
 	ah->ah_current_channel = channel;
 	ah->ah_turbo = channel->hw_value == CHANNEL_T ? true : false;
+	ath5k_hw_set_clockrate(ah);
 
 	return 0;
 }
diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c
index f2a907b4acb8..63ccb39cdcd4 100644
--- a/drivers/net/wireless/ath/ath9k/ani.c
+++ b/drivers/net/wireless/ath/ath9k/ani.c
@@ -465,40 +465,6 @@ static void ath9k_hw_ani_lower_immunity(struct ath_hw *ah)
 		ath9k_hw_set_cck_nil(ah, aniState->cckNoiseImmunityLevel - 1);
 }
 
-static u8 ath9k_hw_chan_2_clockrate_mhz(struct ath_hw *ah)
-{
-	struct ath9k_channel *chan = ah->curchan;
-	struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;
-	u8 clockrate; /* in MHz */
-
-	if (!ah->curchan) /* should really check for CCK instead */
-		clockrate = ATH9K_CLOCK_RATE_CCK;
-	else if (conf->channel->band == IEEE80211_BAND_2GHZ)
-		clockrate = ATH9K_CLOCK_RATE_2GHZ_OFDM;
-	else if (IS_CHAN_A_FAST_CLOCK(ah, chan))
-		clockrate = ATH9K_CLOCK_FAST_RATE_5GHZ_OFDM;
-	else
-		clockrate = ATH9K_CLOCK_RATE_5GHZ_OFDM;
-
-	if (conf_is_ht40(conf))
-		return clockrate * 2;
-
-	return clockrate;
-}
-
-static int32_t ath9k_hw_ani_get_listen_time(struct ath_hw *ah)
-{
-	int32_t listen_time;
-	int32_t clock_rate;
-
-	ath9k_hw_update_cycle_counters(ah);
-	clock_rate = ath9k_hw_chan_2_clockrate_mhz(ah) * 1000;
-	listen_time = ah->listen_time / clock_rate;
-	ah->listen_time = 0;
-
-	return listen_time;
-}
-
 static void ath9k_ani_reset_old(struct ath_hw *ah, bool is_scanning)
 {
 	struct ar5416AniState *aniState;
@@ -667,7 +633,7 @@ void ath9k_ani_reset(struct ath_hw *ah, bool is_scanning)
 	REGWRITE_BUFFER_FLUSH(ah);
 }
 
-static void ath9k_hw_ani_read_counters(struct ath_hw *ah)
+static bool ath9k_hw_ani_read_counters(struct ath_hw *ah)
 {
 	struct ath_common *common = ath9k_hw_common(ah);
 	struct ar5416AniState *aniState = &ah->curchan->ani;
@@ -677,11 +643,13 @@ static void ath9k_hw_ani_read_counters(struct ath_hw *ah)
 	u32 phyCnt1, phyCnt2;
 	int32_t listenTime;
 
-	listenTime = ath9k_hw_ani_get_listen_time(ah);
-	if (listenTime < 0) {
+	ath_hw_cycle_counters_update(common);
+	listenTime = ath_hw_get_listen_time(common);
+
+	if (listenTime <= 0) {
 		ah->stats.ast_ani_lneg++;
 		ath9k_ani_restart(ah);
-		return;
+		return false;
 	}
 
 	if (!use_new_ani(ah)) {
@@ -696,7 +664,7 @@ static void ath9k_hw_ani_read_counters(struct ath_hw *ah)
 	phyCnt1 = REG_READ(ah, AR_PHY_ERR_1);
 	phyCnt2 = REG_READ(ah, AR_PHY_ERR_2);
 
-	if (use_new_ani(ah) && (phyCnt1 < ofdm_base || phyCnt2 < cck_base)) {
+	if (!use_new_ani(ah) && (phyCnt1 < ofdm_base || phyCnt2 < cck_base)) {
 		if (phyCnt1 < ofdm_base) {
 			ath_print(common, ATH_DBG_ANI,
 				  "phyCnt1 0x%x, resetting "
@@ -715,7 +683,7 @@ static void ath9k_hw_ani_read_counters(struct ath_hw *ah)
 			REG_WRITE(ah, AR_PHY_ERR_MASK_2,
 				  AR_PHY_ERR_CCK_TIMING);
 		}
-		return;
+		return false;
 	}
 
 	ofdmPhyErrCnt = phyCnt1 - ofdm_base;
@@ -727,7 +695,7 @@ static void ath9k_hw_ani_read_counters(struct ath_hw *ah)
 	ah->stats.ast_ani_cckerrs +=
 		cckPhyErrCnt - aniState->cckPhyErrCount;
 	aniState->cckPhyErrCount = cckPhyErrCnt;
-
+	return true;
 }
 
 void ath9k_hw_ani_monitor(struct ath_hw *ah, struct ath9k_channel *chan)
@@ -743,7 +711,8 @@ void ath9k_hw_ani_monitor(struct ath_hw *ah, struct ath9k_channel *chan)
 	if (WARN_ON(!aniState))
 		return;
 
-	ath9k_hw_ani_read_counters(ah);
+	if (!ath9k_hw_ani_read_counters(ah))
+		return;
 
 	ofdmPhyErrRate = aniState->ofdmPhyErrCount * 1000 /
 			 aniState->listenTime;
@@ -818,54 +787,6 @@ void ath9k_hw_disable_mib_counters(struct ath_hw *ah)
 }
 EXPORT_SYMBOL(ath9k_hw_disable_mib_counters);
 
-void ath9k_hw_update_cycle_counters(struct ath_hw *ah)
-{
-	struct ath_cycle_counters cc;
-	bool clear;
-
-	memcpy(&cc, &ah->cc, sizeof(cc));
-
-	/* freeze counters */
-	REG_WRITE(ah, AR_MIBC, AR_MIBC_FMC);
-
-	ah->cc.cycles = REG_READ(ah, AR_CCCNT);
-	if (ah->cc.cycles < cc.cycles) {
-		clear = true;
-		goto skip;
-	}
-
-	ah->cc.rx_clear = REG_READ(ah, AR_RCCNT);
-	ah->cc.rx_frame = REG_READ(ah, AR_RFCNT);
-	ah->cc.tx_frame = REG_READ(ah, AR_TFCNT);
-
-	/* prevent wraparound */
-	if (ah->cc.cycles & BIT(31))
-		clear = true;
-
-#define CC_DELTA(_field, _reg) ah->cc_delta._field += ah->cc._field - cc._field
-	CC_DELTA(cycles, AR_CCCNT);
-	CC_DELTA(rx_frame, AR_RFCNT);
-	CC_DELTA(rx_clear, AR_RCCNT);
-	CC_DELTA(tx_frame, AR_TFCNT);
-#undef CC_DELTA
-
-	ah->listen_time += (ah->cc.cycles - cc.cycles) -
-		 ((ah->cc.rx_frame - cc.rx_frame) +
-		  (ah->cc.tx_frame - cc.tx_frame));
-
-skip:
-	if (clear) {
-		REG_WRITE(ah, AR_CCCNT, 0);
-		REG_WRITE(ah, AR_RFCNT, 0);
-		REG_WRITE(ah, AR_RCCNT, 0);
-		REG_WRITE(ah, AR_TFCNT, 0);
-		memset(&ah->cc, 0, sizeof(ah->cc));
-	}
-
-	/* unfreeze counters */
-	REG_WRITE(ah, AR_MIBC, 0);
-}
-
 /*
  * Process a MIB interrupt.  We may potentially be invoked because
  * any of the MIB counters overflow/trigger so don't assume we're
diff --git a/drivers/net/wireless/ath/ath9k/ani.h b/drivers/net/wireless/ath/ath9k/ani.h
index 98cfd8154c71..0cd6783de883 100644
--- a/drivers/net/wireless/ath/ath9k/ani.h
+++ b/drivers/net/wireless/ath/ath9k/ani.h
@@ -93,13 +93,6 @@ struct ath9k_mib_stats {
 	u32 beacons;
 };
 
-struct ath_cycle_counters {
-	u32 cycles;
-	u32 rx_frame;
-	u32 rx_clear;
-	u32 tx_frame;
-};
-
 /* INI default values for ANI registers */
 struct ath9k_ani_default {
 	u16 m1ThreshLow;
@@ -164,7 +157,6 @@ struct ar5416Stats {
 
 void ath9k_enable_mib_counters(struct ath_hw *ah);
 void ath9k_hw_disable_mib_counters(struct ath_hw *ah);
-void ath9k_hw_update_cycle_counters(struct ath_hw *ah);
 void ath9k_hw_ani_setup(struct ath_hw *ah);
 void ath9k_hw_ani_init(struct ath_hw *ah);
 int ath9k_hw_get_ani_channel_idx(struct ath_hw *ah,
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_2p0_initvals.h b/drivers/net/wireless/ath/ath9k/ar9003_2p0_initvals.h
deleted file mode 100644
index d3375fc4ce8b..000000000000
--- a/drivers/net/wireless/ath/ath9k/ar9003_2p0_initvals.h
+++ /dev/null
@@ -1,1784 +0,0 @@
-/*
- * 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_2P0_H
-#define INITVALS_9003_2P0_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},
-	{0x00016140, 0x10804008, 0x10804008, 0x50804008, 0x50804008},
-	{0x0001650c, 0x08000000, 0x00000000, 0x00000000, 0x00000000},
-	{0x00016540, 0x10804008, 0x10804008, 0x50804008, 0x50804008},
-	{0x0001690c, 0x08000000, 0x00000000, 0x00000000, 0x00000000},
-	{0x00016940, 0x10804008, 0x10804008, 0x50804008, 0x50804008},
-};
-
-static const u32 ar9300Modes_lowest_ob_db_tx_gain_table_2p0[][5] = {
-	/* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
-	{0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9},
-	{0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
-	{0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002},
-	{0x0000a508, 0x0a000020, 0x0a000020, 0x08000004, 0x08000004},
-	{0x0000a50c, 0x10000023, 0x10000023, 0x0b000200, 0x0b000200},
-	{0x0000a510, 0x16000220, 0x16000220, 0x0f000202, 0x0f000202},
-	{0x0000a514, 0x1c000223, 0x1c000223, 0x12000400, 0x12000400},
-	{0x0000a518, 0x21020220, 0x21020220, 0x16000402, 0x16000402},
-	{0x0000a51c, 0x27020223, 0x27020223, 0x19000404, 0x19000404},
-	{0x0000a520, 0x2b022220, 0x2b022220, 0x1c000603, 0x1c000603},
-	{0x0000a524, 0x2f022222, 0x2f022222, 0x21000a02, 0x21000a02},
-	{0x0000a528, 0x34022225, 0x34022225, 0x25000a04, 0x25000a04},
-	{0x0000a52c, 0x3a02222a, 0x3a02222a, 0x28000a20, 0x28000a20},
-	{0x0000a530, 0x3e02222c, 0x3e02222c, 0x2c000e20, 0x2c000e20},
-	{0x0000a534, 0x4202242a, 0x4202242a, 0x30000e22, 0x30000e22},
-	{0x0000a538, 0x4702244a, 0x4702244a, 0x34000e24, 0x34000e24},
-	{0x0000a53c, 0x4b02244c, 0x4b02244c, 0x38001640, 0x38001640},
-	{0x0000a540, 0x4e02246c, 0x4e02246c, 0x3c001660, 0x3c001660},
-	{0x0000a544, 0x5302266c, 0x5302266c, 0x3f001861, 0x3f001861},
-	{0x0000a548, 0x5702286c, 0x5702286c, 0x43001a81, 0x43001a81},
-	{0x0000a54c, 0x5c04286b, 0x5c04286b, 0x47001a83, 0x47001a83},
-	{0x0000a550, 0x61042a6c, 0x61042a6c, 0x4a001c84, 0x4a001c84},
-	{0x0000a554, 0x66062a6c, 0x66062a6c, 0x4e001ce3, 0x4e001ce3},
-	{0x0000a558, 0x6b062e6c, 0x6b062e6c, 0x52001ce5, 0x52001ce5},
-	{0x0000a55c, 0x7006308c, 0x7006308c, 0x56001ce9, 0x56001ce9},
-	{0x0000a560, 0x730a308a, 0x730a308a, 0x5a001ceb, 0x5a001ceb},
-	{0x0000a564, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
-	{0x0000a568, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
-	{0x0000a56c, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
-	{0x0000a570, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
-	{0x0000a574, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
-	{0x0000a578, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
-	{0x0000a57c, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
-	{0x0000a580, 0x00800000, 0x00800000, 0x00800000, 0x00800000},
-	{0x0000a584, 0x06800003, 0x06800003, 0x04800002, 0x04800002},
-	{0x0000a588, 0x0a800020, 0x0a800020, 0x08800004, 0x08800004},
-	{0x0000a58c, 0x10800023, 0x10800023, 0x0b800200, 0x0b800200},
-	{0x0000a590, 0x16800220, 0x16800220, 0x0f800202, 0x0f800202},
-	{0x0000a594, 0x1c800223, 0x1c800223, 0x12800400, 0x12800400},
-	{0x0000a598, 0x21820220, 0x21820220, 0x16800402, 0x16800402},
-	{0x0000a59c, 0x27820223, 0x27820223, 0x19800404, 0x19800404},
-	{0x0000a5a0, 0x2b822220, 0x2b822220, 0x1c800603, 0x1c800603},
-	{0x0000a5a4, 0x2f822222, 0x2f822222, 0x21800a02, 0x21800a02},
-	{0x0000a5a8, 0x34822225, 0x34822225, 0x25800a04, 0x25800a04},
-	{0x0000a5ac, 0x3a82222a, 0x3a82222a, 0x28800a20, 0x28800a20},
-	{0x0000a5b0, 0x3e82222c, 0x3e82222c, 0x2c800e20, 0x2c800e20},
-	{0x0000a5b4, 0x4282242a, 0x4282242a, 0x30800e22, 0x30800e22},
-	{0x0000a5b8, 0x4782244a, 0x4782244a, 0x34800e24, 0x34800e24},
-	{0x0000a5bc, 0x4b82244c, 0x4b82244c, 0x38801640, 0x38801640},
-	{0x0000a5c0, 0x4e82246c, 0x4e82246c, 0x3c801660, 0x3c801660},
-	{0x0000a5c4, 0x5382266c, 0x5382266c, 0x3f801861, 0x3f801861},
-	{0x0000a5c8, 0x5782286c, 0x5782286c, 0x43801a81, 0x43801a81},
-	{0x0000a5cc, 0x5c84286b, 0x5c84286b, 0x47801a83, 0x47801a83},
-	{0x0000a5d0, 0x61842a6c, 0x61842a6c, 0x4a801c84, 0x4a801c84},
-	{0x0000a5d4, 0x66862a6c, 0x66862a6c, 0x4e801ce3, 0x4e801ce3},
-	{0x0000a5d8, 0x6b862e6c, 0x6b862e6c, 0x52801ce5, 0x52801ce5},
-	{0x0000a5dc, 0x7086308c, 0x7086308c, 0x56801ce9, 0x56801ce9},
-	{0x0000a5e0, 0x738a308a, 0x738a308a, 0x5a801ceb, 0x5a801ceb},
-	{0x0000a5e4, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
-	{0x0000a5e8, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
-	{0x0000a5ec, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
-	{0x0000a5f0, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
-	{0x0000a5f4, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
-	{0x0000a5f8, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
-	{0x0000a5fc, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
-	{0x00016044, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
-	{0x00016048, 0x62480001, 0x62480001, 0x62480001, 0x62480001},
-	{0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
-	{0x00016444, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
-	{0x00016448, 0x62480001, 0x62480001, 0x62480001, 0x62480001},
-	{0x00016468, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
-	{0x00016844, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
-	{0x00016848, 0x62480001, 0x62480001, 0x62480001, 0x62480001},
-	{0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
-};
-
-static const u32 ar9300Modes_fast_clock_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, 0x13449440},
-	{0x00016058, 0x0c51c92c},
-	{0x0001605c, 0x3db7fffc},
-	{0x00016060, 0xfffffffc},
-	{0x00016064, 0x000f0278},
-	{0x0001606c, 0x6db60000},
-	{0x00016080, 0x00000000},
-	{0x00016084, 0x0e48048c},
-	{0x00016088, 0x54214514},
-	{0x0001608c, 0x119f481e},
-	{0x00016090, 0x24926490},
-	{0x00016098, 0xd2888888},
-	{0x000160a0, 0x0a108ffe},
-	{0x000160a4, 0x812fc370},
-	{0x000160a8, 0x423c8000},
-	{0x000160b4, 0x92480080},
-	{0x000160c0, 0x00adb6d0},
-	{0x000160c4, 0x6db6db60},
-	{0x000160c8, 0x6db6db6c},
-	{0x000160cc, 0x01e6c000},
-	{0x00016100, 0x3fffbe01},
-	{0x00016104, 0xfff80000},
-	{0x00016108, 0x00080010},
-	{0x00016144, 0x02084080},
-	{0x00016148, 0x00000000},
-	{0x00016280, 0x058a0001},
-	{0x00016284, 0x3d840208},
-	{0x00016288, 0x05a20408},
-	{0x0001628c, 0x00038c07},
-	{0x00016290, 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, 0x13449440},
-	{0x00016458, 0x0c51c92c},
-	{0x0001645c, 0x3db7fffc},
-	{0x00016460, 0xfffffffc},
-	{0x00016464, 0x000f0278},
-	{0x0001646c, 0x6db60000},
-	{0x00016500, 0x3fffbe01},
-	{0x00016504, 0xfff80000},
-	{0x00016508, 0x00080010},
-	{0x00016544, 0x02084080},
-	{0x00016548, 0x00000000},
-	{0x00016780, 0x00000000},
-	{0x00016784, 0x00000000},
-	{0x00016788, 0x00800700},
-	{0x0001678c, 0x00800700},
-	{0x00016790, 0x00800700},
-	{0x00016794, 0x00000000},
-	{0x00016798, 0x00000000},
-	{0x0001679c, 0x00000000},
-	{0x000167a0, 0x00000001},
-	{0x000167a4, 0x00000001},
-	{0x000167a8, 0x00000000},
-	{0x000167ac, 0x00000000},
-	{0x000167b0, 0x00000000},
-	{0x000167b4, 0x00000000},
-	{0x000167b8, 0x00000000},
-	{0x000167bc, 0x00000000},
-	{0x000167c0, 0x000000a0},
-	{0x000167c4, 0x000c0000},
-	{0x000167c8, 0x14021402},
-	{0x000167cc, 0x00001402},
-	{0x000167d0, 0x00000000},
-	{0x000167d4, 0x00000000},
-	{0x00016800, 0x36db6db6},
-	{0x00016804, 0x6db6db40},
-	{0x00016808, 0x73f00000},
-	{0x0001680c, 0x00000000},
-	{0x00016840, 0x7f80fff8},
-	{0x0001684c, 0x76d005b5},
-	{0x00016850, 0x556cf031},
-	{0x00016854, 0x13449440},
-	{0x00016858, 0x0c51c92c},
-	{0x0001685c, 0x3db7fffc},
-	{0x00016860, 0xfffffffc},
-	{0x00016864, 0x000f0278},
-	{0x0001686c, 0x6db60000},
-	{0x00016900, 0x3fffbe01},
-	{0x00016904, 0xfff80000},
-	{0x00016908, 0x00080010},
-	{0x00016944, 0x02084080},
-	{0x00016948, 0x00000000},
-	{0x00016b80, 0x00000000},
-	{0x00016b84, 0x00000000},
-	{0x00016b88, 0x00800700},
-	{0x00016b8c, 0x00800700},
-	{0x00016b90, 0x00800700},
-	{0x00016b94, 0x00000000},
-	{0x00016b98, 0x00000000},
-	{0x00016b9c, 0x00000000},
-	{0x00016ba0, 0x00000001},
-	{0x00016ba4, 0x00000001},
-	{0x00016ba8, 0x00000000},
-	{0x00016bac, 0x00000000},
-	{0x00016bb0, 0x00000000},
-	{0x00016bb4, 0x00000000},
-	{0x00016bb8, 0x00000000},
-	{0x00016bbc, 0x00000000},
-	{0x00016bc0, 0x000000a0},
-	{0x00016bc4, 0x000c0000},
-	{0x00016bc8, 0x14021402},
-	{0x00016bcc, 0x00001402},
-	{0x00016bd0, 0x00000000},
-	{0x00016bd4, 0x00000000},
-};
-
-static const u32 ar9300Common_rx_gain_table_merlin_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, 0x00000023, 0x00000023},
-};
-
-static const u32 ar9200_merlin_2p0_radio_core[][2] = {
-	/* Addr      allmodes  */
-	{0x00007800, 0x00040000},
-	{0x00007804, 0xdb005012},
-	{0x00007808, 0x04924914},
-	{0x0000780c, 0x21084210},
-	{0x00007810, 0x6d801300},
-	{0x00007814, 0x0019beff},
-	{0x00007818, 0x07e41000},
-	{0x0000781c, 0x00392000},
-	{0x00007820, 0x92592480},
-	{0x00007824, 0x00040000},
-	{0x00007828, 0xdb005012},
-	{0x0000782c, 0x04924914},
-	{0x00007830, 0x21084210},
-	{0x00007834, 0x6d801300},
-	{0x00007838, 0x0019beff},
-	{0x0000783c, 0x07e40000},
-	{0x00007840, 0x00392000},
-	{0x00007844, 0x92592480},
-	{0x00007848, 0x00100000},
-	{0x0000784c, 0x773f0567},
-	{0x00007850, 0x54214514},
-	{0x00007854, 0x12035828},
-	{0x00007858, 0x92592692},
-	{0x0000785c, 0x00000000},
-	{0x00007860, 0x56400000},
-	{0x00007864, 0x0a8e370e},
-	{0x00007868, 0xc0102850},
-	{0x0000786c, 0x812d4000},
-	{0x00007870, 0x807ec400},
-	{0x00007874, 0x001b6db0},
-	{0x00007878, 0x00376b63},
-	{0x0000787c, 0x06db6db6},
-	{0x00007880, 0x006d8000},
-	{0x00007884, 0xffeffffe},
-	{0x00007888, 0xffeffffe},
-	{0x0000788c, 0x00010000},
-	{0x00007890, 0x02060aeb},
-	{0x00007894, 0x5a108000},
-};
-
-static const u32 ar9300_2p0_baseband_postamble[][5] = {
-	/* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
-	{0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8011, 0xd00a8011},
-	{0x00009820, 0x206a022e, 0x206a022e, 0x206a012e, 0x206a012e},
-	{0x00009824, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0},
-	{0x00009828, 0x06903081, 0x06903081, 0x06903881, 0x06903881},
-	{0x0000982c, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4},
-	{0x00009830, 0x0000059c, 0x0000059c, 0x0000119c, 0x0000119c},
-	{0x00009c00, 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, 0x02291e27, 0x02291e27},
-	{0x00009e48, 0x5030201a, 0x5030201a, 0x50302012, 0x50302012},
-	{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, 0x0038230c},
-	{0x00009e24, 0x990bb515},
-	{0x00009e28, 0x0c6f0000},
-	{0x00009e30, 0x06336f77},
-	{0x00009e34, 0x6af6532f},
-	{0x00009e38, 0x0cc80c00},
-	{0x00009e3c, 0xcf946222},
-	{0x00009e40, 0x0d261820},
-	{0x00009e4c, 0x00001004},
-	{0x00009e50, 0x00ff03f1},
-	{0x00009e54, 0x00000000},
-	{0x00009fc0, 0x803e4788},
-	{0x00009fc4, 0x0001efb5},
-	{0x00009fcc, 0x40000014},
-	{0x00009fd0, 0x01193b93},
-	{0x0000a20c, 0x00000000},
-	{0x0000a220, 0x00000000},
-	{0x0000a224, 0x00000000},
-	{0x0000a228, 0x10002310},
-	{0x0000a22c, 0x01036a1e},
-	{0x0000a234, 0x10000fff},
-	{0x0000a23c, 0x00000000},
-	{0x0000a244, 0x0c000000},
-	{0x0000a2a0, 0x00000001},
-	{0x0000a2c0, 0x00000001},
-	{0x0000a2c8, 0x00000000},
-	{0x0000a2cc, 0x18c43433},
-	{0x0000a2d4, 0x00000000},
-	{0x0000a2dc, 0x00000000},
-	{0x0000a2e0, 0x00000000},
-	{0x0000a2e4, 0x00000000},
-	{0x0000a2e8, 0x00000000},
-	{0x0000a2ec, 0x00000000},
-	{0x0000a2f0, 0x00000000},
-	{0x0000a2f4, 0x00000000},
-	{0x0000a2f8, 0x00000000},
-	{0x0000a344, 0x00000000},
-	{0x0000a34c, 0x00000000},
-	{0x0000a350, 0x0000a000},
-	{0x0000a364, 0x00000000},
-	{0x0000a370, 0x00000000},
-	{0x0000a390, 0x00000001},
-	{0x0000a394, 0x00000444},
-	{0x0000a398, 0x001f0e0f},
-	{0x0000a39c, 0x0075393f},
-	{0x0000a3a0, 0xb79f6427},
-	{0x0000a3a4, 0x00000000},
-	{0x0000a3a8, 0xaaaaaaaa},
-	{0x0000a3ac, 0x3c466478},
-	{0x0000a3c0, 0x20202020},
-	{0x0000a3c4, 0x22222220},
-	{0x0000a3c8, 0x20200020},
-	{0x0000a3cc, 0x20202020},
-	{0x0000a3d0, 0x20202020},
-	{0x0000a3d4, 0x20202020},
-	{0x0000a3d8, 0x20202020},
-	{0x0000a3dc, 0x20202020},
-	{0x0000a3e0, 0x20202020},
-	{0x0000a3e4, 0x20202020},
-	{0x0000a3e8, 0x20202020},
-	{0x0000a3ec, 0x20202020},
-	{0x0000a3f0, 0x00000000},
-	{0x0000a3f4, 0x00000246},
-	{0x0000a3f8, 0x0cdbd380},
-	{0x0000a3fc, 0x000f0f01},
-	{0x0000a400, 0x8fa91f01},
-	{0x0000a404, 0x00000000},
-	{0x0000a408, 0x0e79e5c6},
-	{0x0000a40c, 0x00820820},
-	{0x0000a414, 0x1ce739ce},
-	{0x0000a418, 0x2d001dce},
-	{0x0000a41c, 0x1ce739ce},
-	{0x0000a420, 0x000001ce},
-	{0x0000a424, 0x1ce739ce},
-	{0x0000a428, 0x000001ce},
-	{0x0000a42c, 0x1ce739ce},
-	{0x0000a430, 0x1ce739ce},
-	{0x0000a434, 0x00000000},
-	{0x0000a438, 0x00001801},
-	{0x0000a43c, 0x00000000},
-	{0x0000a440, 0x00000000},
-	{0x0000a444, 0x00000000},
-	{0x0000a448, 0x04000080},
-	{0x0000a44c, 0x00000001},
-	{0x0000a450, 0x00010000},
-	{0x0000a458, 0x00000000},
-	{0x0000a600, 0x00000000},
-	{0x0000a604, 0x00000000},
-	{0x0000a608, 0x00000000},
-	{0x0000a60c, 0x00000000},
-	{0x0000a610, 0x00000000},
-	{0x0000a614, 0x00000000},
-	{0x0000a618, 0x00000000},
-	{0x0000a61c, 0x00000000},
-	{0x0000a620, 0x00000000},
-	{0x0000a624, 0x00000000},
-	{0x0000a628, 0x00000000},
-	{0x0000a62c, 0x00000000},
-	{0x0000a630, 0x00000000},
-	{0x0000a634, 0x00000000},
-	{0x0000a638, 0x00000000},
-	{0x0000a63c, 0x00000000},
-	{0x0000a640, 0x00000000},
-	{0x0000a644, 0x3fad9d74},
-	{0x0000a648, 0x0048060a},
-	{0x0000a64c, 0x00000637},
-	{0x0000a670, 0x03020100},
-	{0x0000a674, 0x09080504},
-	{0x0000a678, 0x0d0c0b0a},
-	{0x0000a67c, 0x13121110},
-	{0x0000a680, 0x31301514},
-	{0x0000a684, 0x35343332},
-	{0x0000a688, 0x00000036},
-	{0x0000a690, 0x00000838},
-	{0x0000a7c0, 0x00000000},
-	{0x0000a7c4, 0xfffffffc},
-	{0x0000a7c8, 0x00000000},
-	{0x0000a7cc, 0x00000000},
-	{0x0000a7d0, 0x00000000},
-	{0x0000a7d4, 0x00000004},
-	{0x0000a7dc, 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, 0x000050d8, 0x000050d8, 0x000050d9, 0x000050d9},
-	{0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000},
-	{0x0000a504, 0x04002222, 0x04002222, 0x04000002, 0x04000002},
-	{0x0000a508, 0x09002421, 0x09002421, 0x08000004, 0x08000004},
-	{0x0000a50c, 0x0d002621, 0x0d002621, 0x0b000200, 0x0b000200},
-	{0x0000a510, 0x13004620, 0x13004620, 0x0f000202, 0x0f000202},
-	{0x0000a514, 0x19004a20, 0x19004a20, 0x11000400, 0x11000400},
-	{0x0000a518, 0x1d004e20, 0x1d004e20, 0x15000402, 0x15000402},
-	{0x0000a51c, 0x21005420, 0x21005420, 0x19000404, 0x19000404},
-	{0x0000a520, 0x26005e20, 0x26005e20, 0x1b000603, 0x1b000603},
-	{0x0000a524, 0x2b005e40, 0x2b005e40, 0x1f000a02, 0x1f000a02},
-	{0x0000a528, 0x2f005e42, 0x2f005e42, 0x23000a04, 0x23000a04},
-	{0x0000a52c, 0x33005e44, 0x33005e44, 0x26000a20, 0x26000a20},
-	{0x0000a530, 0x38005e65, 0x38005e65, 0x2a000e20, 0x2a000e20},
-	{0x0000a534, 0x3c005e69, 0x3c005e69, 0x2e000e22, 0x2e000e22},
-	{0x0000a538, 0x40005e6b, 0x40005e6b, 0x31000e24, 0x31000e24},
-	{0x0000a53c, 0x44005e6d, 0x44005e6d, 0x34001640, 0x34001640},
-	{0x0000a540, 0x49005e72, 0x49005e72, 0x38001660, 0x38001660},
-	{0x0000a544, 0x4e005eb2, 0x4e005eb2, 0x3b001861, 0x3b001861},
-	{0x0000a548, 0x53005f12, 0x53005f12, 0x3e001a81, 0x3e001a81},
-	{0x0000a54c, 0x59025eb5, 0x59025eb5, 0x42001a83, 0x42001a83},
-	{0x0000a550, 0x5e025f12, 0x5e025f12, 0x44001c84, 0x44001c84},
-	{0x0000a554, 0x61027f12, 0x61027f12, 0x48001ce3, 0x48001ce3},
-	{0x0000a558, 0x6702bf12, 0x6702bf12, 0x4c001ce5, 0x4c001ce5},
-	{0x0000a55c, 0x6b02bf14, 0x6b02bf14, 0x50001ce9, 0x50001ce9},
-	{0x0000a560, 0x6f02bf16, 0x6f02bf16, 0x54001ceb, 0x54001ceb},
-	{0x0000a564, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
-	{0x0000a568, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
-	{0x0000a56c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
-	{0x0000a570, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
-	{0x0000a574, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
-	{0x0000a578, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
-	{0x0000a57c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
-	{0x0000a580, 0x00802220, 0x00802220, 0x00800000, 0x00800000},
-	{0x0000a584, 0x04802222, 0x04802222, 0x04800002, 0x04800002},
-	{0x0000a588, 0x09802421, 0x09802421, 0x08800004, 0x08800004},
-	{0x0000a58c, 0x0d802621, 0x0d802621, 0x0b800200, 0x0b800200},
-	{0x0000a590, 0x13804620, 0x13804620, 0x0f800202, 0x0f800202},
-	{0x0000a594, 0x19804a20, 0x19804a20, 0x11800400, 0x11800400},
-	{0x0000a598, 0x1d804e20, 0x1d804e20, 0x15800402, 0x15800402},
-	{0x0000a59c, 0x21805420, 0x21805420, 0x19800404, 0x19800404},
-	{0x0000a5a0, 0x26805e20, 0x26805e20, 0x1b800603, 0x1b800603},
-	{0x0000a5a4, 0x2b805e40, 0x2b805e40, 0x1f800a02, 0x1f800a02},
-	{0x0000a5a8, 0x2f805e42, 0x2f805e42, 0x23800a04, 0x23800a04},
-	{0x0000a5ac, 0x33805e44, 0x33805e44, 0x26800a20, 0x26800a20},
-	{0x0000a5b0, 0x38805e65, 0x38805e65, 0x2a800e20, 0x2a800e20},
-	{0x0000a5b4, 0x3c805e69, 0x3c805e69, 0x2e800e22, 0x2e800e22},
-	{0x0000a5b8, 0x40805e6b, 0x40805e6b, 0x31800e24, 0x31800e24},
-	{0x0000a5bc, 0x44805e6d, 0x44805e6d, 0x34801640, 0x34801640},
-	{0x0000a5c0, 0x49805e72, 0x49805e72, 0x38801660, 0x38801660},
-	{0x0000a5c4, 0x4e805eb2, 0x4e805eb2, 0x3b801861, 0x3b801861},
-	{0x0000a5c8, 0x53805f12, 0x53805f12, 0x3e801a81, 0x3e801a81},
-	{0x0000a5cc, 0x59825eb2, 0x59825eb2, 0x42801a83, 0x42801a83},
-	{0x0000a5d0, 0x5e825f12, 0x5e825f12, 0x44801c84, 0x44801c84},
-	{0x0000a5d4, 0x61827f12, 0x61827f12, 0x48801ce3, 0x48801ce3},
-	{0x0000a5d8, 0x6782bf12, 0x6782bf12, 0x4c801ce5, 0x4c801ce5},
-	{0x0000a5dc, 0x6b82bf14, 0x6b82bf14, 0x50801ce9, 0x50801ce9},
-	{0x0000a5e0, 0x6f82bf16, 0x6f82bf16, 0x54801ceb, 0x54801ceb},
-	{0x0000a5e4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
-	{0x0000a5e8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
-	{0x0000a5ec, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
-	{0x0000a5f0, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
-	{0x0000a5f4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
-	{0x0000a5f8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
-	{0x0000a5fc, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
-	{0x00016044, 0x056db2e6, 0x056db2e6, 0x056db2e6, 0x056db2e6},
-	{0x00016048, 0xae480001, 0xae480001, 0xae480001, 0xae480001},
-	{0x00016068, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c},
-	{0x00016444, 0x056db2e6, 0x056db2e6, 0x056db2e6, 0x056db2e6},
-	{0x00016448, 0xae480001, 0xae480001, 0xae480001, 0xae480001},
-	{0x00016468, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c},
-	{0x00016844, 0x056db2e6, 0x056db2e6, 0x056db2e6, 0x056db2e6},
-	{0x00016848, 0xae480001, 0xae480001, 0xae480001, 0xae480001},
-	{0x00016868, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c},
-};
-
-static const u32 ar9300Modes_high_ob_db_tx_gain_table_2p0[][5] = {
-	/* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
-	{0x0000a410, 0x000050d8, 0x000050d8, 0x000050d9, 0x000050d9},
-	{0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000},
-	{0x0000a504, 0x04002222, 0x04002222, 0x04000002, 0x04000002},
-	{0x0000a508, 0x09002421, 0x09002421, 0x08000004, 0x08000004},
-	{0x0000a50c, 0x0d002621, 0x0d002621, 0x0b000200, 0x0b000200},
-	{0x0000a510, 0x13004620, 0x13004620, 0x0f000202, 0x0f000202},
-	{0x0000a514, 0x19004a20, 0x19004a20, 0x11000400, 0x11000400},
-	{0x0000a518, 0x1d004e20, 0x1d004e20, 0x15000402, 0x15000402},
-	{0x0000a51c, 0x21005420, 0x21005420, 0x19000404, 0x19000404},
-	{0x0000a520, 0x26005e20, 0x26005e20, 0x1b000603, 0x1b000603},
-	{0x0000a524, 0x2b005e40, 0x2b005e40, 0x1f000a02, 0x1f000a02},
-	{0x0000a528, 0x2f005e42, 0x2f005e42, 0x23000a04, 0x23000a04},
-	{0x0000a52c, 0x33005e44, 0x33005e44, 0x26000a20, 0x26000a20},
-	{0x0000a530, 0x38005e65, 0x38005e65, 0x2a000e20, 0x2a000e20},
-	{0x0000a534, 0x3c005e69, 0x3c005e69, 0x2e000e22, 0x2e000e22},
-	{0x0000a538, 0x40005e6b, 0x40005e6b, 0x31000e24, 0x31000e24},
-	{0x0000a53c, 0x44005e6d, 0x44005e6d, 0x34001640, 0x34001640},
-	{0x0000a540, 0x49005e72, 0x49005e72, 0x38001660, 0x38001660},
-	{0x0000a544, 0x4e005eb2, 0x4e005eb2, 0x3b001861, 0x3b001861},
-	{0x0000a548, 0x53005f12, 0x53005f12, 0x3e001a81, 0x3e001a81},
-	{0x0000a54c, 0x59025eb5, 0x59025eb5, 0x42001a83, 0x42001a83},
-	{0x0000a550, 0x5e025f12, 0x5e025f12, 0x44001c84, 0x44001c84},
-	{0x0000a554, 0x61027f12, 0x61027f12, 0x48001ce3, 0x48001ce3},
-	{0x0000a558, 0x6702bf12, 0x6702bf12, 0x4c001ce5, 0x4c001ce5},
-	{0x0000a55c, 0x6b02bf14, 0x6b02bf14, 0x50001ce9, 0x50001ce9},
-	{0x0000a560, 0x6f02bf16, 0x6f02bf16, 0x54001ceb, 0x54001ceb},
-	{0x0000a564, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
-	{0x0000a568, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
-	{0x0000a56c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
-	{0x0000a570, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
-	{0x0000a574, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
-	{0x0000a578, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
-	{0x0000a57c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
-	{0x0000a580, 0x00802220, 0x00802220, 0x00800000, 0x00800000},
-	{0x0000a584, 0x04802222, 0x04802222, 0x04800002, 0x04800002},
-	{0x0000a588, 0x09802421, 0x09802421, 0x08800004, 0x08800004},
-	{0x0000a58c, 0x0d802621, 0x0d802621, 0x0b800200, 0x0b800200},
-	{0x0000a590, 0x13804620, 0x13804620, 0x0f800202, 0x0f800202},
-	{0x0000a594, 0x19804a20, 0x19804a20, 0x11800400, 0x11800400},
-	{0x0000a598, 0x1d804e20, 0x1d804e20, 0x15800402, 0x15800402},
-	{0x0000a59c, 0x21805420, 0x21805420, 0x19800404, 0x19800404},
-	{0x0000a5a0, 0x26805e20, 0x26805e20, 0x1b800603, 0x1b800603},
-	{0x0000a5a4, 0x2b805e40, 0x2b805e40, 0x1f800a02, 0x1f800a02},
-	{0x0000a5a8, 0x2f805e42, 0x2f805e42, 0x23800a04, 0x23800a04},
-	{0x0000a5ac, 0x33805e44, 0x33805e44, 0x26800a20, 0x26800a20},
-	{0x0000a5b0, 0x38805e65, 0x38805e65, 0x2a800e20, 0x2a800e20},
-	{0x0000a5b4, 0x3c805e69, 0x3c805e69, 0x2e800e22, 0x2e800e22},
-	{0x0000a5b8, 0x40805e6b, 0x40805e6b, 0x31800e24, 0x31800e24},
-	{0x0000a5bc, 0x44805e6d, 0x44805e6d, 0x34801640, 0x34801640},
-	{0x0000a5c0, 0x49805e72, 0x49805e72, 0x38801660, 0x38801660},
-	{0x0000a5c4, 0x4e805eb2, 0x4e805eb2, 0x3b801861, 0x3b801861},
-	{0x0000a5c8, 0x53805f12, 0x53805f12, 0x3e801a81, 0x3e801a81},
-	{0x0000a5cc, 0x59825eb2, 0x59825eb2, 0x42801a83, 0x42801a83},
-	{0x0000a5d0, 0x5e825f12, 0x5e825f12, 0x44801c84, 0x44801c84},
-	{0x0000a5d4, 0x61827f12, 0x61827f12, 0x48801ce3, 0x48801ce3},
-	{0x0000a5d8, 0x6782bf12, 0x6782bf12, 0x4c801ce5, 0x4c801ce5},
-	{0x0000a5dc, 0x6b82bf14, 0x6b82bf14, 0x50801ce9, 0x50801ce9},
-	{0x0000a5e0, 0x6f82bf16, 0x6f82bf16, 0x54801ceb, 0x54801ceb},
-	{0x0000a5e4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
-	{0x0000a5e8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
-	{0x0000a5ec, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
-	{0x0000a5f0, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
-	{0x0000a5f4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
-	{0x0000a5f8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
-	{0x0000a5fc, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
-	{0x00016044, 0x056db2e4, 0x056db2e4, 0x056db2e4, 0x056db2e4},
-	{0x00016048, 0x8e480001, 0x8e480001, 0x8e480001, 0x8e480001},
-	{0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
-	{0x00016444, 0x056db2e4, 0x056db2e4, 0x056db2e4, 0x056db2e4},
-	{0x00016448, 0x8e480001, 0x8e480001, 0x8e480001, 0x8e480001},
-	{0x00016468, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
-	{0x00016844, 0x056db2e4, 0x056db2e4, 0x056db2e4, 0x056db2e4},
-	{0x00016848, 0x8e480001, 0x8e480001, 0x8e480001, 0x8e480001},
-	{0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
-};
-
-static const u32 ar9300Common_rx_gain_table_2p0[][2] = {
-	/* Addr      allmodes  */
-	{0x0000a000, 0x00010000},
-	{0x0000a004, 0x00030002},
-	{0x0000a008, 0x00050004},
-	{0x0000a00c, 0x00810080},
-	{0x0000a010, 0x00830082},
-	{0x0000a014, 0x01810180},
-	{0x0000a018, 0x01830182},
-	{0x0000a01c, 0x01850184},
-	{0x0000a020, 0x01890188},
-	{0x0000a024, 0x018b018a},
-	{0x0000a028, 0x018d018c},
-	{0x0000a02c, 0x01910190},
-	{0x0000a030, 0x01930192},
-	{0x0000a034, 0x01950194},
-	{0x0000a038, 0x038a0196},
-	{0x0000a03c, 0x038c038b},
-	{0x0000a040, 0x0390038d},
-	{0x0000a044, 0x03920391},
-	{0x0000a048, 0x03940393},
-	{0x0000a04c, 0x03960395},
-	{0x0000a050, 0x00000000},
-	{0x0000a054, 0x00000000},
-	{0x0000a058, 0x00000000},
-	{0x0000a05c, 0x00000000},
-	{0x0000a060, 0x00000000},
-	{0x0000a064, 0x00000000},
-	{0x0000a068, 0x00000000},
-	{0x0000a06c, 0x00000000},
-	{0x0000a070, 0x00000000},
-	{0x0000a074, 0x00000000},
-	{0x0000a078, 0x00000000},
-	{0x0000a07c, 0x00000000},
-	{0x0000a080, 0x22222229},
-	{0x0000a084, 0x1d1d1d1d},
-	{0x0000a088, 0x1d1d1d1d},
-	{0x0000a08c, 0x1d1d1d1d},
-	{0x0000a090, 0x171d1d1d},
-	{0x0000a094, 0x11111717},
-	{0x0000a098, 0x00030311},
-	{0x0000a09c, 0x00000000},
-	{0x0000a0a0, 0x00000000},
-	{0x0000a0a4, 0x00000000},
-	{0x0000a0a8, 0x00000000},
-	{0x0000a0ac, 0x00000000},
-	{0x0000a0b0, 0x00000000},
-	{0x0000a0b4, 0x00000000},
-	{0x0000a0b8, 0x00000000},
-	{0x0000a0bc, 0x00000000},
-	{0x0000a0c0, 0x001f0000},
-	{0x0000a0c4, 0x01000101},
-	{0x0000a0c8, 0x011e011f},
-	{0x0000a0cc, 0x011c011d},
-	{0x0000a0d0, 0x02030204},
-	{0x0000a0d4, 0x02010202},
-	{0x0000a0d8, 0x021f0200},
-	{0x0000a0dc, 0x0302021e},
-	{0x0000a0e0, 0x03000301},
-	{0x0000a0e4, 0x031e031f},
-	{0x0000a0e8, 0x0402031d},
-	{0x0000a0ec, 0x04000401},
-	{0x0000a0f0, 0x041e041f},
-	{0x0000a0f4, 0x0502041d},
-	{0x0000a0f8, 0x05000501},
-	{0x0000a0fc, 0x051e051f},
-	{0x0000a100, 0x06010602},
-	{0x0000a104, 0x061f0600},
-	{0x0000a108, 0x061d061e},
-	{0x0000a10c, 0x07020703},
-	{0x0000a110, 0x07000701},
-	{0x0000a114, 0x00000000},
-	{0x0000a118, 0x00000000},
-	{0x0000a11c, 0x00000000},
-	{0x0000a120, 0x00000000},
-	{0x0000a124, 0x00000000},
-	{0x0000a128, 0x00000000},
-	{0x0000a12c, 0x00000000},
-	{0x0000a130, 0x00000000},
-	{0x0000a134, 0x00000000},
-	{0x0000a138, 0x00000000},
-	{0x0000a13c, 0x00000000},
-	{0x0000a140, 0x001f0000},
-	{0x0000a144, 0x01000101},
-	{0x0000a148, 0x011e011f},
-	{0x0000a14c, 0x011c011d},
-	{0x0000a150, 0x02030204},
-	{0x0000a154, 0x02010202},
-	{0x0000a158, 0x021f0200},
-	{0x0000a15c, 0x0302021e},
-	{0x0000a160, 0x03000301},
-	{0x0000a164, 0x031e031f},
-	{0x0000a168, 0x0402031d},
-	{0x0000a16c, 0x04000401},
-	{0x0000a170, 0x041e041f},
-	{0x0000a174, 0x0502041d},
-	{0x0000a178, 0x05000501},
-	{0x0000a17c, 0x051e051f},
-	{0x0000a180, 0x06010602},
-	{0x0000a184, 0x061f0600},
-	{0x0000a188, 0x061d061e},
-	{0x0000a18c, 0x07020703},
-	{0x0000a190, 0x07000701},
-	{0x0000a194, 0x00000000},
-	{0x0000a198, 0x00000000},
-	{0x0000a19c, 0x00000000},
-	{0x0000a1a0, 0x00000000},
-	{0x0000a1a4, 0x00000000},
-	{0x0000a1a8, 0x00000000},
-	{0x0000a1ac, 0x00000000},
-	{0x0000a1b0, 0x00000000},
-	{0x0000a1b4, 0x00000000},
-	{0x0000a1b8, 0x00000000},
-	{0x0000a1bc, 0x00000000},
-	{0x0000a1c0, 0x00000000},
-	{0x0000a1c4, 0x00000000},
-	{0x0000a1c8, 0x00000000},
-	{0x0000a1cc, 0x00000000},
-	{0x0000a1d0, 0x00000000},
-	{0x0000a1d4, 0x00000000},
-	{0x0000a1d8, 0x00000000},
-	{0x0000a1dc, 0x00000000},
-	{0x0000a1e0, 0x00000000},
-	{0x0000a1e4, 0x00000000},
-	{0x0000a1e8, 0x00000000},
-	{0x0000a1ec, 0x00000000},
-	{0x0000a1f0, 0x00000396},
-	{0x0000a1f4, 0x00000396},
-	{0x0000a1f8, 0x00000396},
-	{0x0000a1fc, 0x00000196},
-	{0x0000b000, 0x00010000},
-	{0x0000b004, 0x00030002},
-	{0x0000b008, 0x00050004},
-	{0x0000b00c, 0x00810080},
-	{0x0000b010, 0x00830082},
-	{0x0000b014, 0x01810180},
-	{0x0000b018, 0x01830182},
-	{0x0000b01c, 0x01850184},
-	{0x0000b020, 0x02810280},
-	{0x0000b024, 0x02830282},
-	{0x0000b028, 0x02850284},
-	{0x0000b02c, 0x02890288},
-	{0x0000b030, 0x028b028a},
-	{0x0000b034, 0x0388028c},
-	{0x0000b038, 0x038a0389},
-	{0x0000b03c, 0x038c038b},
-	{0x0000b040, 0x0390038d},
-	{0x0000b044, 0x03920391},
-	{0x0000b048, 0x03940393},
-	{0x0000b04c, 0x03960395},
-	{0x0000b050, 0x00000000},
-	{0x0000b054, 0x00000000},
-	{0x0000b058, 0x00000000},
-	{0x0000b05c, 0x00000000},
-	{0x0000b060, 0x00000000},
-	{0x0000b064, 0x00000000},
-	{0x0000b068, 0x00000000},
-	{0x0000b06c, 0x00000000},
-	{0x0000b070, 0x00000000},
-	{0x0000b074, 0x00000000},
-	{0x0000b078, 0x00000000},
-	{0x0000b07c, 0x00000000},
-	{0x0000b080, 0x32323232},
-	{0x0000b084, 0x2f2f3232},
-	{0x0000b088, 0x23282a2d},
-	{0x0000b08c, 0x1c1e2123},
-	{0x0000b090, 0x14171919},
-	{0x0000b094, 0x0e0e1214},
-	{0x0000b098, 0x03050707},
-	{0x0000b09c, 0x00030303},
-	{0x0000b0a0, 0x00000000},
-	{0x0000b0a4, 0x00000000},
-	{0x0000b0a8, 0x00000000},
-	{0x0000b0ac, 0x00000000},
-	{0x0000b0b0, 0x00000000},
-	{0x0000b0b4, 0x00000000},
-	{0x0000b0b8, 0x00000000},
-	{0x0000b0bc, 0x00000000},
-	{0x0000b0c0, 0x003f0020},
-	{0x0000b0c4, 0x00400041},
-	{0x0000b0c8, 0x0140005f},
-	{0x0000b0cc, 0x0160015f},
-	{0x0000b0d0, 0x017e017f},
-	{0x0000b0d4, 0x02410242},
-	{0x0000b0d8, 0x025f0240},
-	{0x0000b0dc, 0x027f0260},
-	{0x0000b0e0, 0x0341027e},
-	{0x0000b0e4, 0x035f0340},
-	{0x0000b0e8, 0x037f0360},
-	{0x0000b0ec, 0x04400441},
-	{0x0000b0f0, 0x0460045f},
-	{0x0000b0f4, 0x0541047f},
-	{0x0000b0f8, 0x055f0540},
-	{0x0000b0fc, 0x057f0560},
-	{0x0000b100, 0x06400641},
-	{0x0000b104, 0x0660065f},
-	{0x0000b108, 0x067e067f},
-	{0x0000b10c, 0x07410742},
-	{0x0000b110, 0x075f0740},
-	{0x0000b114, 0x077f0760},
-	{0x0000b118, 0x07800781},
-	{0x0000b11c, 0x07a0079f},
-	{0x0000b120, 0x07c107bf},
-	{0x0000b124, 0x000007c0},
-	{0x0000b128, 0x00000000},
-	{0x0000b12c, 0x00000000},
-	{0x0000b130, 0x00000000},
-	{0x0000b134, 0x00000000},
-	{0x0000b138, 0x00000000},
-	{0x0000b13c, 0x00000000},
-	{0x0000b140, 0x003f0020},
-	{0x0000b144, 0x00400041},
-	{0x0000b148, 0x0140005f},
-	{0x0000b14c, 0x0160015f},
-	{0x0000b150, 0x017e017f},
-	{0x0000b154, 0x02410242},
-	{0x0000b158, 0x025f0240},
-	{0x0000b15c, 0x027f0260},
-	{0x0000b160, 0x0341027e},
-	{0x0000b164, 0x035f0340},
-	{0x0000b168, 0x037f0360},
-	{0x0000b16c, 0x04400441},
-	{0x0000b170, 0x0460045f},
-	{0x0000b174, 0x0541047f},
-	{0x0000b178, 0x055f0540},
-	{0x0000b17c, 0x057f0560},
-	{0x0000b180, 0x06400641},
-	{0x0000b184, 0x0660065f},
-	{0x0000b188, 0x067e067f},
-	{0x0000b18c, 0x07410742},
-	{0x0000b190, 0x075f0740},
-	{0x0000b194, 0x077f0760},
-	{0x0000b198, 0x07800781},
-	{0x0000b19c, 0x07a0079f},
-	{0x0000b1a0, 0x07c107bf},
-	{0x0000b1a4, 0x000007c0},
-	{0x0000b1a8, 0x00000000},
-	{0x0000b1ac, 0x00000000},
-	{0x0000b1b0, 0x00000000},
-	{0x0000b1b4, 0x00000000},
-	{0x0000b1b8, 0x00000000},
-	{0x0000b1bc, 0x00000000},
-	{0x0000b1c0, 0x00000000},
-	{0x0000b1c4, 0x00000000},
-	{0x0000b1c8, 0x00000000},
-	{0x0000b1cc, 0x00000000},
-	{0x0000b1d0, 0x00000000},
-	{0x0000b1d4, 0x00000000},
-	{0x0000b1d8, 0x00000000},
-	{0x0000b1dc, 0x00000000},
-	{0x0000b1e0, 0x00000000},
-	{0x0000b1e4, 0x00000000},
-	{0x0000b1e8, 0x00000000},
-	{0x0000b1ec, 0x00000000},
-	{0x0000b1f0, 0x00000396},
-	{0x0000b1f4, 0x00000396},
-	{0x0000b1f8, 0x00000396},
-	{0x0000b1fc, 0x00000196},
-};
-
-static const u32 ar9300Modes_low_ob_db_tx_gain_table_2p0[][5] = {
-	/* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
-	{0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9},
-	{0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
-	{0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002},
-	{0x0000a508, 0x0a000020, 0x0a000020, 0x08000004, 0x08000004},
-	{0x0000a50c, 0x10000023, 0x10000023, 0x0b000200, 0x0b000200},
-	{0x0000a510, 0x16000220, 0x16000220, 0x0f000202, 0x0f000202},
-	{0x0000a514, 0x1c000223, 0x1c000223, 0x12000400, 0x12000400},
-	{0x0000a518, 0x21020220, 0x21020220, 0x16000402, 0x16000402},
-	{0x0000a51c, 0x27020223, 0x27020223, 0x19000404, 0x19000404},
-	{0x0000a520, 0x2b022220, 0x2b022220, 0x1c000603, 0x1c000603},
-	{0x0000a524, 0x2f022222, 0x2f022222, 0x21000a02, 0x21000a02},
-	{0x0000a528, 0x34022225, 0x34022225, 0x25000a04, 0x25000a04},
-	{0x0000a52c, 0x3a02222a, 0x3a02222a, 0x28000a20, 0x28000a20},
-	{0x0000a530, 0x3e02222c, 0x3e02222c, 0x2c000e20, 0x2c000e20},
-	{0x0000a534, 0x4202242a, 0x4202242a, 0x30000e22, 0x30000e22},
-	{0x0000a538, 0x4702244a, 0x4702244a, 0x34000e24, 0x34000e24},
-	{0x0000a53c, 0x4b02244c, 0x4b02244c, 0x38001640, 0x38001640},
-	{0x0000a540, 0x4e02246c, 0x4e02246c, 0x3c001660, 0x3c001660},
-	{0x0000a544, 0x5302266c, 0x5302266c, 0x3f001861, 0x3f001861},
-	{0x0000a548, 0x5702286c, 0x5702286c, 0x43001a81, 0x43001a81},
-	{0x0000a54c, 0x5c04286b, 0x5c04286b, 0x47001a83, 0x47001a83},
-	{0x0000a550, 0x61042a6c, 0x61042a6c, 0x4a001c84, 0x4a001c84},
-	{0x0000a554, 0x66062a6c, 0x66062a6c, 0x4e001ce3, 0x4e001ce3},
-	{0x0000a558, 0x6b062e6c, 0x6b062e6c, 0x52001ce5, 0x52001ce5},
-	{0x0000a55c, 0x7006308c, 0x7006308c, 0x56001ce9, 0x56001ce9},
-	{0x0000a560, 0x730a308a, 0x730a308a, 0x5a001ceb, 0x5a001ceb},
-	{0x0000a564, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
-	{0x0000a568, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
-	{0x0000a56c, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
-	{0x0000a570, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
-	{0x0000a574, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
-	{0x0000a578, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
-	{0x0000a57c, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
-	{0x0000a580, 0x00800000, 0x00800000, 0x00800000, 0x00800000},
-	{0x0000a584, 0x06800003, 0x06800003, 0x04800002, 0x04800002},
-	{0x0000a588, 0x0a800020, 0x0a800020, 0x08800004, 0x08800004},
-	{0x0000a58c, 0x10800023, 0x10800023, 0x0b800200, 0x0b800200},
-	{0x0000a590, 0x16800220, 0x16800220, 0x0f800202, 0x0f800202},
-	{0x0000a594, 0x1c800223, 0x1c800223, 0x12800400, 0x12800400},
-	{0x0000a598, 0x21820220, 0x21820220, 0x16800402, 0x16800402},
-	{0x0000a59c, 0x27820223, 0x27820223, 0x19800404, 0x19800404},
-	{0x0000a5a0, 0x2b822220, 0x2b822220, 0x1c800603, 0x1c800603},
-	{0x0000a5a4, 0x2f822222, 0x2f822222, 0x21800a02, 0x21800a02},
-	{0x0000a5a8, 0x34822225, 0x34822225, 0x25800a04, 0x25800a04},
-	{0x0000a5ac, 0x3a82222a, 0x3a82222a, 0x28800a20, 0x28800a20},
-	{0x0000a5b0, 0x3e82222c, 0x3e82222c, 0x2c800e20, 0x2c800e20},
-	{0x0000a5b4, 0x4282242a, 0x4282242a, 0x30800e22, 0x30800e22},
-	{0x0000a5b8, 0x4782244a, 0x4782244a, 0x34800e24, 0x34800e24},
-	{0x0000a5bc, 0x4b82244c, 0x4b82244c, 0x38801640, 0x38801640},
-	{0x0000a5c0, 0x4e82246c, 0x4e82246c, 0x3c801660, 0x3c801660},
-	{0x0000a5c4, 0x5382266c, 0x5382266c, 0x3f801861, 0x3f801861},
-	{0x0000a5c8, 0x5782286c, 0x5782286c, 0x43801a81, 0x43801a81},
-	{0x0000a5cc, 0x5c84286b, 0x5c84286b, 0x47801a83, 0x47801a83},
-	{0x0000a5d0, 0x61842a6c, 0x61842a6c, 0x4a801c84, 0x4a801c84},
-	{0x0000a5d4, 0x66862a6c, 0x66862a6c, 0x4e801ce3, 0x4e801ce3},
-	{0x0000a5d8, 0x6b862e6c, 0x6b862e6c, 0x52801ce5, 0x52801ce5},
-	{0x0000a5dc, 0x7086308c, 0x7086308c, 0x56801ce9, 0x56801ce9},
-	{0x0000a5e0, 0x738a308a, 0x738a308a, 0x5a801ceb, 0x5a801ceb},
-	{0x0000a5e4, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
-	{0x0000a5e8, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
-	{0x0000a5ec, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
-	{0x0000a5f0, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
-	{0x0000a5f4, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
-	{0x0000a5f8, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
-	{0x0000a5fc, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
-	{0x00016044, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
-	{0x00016048, 0x64000001, 0x64000001, 0x64000001, 0x64000001},
-	{0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
-	{0x00016444, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
-	{0x00016448, 0x64000001, 0x64000001, 0x64000001, 0x64000001},
-	{0x00016468, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
-	{0x00016844, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
-	{0x00016848, 0x64000001, 0x64000001, 0x64000001, 0x64000001},
-	{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, 0x00830082},
-	{0x0000a014, 0x01810180},
-	{0x0000a018, 0x01830182},
-	{0x0000a01c, 0x01850184},
-	{0x0000a020, 0x01890188},
-	{0x0000a024, 0x018b018a},
-	{0x0000a028, 0x018d018c},
-	{0x0000a02c, 0x03820190},
-	{0x0000a030, 0x03840383},
-	{0x0000a034, 0x03880385},
-	{0x0000a038, 0x038a0389},
-	{0x0000a03c, 0x038c038b},
-	{0x0000a040, 0x0390038d},
-	{0x0000a044, 0x03920391},
-	{0x0000a048, 0x03940393},
-	{0x0000a04c, 0x03960395},
-	{0x0000a050, 0x00000000},
-	{0x0000a054, 0x00000000},
-	{0x0000a058, 0x00000000},
-	{0x0000a05c, 0x00000000},
-	{0x0000a060, 0x00000000},
-	{0x0000a064, 0x00000000},
-	{0x0000a068, 0x00000000},
-	{0x0000a06c, 0x00000000},
-	{0x0000a070, 0x00000000},
-	{0x0000a074, 0x00000000},
-	{0x0000a078, 0x00000000},
-	{0x0000a07c, 0x00000000},
-	{0x0000a080, 0x29292929},
-	{0x0000a084, 0x29292929},
-	{0x0000a088, 0x29292929},
-	{0x0000a08c, 0x29292929},
-	{0x0000a090, 0x22292929},
-	{0x0000a094, 0x1d1d2222},
-	{0x0000a098, 0x0c111117},
-	{0x0000a09c, 0x00030303},
-	{0x0000a0a0, 0x00000000},
-	{0x0000a0a4, 0x00000000},
-	{0x0000a0a8, 0x00000000},
-	{0x0000a0ac, 0x00000000},
-	{0x0000a0b0, 0x00000000},
-	{0x0000a0b4, 0x00000000},
-	{0x0000a0b8, 0x00000000},
-	{0x0000a0bc, 0x00000000},
-	{0x0000a0c0, 0x001f0000},
-	{0x0000a0c4, 0x01000101},
-	{0x0000a0c8, 0x011e011f},
-	{0x0000a0cc, 0x011c011d},
-	{0x0000a0d0, 0x02030204},
-	{0x0000a0d4, 0x02010202},
-	{0x0000a0d8, 0x021f0200},
-	{0x0000a0dc, 0x0302021e},
-	{0x0000a0e0, 0x03000301},
-	{0x0000a0e4, 0x031e031f},
-	{0x0000a0e8, 0x0402031d},
-	{0x0000a0ec, 0x04000401},
-	{0x0000a0f0, 0x041e041f},
-	{0x0000a0f4, 0x0502041d},
-	{0x0000a0f8, 0x05000501},
-	{0x0000a0fc, 0x051e051f},
-	{0x0000a100, 0x06010602},
-	{0x0000a104, 0x061f0600},
-	{0x0000a108, 0x061d061e},
-	{0x0000a10c, 0x07020703},
-	{0x0000a110, 0x07000701},
-	{0x0000a114, 0x00000000},
-	{0x0000a118, 0x00000000},
-	{0x0000a11c, 0x00000000},
-	{0x0000a120, 0x00000000},
-	{0x0000a124, 0x00000000},
-	{0x0000a128, 0x00000000},
-	{0x0000a12c, 0x00000000},
-	{0x0000a130, 0x00000000},
-	{0x0000a134, 0x00000000},
-	{0x0000a138, 0x00000000},
-	{0x0000a13c, 0x00000000},
-	{0x0000a140, 0x001f0000},
-	{0x0000a144, 0x01000101},
-	{0x0000a148, 0x011e011f},
-	{0x0000a14c, 0x011c011d},
-	{0x0000a150, 0x02030204},
-	{0x0000a154, 0x02010202},
-	{0x0000a158, 0x021f0200},
-	{0x0000a15c, 0x0302021e},
-	{0x0000a160, 0x03000301},
-	{0x0000a164, 0x031e031f},
-	{0x0000a168, 0x0402031d},
-	{0x0000a16c, 0x04000401},
-	{0x0000a170, 0x041e041f},
-	{0x0000a174, 0x0502041d},
-	{0x0000a178, 0x05000501},
-	{0x0000a17c, 0x051e051f},
-	{0x0000a180, 0x06010602},
-	{0x0000a184, 0x061f0600},
-	{0x0000a188, 0x061d061e},
-	{0x0000a18c, 0x07020703},
-	{0x0000a190, 0x07000701},
-	{0x0000a194, 0x00000000},
-	{0x0000a198, 0x00000000},
-	{0x0000a19c, 0x00000000},
-	{0x0000a1a0, 0x00000000},
-	{0x0000a1a4, 0x00000000},
-	{0x0000a1a8, 0x00000000},
-	{0x0000a1ac, 0x00000000},
-	{0x0000a1b0, 0x00000000},
-	{0x0000a1b4, 0x00000000},
-	{0x0000a1b8, 0x00000000},
-	{0x0000a1bc, 0x00000000},
-	{0x0000a1c0, 0x00000000},
-	{0x0000a1c4, 0x00000000},
-	{0x0000a1c8, 0x00000000},
-	{0x0000a1cc, 0x00000000},
-	{0x0000a1d0, 0x00000000},
-	{0x0000a1d4, 0x00000000},
-	{0x0000a1d8, 0x00000000},
-	{0x0000a1dc, 0x00000000},
-	{0x0000a1e0, 0x00000000},
-	{0x0000a1e4, 0x00000000},
-	{0x0000a1e8, 0x00000000},
-	{0x0000a1ec, 0x00000000},
-	{0x0000a1f0, 0x00000396},
-	{0x0000a1f4, 0x00000396},
-	{0x0000a1f8, 0x00000396},
-	{0x0000a1fc, 0x00000196},
-	{0x0000b000, 0x00010000},
-	{0x0000b004, 0x00030002},
-	{0x0000b008, 0x00050004},
-	{0x0000b00c, 0x00810080},
-	{0x0000b010, 0x00830082},
-	{0x0000b014, 0x01810180},
-	{0x0000b018, 0x01830182},
-	{0x0000b01c, 0x01850184},
-	{0x0000b020, 0x02810280},
-	{0x0000b024, 0x02830282},
-	{0x0000b028, 0x02850284},
-	{0x0000b02c, 0x02890288},
-	{0x0000b030, 0x028b028a},
-	{0x0000b034, 0x0388028c},
-	{0x0000b038, 0x038a0389},
-	{0x0000b03c, 0x038c038b},
-	{0x0000b040, 0x0390038d},
-	{0x0000b044, 0x03920391},
-	{0x0000b048, 0x03940393},
-	{0x0000b04c, 0x03960395},
-	{0x0000b050, 0x00000000},
-	{0x0000b054, 0x00000000},
-	{0x0000b058, 0x00000000},
-	{0x0000b05c, 0x00000000},
-	{0x0000b060, 0x00000000},
-	{0x0000b064, 0x00000000},
-	{0x0000b068, 0x00000000},
-	{0x0000b06c, 0x00000000},
-	{0x0000b070, 0x00000000},
-	{0x0000b074, 0x00000000},
-	{0x0000b078, 0x00000000},
-	{0x0000b07c, 0x00000000},
-	{0x0000b080, 0x32323232},
-	{0x0000b084, 0x2f2f3232},
-	{0x0000b088, 0x23282a2d},
-	{0x0000b08c, 0x1c1e2123},
-	{0x0000b090, 0x14171919},
-	{0x0000b094, 0x0e0e1214},
-	{0x0000b098, 0x03050707},
-	{0x0000b09c, 0x00030303},
-	{0x0000b0a0, 0x00000000},
-	{0x0000b0a4, 0x00000000},
-	{0x0000b0a8, 0x00000000},
-	{0x0000b0ac, 0x00000000},
-	{0x0000b0b0, 0x00000000},
-	{0x0000b0b4, 0x00000000},
-	{0x0000b0b8, 0x00000000},
-	{0x0000b0bc, 0x00000000},
-	{0x0000b0c0, 0x003f0020},
-	{0x0000b0c4, 0x00400041},
-	{0x0000b0c8, 0x0140005f},
-	{0x0000b0cc, 0x0160015f},
-	{0x0000b0d0, 0x017e017f},
-	{0x0000b0d4, 0x02410242},
-	{0x0000b0d8, 0x025f0240},
-	{0x0000b0dc, 0x027f0260},
-	{0x0000b0e0, 0x0341027e},
-	{0x0000b0e4, 0x035f0340},
-	{0x0000b0e8, 0x037f0360},
-	{0x0000b0ec, 0x04400441},
-	{0x0000b0f0, 0x0460045f},
-	{0x0000b0f4, 0x0541047f},
-	{0x0000b0f8, 0x055f0540},
-	{0x0000b0fc, 0x057f0560},
-	{0x0000b100, 0x06400641},
-	{0x0000b104, 0x0660065f},
-	{0x0000b108, 0x067e067f},
-	{0x0000b10c, 0x07410742},
-	{0x0000b110, 0x075f0740},
-	{0x0000b114, 0x077f0760},
-	{0x0000b118, 0x07800781},
-	{0x0000b11c, 0x07a0079f},
-	{0x0000b120, 0x07c107bf},
-	{0x0000b124, 0x000007c0},
-	{0x0000b128, 0x00000000},
-	{0x0000b12c, 0x00000000},
-	{0x0000b130, 0x00000000},
-	{0x0000b134, 0x00000000},
-	{0x0000b138, 0x00000000},
-	{0x0000b13c, 0x00000000},
-	{0x0000b140, 0x003f0020},
-	{0x0000b144, 0x00400041},
-	{0x0000b148, 0x0140005f},
-	{0x0000b14c, 0x0160015f},
-	{0x0000b150, 0x017e017f},
-	{0x0000b154, 0x02410242},
-	{0x0000b158, 0x025f0240},
-	{0x0000b15c, 0x027f0260},
-	{0x0000b160, 0x0341027e},
-	{0x0000b164, 0x035f0340},
-	{0x0000b168, 0x037f0360},
-	{0x0000b16c, 0x04400441},
-	{0x0000b170, 0x0460045f},
-	{0x0000b174, 0x0541047f},
-	{0x0000b178, 0x055f0540},
-	{0x0000b17c, 0x057f0560},
-	{0x0000b180, 0x06400641},
-	{0x0000b184, 0x0660065f},
-	{0x0000b188, 0x067e067f},
-	{0x0000b18c, 0x07410742},
-	{0x0000b190, 0x075f0740},
-	{0x0000b194, 0x077f0760},
-	{0x0000b198, 0x07800781},
-	{0x0000b19c, 0x07a0079f},
-	{0x0000b1a0, 0x07c107bf},
-	{0x0000b1a4, 0x000007c0},
-	{0x0000b1a8, 0x00000000},
-	{0x0000b1ac, 0x00000000},
-	{0x0000b1b0, 0x00000000},
-	{0x0000b1b4, 0x00000000},
-	{0x0000b1b8, 0x00000000},
-	{0x0000b1bc, 0x00000000},
-	{0x0000b1c0, 0x00000000},
-	{0x0000b1c4, 0x00000000},
-	{0x0000b1c8, 0x00000000},
-	{0x0000b1cc, 0x00000000},
-	{0x0000b1d0, 0x00000000},
-	{0x0000b1d4, 0x00000000},
-	{0x0000b1d8, 0x00000000},
-	{0x0000b1dc, 0x00000000},
-	{0x0000b1e0, 0x00000000},
-	{0x0000b1e4, 0x00000000},
-	{0x0000b1e8, 0x00000000},
-	{0x0000b1ec, 0x00000000},
-	{0x0000b1f0, 0x00000396},
-	{0x0000b1f4, 0x00000396},
-	{0x0000b1f8, 0x00000396},
-	{0x0000b1fc, 0x00000196},
-};
-
-static const u32 ar9300_2p0_soc_preamble[][2] = {
-	/* Addr      allmodes  */
-	{0x000040a4, 0x00a0c1c9},
-	{0x00007008, 0x00000000},
-	{0x00007020, 0x00000000},
-	{0x00007034, 0x00000002},
-	{0x00007038, 0x000004c2},
-};
-
-static const u32 ar9300PciePhy_pll_on_clkreq_disable_L1_2p0[][2] = {
-	/* Addr      allmodes  */
-	{0x00004040, 0x08212e5e},
-	{0x00004040, 0x0008003b},
-	{0x00004044, 0x00000000},
-};
-
-static const u32 ar9300PciePhy_clkreq_enable_L1_2p0[][2] = {
-	/* Addr      allmodes  */
-	{0x00004040, 0x08253e5e},
-	{0x00004040, 0x0008003b},
-	{0x00004044, 0x00000000},
-};
-
-static const u32 ar9300PciePhy_clkreq_disable_L1_2p0[][2] = {
-	/* Addr      allmodes  */
-	{0x00004040, 0x08213e5e},
-	{0x00004040, 0x0008003b},
-	{0x00004044, 0x00000000},
-};
-
-#endif /* INITVALS_9003_2P0_H */
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_hw.c b/drivers/net/wireless/ath/ath9k/ar9003_hw.c
index 02c970819f79..c2a057156bfa 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_hw.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_hw.c
@@ -16,7 +16,6 @@
 
 #include "hw.h"
 #include "ar9003_mac.h"
-#include "ar9003_2p0_initvals.h"
 #include "ar9003_2p2_initvals.h"
 
 /* General hardware code for the AR9003 hadware family */
@@ -32,79 +31,12 @@ static bool ar9003_hw_macversion_supported(u32 macversion)
 	return false;
 }
 
-/* AR9003 2.0 */
-static void ar9003_2p0_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);
-}
-
-/* AR9003 2.2 */
-static void ar9003_2p2_hw_init_mode_regs(struct ath_hw *ah)
+/*
+ * The AR9003 family uses a new INI format (pre, core, post
+ * arrays per subsystem). This provides support for the
+ * AR9003 2.2 chipsets.
+ */
+static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
 {
 	/* mac */
 	INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0);
@@ -174,57 +106,27 @@ static void ar9003_2p2_hw_init_mode_regs(struct ath_hw *ah)
 		       3);
 }
 
-/*
- * The AR9003 family uses a new INI format (pre, core, post
- * arrays per subsystem).
- */
-static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
-{
-	if (AR_SREV_9300_20(ah))
-		ar9003_2p0_hw_init_mode_regs(ah);
-	else
-		ar9003_2p2_hw_init_mode_regs(ah);
-}
-
 static void ar9003_tx_gain_table_apply(struct ath_hw *ah)
 {
 	switch (ar9003_hw_get_tx_gain_idx(ah)) {
 	case 0:
 	default:
-		if (AR_SREV_9300_20(ah))
-			INIT_INI_ARRAY(&ah->iniModesTxGain,
-				       ar9300Modes_lowest_ob_db_tx_gain_table_2p0,
-				       ARRAY_SIZE(ar9300Modes_lowest_ob_db_tx_gain_table_2p0),
-				       5);
-		else
-			INIT_INI_ARRAY(&ah->iniModesTxGain,
-				       ar9300Modes_lowest_ob_db_tx_gain_table_2p2,
-				       ARRAY_SIZE(ar9300Modes_lowest_ob_db_tx_gain_table_2p2),
-				       5);
+		INIT_INI_ARRAY(&ah->iniModesTxGain,
+			       ar9300Modes_lowest_ob_db_tx_gain_table_2p2,
+			       ARRAY_SIZE(ar9300Modes_lowest_ob_db_tx_gain_table_2p2),
+			       5);
 		break;
 	case 1:
-		if (AR_SREV_9300_20(ah))
-			INIT_INI_ARRAY(&ah->iniModesTxGain,
-				       ar9300Modes_high_ob_db_tx_gain_table_2p0,
-				       ARRAY_SIZE(ar9300Modes_high_ob_db_tx_gain_table_2p0),
-				       5);
-		else
-			INIT_INI_ARRAY(&ah->iniModesTxGain,
-				       ar9300Modes_high_ob_db_tx_gain_table_2p2,
-				       ARRAY_SIZE(ar9300Modes_high_ob_db_tx_gain_table_2p2),
-				       5);
+		INIT_INI_ARRAY(&ah->iniModesTxGain,
+			       ar9300Modes_high_ob_db_tx_gain_table_2p2,
+			       ARRAY_SIZE(ar9300Modes_high_ob_db_tx_gain_table_2p2),
+			       5);
 		break;
 	case 2:
-		if (AR_SREV_9300_20(ah))
-			INIT_INI_ARRAY(&ah->iniModesTxGain,
-				       ar9300Modes_low_ob_db_tx_gain_table_2p0,
-				       ARRAY_SIZE(ar9300Modes_low_ob_db_tx_gain_table_2p0),
-				       5);
-		else
-			INIT_INI_ARRAY(&ah->iniModesTxGain,
-				       ar9300Modes_low_ob_db_tx_gain_table_2p2,
-				       ARRAY_SIZE(ar9300Modes_low_ob_db_tx_gain_table_2p2),
-				       5);
+		INIT_INI_ARRAY(&ah->iniModesTxGain,
+			       ar9300Modes_low_ob_db_tx_gain_table_2p2,
+			       ARRAY_SIZE(ar9300Modes_low_ob_db_tx_gain_table_2p2),
+			       5);
 		break;
 	}
 }
@@ -234,28 +136,16 @@ static void ar9003_rx_gain_table_apply(struct ath_hw *ah)
 	switch (ar9003_hw_get_rx_gain_idx(ah)) {
 	case 0:
 	default:
-		if (AR_SREV_9300_20(ah))
-			INIT_INI_ARRAY(&ah->iniModesRxGain,
-				       ar9300Common_rx_gain_table_2p0,
-				       ARRAY_SIZE(ar9300Common_rx_gain_table_2p0),
-				       2);
-		else
-			INIT_INI_ARRAY(&ah->iniModesRxGain,
-				       ar9300Common_rx_gain_table_2p2,
-				       ARRAY_SIZE(ar9300Common_rx_gain_table_2p2),
-				       2);
+		INIT_INI_ARRAY(&ah->iniModesRxGain,
+			       ar9300Common_rx_gain_table_2p2,
+			       ARRAY_SIZE(ar9300Common_rx_gain_table_2p2),
+			       2);
 		break;
 	case 1:
-		if (AR_SREV_9300_20(ah))
-			INIT_INI_ARRAY(&ah->iniModesRxGain,
-				       ar9300Common_wo_xlna_rx_gain_table_2p0,
-				       ARRAY_SIZE(ar9300Common_wo_xlna_rx_gain_table_2p0),
-				       2);
-		else
-			INIT_INI_ARRAY(&ah->iniModesRxGain,
-				       ar9300Common_wo_xlna_rx_gain_table_2p2,
-				       ARRAY_SIZE(ar9300Common_wo_xlna_rx_gain_table_2p2),
-				       2);
+		INIT_INI_ARRAY(&ah->iniModesRxGain,
+			       ar9300Common_wo_xlna_rx_gain_table_2p2,
+			       ARRAY_SIZE(ar9300Common_wo_xlna_rx_gain_table_2p2),
+			       2);
 		break;
 	}
 }
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
index efb05599b84c..669b777729b3 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
@@ -1254,13 +1254,12 @@ void ar9003_hw_bb_watchdog_dbg_info(struct ath_hw *ah)
 		  "** BB mode: BB_gen_controls=0x%08x **\n",
 		  REG_READ(ah, AR_PHY_GEN_CTRL));
 
-	ath9k_hw_update_cycle_counters(ah);
-#define PCT(_field) (ah->cc_delta._field * 100 / ah->cc_delta.cycles)
-	if (ah->cc_delta.cycles)
+#define PCT(_field) (common->cc_survey._field * 100 / common->cc_survey.cycles)
+	if (common->cc_survey.cycles)
 		ath_print(common, ATH_DBG_RESET,
 			  "** BB busy times: rx_clear=%d%%, "
 			  "rx_frame=%d%%, tx_frame=%d%% **\n",
-			  PCT(rx_clear), PCT(rx_frame), PCT(tx_frame));
+			  PCT(rx_busy), PCT(rx_frame), PCT(tx_frame));
 
 	ath_print(common, ATH_DBG_RESET,
 		  "==== BB update: done ====\n\n");
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index de2b18ee7f77..973c919fdd27 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -239,12 +239,11 @@ struct ath_buf {
 	struct sk_buff *bf_mpdu;	/* enclosing frame structure */
 	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 */
+	dma_addr_t bf_buf_addr;	/* physical addr of data buffer, for DMA */
 	bool bf_stale;
 	bool bf_tx_aborted;
 	u16 bf_flags;
 	struct ath_buf_state bf_state;
-	dma_addr_t bf_dmacontext;
 	struct ath_wiphy *aphy;
 };
 
@@ -593,6 +592,8 @@ struct ath_softc {
 	struct delayed_work wiphy_work;
 	unsigned long wiphy_scheduler_int;
 	int wiphy_scheduler_index;
+	struct survey_info *cur_survey;
+	struct survey_info survey[ATH9K_NUM_CHANNELS];
 
 	struct tasklet_struct intr_tq;
 	struct tasklet_struct bcon_tasklet;
@@ -621,8 +622,6 @@ struct ath_softc {
 	struct ath_rx rx;
 	struct ath_tx tx;
 	struct ath_beacon beacon;
-	const struct ath_rate_table *cur_rate_table;
-	enum wireless_mode cur_rate_mode;
 	struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS];
 
 	struct ath_led radio_led;
diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c
index 081192e78a46..4ed010d4ef96 100644
--- a/drivers/net/wireless/ath/ath9k/beacon.c
+++ b/drivers/net/wireless/ath/ath9k/beacon.c
@@ -136,9 +136,10 @@ static struct ath_buf *ath_beacon_generate(struct ieee80211_hw *hw,
 	bf = avp->av_bcbuf;
 	skb = bf->bf_mpdu;
 	if (skb) {
-		dma_unmap_single(sc->dev, bf->bf_dmacontext,
+		dma_unmap_single(sc->dev, bf->bf_buf_addr,
 				 skb->len, DMA_TO_DEVICE);
 		dev_kfree_skb_any(skb);
+		bf->bf_buf_addr = 0;
 	}
 
 	/* Get a new beacon from mac80211 */
@@ -162,12 +163,12 @@ static struct ath_buf *ath_beacon_generate(struct ieee80211_hw *hw,
 		hdr->seq_ctrl |= cpu_to_le16(sc->tx.seq_no);
 	}
 
-	bf->bf_buf_addr = bf->bf_dmacontext =
-		dma_map_single(sc->dev, skb->data,
-			       skb->len, DMA_TO_DEVICE);
+	bf->bf_buf_addr = dma_map_single(sc->dev, skb->data,
+					 skb->len, DMA_TO_DEVICE);
 	if (unlikely(dma_mapping_error(sc->dev, bf->bf_buf_addr))) {
 		dev_kfree_skb_any(skb);
 		bf->bf_mpdu = NULL;
+		bf->bf_buf_addr = 0;
 		ath_print(common, ATH_DBG_FATAL,
 			  "dma_mapping_error on beaconing\n");
 		return NULL;
@@ -252,10 +253,11 @@ int ath_beacon_alloc(struct ath_wiphy *aphy, struct ieee80211_vif *vif)
 	bf = avp->av_bcbuf;
 	if (bf->bf_mpdu != NULL) {
 		skb = bf->bf_mpdu;
-		dma_unmap_single(sc->dev, bf->bf_dmacontext,
+		dma_unmap_single(sc->dev, bf->bf_buf_addr,
 				 skb->len, DMA_TO_DEVICE);
 		dev_kfree_skb_any(skb);
 		bf->bf_mpdu = NULL;
+		bf->bf_buf_addr = 0;
 	}
 
 	/* NB: the beacon data buffer must be 32-bit aligned. */
@@ -296,12 +298,12 @@ int ath_beacon_alloc(struct ath_wiphy *aphy, struct ieee80211_vif *vif)
 		avp->tsf_adjust = cpu_to_le64(0);
 
 	bf->bf_mpdu = skb;
-	bf->bf_buf_addr = bf->bf_dmacontext =
-		dma_map_single(sc->dev, skb->data,
-			       skb->len, DMA_TO_DEVICE);
+	bf->bf_buf_addr = dma_map_single(sc->dev, skb->data,
+					 skb->len, DMA_TO_DEVICE);
 	if (unlikely(dma_mapping_error(sc->dev, bf->bf_buf_addr))) {
 		dev_kfree_skb_any(skb);
 		bf->bf_mpdu = NULL;
+		bf->bf_buf_addr = 0;
 		ath_print(common, ATH_DBG_FATAL,
 			  "dma_mapping_error on beacon alloc\n");
 		return -ENOMEM;
@@ -324,10 +326,11 @@ void ath_beacon_return(struct ath_softc *sc, struct ath_vif *avp)
 		bf = avp->av_bcbuf;
 		if (bf->bf_mpdu != NULL) {
 			struct sk_buff *skb = bf->bf_mpdu;
-			dma_unmap_single(sc->dev, bf->bf_dmacontext,
+			dma_unmap_single(sc->dev, bf->bf_buf_addr,
 					 skb->len, DMA_TO_DEVICE);
 			dev_kfree_skb_any(skb);
 			bf->bf_mpdu = NULL;
+			bf->bf_buf_addr = 0;
 		}
 		list_add_tail(&bf->list, &sc->beacon.bbuf);
 
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c
index 74a4570dc87f..7f764e3d1c0a 100644
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -378,95 +378,6 @@ static const struct file_operations fops_interrupt = {
 	.owner = THIS_MODULE
 };
 
-void ath_debug_stat_rc(struct ath_softc *sc, int final_rate)
-{
-	struct ath_rc_stats *stats;
-
-	stats = &sc->debug.stats.rcstats[final_rate];
-	stats->success++;
-}
-
-void ath_debug_stat_retries(struct ath_softc *sc, int rix,
-			    int xretries, int retries, u8 per)
-{
-	struct ath_rc_stats *stats = &sc->debug.stats.rcstats[rix];
-
-	stats->xretries += xretries;
-	stats->retries += retries;
-	stats->per = per;
-}
-
-static ssize_t read_file_rcstat(struct file *file, char __user *user_buf,
-				size_t count, loff_t *ppos)
-{
-	struct ath_softc *sc = file->private_data;
-	char *buf;
-	unsigned int len = 0, max;
-	int i = 0;
-	ssize_t retval;
-
-	if (sc->cur_rate_table == NULL)
-		return 0;
-
-	max = 80 + sc->cur_rate_table->rate_cnt * 1024 + 1;
-	buf = kmalloc(max, GFP_KERNEL);
-	if (buf == NULL)
-		return -ENOMEM;
-
-	len += sprintf(buf, "%6s %6s %6s "
-		       "%10s %10s %10s %10s\n",
-		       "HT", "MCS", "Rate",
-		       "Success", "Retries", "XRetries", "PER");
-
-	for (i = 0; i < sc->cur_rate_table->rate_cnt; i++) {
-		u32 ratekbps = sc->cur_rate_table->info[i].ratekbps;
-		struct ath_rc_stats *stats = &sc->debug.stats.rcstats[i];
-		char mcs[5];
-		char htmode[5];
-		int used_mcs = 0, used_htmode = 0;
-
-		if (WLAN_RC_PHY_HT(sc->cur_rate_table->info[i].phy)) {
-			used_mcs = snprintf(mcs, 5, "%d",
-				sc->cur_rate_table->info[i].ratecode);
-
-			if (WLAN_RC_PHY_40(sc->cur_rate_table->info[i].phy))
-				used_htmode = snprintf(htmode, 5, "HT40");
-			else if (WLAN_RC_PHY_20(sc->cur_rate_table->info[i].phy))
-				used_htmode = snprintf(htmode, 5, "HT20");
-			else
-				used_htmode = snprintf(htmode, 5, "????");
-		}
-
-		mcs[used_mcs] = '\0';
-		htmode[used_htmode] = '\0';
-
-		len += snprintf(buf + len, max - len,
-			"%6s %6s %3u.%d: "
-			"%10u %10u %10u %10u\n",
-			htmode,
-			mcs,
-			ratekbps / 1000,
-			(ratekbps % 1000) / 100,
-			stats->success,
-			stats->retries,
-			stats->xretries,
-			stats->per);
-	}
-
-	if (len > max)
-		len = max;
-
-	retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
-	kfree(buf);
-	return retval;
-}
-
-static const struct file_operations fops_rcstat = {
-	.read = read_file_rcstat,
-	.open = ath9k_debugfs_open,
-	.owner = THIS_MODULE
-};
-
 static const char * ath_wiphy_state_str(enum ath_wiphy_state state)
 {
 	switch (state) {
@@ -977,10 +888,6 @@ int ath9k_init_debug(struct ath_hw *ah)
 			sc, &fops_interrupt))
 		goto err;
 
-	if (!debugfs_create_file("rcstat", S_IRUSR, sc->debug.debugfs_phy,
-			sc, &fops_rcstat))
-		goto err;
-
 	if (!debugfs_create_file("wiphy", S_IRUSR | S_IWUSR,
 			sc->debug.debugfs_phy, sc, &fops_wiphy))
 		goto err;
diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h
index 822b6f3f23c5..bb0823242ba0 100644
--- a/drivers/net/wireless/ath/ath9k/debug.h
+++ b/drivers/net/wireless/ath/ath9k/debug.h
@@ -80,13 +80,6 @@ struct ath_interrupt_stats {
 	u32 bb_watchdog;
 };
 
-struct ath_rc_stats {
-	u32 success;
-	u32 retries;
-	u32 xretries;
-	u8 per;
-};
-
 /**
  * struct ath_tx_stats - Statistics about TX
  * @tx_pkts_all:  No. of total frames transmitted, including ones that
@@ -160,7 +153,6 @@ struct ath_rx_stats {
 
 struct ath_stats {
 	struct ath_interrupt_stats istats;
-	struct ath_rc_stats rcstats[RATE_TABLE_SIZE];
 	struct ath_tx_stats txstats[ATH9K_NUM_TX_QUEUES];
 	struct ath_rx_stats rxstats;
 };
@@ -177,12 +169,9 @@ void ath9k_exit_debug(struct ath_hw *ah);
 int ath9k_debug_create_root(void);
 void ath9k_debug_remove_root(void);
 void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status);
-void ath_debug_stat_rc(struct ath_softc *sc, int final_rate);
 void ath_debug_stat_tx(struct ath_softc *sc, struct ath_txq *txq,
 		       struct ath_buf *bf, struct ath_tx_status *ts);
 void ath_debug_stat_rx(struct ath_softc *sc, struct ath_rx_status *rs);
-void ath_debug_stat_retries(struct ath_softc *sc, int rix,
-			    int xretries, int retries, u8 per);
 
 #else
 
@@ -209,11 +198,6 @@ static inline void ath_debug_stat_interrupt(struct ath_softc *sc,
 {
 }
 
-static inline void ath_debug_stat_rc(struct ath_softc *sc,
-				     int final_rate)
-{
-}
-
 static inline void ath_debug_stat_tx(struct ath_softc *sc,
 				     struct ath_txq *txq,
 				     struct ath_buf *bf,
@@ -226,11 +210,6 @@ static inline void ath_debug_stat_rx(struct ath_softc *sc,
 {
 }
 
-static inline void ath_debug_stat_retries(struct ath_softc *sc, int rix,
-					  int xretries, int retries, u8 per)
-{
-}
-
 #endif /* CONFIG_ATH9K_DEBUGFS */
 
 #endif /* DEBUG_H */
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
index bbb54bc28a44..3d7b97f1b3ae 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
@@ -566,7 +566,7 @@ static void ath9k_init_crypto(struct ath9k_htc_priv *priv)
 
 static void ath9k_init_channels_rates(struct ath9k_htc_priv *priv)
 {
-	if (test_bit(ATH9K_MODE_11G, priv->ah->caps.wireless_modes)) {
+	if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ) {
 		priv->sbands[IEEE80211_BAND_2GHZ].channels =
 			ath9k_2ghz_channels;
 		priv->sbands[IEEE80211_BAND_2GHZ].band = IEEE80211_BAND_2GHZ;
@@ -577,7 +577,7 @@ static void ath9k_init_channels_rates(struct ath9k_htc_priv *priv)
 			ARRAY_SIZE(ath9k_legacy_rates);
 	}
 
-	if (test_bit(ATH9K_MODE_11A, priv->ah->caps.wireless_modes)) {
+	if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ) {
 		priv->sbands[IEEE80211_BAND_5GHZ].channels = ath9k_5ghz_channels;
 		priv->sbands[IEEE80211_BAND_5GHZ].band = IEEE80211_BAND_5GHZ;
 		priv->sbands[IEEE80211_BAND_5GHZ].n_channels =
@@ -740,18 +740,18 @@ static void ath9k_set_hw_capab(struct ath9k_htc_priv *priv,
 	hw->extra_tx_headroom = sizeof(struct tx_frame_hdr) +
 		sizeof(struct htc_frame_hdr) + 4;
 
-	if (test_bit(ATH9K_MODE_11G, priv->ah->caps.wireless_modes))
+	if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ)
 		hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
 			&priv->sbands[IEEE80211_BAND_2GHZ];
-	if (test_bit(ATH9K_MODE_11A, priv->ah->caps.wireless_modes))
+	if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ)
 		hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
 			&priv->sbands[IEEE80211_BAND_5GHZ];
 
 	if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_HT) {
-		if (test_bit(ATH9K_MODE_11G, priv->ah->caps.wireless_modes))
+		if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ)
 			setup_ht_cap(priv,
 				     &priv->sbands[IEEE80211_BAND_2GHZ].ht_cap);
-		if (test_bit(ATH9K_MODE_11A, priv->ah->caps.wireless_modes))
+		if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ)
 			setup_ht_cap(priv,
 				     &priv->sbands[IEEE80211_BAND_5GHZ].ht_cap);
 	}
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
index f12591f5d02a..55c80866dfc6 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
@@ -1454,6 +1454,7 @@ out:
 	FIF_PSPOLL |				\
 	FIF_OTHER_BSS |				\
 	FIF_BCN_PRBRESP_PROMISC |		\
+	FIF_PROBE_REQ |				\
 	FIF_FCSFAIL)
 
 static void ath9k_htc_configure_filter(struct ieee80211_hw *hw,
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
index c99600aff76d..3d19b5bc937f 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
@@ -369,8 +369,7 @@ u32 ath9k_htc_calcrxfilter(struct ath9k_htc_priv *priv)
 		| ATH9K_RX_FILTER_UCAST | ATH9K_RX_FILTER_BCAST
 		| ATH9K_RX_FILTER_MCAST;
 
-	/* If not a STA, enable processing of Probe Requests */
-	if (ah->opmode != NL80211_IFTYPE_STATION)
+	if (priv->rxfilter & FIF_PROBE_REQ)
 		rfilt |= ATH9K_RX_FILTER_PROBEREQ;
 
 	/*
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 05e9935ef160..cc13ee117823 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -88,29 +88,32 @@ static void ath9k_hw_ani_cache_ini_regs(struct ath_hw *ah)
 /* Helper Functions */
 /********************/
 
-static u32 ath9k_hw_mac_clks(struct ath_hw *ah, u32 usecs)
+static void ath9k_hw_set_clockrate(struct ath_hw *ah)
 {
 	struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;
+	struct ath_common *common = ath9k_hw_common(ah);
+	unsigned int clockrate;
 
 	if (!ah->curchan) /* should really check for CCK instead */
-		return usecs *ATH9K_CLOCK_RATE_CCK;
-	if (conf->channel->band == IEEE80211_BAND_2GHZ)
-		return usecs *ATH9K_CLOCK_RATE_2GHZ_OFDM;
-
-	if (ah->caps.hw_caps & ATH9K_HW_CAP_FASTCLOCK)
-		return usecs * ATH9K_CLOCK_FAST_RATE_5GHZ_OFDM;
+		clockrate = ATH9K_CLOCK_RATE_CCK;
+	else if (conf->channel->band == IEEE80211_BAND_2GHZ)
+		clockrate = ATH9K_CLOCK_RATE_2GHZ_OFDM;
+	else if (ah->caps.hw_caps & ATH9K_HW_CAP_FASTCLOCK)
+		clockrate = ATH9K_CLOCK_FAST_RATE_5GHZ_OFDM;
 	else
-		return usecs * ATH9K_CLOCK_RATE_5GHZ_OFDM;
+		clockrate = ATH9K_CLOCK_RATE_5GHZ_OFDM;
+
+	if (conf_is_ht40(conf))
+		clockrate *= 2;
+
+	common->clockrate = clockrate;
 }
 
 static u32 ath9k_hw_mac_to_clks(struct ath_hw *ah, u32 usecs)
 {
-	struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;
+	struct ath_common *common = ath9k_hw_common(ah);
 
-	if (conf_is_ht40(conf))
-		return ath9k_hw_mac_clks(ah, usecs) * 2;
-	else
-		return ath9k_hw_mac_clks(ah, usecs);
+	return usecs * common->clockrate;
 }
 
 bool ath9k_hw_wait(struct ath_hw *ah, u32 reg, u32 mask, u32 val, u32 timeout)
@@ -1156,6 +1159,7 @@ static bool ath9k_hw_channel_change(struct ath_hw *ah,
 			  "Failed to set channel\n");
 		return false;
 	}
+	ath9k_hw_set_clockrate(ah);
 
 	ah->eep_ops->set_txpower(ah, chan,
 			     ath9k_regd_get_ctl(regulatory, chan),
@@ -1368,6 +1372,8 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
 	if (r)
 		return r;
 
+	ath9k_hw_set_clockrate(ah);
+
 	ENABLE_REGWRITE_BUFFER(ah);
 
 	for (i = 0; i < AR_NUM_DCU; i++)
@@ -1794,37 +1800,11 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
 		return -EINVAL;
 	}
 
-	bitmap_zero(pCap->wireless_modes, ATH9K_MODE_MAX);
-
-	if (eeval & AR5416_OPFLAGS_11A) {
-		set_bit(ATH9K_MODE_11A, pCap->wireless_modes);
-		if (ah->config.ht_enable) {
-			if (!(eeval & AR5416_OPFLAGS_N_5G_HT20))
-				set_bit(ATH9K_MODE_11NA_HT20,
-					pCap->wireless_modes);
-			if (!(eeval & AR5416_OPFLAGS_N_5G_HT40)) {
-				set_bit(ATH9K_MODE_11NA_HT40PLUS,
-					pCap->wireless_modes);
-				set_bit(ATH9K_MODE_11NA_HT40MINUS,
-					pCap->wireless_modes);
-			}
-		}
-	}
+	if (eeval & AR5416_OPFLAGS_11A)
+		pCap->hw_caps |= ATH9K_HW_CAP_5GHZ;
 
-	if (eeval & AR5416_OPFLAGS_11G) {
-		set_bit(ATH9K_MODE_11G, pCap->wireless_modes);
-		if (ah->config.ht_enable) {
-			if (!(eeval & AR5416_OPFLAGS_N_2G_HT20))
-				set_bit(ATH9K_MODE_11NG_HT20,
-					pCap->wireless_modes);
-			if (!(eeval & AR5416_OPFLAGS_N_2G_HT40)) {
-				set_bit(ATH9K_MODE_11NG_HT40PLUS,
-					pCap->wireless_modes);
-				set_bit(ATH9K_MODE_11NG_HT40MINUS,
-					pCap->wireless_modes);
-			}
-		}
-	}
+	if (eeval & AR5416_OPFLAGS_11G)
+		pCap->hw_caps |= ATH9K_HW_CAP_2GHZ;
 
 	pCap->tx_chainmask = ah->eep_ops->get_eeprom(ah, EEP_TX_MASK);
 	/*
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 87627dd63463..d032939768b0 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -61,6 +61,8 @@
 
 #define ATH9K_RSSI_BAD			-128
 
+#define ATH9K_NUM_CHANNELS	38
+
 /* Register read/write primitives */
 #define REG_WRITE(_ah, _reg, _val) \
 	ath9k_hw_common(_ah)->ops->write((_ah), (_val), (_reg))
@@ -162,18 +164,6 @@ enum ath_ini_subsys {
 	ATH_INI_NUM_SPLIT,
 };
 
-enum wireless_mode {
-	ATH9K_MODE_11A = 0,
-	ATH9K_MODE_11G,
-	ATH9K_MODE_11NA_HT20,
-	ATH9K_MODE_11NG_HT20,
-	ATH9K_MODE_11NA_HT40PLUS,
-	ATH9K_MODE_11NA_HT40MINUS,
-	ATH9K_MODE_11NG_HT40PLUS,
-	ATH9K_MODE_11NG_HT40MINUS,
-	ATH9K_MODE_MAX,
-};
-
 enum ath9k_hw_caps {
 	ATH9K_HW_CAP_HT                         = BIT(0),
 	ATH9K_HW_CAP_RFSILENT                   = BIT(1),
@@ -188,11 +178,12 @@ enum ath9k_hw_caps {
 	ATH9K_HW_CAP_SGI_20			= BIT(10),
 	ATH9K_HW_CAP_PAPRD			= BIT(11),
 	ATH9K_HW_CAP_ANT_DIV_COMB		= BIT(12),
+	ATH9K_HW_CAP_2GHZ			= BIT(13),
+	ATH9K_HW_CAP_5GHZ			= BIT(14),
 };
 
 struct ath9k_hw_capabilities {
 	u32 hw_caps; /* ATH9K_HW_CAP_* from ath9k_hw_caps */
-	DECLARE_BITMAP(wireless_modes, ATH9K_MODE_MAX); /* ATH9K_MODE_* */
 	u16 total_queues;
 	u16 keycache_size;
 	u16 low_5ghz_chan, high_5ghz_chan;
@@ -618,7 +609,7 @@ struct ath_hw {
 	struct ath9k_hw_version hw_version;
 	struct ath9k_ops_config config;
 	struct ath9k_hw_capabilities caps;
-	struct ath9k_channel channels[38];
+	struct ath9k_channel channels[ATH9K_NUM_CHANNELS];
 	struct ath9k_channel *curchan;
 
 	union {
@@ -740,8 +731,6 @@ struct ath_hw {
 	int coarse_low[5];
 	int firpwr[5];
 	enum ath9k_ani_cmd ani_function;
-	struct ath_cycle_counters cc, cc_delta;
-	int32_t listen_time;
 
 	/* Bluetooth coexistance */
 	struct ath_btcoex_hw btcoex_hw;
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index d76003c06fe4..bc6c4df9712c 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -481,7 +481,11 @@ static int ath9k_init_channels_rates(struct ath_softc *sc)
 {
 	void *channels;
 
-	if (test_bit(ATH9K_MODE_11G, sc->sc_ah->caps.wireless_modes)) {
+	BUILD_BUG_ON(ARRAY_SIZE(ath9k_2ghz_chantable) +
+		     ARRAY_SIZE(ath9k_5ghz_chantable) !=
+		     ATH9K_NUM_CHANNELS);
+
+	if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ) {
 		channels = kmemdup(ath9k_2ghz_chantable,
 			sizeof(ath9k_2ghz_chantable), GFP_KERNEL);
 		if (!channels)
@@ -496,7 +500,7 @@ static int ath9k_init_channels_rates(struct ath_softc *sc)
 			ARRAY_SIZE(ath9k_legacy_rates);
 	}
 
-	if (test_bit(ATH9K_MODE_11A, sc->sc_ah->caps.wireless_modes)) {
+	if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ) {
 		channels = kmemdup(ath9k_5ghz_chantable,
 			sizeof(ath9k_5ghz_chantable), GFP_KERNEL);
 		if (!channels) {
@@ -677,17 +681,17 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
 	hw->rate_control_algorithm = "ath9k_rate_control";
 #endif
 
-	if (test_bit(ATH9K_MODE_11G, sc->sc_ah->caps.wireless_modes))
+	if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ)
 		hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
 			&sc->sbands[IEEE80211_BAND_2GHZ];
-	if (test_bit(ATH9K_MODE_11A, sc->sc_ah->caps.wireless_modes))
+	if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ)
 		hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
 			&sc->sbands[IEEE80211_BAND_5GHZ];
 
 	if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) {
-		if (test_bit(ATH9K_MODE_11G, sc->sc_ah->caps.wireless_modes))
+		if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ)
 			setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_2GHZ].ht_cap);
-		if (test_bit(ATH9K_MODE_11A, sc->sc_ah->caps.wireless_modes))
+		if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ)
 			setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_5GHZ].ht_cap);
 	}
 
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 74c2dc8a8b8a..3ff0e476c2b3 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -18,36 +18,6 @@
 #include "ath9k.h"
 #include "btcoex.h"
 
-static void ath_cache_conf_rate(struct ath_softc *sc,
-				struct ieee80211_conf *conf)
-{
-	switch (conf->channel->band) {
-	case IEEE80211_BAND_2GHZ:
-		if (conf_is_ht20(conf))
-			sc->cur_rate_mode = ATH9K_MODE_11NG_HT20;
-		else if (conf_is_ht40_minus(conf))
-			sc->cur_rate_mode = ATH9K_MODE_11NG_HT40MINUS;
-		else if (conf_is_ht40_plus(conf))
-			sc->cur_rate_mode = ATH9K_MODE_11NG_HT40PLUS;
-		else
-			sc->cur_rate_mode = ATH9K_MODE_11G;
-		break;
-	case IEEE80211_BAND_5GHZ:
-		if (conf_is_ht20(conf))
-			sc->cur_rate_mode = ATH9K_MODE_11NA_HT20;
-		else if (conf_is_ht40_minus(conf))
-			sc->cur_rate_mode = ATH9K_MODE_11NA_HT40MINUS;
-		else if (conf_is_ht40_plus(conf))
-			sc->cur_rate_mode = ATH9K_MODE_11NA_HT40PLUS;
-		else
-			sc->cur_rate_mode = ATH9K_MODE_11A;
-		break;
-	default:
-		BUG_ON(1);
-		break;
-	}
-}
-
 static void ath_update_txpow(struct ath_softc *sc)
 {
 	struct ath_hw *ah = sc->sc_ah;
@@ -121,6 +91,7 @@ bool ath9k_setpower(struct ath_softc *sc, enum ath9k_power_mode mode)
 
 void ath9k_ps_wakeup(struct ath_softc *sc)
 {
+	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
 	unsigned long flags;
 
 	spin_lock_irqsave(&sc->sc_pm_lock, flags);
@@ -129,18 +100,33 @@ void ath9k_ps_wakeup(struct ath_softc *sc)
 
 	ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE);
 
+	/*
+	 * While the hardware is asleep, the cycle counters contain no
+	 * useful data. Better clear them now so that they don't mess up
+	 * survey data results.
+	 */
+	spin_lock(&common->cc_lock);
+	ath_hw_cycle_counters_update(common);
+	memset(&common->cc_survey, 0, sizeof(common->cc_survey));
+	spin_unlock(&common->cc_lock);
+
  unlock:
 	spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
 }
 
 void ath9k_ps_restore(struct ath_softc *sc)
 {
+	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
 	unsigned long flags;
 
 	spin_lock_irqsave(&sc->sc_pm_lock, flags);
 	if (--sc->ps_usecount != 0)
 		goto unlock;
 
+	spin_lock(&common->cc_lock);
+	ath_hw_cycle_counters_update(common);
+	spin_unlock(&common->cc_lock);
+
 	if (sc->ps_idle)
 		ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_FULL_SLEEP);
 	else if (sc->ps_enabled &&
@@ -175,6 +161,45 @@ static void ath_start_ani(struct ath_common *common)
 			msecs_to_jiffies((u32)ah->config.ani_poll_interval));
 }
 
+static void ath_update_survey_nf(struct ath_softc *sc, int channel)
+{
+	struct ath_hw *ah = sc->sc_ah;
+	struct ath9k_channel *chan = &ah->channels[channel];
+	struct survey_info *survey = &sc->survey[channel];
+
+	if (chan->noisefloor) {
+		survey->filled |= SURVEY_INFO_NOISE_DBM;
+		survey->noise = chan->noisefloor;
+	}
+}
+
+static void ath_update_survey_stats(struct ath_softc *sc)
+{
+	struct ath_hw *ah = sc->sc_ah;
+	struct ath_common *common = ath9k_hw_common(ah);
+	int pos = ah->curchan - &ah->channels[0];
+	struct survey_info *survey = &sc->survey[pos];
+	struct ath_cycle_counters *cc = &common->cc_survey;
+	unsigned int div = common->clockrate * 1000;
+
+	if (ah->power_mode == ATH9K_PM_AWAKE)
+		ath_hw_cycle_counters_update(common);
+
+	if (cc->cycles > 0) {
+		survey->filled |= SURVEY_INFO_CHANNEL_TIME |
+			SURVEY_INFO_CHANNEL_TIME_BUSY |
+			SURVEY_INFO_CHANNEL_TIME_RX |
+			SURVEY_INFO_CHANNEL_TIME_TX;
+		survey->channel_time += cc->cycles / div;
+		survey->channel_time_busy += cc->rx_busy / div;
+		survey->channel_time_rx += cc->rx_frame / div;
+		survey->channel_time_tx += cc->tx_frame / div;
+	}
+	memset(cc, 0, sizeof(*cc));
+
+	ath_update_survey_nf(sc, pos);
+}
+
 /*
  * Set/change channels.  If the channel is really being changed, it's done
  * by reseting the chip.  To accomplish this we must first cleanup any pending
@@ -251,7 +276,6 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
 		goto ps_restore;
 	}
 
-	ath_cache_conf_rate(sc, &hw->conf);
 	ath_update_txpow(sc);
 	ath9k_hw_set_interrupts(ah, ah->imask);
 
@@ -399,6 +423,7 @@ void ath_ani_calibrate(unsigned long data)
 	bool aniflag = false;
 	unsigned int timestamp = jiffies_to_msecs(jiffies);
 	u32 cal_interval, short_cal_interval, long_cal_interval;
+	unsigned long flags;
 
 	if (ah->caldata && ah->caldata->nfcal_interference)
 		long_cal_interval = ATH_LONG_CALINTERVAL_INT;
@@ -449,8 +474,12 @@ void ath_ani_calibrate(unsigned long data)
 	/* Skip all processing if there's nothing to do. */
 	if (longcal || shortcal || aniflag) {
 		/* Call ANI routine if necessary */
-		if (aniflag)
+		if (aniflag) {
+			spin_lock_irqsave(&common->cc_lock, flags);
 			ath9k_hw_ani_monitor(ah, ah->curchan);
+			ath_update_survey_stats(sc);
+			spin_unlock_irqrestore(&common->cc_lock, flags);
+		}
 
 		/* Perform calibration if necessary */
 		if (longcal || shortcal) {
@@ -635,6 +664,7 @@ irqreturn_t ath_isr(int irq, void *dev)
 
 	struct ath_softc *sc = dev;
 	struct ath_hw *ah = sc->sc_ah;
+	struct ath_common *common = ath9k_hw_common(ah);
 	enum ath9k_int status;
 	bool sched = false;
 
@@ -684,7 +714,12 @@ irqreturn_t ath_isr(int irq, void *dev)
 
 	if ((ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) &&
 	    (status & ATH9K_INT_BB_WATCHDOG)) {
+
+		spin_lock(&common->cc_lock);
+		ath_hw_cycle_counters_update(common);
 		ar9003_hw_bb_watchdog_dbg_info(ah);
+		spin_unlock(&common->cc_lock);
+
 		goto chip_reset;
 	}
 
@@ -713,7 +748,9 @@ irqreturn_t ath_isr(int irq, void *dev)
 		 * it will clear whatever condition caused
 		 * the interrupt.
 		 */
+		spin_lock(&common->cc_lock);
 		ath9k_hw_proc_mib_event(ah);
+		spin_unlock(&common->cc_lock);
 		ath9k_hw_set_interrupts(ah, ah->imask);
 	}
 
@@ -945,8 +982,6 @@ int ath_reset(struct ath_softc *sc, bool retry_tx)
 	 * that changes the channel so update any state that
 	 * might change as a result.
 	 */
-	ath_cache_conf_rate(sc, &hw->conf);
-
 	ath_update_txpow(sc);
 
 	if ((sc->sc_flags & SC_OP_BEACONS) || !(sc->sc_flags & (SC_OP_OFFCHANNEL)))
@@ -1153,8 +1188,6 @@ static int ath9k_start(struct ieee80211_hw *hw)
 	if (ah->caps.hw_caps & ATH9K_HW_CAP_HT)
 		ah->imask |= ATH9K_INT_CST;
 
-	ath_cache_conf_rate(sc, &hw->conf);
-
 	sc->sc_flags &= ~SC_OP_INVALID;
 
 	/* Disable BMISS interrupt when we're not associated */
@@ -1522,7 +1555,8 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
 {
 	struct ath_wiphy *aphy = hw->priv;
 	struct ath_softc *sc = aphy->sc;
-	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
+	struct ath_hw *ah = sc->sc_ah;
+	struct ath_common *common = ath9k_hw_common(ah);
 	struct ieee80211_conf *conf = &hw->conf;
 	bool disable_radio;
 
@@ -1588,6 +1622,11 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
 	if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
 		struct ieee80211_channel *curchan = hw->conf.channel;
 		int pos = curchan->hw_value;
+		int old_pos = -1;
+		unsigned long flags;
+
+		if (ah->curchan)
+			old_pos = ah->curchan - &ah->channels[0];
 
 		aphy->chan_idx = pos;
 		aphy->chan_is_ht = conf_is_ht(conf);
@@ -1615,12 +1654,45 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
 
 		ath_update_chainmask(sc, conf_is_ht(conf));
 
+		/* update survey stats for the old channel before switching */
+		spin_lock_irqsave(&common->cc_lock, flags);
+		ath_update_survey_stats(sc);
+		spin_unlock_irqrestore(&common->cc_lock, flags);
+
+		/*
+		 * If the operating channel changes, change the survey in-use flags
+		 * along with it.
+		 * Reset the survey data for the new channel, unless we're switching
+		 * back to the operating channel from an off-channel operation.
+		 */
+		if (!(hw->conf.flags & IEEE80211_CONF_OFFCHANNEL) &&
+		    sc->cur_survey != &sc->survey[pos]) {
+
+			if (sc->cur_survey)
+				sc->cur_survey->filled &= ~SURVEY_INFO_IN_USE;
+
+			sc->cur_survey = &sc->survey[pos];
+
+			memset(sc->cur_survey, 0, sizeof(struct survey_info));
+			sc->cur_survey->filled |= SURVEY_INFO_IN_USE;
+		} else if (!(sc->survey[pos].filled & SURVEY_INFO_IN_USE)) {
+			memset(&sc->survey[pos], 0, sizeof(struct survey_info));
+		}
+
 		if (ath_set_channel(sc, hw, &sc->sc_ah->channels[pos]) < 0) {
 			ath_print(common, ATH_DBG_FATAL,
 				  "Unable to set channel\n");
 			mutex_unlock(&sc->mutex);
 			return -EINVAL;
 		}
+
+		/*
+		 * The most recent snapshot of channel->noisefloor for the old
+		 * channel is only available after the hardware reset. Copy it to
+		 * the survey stats now.
+		 */
+		if (old_pos >= 0)
+			ath_update_survey_nf(sc, old_pos);
 	}
 
 skip_chan_change:
@@ -1651,6 +1723,7 @@ skip_chan_change:
 	FIF_PSPOLL |				\
 	FIF_OTHER_BSS |				\
 	FIF_BCN_PRBRESP_PROMISC |		\
+	FIF_PROBE_REQ |				\
 	FIF_FCSFAIL)
 
 /* FIXME: sc->sc_full_reset ? */
@@ -1990,9 +2063,15 @@ static int ath9k_get_survey(struct ieee80211_hw *hw, int idx,
 {
 	struct ath_wiphy *aphy = hw->priv;
 	struct ath_softc *sc = aphy->sc;
-	struct ath_hw *ah = sc->sc_ah;
+	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
 	struct ieee80211_supported_band *sband;
-	struct ath9k_channel *chan;
+	struct ieee80211_channel *chan;
+	unsigned long flags;
+	int pos;
+
+	spin_lock_irqsave(&common->cc_lock, flags);
+	if (idx == 0)
+		ath_update_survey_stats(sc);
 
 	sband = hw->wiphy->bands[IEEE80211_BAND_2GHZ];
 	if (sband && idx >= sband->n_channels) {
@@ -2003,21 +2082,17 @@ static int ath9k_get_survey(struct ieee80211_hw *hw, int idx,
 	if (!sband)
 		sband = hw->wiphy->bands[IEEE80211_BAND_5GHZ];
 
-	if (!sband || idx >= sband->n_channels)
-	    return -ENOENT;
-
-	survey->channel = &sband->channels[idx];
-	chan = &ah->channels[survey->channel->hw_value];
-	survey->filled = 0;
-
-	if (chan == ah->curchan)
-		survey->filled |= SURVEY_INFO_IN_USE;
-
-	if (chan->noisefloor) {
-		survey->filled |= SURVEY_INFO_NOISE_DBM;
-		survey->noise = chan->noisefloor;
+	if (!sband || idx >= sband->n_channels) {
+		spin_unlock_irqrestore(&common->cc_lock, flags);
+		return -ENOENT;
 	}
 
+	chan = &sband->channels[idx];
+	pos = chan->hw_value;
+	memcpy(survey, &sc->survey[pos], sizeof(*survey));
+	survey->channel = chan;
+	spin_unlock_irqrestore(&common->cc_lock, flags);
+
 	return 0;
 }
 
diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c
index ce1cd6d85847..0cee90cf8dc9 100644
--- a/drivers/net/wireless/ath/ath9k/rc.c
+++ b/drivers/net/wireless/ath/ath9k/rc.c
@@ -302,7 +302,7 @@ static const struct ath_rate_table ar5416_11ng_ratetable = {
 		[64] = {  RC_INVALID, WLAN_RC_PHY_HT_40_TS, 243000,
 			205100, 20, 20, 8, 64, 65, 65 }, /* 243 Mb */
 		[65] = {  RC_INVALID, WLAN_RC_PHY_HT_40_TS_HGI, 270000,
-			224700, 20, 20, 8, 64, 65, 65 }, /* 170 Mb */
+			224700, 20, 20, 8, 64, 65, 65 }, /* 270 Mb */
 		[66] = {  RC_HT_T_40, WLAN_RC_PHY_HT_40_TS, 324000,
 			263100, 21, 21, 8, 66, 67, 67 }, /* 324 Mb */
 		[67] = {  RC_HT_T_40, WLAN_RC_PHY_HT_40_TS_HGI, 360000,
@@ -378,17 +378,6 @@ static const struct ath_rate_table ar5416_11g_ratetable = {
 	0,   /* Phy rates allowed initially */
 };
 
-static const struct ath_rate_table *hw_rate_table[ATH9K_MODE_MAX] = {
-	[ATH9K_MODE_11A] = &ar5416_11a_ratetable,
-	[ATH9K_MODE_11G] = &ar5416_11g_ratetable,
-	[ATH9K_MODE_11NA_HT20] = &ar5416_11na_ratetable,
-	[ATH9K_MODE_11NG_HT20] = &ar5416_11ng_ratetable,
-	[ATH9K_MODE_11NA_HT40PLUS] = &ar5416_11na_ratetable,
-	[ATH9K_MODE_11NA_HT40MINUS] = &ar5416_11na_ratetable,
-	[ATH9K_MODE_11NG_HT40PLUS] = &ar5416_11ng_ratetable,
-	[ATH9K_MODE_11NG_HT40MINUS] = &ar5416_11ng_ratetable,
-};
-
 static int ath_rc_get_rateindex(const struct ath_rate_table *rate_table,
 				struct ieee80211_tx_rate *rate);
 
@@ -791,7 +780,7 @@ static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
 	 */
 	try_per_rate = 4;
 
-	rate_table = sc->cur_rate_table;
+	rate_table = ath_rc_priv->rate_table;
 	rix = ath_rc_get_highest_rix(sc, ath_rc_priv, rate_table, &is_probe);
 
 	/*
@@ -1026,6 +1015,16 @@ static bool ath_rc_update_per(struct ath_softc *sc,
 	return state_change;
 }
 
+static void ath_debug_stat_retries(struct ath_rate_priv *rc, int rix,
+				   int xretries, int retries, u8 per)
+{
+	struct ath_rc_stats *stats = &rc->rcstats[rix];
+
+	stats->xretries += xretries;
+	stats->retries += retries;
+	stats->per = per;
+}
+
 /* Update PER, RSSI and whatever else that the code thinks it is doing.
    If you can make sense of all this, you really need to go out more. */
 
@@ -1038,7 +1037,7 @@ static void ath_rc_update_ht(struct ath_softc *sc,
 	int rate;
 	u8 last_per;
 	bool state_change = false;
-	const struct ath_rate_table *rate_table = sc->cur_rate_table;
+	const struct ath_rate_table *rate_table = ath_rc_priv->rate_table;
 	int size = ath_rc_priv->rate_table_size;
 
 	if ((tx_rate < 0) || (tx_rate > rate_table->rate_cnt))
@@ -1098,7 +1097,7 @@ static void ath_rc_update_ht(struct ath_softc *sc,
 		ath_rc_priv->per_down_time = now_msec;
 	}
 
-	ath_debug_stat_retries(sc, tx_rate, xretries, retries,
+	ath_debug_stat_retries(ath_rc_priv, tx_rate, xretries, retries,
 			       ath_rc_priv->per[tx_rate]);
 
 }
@@ -1140,7 +1139,7 @@ static void ath_rc_tx_status(struct ath_softc *sc,
 	u8 flags;
 	u32 i = 0, rix;
 
-	rate_table = sc->cur_rate_table;
+	rate_table = ath_rc_priv->rate_table;
 
 	/*
 	 * If the first rate is not the final index, there
@@ -1190,39 +1189,23 @@ static void ath_rc_tx_status(struct ath_softc *sc,
 static const
 struct ath_rate_table *ath_choose_rate_table(struct ath_softc *sc,
 					     enum ieee80211_band band,
-					     bool is_ht,
-					     bool is_cw_40)
+					     bool is_ht)
 {
-	int mode = 0;
 	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
 
 	switch(band) {
 	case IEEE80211_BAND_2GHZ:
-		mode = ATH9K_MODE_11G;
 		if (is_ht)
-			mode = ATH9K_MODE_11NG_HT20;
-		if (is_cw_40)
-			mode = ATH9K_MODE_11NG_HT40PLUS;
-		break;
+			return &ar5416_11ng_ratetable;
+		return &ar5416_11g_ratetable;
 	case IEEE80211_BAND_5GHZ:
-		mode = ATH9K_MODE_11A;
 		if (is_ht)
-			mode = ATH9K_MODE_11NA_HT20;
-		if (is_cw_40)
-			mode = ATH9K_MODE_11NA_HT40PLUS;
-		break;
+			return &ar5416_11na_ratetable;
+		return &ar5416_11a_ratetable;
 	default:
 		ath_print(common, ATH_DBG_CONFIG, "Invalid band\n");
 		return NULL;
 	}
-
-	BUG_ON(mode >= ATH9K_MODE_MAX);
-
-	ath_print(common, ATH_DBG_CONFIG,
-		  "Choosing rate table for mode: %d\n", mode);
-
-	sc->cur_rate_mode = mode;
-	return hw_rate_table[mode];
 }
 
 static void ath_rc_init(struct ath_softc *sc,
@@ -1293,7 +1276,7 @@ static void ath_rc_init(struct ath_softc *sc,
 	ath_rc_priv->max_valid_rate = k;
 	ath_rc_sort_validrates(rate_table, ath_rc_priv);
 	ath_rc_priv->rate_max_phy = ath_rc_priv->valid_rate_index[k-4];
-	sc->cur_rate_table = rate_table;
+	ath_rc_priv->rate_table = rate_table;
 
 	ath_print(common, ATH_DBG_CONFIG,
 		  "RC Initialized with capabilities: 0x%x\n",
@@ -1340,6 +1323,15 @@ static bool ath_tx_aggr_check(struct ath_softc *sc, struct ath_node *an,
 /* mac80211 Rate Control callbacks */
 /***********************************/
 
+static void ath_debug_stat_rc(struct ath_rate_priv *rc, int final_rate)
+{
+	struct ath_rc_stats *stats;
+
+	stats = &rc->rcstats[final_rate];
+	stats->success++;
+}
+
+
 static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband,
 			  struct ieee80211_sta *sta, void *priv_sta,
 			  struct sk_buff *skb)
@@ -1375,6 +1367,12 @@ static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband,
 	if (tx_info->flags & IEEE80211_TX_STAT_TX_FILTERED)
 		return;
 
+	if (!(tx_info->flags & IEEE80211_TX_STAT_AMPDU)) {
+		tx_info->status.ampdu_ack_len =
+			(tx_info->flags & IEEE80211_TX_STAT_ACK ? 1 : 0);
+		tx_info->status.ampdu_len = 1;
+	}
+
 	/*
 	 * If an underrun error is seen assume it as an excessive retry only
 	 * if max frame trigger level has been reached (2 KB for singel stream,
@@ -1413,8 +1411,9 @@ static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband,
 		}
 	}
 
-	ath_debug_stat_rc(sc, ath_rc_get_rateindex(sc->cur_rate_table,
-		&tx_info->status.rates[final_ts_idx]));
+	ath_debug_stat_rc(ath_rc_priv,
+		ath_rc_get_rateindex(ath_rc_priv->rate_table,
+			&tx_info->status.rates[final_ts_idx]));
 }
 
 static void ath_rate_init(void *priv, struct ieee80211_supported_band *sband,
@@ -1454,14 +1453,8 @@ static void ath_rate_init(void *priv, struct ieee80211_supported_band *sband,
 
 	/* Choose rate table first */
 
-	if ((sc->sc_ah->opmode == NL80211_IFTYPE_STATION) ||
-	    (sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT) ||
-	    (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC)) {
-		rate_table = ath_choose_rate_table(sc, sband->band,
-		                      sta->ht_cap.ht_supported, is_cw40);
-	} else {
-		rate_table = hw_rate_table[sc->cur_rate_mode];
-	}
+	rate_table = ath_choose_rate_table(sc, sband->band,
+	                      sta->ht_cap.ht_supported);
 
 	ath_rc_priv->ht_cap = ath_rc_build_ht_caps(sc, sta, is_cw40, is_sgi);
 	ath_rc_init(sc, priv_sta, sband, sta, rate_table);
@@ -1501,8 +1494,7 @@ static void ath_rate_update(void *priv, struct ieee80211_supported_band *sband,
 
 		if ((local_cw40 != oper_cw40) || (local_sgi != oper_sgi)) {
 			rate_table = ath_choose_rate_table(sc, sband->band,
-						   sta->ht_cap.ht_supported,
-						   oper_cw40);
+						   sta->ht_cap.ht_supported);
 			ath_rc_priv->ht_cap = ath_rc_build_ht_caps(sc, sta,
 						   oper_cw40, oper_sgi);
 			ath_rc_init(sc, priv_sta, sband, sta, rate_table);
@@ -1510,11 +1502,98 @@ static void ath_rate_update(void *priv, struct ieee80211_supported_band *sband,
 			ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_CONFIG,
 				  "Operating HT Bandwidth changed to: %d\n",
 				  sc->hw->conf.channel_type);
-			sc->cur_rate_table = hw_rate_table[sc->cur_rate_mode];
 		}
 	}
 }
 
+#ifdef CONFIG_ATH9K_DEBUGFS
+
+static int ath9k_debugfs_open(struct inode *inode, struct file *file)
+{
+	file->private_data = inode->i_private;
+	return 0;
+}
+
+static ssize_t read_file_rcstat(struct file *file, char __user *user_buf,
+				size_t count, loff_t *ppos)
+{
+	struct ath_rate_priv *rc = file->private_data;
+	char *buf;
+	unsigned int len = 0, max;
+	int i = 0;
+	ssize_t retval;
+
+	if (rc->rate_table == NULL)
+		return 0;
+
+	max = 80 + rc->rate_table->rate_cnt * 1024 + 1;
+	buf = kmalloc(max, GFP_KERNEL);
+	if (buf == NULL)
+		return -ENOMEM;
+
+	len += sprintf(buf, "%6s %6s %6s "
+		       "%10s %10s %10s %10s\n",
+		       "HT", "MCS", "Rate",
+		       "Success", "Retries", "XRetries", "PER");
+
+	for (i = 0; i < rc->rate_table->rate_cnt; i++) {
+		u32 ratekbps = rc->rate_table->info[i].ratekbps;
+		struct ath_rc_stats *stats = &rc->rcstats[i];
+		char mcs[5];
+		char htmode[5];
+		int used_mcs = 0, used_htmode = 0;
+
+		if (WLAN_RC_PHY_HT(rc->rate_table->info[i].phy)) {
+			used_mcs = snprintf(mcs, 5, "%d",
+				rc->rate_table->info[i].ratecode);
+
+			if (WLAN_RC_PHY_40(rc->rate_table->info[i].phy))
+				used_htmode = snprintf(htmode, 5, "HT40");
+			else if (WLAN_RC_PHY_20(rc->rate_table->info[i].phy))
+				used_htmode = snprintf(htmode, 5, "HT20");
+			else
+				used_htmode = snprintf(htmode, 5, "????");
+		}
+
+		mcs[used_mcs] = '\0';
+		htmode[used_htmode] = '\0';
+
+		len += snprintf(buf + len, max - len,
+			"%6s %6s %3u.%d: "
+			"%10u %10u %10u %10u\n",
+			htmode,
+			mcs,
+			ratekbps / 1000,
+			(ratekbps % 1000) / 100,
+			stats->success,
+			stats->retries,
+			stats->xretries,
+			stats->per);
+	}
+
+	if (len > max)
+		len = max;
+
+	retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
+	kfree(buf);
+	return retval;
+}
+
+static const struct file_operations fops_rcstat = {
+	.read = read_file_rcstat,
+	.open = ath9k_debugfs_open,
+	.owner = THIS_MODULE
+};
+
+static void ath_rate_add_sta_debugfs(void *priv, void *priv_sta,
+				     struct dentry *dir)
+{
+	struct ath_rate_priv *rc = priv_sta;
+	debugfs_create_file("rc_stats", S_IRUGO, dir, rc, &fops_rcstat);
+}
+
+#endif /* CONFIG_ATH9K_DEBUGFS */
+
 static void *ath_rate_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir)
 {
 	struct ath_wiphy *aphy = hw->priv;
@@ -1561,6 +1640,9 @@ static struct rate_control_ops ath_rate_ops = {
 	.free = ath_rate_free,
 	.alloc_sta = ath_rate_alloc_sta,
 	.free_sta = ath_rate_free_sta,
+#ifdef CONFIG_ATH9K_DEBUGFS
+	.add_sta_debugfs = ath_rate_add_sta_debugfs,
+#endif
 };
 
 int ath_rate_control_register(void)
diff --git a/drivers/net/wireless/ath/ath9k/rc.h b/drivers/net/wireless/ath/ath9k/rc.h
index 268072fd3c1c..2f46a2266ba1 100644
--- a/drivers/net/wireless/ath/ath9k/rc.h
+++ b/drivers/net/wireless/ath/ath9k/rc.h
@@ -135,20 +135,21 @@ enum {
 
 /**
  * struct ath_rate_table - Rate Control table
- * @valid: valid for use in rate control
- * @valid_single_stream: valid for use in rate control for
- * 	single stream operation
- * @phy: CCK/OFDM
+ * @rate_cnt: total number of rates for the given wireless mode
+ * @mcs_start: MCS rate index offset
+ * @rate_flags: Rate Control flags
+ * @phy: CCK/OFDM/HT20/HT40
  * @ratekbps: rate in Kbits per second
  * @user_ratekbps: user rate in Kbits per second
  * @ratecode: rate that goes into HW descriptors
- * @short_preamble: Mask for enabling short preamble in ratecode for CCK
  * @dot11rate: value that goes into supported
  * 	rates info element of MLME
  * @ctrl_rate: Index of next lower basic rate, used for duration computation
- * @max_4ms_framelen: maximum frame length(bytes) for tx duration
+ * @cw40index: Index of rates having 40MHz channel width
+ * @sgi_index: Index of rates having Short Guard Interval
+ * @ht_index: high throughput rates having 40MHz channel width and
+ * 	Short Guard Interval
  * @probe_interval: interval for rate control to probe for other rates
- * @rssi_reduce_interval: interval for rate control to reduce rssi
  * @initial_ratemax: initial ratemax value
  */
 struct ath_rate_table {
@@ -175,6 +176,13 @@ struct ath_rateset {
 	u8 rs_rates[ATH_RATE_MAX];
 };
 
+struct ath_rc_stats {
+	u32 success;
+	u32 retries;
+	u32 xretries;
+	u8 per;
+};
+
 /**
  * struct ath_rate_priv - Rate Control priv data
  * @state: RC state
@@ -211,6 +219,10 @@ struct ath_rate_priv {
 	struct ath_rateset neg_rates;
 	struct ath_rateset neg_ht_rates;
 	struct ath_rate_softc *asc;
+	const struct ath_rate_table *rate_table;
+
+	struct dentry *debugfs_rcstats;
+	struct ath_rc_stats rcstats[RATE_TABLE_SIZE];
 };
 
 #define ATH_TX_INFO_FRAME_TYPE_INTERNAL	(1 << 0)
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index 9c166f3804ab..fe73fc50082a 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -268,6 +268,7 @@ static int ath_rx_edma_init(struct ath_softc *sc, int nbufs)
 						bf->bf_buf_addr))) {
 				dev_kfree_skb_any(skb);
 				bf->bf_mpdu = NULL;
+				bf->bf_buf_addr = 0;
 				ath_print(common, ATH_DBG_FATAL,
 					"dma_mapping_error() on RX init\n");
 				error = -ENOMEM;
@@ -358,12 +359,12 @@ int ath_rx_init(struct ath_softc *sc, int nbufs)
 							bf->bf_buf_addr))) {
 				dev_kfree_skb_any(skb);
 				bf->bf_mpdu = NULL;
+				bf->bf_buf_addr = 0;
 				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;
 	}
@@ -393,6 +394,8 @@ void ath_rx_cleanup(struct ath_softc *sc)
 						common->rx_bufsize,
 						DMA_FROM_DEVICE);
 				dev_kfree_skb(skb);
+				bf->bf_buf_addr = 0;
+				bf->bf_mpdu = NULL;
 			}
 		}
 
@@ -430,8 +433,7 @@ u32 ath_calcrxfilter(struct ath_softc *sc)
 		| ATH9K_RX_FILTER_UCAST | ATH9K_RX_FILTER_BCAST
 		| ATH9K_RX_FILTER_MCAST;
 
-	/* If not a STA, enable processing of Probe Requests */
-	if (sc->sc_ah->opmode != NL80211_IFTYPE_STATION)
+	if (sc->rx.rxfilter & FIF_PROBE_REQ)
 		rfilt |= ATH9K_RX_FILTER_PROBEREQ;
 
 	/*
@@ -1735,12 +1737,12 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
 			  bf->bf_buf_addr))) {
 			dev_kfree_skb_any(requeue_skb);
 			bf->bf_mpdu = NULL;
+			bf->bf_buf_addr = 0;
 			ath_print(common, ATH_DBG_FATAL,
 				  "dma_mapping_error() on RX\n");
 			ath_rx_send_to_mac80211(hw, sc, skb, rxs);
 			break;
 		}
-		bf->bf_dmacontext = bf->bf_buf_addr;
 
 		/*
 		 * change the default rx antenna if rx diversity chooses the
diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h
index 6d01e501b9b4..42976b0a01c1 100644
--- a/drivers/net/wireless/ath/ath9k/reg.h
+++ b/drivers/net/wireless/ath/ath9k/reg.h
@@ -107,12 +107,6 @@
 #define AR_RXCFG_DMASZ_256B  6
 #define AR_RXCFG_DMASZ_512B  7
 
-#define AR_MIBC              0x0040
-#define AR_MIBC_COW          0x00000001
-#define AR_MIBC_FMC          0x00000002
-#define AR_MIBC_CMC          0x00000004
-#define AR_MIBC_MCS          0x00000008
-
 #define AR_TOPS              0x0044
 #define AR_TOPS_MASK         0x0000FFFF
 
@@ -859,9 +853,6 @@
 
 #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) && \
@@ -1524,11 +1515,6 @@ enum {
 #define AR_TPC_CHIRP           0x003f0000
 #define AR_TPC_CHIRP_S         0x16
 
-#define AR_TFCNT           0x80ec
-#define AR_RFCNT           0x80f0
-#define AR_RCCNT           0x80f4
-#define AR_CCCNT           0x80f8
-
 #define AR_QUIET1          0x80fc
 #define AR_QUIET1_NEXT_QUIET_S         0
 #define AR_QUIET1_NEXT_QUIET_M         0x0000ffff
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index aa447770eb2b..d077186da870 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -294,7 +294,6 @@ static struct ath_buf* ath_clone_txbuf(struct ath_softc *sc, struct ath_buf *bf)
 	tbf->bf_buf_addr = bf->bf_buf_addr;
 	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;
 
 	return tbf;
 }
@@ -317,6 +316,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
 	int isaggr, txfail, txpending, sendbar = 0, needreset = 0, nbad = 0;
 	bool rc_update = true;
 	struct ieee80211_tx_rate rates[4];
+	int nframes;
 
 	skb = bf->bf_mpdu;
 	hdr = (struct ieee80211_hdr *)skb->data;
@@ -325,6 +325,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
 	hw = bf->aphy->hw;
 
 	memcpy(rates, tx_info->control.rates, sizeof(rates));
+	nframes = bf->bf_nframes;
 
 	rcu_read_lock();
 
@@ -341,7 +342,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
 			    !bf->bf_stale || bf_next != NULL)
 				list_move_tail(&bf->list, &bf_head);
 
-			ath_tx_rc_status(bf, ts, 0, 0, false);
+			ath_tx_rc_status(bf, ts, 1, 0, false);
 			ath_tx_complete_buf(sc, bf, txq, &bf_head, ts,
 				0, 0);
 
@@ -446,6 +447,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
 
 			if (rc_update && (acked_cnt == 1 || txfail_cnt == 1)) {
 				memcpy(tx_info->control.rates, rates, sizeof(rates));
+				bf->bf_nframes = nframes;
 				ath_tx_rc_status(bf, ts, nbad, txok, true);
 				rc_update = false;
 			} else {
@@ -1637,17 +1639,16 @@ static int ath_tx_setup_buffer(struct ieee80211_hw *hw, struct ath_buf *bf,
 
 	bf->bf_mpdu = skb;
 
-	bf->bf_dmacontext = dma_map_single(sc->dev, skb->data,
-					   skb->len, DMA_TO_DEVICE);
-	if (unlikely(dma_mapping_error(sc->dev, bf->bf_dmacontext))) {
+	bf->bf_buf_addr = dma_map_single(sc->dev, skb->data,
+					 skb->len, DMA_TO_DEVICE);
+	if (unlikely(dma_mapping_error(sc->dev, bf->bf_buf_addr))) {
 		bf->bf_mpdu = NULL;
+		bf->bf_buf_addr = 0;
 		ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL,
 			  "dma_mapping_error() on TX\n");
 		return -ENOMEM;
 	}
 
-	bf->bf_buf_addr = bf->bf_dmacontext;
-
 	bf->bf_tx_aborted = false;
 
 	return 0;
@@ -1911,7 +1912,8 @@ static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
 			tx_flags |= ATH_TX_XRETRY;
 	}
 
-	dma_unmap_single(sc->dev, bf->bf_dmacontext, skb->len, DMA_TO_DEVICE);
+	dma_unmap_single(sc->dev, bf->bf_buf_addr, skb->len, DMA_TO_DEVICE);
+	bf->bf_buf_addr = 0;
 
 	if (bf->bf_state.bfs_paprd) {
 		if (time_after(jiffies,
@@ -1921,9 +1923,13 @@ static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
 		else
 			complete(&sc->paprd_complete);
 	} else {
-		ath_tx_complete(sc, skb, bf->aphy, tx_flags);
 		ath_debug_stat_tx(sc, txq, bf, ts);
+		ath_tx_complete(sc, skb, bf->aphy, tx_flags);
 	}
+	/* At this point, skb (bf->bf_mpdu) is consumed...make sure we don't
+	 * accidentally reference it later.
+	 */
+	bf->bf_mpdu = NULL;
 
 	/*
 	 * Return the list of ath_buf of this mpdu to free queue
@@ -1979,9 +1985,15 @@ static void ath_tx_rc_status(struct ath_buf *bf, struct ath_tx_status *ts,
 
 	if (ts->ts_status & ATH9K_TXERR_FILT)
 		tx_info->flags |= IEEE80211_TX_STAT_TX_FILTERED;
-	if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && update_rc)
+	if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && update_rc) {
 		tx_info->flags |= IEEE80211_TX_STAT_AMPDU;
 
+		BUG_ON(nbad > bf->bf_nframes);
+
+		tx_info->status.ampdu_len = bf->bf_nframes;
+		tx_info->status.ampdu_ack_len = bf->bf_nframes - nbad;
+	}
+
 	if ((ts->ts_status & ATH9K_TXERR_FILT) == 0 &&
 	    (bf->bf_flags & ATH9K_TXDESC_NOACK) == 0 && update_rc) {
 		if (ieee80211_is_data(hdr->frame_control)) {
@@ -1991,8 +2003,6 @@ static void ath_tx_rc_status(struct ath_buf *bf, struct ath_tx_status *ts,
 			if ((ts->ts_status & ATH9K_TXERR_XRETRY) ||
 			    (ts->ts_status & ATH9K_TXERR_FIFO))
 				tx_info->pad[0] |= ATH_TX_INFO_XRETRY;
-			tx_info->status.ampdu_len = bf->bf_nframes;
-			tx_info->status.ampdu_ack_len = bf->bf_nframes - nbad;
 		}
 	}
 
@@ -2102,7 +2112,7 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
 			 */
 			if (ts.ts_status & ATH9K_TXERR_XRETRY)
 				bf->bf_state.bf_type |= BUF_XRETRY;
-			ath_tx_rc_status(bf, &ts, 0, txok, true);
+			ath_tx_rc_status(bf, &ts, txok ? 0 : 1, txok, true);
 		}
 
 		if (bf_isampdu(bf))
@@ -2220,7 +2230,7 @@ void ath_tx_edma_tasklet(struct ath_softc *sc)
 		if (!bf_isampdu(bf)) {
 			if (txs.ts_status & ATH9K_TXERR_XRETRY)
 				bf->bf_state.bf_type |= BUF_XRETRY;
-			ath_tx_rc_status(bf, &txs, 0, txok, true);
+			ath_tx_rc_status(bf, &txs, txok ? 0 : 1, txok, true);
 		}
 
 		if (bf_isampdu(bf))
diff --git a/drivers/net/wireless/ath/carl9170/rx.c b/drivers/net/wireless/ath/carl9170/rx.c
index 671dbc429547..939a0e96ed1f 100644
--- a/drivers/net/wireless/ath/carl9170/rx.c
+++ b/drivers/net/wireless/ath/carl9170/rx.c
@@ -576,6 +576,41 @@ static void carl9170_ps_beacon(struct ar9170 *ar, void *data, unsigned int len)
 	}
 }
 
+static bool carl9170_ampdu_check(struct ar9170 *ar, u8 *buf, u8 ms)
+{
+	__le16 fc;
+
+	if ((ms & AR9170_RX_STATUS_MPDU) == AR9170_RX_STATUS_MPDU_SINGLE) {
+		/*
+		 * This frame is not part of an aMPDU.
+		 * Therefore it is not subjected to any
+		 * of the following content restrictions.
+		 */
+		return true;
+	}
+
+	/*
+	 * "802.11n - 7.4a.3 A-MPDU contents" describes in which contexts
+	 * certain frame types can be part of an aMPDU.
+	 *
+	 * In order to keep the processing cost down, I opted for a
+	 * stateless filter solely based on the frame control field.
+	 */
+
+	fc = ((struct ieee80211_hdr *)buf)->frame_control;
+	if (ieee80211_is_data_qos(fc) && ieee80211_is_data_present(fc))
+		return true;
+
+	if (ieee80211_is_ack(fc) || ieee80211_is_back(fc) ||
+	    ieee80211_is_back_req(fc))
+		return true;
+
+	if (ieee80211_is_action(fc))
+		return true;
+
+	return false;
+}
+
 /*
  * If the frame alignment is right (or the kernel has
  * CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS), and there
@@ -594,24 +629,19 @@ static void carl9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len)
 	struct ieee80211_rx_status status;
 	struct sk_buff *skb;
 	int mpdu_len;
+	u8 mac_status;
 
 	if (!IS_STARTED(ar))
 		return;
 
-	if (unlikely(len < sizeof(*mac))) {
-		ar->rx_dropped++;
-		return;
-	}
+	if (unlikely(len < sizeof(*mac)))
+		goto drop;
 
 	mpdu_len = len - sizeof(*mac);
 
 	mac = (void *)(buf + mpdu_len);
-	if (unlikely(mac->error & AR9170_RX_ERROR_FATAL)) {
-		ar->rx_dropped++;
-		return;
-	}
-
-	switch (mac->status & AR9170_RX_STATUS_MPDU) {
+	mac_status = mac->status;
+	switch (mac_status & AR9170_RX_STATUS_MPDU) {
 	case AR9170_RX_STATUS_MPDU_FIRST:
 		/* Aggregated MPDUs start with an PLCP header */
 		if (likely(mpdu_len >= sizeof(struct ar9170_rx_head))) {
@@ -638,8 +668,7 @@ static void carl9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len)
 					"is clipped.\n");
 			}
 
-			ar->rx_dropped++;
-			return;
+			goto drop;
 		}
 		break;
 
@@ -659,8 +688,7 @@ static void carl9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len)
 					"is clipped.\n");
 			}
 
-			ar->rx_dropped++;
-			return;
+			goto drop;
 		}
 
 	case AR9170_RX_STATUS_MPDU_MIDDLE:
@@ -672,8 +700,7 @@ static void carl9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len)
 			wiphy_err(ar->hw->wiphy, "rx stream does not start "
 					"with a first_mpdu frame tag.\n");
 
-			ar->rx_dropped++;
-			return;
+			goto drop;
 		}
 
 		head = &ar->rx_plcp;
@@ -696,16 +723,15 @@ static void carl9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len)
 	}
 
 	/* FC + DU + RA + FCS */
-	if (unlikely(mpdu_len < (2 + 2 + 6 + FCS_LEN))) {
-		ar->rx_dropped++;
-		return;
-	}
+	if (unlikely(mpdu_len < (2 + 2 + ETH_ALEN + FCS_LEN)))
+		goto drop;
 
 	memset(&status, 0, sizeof(status));
-	if (unlikely(carl9170_rx_mac_status(ar, head, mac, &status))) {
-		ar->rx_dropped++;
-		return;
-	}
+	if (unlikely(carl9170_rx_mac_status(ar, head, mac, &status)))
+		goto drop;
+
+	if (!carl9170_ampdu_check(ar, buf, mac_status))
+		goto drop;
 
 	if (phy)
 		carl9170_rx_phy_status(ar, phy, &status);
@@ -713,12 +739,15 @@ static void carl9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len)
 	carl9170_ps_beacon(ar, buf, mpdu_len);
 
 	skb = carl9170_rx_copy_data(buf, mpdu_len);
-	if (likely(skb)) {
-		memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status));
-		ieee80211_rx(ar->hw, skb);
-	} else {
-		ar->rx_dropped++;
-	}
+	if (!skb)
+		goto drop;
+
+	memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status));
+	ieee80211_rx(ar->hw, skb);
+	return;
+
+drop:
+	ar->rx_dropped++;
 }
 
 static void carl9170_rx_untie_cmds(struct ar9170 *ar, const u8 *respbuf,
diff --git a/drivers/net/wireless/ath/carl9170/wlan.h b/drivers/net/wireless/ath/carl9170/wlan.h
index 48ead2268f50..24d63b583b6b 100644
--- a/drivers/net/wireless/ath/carl9170/wlan.h
+++ b/drivers/net/wireless/ath/carl9170/wlan.h
@@ -74,6 +74,9 @@
 #define	AR9170_RX_STATUS_MPDU_MIDDLE		0x30
 #define	AR9170_RX_STATUS_MPDU_LAST		0x10
 
+#define	AR9170_RX_STATUS_CONT_AGGR		0x40
+#define	AR9170_RX_STATUS_TOTAL_ERROR		0x80
+
 #define	AR9170_RX_ERROR_RXTO			0x01
 #define	AR9170_RX_ERROR_OVERRUN			0x02
 #define	AR9170_RX_ERROR_DECRYPT			0x04
@@ -81,7 +84,6 @@
 #define	AR9170_RX_ERROR_WRONG_RA		0x10
 #define	AR9170_RX_ERROR_PLCP			0x20
 #define	AR9170_RX_ERROR_MMIC			0x40
-#define	AR9170_RX_ERROR_FATAL			0x80
 
 /* these are either-or */
 #define	AR9170_TX_MAC_PROT_RTS			0x0001
@@ -329,13 +331,15 @@ struct _carl9170_tx_superframe {
 
 #define	CARL9170_TX_SUPERDESC_LEN		24
 #define	AR9170_TX_HWDESC_LEN			8
-#define	AR9170_TX_SUPERFRAME_LEN		(CARL9170_TX_HWDESC_LEN + \
-						 AR9170_TX_SUPERDESC_LEN)
+#define	CARL9170_TX_SUPERFRAME_LEN		(CARL9170_TX_SUPERDESC_LEN + \
+						 AR9170_TX_HWDESC_LEN)
 
 struct ar9170_rx_head {
 	u8 plcp[12];
 } __packed;
 
+#define	AR9170_RX_HEAD_LEN			12
+
 struct ar9170_rx_phystatus {
 	union {
 		struct {
@@ -350,12 +354,16 @@ struct ar9170_rx_phystatus {
 	u8 phy_err;
 } __packed;
 
+#define	AR9170_RX_PHYSTATUS_LEN			20
+
 struct ar9170_rx_macstatus {
 	u8 SAidx, DAidx;
 	u8 error;
 	u8 status;
 } __packed;
 
+#define	AR9170_RX_MACSTATUS_LEN			4
+
 struct ar9170_rx_frame_single {
 	struct ar9170_rx_head phy_head;
 	struct ieee80211_hdr i3e;
diff --git a/drivers/net/wireless/ath/debug.c b/drivers/net/wireless/ath/debug.c
index 53e77bd131b9..dacfb234f491 100644
--- a/drivers/net/wireless/ath/debug.c
+++ b/drivers/net/wireless/ath/debug.c
@@ -30,3 +30,32 @@ void ath_print(struct ath_common *common, int dbg_mask, const char *fmt, ...)
 	va_end(args);
 }
 EXPORT_SYMBOL(ath_print);
+
+const char *ath_opmode_to_string(enum nl80211_iftype opmode)
+{
+	switch (opmode) {
+	case NL80211_IFTYPE_UNSPECIFIED:
+		return "UNSPEC";
+	case NL80211_IFTYPE_ADHOC:
+		return "ADHOC";
+	case NL80211_IFTYPE_STATION:
+		return "STATION";
+	case NL80211_IFTYPE_AP:
+		return "AP";
+	case NL80211_IFTYPE_AP_VLAN:
+		return "AP-VLAN";
+	case NL80211_IFTYPE_WDS:
+		return "WDS";
+	case NL80211_IFTYPE_MONITOR:
+		return "MONITOR";
+	case NL80211_IFTYPE_MESH_POINT:
+		return "MESH";
+	case NL80211_IFTYPE_P2P_CLIENT:
+		return "P2P-CLIENT";
+	case NL80211_IFTYPE_P2P_GO:
+		return "P2P-GO";
+	default:
+		return "UNKNOWN";
+	}
+}
+EXPORT_SYMBOL(ath_opmode_to_string);
diff --git a/drivers/net/wireless/ath/debug.h b/drivers/net/wireless/ath/debug.h
index fd3a020682dc..64e4af2c2887 100644
--- a/drivers/net/wireless/ath/debug.h
+++ b/drivers/net/wireless/ath/debug.h
@@ -77,4 +77,14 @@ ath_print(struct ath_common *common, int dbg_mask, const char *fmt, ...)
 }
 #endif /* CONFIG_ATH_DEBUG */
 
+/** Returns string describing opmode, or NULL if unknown mode. */
+#ifdef CONFIG_ATH_DEBUG
+const char *ath_opmode_to_string(enum nl80211_iftype opmode);
+#else
+static inline const char *ath_opmode_to_string(enum nl80211_iftype opmode)
+{
+	return "UNKNOWN";
+}
+#endif
+
 #endif /* ATH_DEBUG_H */
diff --git a/drivers/net/wireless/ath/hw.c b/drivers/net/wireless/ath/hw.c
index a8f81ea09f14..183c28281385 100644
--- a/drivers/net/wireless/ath/hw.c
+++ b/drivers/net/wireless/ath/hw.c
@@ -124,3 +124,62 @@ void ath_hw_setbssidmask(struct ath_common *common)
 	REG_WRITE(ah, get_unaligned_le16(common->bssidmask + 4), AR_BSSMSKU);
 }
 EXPORT_SYMBOL(ath_hw_setbssidmask);
+
+
+/**
+ * ath_hw_cycle_counters_update - common function to update cycle counters
+ *
+ * @common: the ath_common struct for the device.
+ *
+ * This function is used to update all cycle counters in one place.
+ * It has to be called while holding common->cc_lock!
+ */
+void ath_hw_cycle_counters_update(struct ath_common *common)
+{
+	u32 cycles, busy, rx, tx;
+	void *ah = common->ah;
+
+	/* freeze */
+	REG_WRITE(ah, AR_MIBC_FMC, AR_MIBC);
+
+	/* read */
+	cycles = REG_READ(ah, AR_CCCNT);
+	busy = REG_READ(ah, AR_RCCNT);
+	rx = REG_READ(ah, AR_RFCNT);
+	tx = REG_READ(ah, AR_TFCNT);
+
+	/* clear */
+	REG_WRITE(ah, 0, AR_CCCNT);
+	REG_WRITE(ah, 0, AR_RFCNT);
+	REG_WRITE(ah, 0, AR_RCCNT);
+	REG_WRITE(ah, 0, AR_TFCNT);
+
+	/* unfreeze */
+	REG_WRITE(ah, 0, AR_MIBC);
+
+	/* update all cycle counters here */
+	common->cc_ani.cycles += cycles;
+	common->cc_ani.rx_busy += busy;
+	common->cc_ani.rx_frame += rx;
+	common->cc_ani.tx_frame += tx;
+
+	common->cc_survey.cycles += cycles;
+	common->cc_survey.rx_busy += busy;
+	common->cc_survey.rx_frame += rx;
+	common->cc_survey.tx_frame += tx;
+}
+EXPORT_SYMBOL(ath_hw_cycle_counters_update);
+
+int32_t ath_hw_get_listen_time(struct ath_common *common)
+{
+	struct ath_cycle_counters *cc = &common->cc_ani;
+	int32_t listen_time;
+
+	listen_time = (cc->cycles - cc->rx_frame - cc->tx_frame) /
+		      (common->clockrate * 1000);
+
+	memset(cc, 0, sizeof(*cc));
+
+	return listen_time;
+}
+EXPORT_SYMBOL(ath_hw_get_listen_time);
diff --git a/drivers/net/wireless/ath/reg.h b/drivers/net/wireless/ath/reg.h
index e798ef476581..298e53f3fa48 100644
--- a/drivers/net/wireless/ath/reg.h
+++ b/drivers/net/wireless/ath/reg.h
@@ -17,6 +17,12 @@
 #ifndef ATH_REGISTERS_H
 #define ATH_REGISTERS_H
 
+#define AR_MIBC			0x0040
+#define AR_MIBC_COW		0x00000001
+#define AR_MIBC_FMC		0x00000002
+#define AR_MIBC_CMC		0x00000004
+#define AR_MIBC_MCS		0x00000008
+
 /*
  * BSSID mask registers. See ath_hw_set_bssid_mask()
  * for detailed documentation about these registers.
@@ -24,6 +30,11 @@
 #define AR_BSSMSKL		0x80e0
 #define AR_BSSMSKU		0x80e4
 
+#define AR_TFCNT		0x80ec
+#define AR_RFCNT		0x80f0
+#define AR_RCCNT		0x80f4
+#define AR_CCCNT		0x80f8
+
 #define AR_KEYTABLE_0           0x8800
 #define AR_KEYTABLE(_n)         (AR_KEYTABLE_0 + ((_n)*32))
 #define AR_KEY_CACHE_SIZE       128
diff --git a/drivers/net/wireless/b43/Makefile b/drivers/net/wireless/b43/Makefile
index 5e83b6f0a3a0..69d4af09a6cb 100644
--- a/drivers/net/wireless/b43/Makefile
+++ b/drivers/net/wireless/b43/Makefile
@@ -1,6 +1,8 @@
 b43-y				+= main.o
 b43-y				+= tables.o
 b43-$(CONFIG_B43_NPHY)		+= tables_nphy.o
+b43-$(CONFIG_B43_NPHY)		+= radio_2055.o
+b43-$(CONFIG_B43_NPHY)		+= radio_2056.o
 b43-y				+= phy_common.o
 b43-y				+= phy_g.o
 b43-y				+= phy_a.o
diff --git a/drivers/net/wireless/b43/phy_common.h b/drivers/net/wireless/b43/phy_common.h
index bd480b481bfc..0e6194228845 100644
--- a/drivers/net/wireless/b43/phy_common.h
+++ b/drivers/net/wireless/b43/phy_common.h
@@ -2,6 +2,7 @@
 #define LINUX_B43_PHY_COMMON_H_
 
 #include <linux/types.h>
+#include <linux/nl80211.h>
 
 struct b43_wldev;
 
@@ -250,8 +251,10 @@ struct b43_phy {
 	 * check is needed. */
 	unsigned long next_txpwr_check_time;
 
-	/* current channel */
+	/* Current channel */
 	unsigned int channel;
+	u16 channel_freq;
+	enum nl80211_channel_type channel_type;
 
 	/* PHY TX errors counter. */
 	atomic_t txerr_cnt;
diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c
index f575e757caeb..dfec5496055e 100644
--- a/drivers/net/wireless/b43/phy_n.c
+++ b/drivers/net/wireless/b43/phy_n.c
@@ -29,6 +29,8 @@
 #include "b43.h"
 #include "phy_n.h"
 #include "tables_nphy.h"
+#include "radio_2055.h"
+#include "radio_2056.h"
 #include "main.h"
 
 struct nphy_txgains {
@@ -74,19 +76,11 @@ static void b43_nphy_rf_control_override(struct b43_wldev *dev, u16 field,
 static void b43_nphy_rf_control_intc_override(struct b43_wldev *dev, u8 field,
 						u16 value, u8 core);
 
-static inline bool b43_empty_chanspec(struct b43_chanspec *chanspec)
+static inline bool b43_channel_type_is_40mhz(
+					enum nl80211_channel_type channel_type)
 {
-	return !chanspec->channel && !chanspec->sideband &&
-		!chanspec->b_width && !chanspec->b_freq;
-}
-
-static inline bool b43_eq_chanspecs(struct b43_chanspec *chanspec1,
-					struct b43_chanspec *chanspec2)
-{
-	return (chanspec1->channel == chanspec2->channel &&
-		chanspec1->sideband == chanspec2->sideband &&
-		chanspec1->b_width == chanspec2->b_width &&
-		chanspec1->b_freq == chanspec2->b_freq);
+	return (channel_type == NL80211_CHAN_HT40MINUS ||
+		channel_type == NL80211_CHAN_HT40PLUS);
 }
 
 void b43_nphy_set_rxantenna(struct b43_wldev *dev, int antenna)
@@ -781,7 +775,7 @@ static void b43_nphy_spur_workaround(struct b43_wldev *dev)
 {
 	struct b43_phy_n *nphy = dev->phy.n;
 
-	u8 channel = nphy->radio_chanspec.channel;
+	u8 channel = dev->phy.channel;
 	int tone[2] = { 57, 58 };
 	u32 noise[2] = { 0x3FF, 0x3FF };
 
@@ -855,9 +849,9 @@ static void b43_nphy_adjust_lna_gain_table(struct b43_wldev *dev)
 			gain[0] = 6;
 			gain[1] = 6;
 		} else {
-			tmp = 40370 - 315 * nphy->radio_chanspec.channel;
+			tmp = 40370 - 315 * dev->phy.channel;
 			gain[0] = ((tmp >> 13) + ((tmp >> 12) & 1));
-			tmp = 23242 - 224 * nphy->radio_chanspec.channel;
+			tmp = 23242 - 224 * dev->phy.channel;
 			gain[1] = ((tmp >> 13) + ((tmp >> 12) & 1));
 		}
 	} else {
@@ -2083,12 +2077,12 @@ static void b43_nphy_restore_rssi_cal(struct b43_wldev *dev)
 	u16 *rssical_phy_regs = NULL;
 
 	if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
-		if (b43_empty_chanspec(&nphy->rssical_chanspec_2G))
+		if (!nphy->rssical_chanspec_2G.center_freq)
 			return;
 		rssical_radio_regs = nphy->rssical_cache.rssical_radio_regs_2G;
 		rssical_phy_regs = nphy->rssical_cache.rssical_phy_regs_2G;
 	} else {
-		if (b43_empty_chanspec(&nphy->rssical_chanspec_5G))
+		if (!nphy->rssical_chanspec_5G.center_freq)
 			return;
 		rssical_radio_regs = nphy->rssical_cache.rssical_radio_regs_5G;
 		rssical_phy_regs = nphy->rssical_cache.rssical_phy_regs_5G;
@@ -2544,8 +2538,9 @@ static void b43_nphy_save_cal(struct b43_wldev *dev)
 		txcal_radio_regs[2] = b43_radio_read(dev, 0x8D);
 		txcal_radio_regs[3] = b43_radio_read(dev, 0xBC);
 	}
-	*iqcal_chanspec = nphy->radio_chanspec;
-	b43_ntab_write_bulk(dev, B43_NTAB16(15, 80), 8, table);
+	iqcal_chanspec->center_freq = dev->phy.channel_freq;
+	iqcal_chanspec->channel_type = dev->phy.channel_type;
+	b43_ntab_read_bulk(dev, B43_NTAB16(15, 80), 8, table);
 
 	if (nphy->hang_avoid)
 		b43_nphy_stay_in_carrier_search(dev, 0);
@@ -2565,12 +2560,12 @@ static void b43_nphy_restore_cal(struct b43_wldev *dev)
 	struct b43_phy_n_iq_comp *rxcal_coeffs = NULL;
 
 	if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
-		if (b43_empty_chanspec(&nphy->iqcal_chanspec_2G))
+		if (!nphy->iqcal_chanspec_2G.center_freq)
 			return;
 		table = nphy->cal_cache.txcal_coeffs_2G;
 		loft = &nphy->cal_cache.txcal_coeffs_2G[5];
 	} else {
-		if (b43_empty_chanspec(&nphy->iqcal_chanspec_5G))
+		if (!nphy->iqcal_chanspec_5G.center_freq)
 			return;
 		table = nphy->cal_cache.txcal_coeffs_5G;
 		loft = &nphy->cal_cache.txcal_coeffs_5G[5];
@@ -2815,7 +2810,10 @@ static int b43_nphy_cal_tx_iq_lo(struct b43_wldev *dev,
 			b43_ntab_read_bulk(dev, B43_NTAB16(15, 96), length,
 						nphy->txiqlocal_bestc);
 			nphy->txiqlocal_coeffsvalid = true;
-			nphy->txiqlocal_chanspec = nphy->radio_chanspec;
+			nphy->txiqlocal_chanspec.center_freq =
+							dev->phy.channel_freq;
+			nphy->txiqlocal_chanspec.channel_type =
+							dev->phy.channel_type;
 		} else {
 			length = 11;
 			if (dev->phy.rev < 3)
@@ -2851,7 +2849,8 @@ static void b43_nphy_reapply_tx_cal_coeffs(struct b43_wldev *dev)
 	bool equal = true;
 
 	if (!nphy->txiqlocal_coeffsvalid ||
-	    b43_eq_chanspecs(&nphy->txiqlocal_chanspec, &nphy->radio_chanspec))
+	    nphy->txiqlocal_chanspec.center_freq != dev->phy.channel_freq ||
+	    nphy->txiqlocal_chanspec.channel_type != dev->phy.channel_type)
 		return;
 
 	b43_ntab_read_bulk(dev, B43_NTAB16(15, 80), 7, buffer);
@@ -3257,11 +3256,9 @@ int b43_phy_initn(struct b43_wldev *dev)
 	do_rssi_cal = false;
 	if (phy->rev >= 3) {
 		if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
-			do_rssi_cal =
-				b43_empty_chanspec(&nphy->rssical_chanspec_2G);
+			do_rssi_cal = !nphy->rssical_chanspec_2G.center_freq;
 		else
-			do_rssi_cal =
-				b43_empty_chanspec(&nphy->rssical_chanspec_5G);
+			do_rssi_cal = !nphy->rssical_chanspec_5G.center_freq;
 
 		if (do_rssi_cal)
 			b43_nphy_rssi_cal(dev);
@@ -3273,9 +3270,9 @@ int b43_phy_initn(struct b43_wldev *dev)
 
 	if (!((nphy->measure_hold & 0x6) != 0)) {
 		if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
-			do_cal = b43_empty_chanspec(&nphy->iqcal_chanspec_2G);
+			do_cal = !nphy->iqcal_chanspec_2G.center_freq;
 		else
-			do_cal = b43_empty_chanspec(&nphy->iqcal_chanspec_5G);
+			do_cal = !nphy->iqcal_chanspec_5G.center_freq;
 
 		if (nphy->mute)
 			do_cal = false;
@@ -3323,24 +3320,25 @@ int b43_phy_initn(struct b43_wldev *dev)
 }
 
 /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/ChanspecSetup */
-static void b43_nphy_chanspec_setup(struct b43_wldev *dev,
+static void b43_nphy_channel_setup(struct b43_wldev *dev,
 				const struct b43_phy_n_sfo_cfg *e,
-				struct b43_chanspec chanspec)
+				struct ieee80211_channel *new_channel)
 {
 	struct b43_phy *phy = &dev->phy;
 	struct b43_phy_n *nphy = dev->phy.n;
 
-	u16 tmp;
+	u16 old_band_5ghz;
 	u32 tmp32;
 
-	tmp = b43_phy_read(dev, B43_NPHY_BANDCTL) & B43_NPHY_BANDCTL_5GHZ;
-	if (chanspec.b_freq == 1 && tmp == 0) {
+	old_band_5ghz =
+		b43_phy_read(dev, B43_NPHY_BANDCTL) & B43_NPHY_BANDCTL_5GHZ;
+	if (new_channel->band == IEEE80211_BAND_5GHZ && !old_band_5ghz) {
 		tmp32 = b43_read32(dev, B43_MMIO_PSM_PHY_HDR);
 		b43_write32(dev, B43_MMIO_PSM_PHY_HDR, tmp32 | 4);
 		b43_phy_set(dev, B43_PHY_B_BBCFG, 0xC000);
 		b43_write32(dev, B43_MMIO_PSM_PHY_HDR, tmp32);
 		b43_phy_set(dev, B43_NPHY_BANDCTL, B43_NPHY_BANDCTL_5GHZ);
-	} else if (chanspec.b_freq == 1) {
+	} else if (new_channel->band == IEEE80211_BAND_2GHZ && old_band_5ghz) {
 		b43_phy_mask(dev, B43_NPHY_BANDCTL, ~B43_NPHY_BANDCTL_5GHZ);
 		tmp32 = b43_read32(dev, B43_MMIO_PSM_PHY_HDR);
 		b43_write32(dev, B43_MMIO_PSM_PHY_HDR, tmp32 | 4);
@@ -3350,13 +3348,12 @@ static void b43_nphy_chanspec_setup(struct b43_wldev *dev,
 
 	b43_chantab_phy_upload(dev, e);
 
-
-	if (nphy->radio_chanspec.channel == 14) {
+	if (new_channel->hw_value == 14) {
 		b43_nphy_classifier(dev, 2, 0);
 		b43_phy_set(dev, B43_PHY_B_TEST, 0x0800);
 	} else {
 		b43_nphy_classifier(dev, 2, 2);
-		if (chanspec.b_freq == 2)
+		if (new_channel->band == IEEE80211_BAND_2GHZ)
 			b43_phy_mask(dev, B43_PHY_B_TEST, ~0x840);
 	}
 
@@ -3379,53 +3376,57 @@ static void b43_nphy_chanspec_setup(struct b43_wldev *dev,
 }
 
 /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/SetChanspec */
-static int b43_nphy_set_chanspec(struct b43_wldev *dev,
-					struct b43_chanspec chanspec)
+static int b43_nphy_set_channel(struct b43_wldev *dev,
+				struct ieee80211_channel *channel,
+				enum nl80211_channel_type channel_type)
 {
+	struct b43_phy *phy = &dev->phy;
 	struct b43_phy_n *nphy = dev->phy.n;
 
 	const struct b43_nphy_channeltab_entry_rev2 *tabent_r2;
 	const struct b43_nphy_channeltab_entry_rev3 *tabent_r3;
 
 	u8 tmp;
-	u8 channel = chanspec.channel;
 
 	if (dev->phy.rev >= 3) {
-		/* TODO */
+		tabent_r3 = b43_nphy_get_chantabent_rev3(dev,
+							channel->center_freq);
 		tabent_r3 = NULL;
 		if (!tabent_r3)
 			return -ESRCH;
 	} else {
-		tabent_r2 = b43_nphy_get_chantabent_rev2(dev, channel);
+		tabent_r2 = b43_nphy_get_chantabent_rev2(dev,
+							channel->hw_value);
 		if (!tabent_r2)
 			return -ESRCH;
 	}
 
-	nphy->radio_chanspec = chanspec;
+	/* Channel is set later in common code, but we need to set it on our
+	   own to let this function's subcalls work properly. */
+	phy->channel = channel->hw_value;
+	phy->channel_freq = channel->center_freq;
 
-	if (chanspec.b_width != nphy->b_width)
-		; /* TODO: BMAC BW Set (chanspec.b_width) */
+	if (b43_channel_type_is_40mhz(phy->channel_type) !=
+		b43_channel_type_is_40mhz(channel_type))
+		; /* TODO: BMAC BW Set (channel_type) */
 
-	/* TODO: use defines */
-	if (chanspec.b_width == 3) {
-		if (chanspec.sideband == 2)
-			b43_phy_set(dev, B43_NPHY_RXCTL,
-					B43_NPHY_RXCTL_BSELU20);
-		else
-			b43_phy_mask(dev, B43_NPHY_RXCTL,
-					~B43_NPHY_RXCTL_BSELU20);
-	}
+	if (channel_type == NL80211_CHAN_HT40PLUS)
+		b43_phy_set(dev, B43_NPHY_RXCTL,
+				B43_NPHY_RXCTL_BSELU20);
+	else if (channel_type == NL80211_CHAN_HT40MINUS)
+		b43_phy_mask(dev, B43_NPHY_RXCTL,
+				~B43_NPHY_RXCTL_BSELU20);
 
 	if (dev->phy.rev >= 3) {
-		tmp = (chanspec.b_freq == 1) ? 4 : 0;
+		tmp = (channel->band == IEEE80211_BAND_5GHZ) ? 4 : 0;
 		b43_radio_maskset(dev, 0x08, 0xFFFB, tmp);
 		/* TODO: PHY Radio2056 Setup (dev, tabent_r3); */
-		b43_nphy_chanspec_setup(dev, &(tabent_r3->phy_regs), chanspec);
+		b43_nphy_channel_setup(dev, &(tabent_r3->phy_regs), channel);
 	} else {
-		tmp = (chanspec.b_freq == 1) ? 0x0020 : 0x0050;
+		tmp = (channel->band == IEEE80211_BAND_5GHZ) ? 0x0020 : 0x0050;
 		b43_radio_maskset(dev, B2055_MASTER1, 0xFF8F, tmp);
 		b43_radio_2055_setup(dev, tabent_r2);
-		b43_nphy_chanspec_setup(dev, &(tabent_r2->phy_regs), chanspec);
+		b43_nphy_channel_setup(dev, &(tabent_r2->phy_regs), channel);
 	}
 
 	return 0;
@@ -3567,8 +3568,8 @@ static void b43_nphy_op_switch_analog(struct b43_wldev *dev, bool on)
 static int b43_nphy_op_switch_channel(struct b43_wldev *dev,
 				      unsigned int new_channel)
 {
-	struct b43_phy_n *nphy = dev->phy.n;
-	struct b43_chanspec chanspec;
+	struct ieee80211_channel *channel = dev->wl->hw->conf.channel;
+	enum nl80211_channel_type channel_type = dev->wl->hw->conf.channel_type;
 
 	if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
 		if ((new_channel < 1) || (new_channel > 14))
@@ -3578,10 +3579,7 @@ static int b43_nphy_op_switch_channel(struct b43_wldev *dev,
 			return -EINVAL;
 	}
 
-	chanspec = nphy->radio_chanspec;
-	chanspec.channel = new_channel;
-
-	return b43_nphy_set_chanspec(dev, chanspec);
+	return b43_nphy_set_channel(dev, channel, channel_type);
 }
 
 static unsigned int b43_nphy_op_get_default_chan(struct b43_wldev *dev)
diff --git a/drivers/net/wireless/b43/phy_n.h b/drivers/net/wireless/b43/phy_n.h
index 8b6d570dd0aa..c144e59a708b 100644
--- a/drivers/net/wireless/b43/phy_n.h
+++ b/drivers/net/wireless/b43/phy_n.h
@@ -714,223 +714,11 @@
 #define B43_PHY_B_BBCFG				B43_PHY_N_BMODE(0x001) /* BB config */
 #define B43_PHY_B_TEST				B43_PHY_N_BMODE(0x00A)
 
-
-/* Broadcom 2055 radio registers */
-
-#define B2055_GEN_SPARE			0x00 /* GEN spare */
-#define B2055_SP_PINPD			0x02 /* SP PIN PD */
-#define B2055_C1_SP_RSSI		0x03 /* SP RSSI Core 1 */
-#define B2055_C1_SP_PDMISC		0x04 /* SP PD MISC Core 1 */
-#define B2055_C2_SP_RSSI		0x05 /* SP RSSI Core 2 */
-#define B2055_C2_SP_PDMISC		0x06 /* SP PD MISC Core 2 */
-#define B2055_C1_SP_RXGC1		0x07 /* SP RX GC1 Core 1 */
-#define B2055_C1_SP_RXGC2		0x08 /* SP RX GC2 Core 1 */
-#define B2055_C2_SP_RXGC1		0x09 /* SP RX GC1 Core 2 */
-#define B2055_C2_SP_RXGC2		0x0A /* SP RX GC2 Core 2 */
-#define B2055_C1_SP_LPFBWSEL		0x0B /* SP LPF BW select Core 1 */
-#define B2055_C2_SP_LPFBWSEL		0x0C /* SP LPF BW select Core 2 */
-#define B2055_C1_SP_TXGC1		0x0D /* SP TX GC1 Core 1 */
-#define B2055_C1_SP_TXGC2		0x0E /* SP TX GC2 Core 1 */
-#define B2055_C2_SP_TXGC1		0x0F /* SP TX GC1 Core 2 */
-#define B2055_C2_SP_TXGC2		0x10 /* SP TX GC2 Core 2 */
-#define B2055_MASTER1			0x11 /* Master control 1 */
-#define B2055_MASTER2			0x12 /* Master control 2 */
-#define B2055_PD_LGEN			0x13 /* PD LGEN */
-#define B2055_PD_PLLTS			0x14 /* PD PLL TS */
-#define B2055_C1_PD_LGBUF		0x15 /* PD Core 1 LGBUF */
-#define B2055_C1_PD_TX			0x16 /* PD Core 1 TX */
-#define B2055_C1_PD_RXTX		0x17 /* PD Core 1 RXTX */
-#define B2055_C1_PD_RSSIMISC		0x18 /* PD Core 1 RSSI MISC */
-#define B2055_C2_PD_LGBUF		0x19 /* PD Core 2 LGBUF */
-#define B2055_C2_PD_TX			0x1A /* PD Core 2 TX */
-#define B2055_C2_PD_RXTX		0x1B /* PD Core 2 RXTX */
-#define B2055_C2_PD_RSSIMISC		0x1C /* PD Core 2 RSSI MISC */
-#define B2055_PWRDET_LGEN		0x1D /* PWRDET LGEN */
-#define B2055_C1_PWRDET_LGBUF		0x1E /* PWRDET LGBUF Core 1 */
-#define B2055_C1_PWRDET_RXTX		0x1F /* PWRDET RXTX Core 1 */
-#define B2055_C2_PWRDET_LGBUF		0x20 /* PWRDET LGBUF Core 2 */
-#define B2055_C2_PWRDET_RXTX		0x21 /* PWRDET RXTX Core 2 */
-#define B2055_RRCCAL_CS			0x22 /* RRCCAL Control spare */
-#define B2055_RRCCAL_NOPTSEL		0x23 /* RRCCAL N OPT SEL */
-#define B2055_CAL_MISC			0x24 /* CAL MISC */
-#define B2055_CAL_COUT			0x25 /* CAL Counter out */
-#define B2055_CAL_COUT2			0x26 /* CAL Counter out 2 */
-#define B2055_CAL_CVARCTL		0x27 /* CAL CVAR Control */
-#define B2055_CAL_RVARCTL		0x28 /* CAL RVAR Control */
-#define B2055_CAL_LPOCTL		0x29 /* CAL LPO Control */
-#define B2055_CAL_TS			0x2A /* CAL TS */
-#define B2055_CAL_RCCALRTS		0x2B /* CAL RCCAL READ TS */
-#define B2055_CAL_RCALRTS		0x2C /* CAL RCAL READ TS */
-#define B2055_PADDRV			0x2D /* PAD driver */
-#define B2055_XOCTL1			0x2E /* XO Control 1 */
-#define B2055_XOCTL2			0x2F /* XO Control 2 */
-#define B2055_XOREGUL			0x30 /* XO Regulator */
-#define B2055_XOMISC			0x31 /* XO misc */
-#define B2055_PLL_LFC1			0x32 /* PLL LF C1 */
-#define B2055_PLL_CALVTH		0x33 /* PLL CAL VTH */
-#define B2055_PLL_LFC2			0x34 /* PLL LF C2 */
-#define B2055_PLL_REF			0x35 /* PLL reference */
-#define B2055_PLL_LFR1			0x36 /* PLL LF R1 */
-#define B2055_PLL_PFDCP			0x37 /* PLL PFD CP */
-#define B2055_PLL_IDAC_CPOPAMP		0x38 /* PLL IDAC CPOPAMP */
-#define B2055_PLL_CPREG			0x39 /* PLL CP Regulator */
-#define B2055_PLL_RCAL			0x3A /* PLL RCAL */
-#define B2055_RF_PLLMOD0		0x3B /* RF PLL MOD0 */
-#define B2055_RF_PLLMOD1		0x3C /* RF PLL MOD1 */
-#define B2055_RF_MMDIDAC1		0x3D /* RF MMD IDAC 1 */
-#define B2055_RF_MMDIDAC0		0x3E /* RF MMD IDAC 0 */
-#define B2055_RF_MMDSP			0x3F /* RF MMD spare */
-#define B2055_VCO_CAL1			0x40 /* VCO cal 1 */
-#define B2055_VCO_CAL2			0x41 /* VCO cal 2 */
-#define B2055_VCO_CAL3			0x42 /* VCO cal 3 */
-#define B2055_VCO_CAL4			0x43 /* VCO cal 4 */
-#define B2055_VCO_CAL5			0x44 /* VCO cal 5 */
-#define B2055_VCO_CAL6			0x45 /* VCO cal 6 */
-#define B2055_VCO_CAL7			0x46 /* VCO cal 7 */
-#define B2055_VCO_CAL8			0x47 /* VCO cal 8 */
-#define B2055_VCO_CAL9			0x48 /* VCO cal 9 */
-#define B2055_VCO_CAL10			0x49 /* VCO cal 10 */
-#define B2055_VCO_CAL11			0x4A /* VCO cal 11 */
-#define B2055_VCO_CAL12			0x4B /* VCO cal 12 */
-#define B2055_VCO_CAL13			0x4C /* VCO cal 13 */
-#define B2055_VCO_CAL14			0x4D /* VCO cal 14 */
-#define B2055_VCO_CAL15			0x4E /* VCO cal 15 */
-#define B2055_VCO_CAL16			0x4F /* VCO cal 16 */
-#define B2055_VCO_KVCO			0x50 /* VCO KVCO */
-#define B2055_VCO_CAPTAIL		0x51 /* VCO CAP TAIL */
-#define B2055_VCO_IDACVCO		0x52 /* VCO IDAC VCO */
-#define B2055_VCO_REG			0x53 /* VCO Regulator */
-#define B2055_PLL_RFVTH			0x54 /* PLL RF VTH */
-#define B2055_LGBUF_CENBUF		0x55 /* LGBUF CEN BUF */
-#define B2055_LGEN_TUNE1		0x56 /* LGEN tune 1 */
-#define B2055_LGEN_TUNE2		0x57 /* LGEN tune 2 */
-#define B2055_LGEN_IDAC1		0x58 /* LGEN IDAC 1 */
-#define B2055_LGEN_IDAC2		0x59 /* LGEN IDAC 2 */
-#define B2055_LGEN_BIASC		0x5A /* LGEN BIAS counter */
-#define B2055_LGEN_BIASIDAC		0x5B /* LGEN BIAS IDAC */
-#define B2055_LGEN_RCAL			0x5C /* LGEN RCAL */
-#define B2055_LGEN_DIV			0x5D /* LGEN div */
-#define B2055_LGEN_SPARE2		0x5E /* LGEN spare 2 */
-#define B2055_C1_LGBUF_ATUNE		0x5F /* Core 1 LGBUF A tune */
-#define B2055_C1_LGBUF_GTUNE		0x60 /* Core 1 LGBUF G tune */
-#define B2055_C1_LGBUF_DIV		0x61 /* Core 1 LGBUF div */
-#define B2055_C1_LGBUF_AIDAC		0x62 /* Core 1 LGBUF A IDAC */
-#define B2055_C1_LGBUF_GIDAC		0x63 /* Core 1 LGBUF G IDAC */
-#define B2055_C1_LGBUF_IDACFO		0x64 /* Core 1 LGBUF IDAC filter override */
-#define B2055_C1_LGBUF_SPARE		0x65 /* Core 1 LGBUF spare */
-#define B2055_C1_RX_RFSPC1		0x66 /* Core 1 RX RF SPC1 */
-#define B2055_C1_RX_RFR1		0x67 /* Core 1 RX RF reg 1 */
-#define B2055_C1_RX_RFR2		0x68 /* Core 1 RX RF reg 2 */
-#define B2055_C1_RX_RFRCAL		0x69 /* Core 1 RX RF RCAL */
-#define B2055_C1_RX_BB_BLCMP		0x6A /* Core 1 RX Baseband BUFI LPF CMP */
-#define B2055_C1_RX_BB_LPF		0x6B /* Core 1 RX Baseband LPF */
-#define B2055_C1_RX_BB_MIDACHP		0x6C /* Core 1 RX Baseband MIDAC High-pass */
-#define B2055_C1_RX_BB_VGA1IDAC		0x6D /* Core 1 RX Baseband VGA1 IDAC */
-#define B2055_C1_RX_BB_VGA2IDAC		0x6E /* Core 1 RX Baseband VGA2 IDAC */
-#define B2055_C1_RX_BB_VGA3IDAC		0x6F /* Core 1 RX Baseband VGA3 IDAC */
-#define B2055_C1_RX_BB_BUFOCTL		0x70 /* Core 1 RX Baseband BUFO Control */
-#define B2055_C1_RX_BB_RCCALCTL		0x71 /* Core 1 RX Baseband RCCAL Control */
-#define B2055_C1_RX_BB_RSSICTL1		0x72 /* Core 1 RX Baseband RSSI Control 1 */
-#define B2055_C1_RX_BB_RSSICTL2		0x73 /* Core 1 RX Baseband RSSI Control 2 */
-#define B2055_C1_RX_BB_RSSICTL3		0x74 /* Core 1 RX Baseband RSSI Control 3 */
-#define B2055_C1_RX_BB_RSSICTL4		0x75 /* Core 1 RX Baseband RSSI Control 4 */
-#define B2055_C1_RX_BB_RSSICTL5		0x76 /* Core 1 RX Baseband RSSI Control 5 */
-#define B2055_C1_RX_BB_REG		0x77 /* Core 1 RX Baseband Regulator */
-#define B2055_C1_RX_BB_SPARE1		0x78 /* Core 1 RX Baseband spare 1 */
-#define B2055_C1_RX_TXBBRCAL		0x79 /* Core 1 RX TX BB RCAL */
-#define B2055_C1_TX_RF_SPGA		0x7A /* Core 1 TX RF SGM PGA */
-#define B2055_C1_TX_RF_SPAD		0x7B /* Core 1 TX RF SGM PAD */
-#define B2055_C1_TX_RF_CNTPGA1		0x7C /* Core 1 TX RF counter PGA 1 */
-#define B2055_C1_TX_RF_CNTPAD1		0x7D /* Core 1 TX RF counter PAD 1 */
-#define B2055_C1_TX_RF_PGAIDAC		0x7E /* Core 1 TX RF PGA IDAC */
-#define B2055_C1_TX_PGAPADTN		0x7F /* Core 1 TX PGA PAD TN */
-#define B2055_C1_TX_PADIDAC1		0x80 /* Core 1 TX PAD IDAC 1 */
-#define B2055_C1_TX_PADIDAC2		0x81 /* Core 1 TX PAD IDAC 2 */
-#define B2055_C1_TX_MXBGTRIM		0x82 /* Core 1 TX MX B/G TRIM */
-#define B2055_C1_TX_RF_RCAL		0x83 /* Core 1 TX RF RCAL */
-#define B2055_C1_TX_RF_PADTSSI1		0x84 /* Core 1 TX RF PAD TSSI1 */
-#define B2055_C1_TX_RF_PADTSSI2		0x85 /* Core 1 TX RF PAD TSSI2 */
-#define B2055_C1_TX_RF_SPARE		0x86 /* Core 1 TX RF spare */
-#define B2055_C1_TX_RF_IQCAL1		0x87 /* Core 1 TX RF I/Q CAL 1 */
-#define B2055_C1_TX_RF_IQCAL2		0x88 /* Core 1 TX RF I/Q CAL 2 */
-#define B2055_C1_TXBB_RCCAL		0x89 /* Core 1 TXBB RC CAL Control */
-#define B2055_C1_TXBB_LPF1		0x8A /* Core 1 TXBB LPF 1 */
-#define B2055_C1_TX_VOSCNCL		0x8B /* Core 1 TX VOS CNCL */
-#define B2055_C1_TX_LPF_MXGMIDAC	0x8C /* Core 1 TX LPF MXGM IDAC */
-#define B2055_C1_TX_BB_MXGM		0x8D /* Core 1 TX BB MXGM */
-#define B2055_C2_LGBUF_ATUNE		0x8E /* Core 2 LGBUF A tune */
-#define B2055_C2_LGBUF_GTUNE		0x8F /* Core 2 LGBUF G tune */
-#define B2055_C2_LGBUF_DIV		0x90 /* Core 2 LGBUF div */
-#define B2055_C2_LGBUF_AIDAC		0x91 /* Core 2 LGBUF A IDAC */
-#define B2055_C2_LGBUF_GIDAC		0x92 /* Core 2 LGBUF G IDAC */
-#define B2055_C2_LGBUF_IDACFO		0x93 /* Core 2 LGBUF IDAC filter override */
-#define B2055_C2_LGBUF_SPARE		0x94 /* Core 2 LGBUF spare */
-#define B2055_C2_RX_RFSPC1		0x95 /* Core 2 RX RF SPC1 */
-#define B2055_C2_RX_RFR1		0x96 /* Core 2 RX RF reg 1 */
-#define B2055_C2_RX_RFR2		0x97 /* Core 2 RX RF reg 2 */
-#define B2055_C2_RX_RFRCAL		0x98 /* Core 2 RX RF RCAL */
-#define B2055_C2_RX_BB_BLCMP		0x99 /* Core 2 RX Baseband BUFI LPF CMP */
-#define B2055_C2_RX_BB_LPF		0x9A /* Core 2 RX Baseband LPF */
-#define B2055_C2_RX_BB_MIDACHP		0x9B /* Core 2 RX Baseband MIDAC High-pass */
-#define B2055_C2_RX_BB_VGA1IDAC		0x9C /* Core 2 RX Baseband VGA1 IDAC */
-#define B2055_C2_RX_BB_VGA2IDAC		0x9D /* Core 2 RX Baseband VGA2 IDAC */
-#define B2055_C2_RX_BB_VGA3IDAC		0x9E /* Core 2 RX Baseband VGA3 IDAC */
-#define B2055_C2_RX_BB_BUFOCTL		0x9F /* Core 2 RX Baseband BUFO Control */
-#define B2055_C2_RX_BB_RCCALCTL		0xA0 /* Core 2 RX Baseband RCCAL Control */
-#define B2055_C2_RX_BB_RSSICTL1		0xA1 /* Core 2 RX Baseband RSSI Control 1 */
-#define B2055_C2_RX_BB_RSSICTL2		0xA2 /* Core 2 RX Baseband RSSI Control 2 */
-#define B2055_C2_RX_BB_RSSICTL3		0xA3 /* Core 2 RX Baseband RSSI Control 3 */
-#define B2055_C2_RX_BB_RSSICTL4		0xA4 /* Core 2 RX Baseband RSSI Control 4 */
-#define B2055_C2_RX_BB_RSSICTL5		0xA5 /* Core 2 RX Baseband RSSI Control 5 */
-#define B2055_C2_RX_BB_REG		0xA6 /* Core 2 RX Baseband Regulator */
-#define B2055_C2_RX_BB_SPARE1		0xA7 /* Core 2 RX Baseband spare 1 */
-#define B2055_C2_RX_TXBBRCAL		0xA8 /* Core 2 RX TX BB RCAL */
-#define B2055_C2_TX_RF_SPGA		0xA9 /* Core 2 TX RF SGM PGA */
-#define B2055_C2_TX_RF_SPAD		0xAA /* Core 2 TX RF SGM PAD */
-#define B2055_C2_TX_RF_CNTPGA1		0xAB /* Core 2 TX RF counter PGA 1 */
-#define B2055_C2_TX_RF_CNTPAD1		0xAC /* Core 2 TX RF counter PAD 1 */
-#define B2055_C2_TX_RF_PGAIDAC		0xAD /* Core 2 TX RF PGA IDAC */
-#define B2055_C2_TX_PGAPADTN		0xAE /* Core 2 TX PGA PAD TN */
-#define B2055_C2_TX_PADIDAC1		0xAF /* Core 2 TX PAD IDAC 1 */
-#define B2055_C2_TX_PADIDAC2		0xB0 /* Core 2 TX PAD IDAC 2 */
-#define B2055_C2_TX_MXBGTRIM		0xB1 /* Core 2 TX MX B/G TRIM */
-#define B2055_C2_TX_RF_RCAL		0xB2 /* Core 2 TX RF RCAL */
-#define B2055_C2_TX_RF_PADTSSI1		0xB3 /* Core 2 TX RF PAD TSSI1 */
-#define B2055_C2_TX_RF_PADTSSI2		0xB4 /* Core 2 TX RF PAD TSSI2 */
-#define B2055_C2_TX_RF_SPARE		0xB5 /* Core 2 TX RF spare */
-#define B2055_C2_TX_RF_IQCAL1		0xB6 /* Core 2 TX RF I/Q CAL 1 */
-#define B2055_C2_TX_RF_IQCAL2		0xB7 /* Core 2 TX RF I/Q CAL 2 */
-#define B2055_C2_TXBB_RCCAL		0xB8 /* Core 2 TXBB RC CAL Control */
-#define B2055_C2_TXBB_LPF1		0xB9 /* Core 2 TXBB LPF 1 */
-#define B2055_C2_TX_VOSCNCL		0xBA /* Core 2 TX VOS CNCL */
-#define B2055_C2_TX_LPF_MXGMIDAC	0xBB /* Core 2 TX LPF MXGM IDAC */
-#define B2055_C2_TX_BB_MXGM		0xBC /* Core 2 TX BB MXGM */
-#define B2055_PRG_GCHP21		0xBD /* PRG GC HPVGA23 21 */
-#define B2055_PRG_GCHP22		0xBE /* PRG GC HPVGA23 22 */
-#define B2055_PRG_GCHP23		0xBF /* PRG GC HPVGA23 23 */
-#define B2055_PRG_GCHP24		0xC0 /* PRG GC HPVGA23 24 */
-#define B2055_PRG_GCHP25		0xC1 /* PRG GC HPVGA23 25 */
-#define B2055_PRG_GCHP26		0xC2 /* PRG GC HPVGA23 26 */
-#define B2055_PRG_GCHP27		0xC3 /* PRG GC HPVGA23 27 */
-#define B2055_PRG_GCHP28		0xC4 /* PRG GC HPVGA23 28 */
-#define B2055_PRG_GCHP29		0xC5 /* PRG GC HPVGA23 29 */
-#define B2055_PRG_GCHP30		0xC6 /* PRG GC HPVGA23 30 */
-#define B2055_C1_LNA_GAINBST		0xCD /* Core 1 LNA GAINBST */
-#define B2055_C1_B0NB_RSSIVCM		0xD2 /* Core 1 B0 narrow-band RSSI VCM */
-#define B2055_C1_GENSPARE2		0xD6 /* Core 1 GEN spare 2 */
-#define B2055_C2_LNA_GAINBST		0xD9 /* Core 2 LNA GAINBST */
-#define B2055_C2_B0NB_RSSIVCM		0xDE /* Core 2 B0 narrow-band RSSI VCM */
-#define B2055_C2_GENSPARE2		0xE2 /* Core 2 GEN spare 2 */
-
-
-
 struct b43_wldev;
 
 struct b43_chanspec {
-	u8 channel;
-	u8 sideband;
-	u8 b_width;
-	u8 b_freq;
+	u16 center_freq;
+	enum nl80211_channel_type channel_type;
 };
 
 struct b43_phy_n_iq_comp {
@@ -984,8 +772,6 @@ struct b43_phy_n {
 	u16 papd_epsilon_offset[2];
 	s32 preamble_override;
 	u32 bb_mult_save;
-	u8 b_width;
-	struct b43_chanspec radio_chanspec;
 
 	bool gain_boost;
 	bool elna_gain_config;
diff --git a/drivers/net/wireless/b43/radio_2055.c b/drivers/net/wireless/b43/radio_2055.c
new file mode 100644
index 000000000000..1b5316586cbf
--- /dev/null
+++ b/drivers/net/wireless/b43/radio_2055.c
@@ -0,0 +1,1332 @@
+/*
+
+  Broadcom B43 wireless driver
+  IEEE 802.11n PHY and radio device data tables
+
+  Copyright (c) 2008 Michael Buesch <mb@bu3sch.de>
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; see the file COPYING.  If not, write to
+  the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
+  Boston, MA 02110-1301, USA.
+
+*/
+
+#include "b43.h"
+#include "radio_2055.h"
+#include "phy_common.h"
+
+struct b2055_inittab_entry {
+	/* Value to write if we use the 5GHz band. */
+	u16 ghz5;
+	/* Value to write if we use the 2.4GHz band. */
+	u16 ghz2;
+	/* Flags */
+	u8 flags;
+#define B2055_INITTAB_ENTRY_OK	0x01
+#define B2055_INITTAB_UPLOAD	0x02
+};
+#define UPLOAD		.flags = B2055_INITTAB_ENTRY_OK | B2055_INITTAB_UPLOAD
+#define NOUPLOAD	.flags = B2055_INITTAB_ENTRY_OK
+
+static const struct b2055_inittab_entry b2055_inittab [] = {
+  [B2055_SP_PINPD]		= { .ghz5 = 0x0080, .ghz2 = 0x0080, NOUPLOAD, },
+  [B2055_C1_SP_RSSI]		= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_C1_SP_PDMISC]		= { .ghz5 = 0x0027, .ghz2 = 0x0027, NOUPLOAD, },
+  [B2055_C2_SP_RSSI]		= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_C2_SP_PDMISC]		= { .ghz5 = 0x0027, .ghz2 = 0x0027, NOUPLOAD, },
+  [B2055_C1_SP_RXGC1]		= { .ghz5 = 0x007F, .ghz2 = 0x007F, UPLOAD, },
+  [B2055_C1_SP_RXGC2]		= { .ghz5 = 0x0007, .ghz2 = 0x0007, UPLOAD, },
+  [B2055_C2_SP_RXGC1]		= { .ghz5 = 0x007F, .ghz2 = 0x007F, UPLOAD, },
+  [B2055_C2_SP_RXGC2]		= { .ghz5 = 0x0007, .ghz2 = 0x0007, UPLOAD, },
+  [B2055_C1_SP_LPFBWSEL]	= { .ghz5 = 0x0015, .ghz2 = 0x0015, NOUPLOAD, },
+  [B2055_C2_SP_LPFBWSEL]	= { .ghz5 = 0x0015, .ghz2 = 0x0015, NOUPLOAD, },
+  [B2055_C1_SP_TXGC1]		= { .ghz5 = 0x004F, .ghz2 = 0x004F, UPLOAD, },
+  [B2055_C1_SP_TXGC2]		= { .ghz5 = 0x0005, .ghz2 = 0x0005, UPLOAD, },
+  [B2055_C2_SP_TXGC1]		= { .ghz5 = 0x004F, .ghz2 = 0x004F, UPLOAD, },
+  [B2055_C2_SP_TXGC2]		= { .ghz5 = 0x0005, .ghz2 = 0x0005, UPLOAD, },
+  [B2055_MASTER1]		= { .ghz5 = 0x00D0, .ghz2 = 0x00D0, NOUPLOAD, },
+  [B2055_MASTER2]		= { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, },
+  [B2055_PD_LGEN]		= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_PD_PLLTS]		= { .ghz5 = 0x0040, .ghz2 = 0x0040, NOUPLOAD, },
+  [B2055_C1_PD_LGBUF]		= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_C1_PD_TX]		= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_C1_PD_RXTX]		= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_C1_PD_RSSIMISC]	= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_C2_PD_LGBUF]		= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_C2_PD_TX]		= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_C2_PD_RXTX]		= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_C2_PD_RSSIMISC]	= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_PWRDET_LGEN]		= { .ghz5 = 0x00C0, .ghz2 = 0x00C0, NOUPLOAD, },
+  [B2055_C1_PWRDET_LGBUF]	= { .ghz5 = 0x00FF, .ghz2 = 0x00FF, NOUPLOAD, },
+  [B2055_C1_PWRDET_RXTX]	= { .ghz5 = 0x00C0, .ghz2 = 0x00C0, NOUPLOAD, },
+  [B2055_C2_PWRDET_LGBUF]	= { .ghz5 = 0x00FF, .ghz2 = 0x00FF, NOUPLOAD, },
+  [B2055_C2_PWRDET_RXTX]	= { .ghz5 = 0x00C0, .ghz2 = 0x00C0, NOUPLOAD, },
+  [B2055_RRCCAL_CS]		= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_RRCCAL_NOPTSEL]	= { .ghz5 = 0x002C, .ghz2 = 0x002C, NOUPLOAD, },
+  [B2055_CAL_MISC]		= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_CAL_COUT]		= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_CAL_COUT2]		= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_CAL_CVARCTL]		= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_CAL_RVARCTL]		= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_CAL_LPOCTL]		= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_CAL_TS]		= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_CAL_RCCALRTS]		= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_CAL_RCALRTS]		= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_PADDRV]		= { .ghz5 = 0x00A4, .ghz2 = 0x00A4, NOUPLOAD, },
+  [B2055_XOCTL1]		= { .ghz5 = 0x0038, .ghz2 = 0x0038, NOUPLOAD, },
+  [B2055_XOCTL2]		= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_XOREGUL]		= { .ghz5 = 0x0004, .ghz2 = 0x0004, UPLOAD, },
+  [B2055_XOMISC]		= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_PLL_LFC1]		= { .ghz5 = 0x000A, .ghz2 = 0x000A, NOUPLOAD, },
+  [B2055_PLL_CALVTH]		= { .ghz5 = 0x0087, .ghz2 = 0x0087, NOUPLOAD, },
+  [B2055_PLL_LFC2]		= { .ghz5 = 0x0009, .ghz2 = 0x0009, NOUPLOAD, },
+  [B2055_PLL_REF]		= { .ghz5 = 0x0070, .ghz2 = 0x0070, NOUPLOAD, },
+  [B2055_PLL_LFR1]		= { .ghz5 = 0x0011, .ghz2 = 0x0011, NOUPLOAD, },
+  [B2055_PLL_PFDCP]		= { .ghz5 = 0x0018, .ghz2 = 0x0018, UPLOAD, },
+  [B2055_PLL_IDAC_CPOPAMP]	= { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
+  [B2055_PLL_CPREG]		= { .ghz5 = 0x0004, .ghz2 = 0x0004, UPLOAD, },
+  [B2055_PLL_RCAL]		= { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
+  [B2055_RF_PLLMOD0]		= { .ghz5 = 0x009E, .ghz2 = 0x009E, NOUPLOAD, },
+  [B2055_RF_PLLMOD1]		= { .ghz5 = 0x0009, .ghz2 = 0x0009, NOUPLOAD, },
+  [B2055_RF_MMDIDAC1]		= { .ghz5 = 0x00C8, .ghz2 = 0x00C8, UPLOAD, },
+  [B2055_RF_MMDIDAC0]		= { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
+  [B2055_RF_MMDSP]		= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_VCO_CAL1]		= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_VCO_CAL2]		= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_VCO_CAL3]		= { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, },
+  [B2055_VCO_CAL4]		= { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, },
+  [B2055_VCO_CAL5]		= { .ghz5 = 0x0096, .ghz2 = 0x0096, NOUPLOAD, },
+  [B2055_VCO_CAL6]		= { .ghz5 = 0x003E, .ghz2 = 0x003E, NOUPLOAD, },
+  [B2055_VCO_CAL7]		= { .ghz5 = 0x003E, .ghz2 = 0x003E, NOUPLOAD, },
+  [B2055_VCO_CAL8]		= { .ghz5 = 0x0013, .ghz2 = 0x0013, NOUPLOAD, },
+  [B2055_VCO_CAL9]		= { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, },
+  [B2055_VCO_CAL10]		= { .ghz5 = 0x0015, .ghz2 = 0x0015, NOUPLOAD, },
+  [B2055_VCO_CAL11]		= { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, },
+  [B2055_VCO_CAL12]		= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_VCO_CAL13]		= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_VCO_CAL14]		= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_VCO_CAL15]		= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_VCO_CAL16]		= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_VCO_KVCO]		= { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, },
+  [B2055_VCO_CAPTAIL]		= { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, },
+  [B2055_VCO_IDACVCO]		= { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
+  [B2055_VCO_REG]		= { .ghz5 = 0x0084, .ghz2 = 0x0084, UPLOAD, },
+  [B2055_PLL_RFVTH]		= { .ghz5 = 0x00C3, .ghz2 = 0x00C3, NOUPLOAD, },
+  [B2055_LGBUF_CENBUF]		= { .ghz5 = 0x008F, .ghz2 = 0x008F, NOUPLOAD, },
+  [B2055_LGEN_TUNE1]		= { .ghz5 = 0x00FF, .ghz2 = 0x00FF, NOUPLOAD, },
+  [B2055_LGEN_TUNE2]		= { .ghz5 = 0x00FF, .ghz2 = 0x00FF, NOUPLOAD, },
+  [B2055_LGEN_IDAC1]		= { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
+  [B2055_LGEN_IDAC2]		= { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
+  [B2055_LGEN_BIASC]		= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_LGEN_BIASIDAC]		= { .ghz5 = 0x00CC, .ghz2 = 0x00CC, NOUPLOAD, },
+  [B2055_LGEN_RCAL]		= { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
+  [B2055_LGEN_DIV]		= { .ghz5 = 0x0080, .ghz2 = 0x0080, NOUPLOAD, },
+  [B2055_LGEN_SPARE2]		= { .ghz5 = 0x0080, .ghz2 = 0x0080, NOUPLOAD, },
+  [B2055_C1_LGBUF_ATUNE]	= { .ghz5 = 0x00F8, .ghz2 = 0x00F8, NOUPLOAD, },
+  [B2055_C1_LGBUF_GTUNE]	= { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
+  [B2055_C1_LGBUF_DIV]		= { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
+  [B2055_C1_LGBUF_AIDAC]	= { .ghz5 = 0x0088, .ghz2 = 0x0008, UPLOAD, },
+  [B2055_C1_LGBUF_GIDAC]	= { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
+  [B2055_C1_LGBUF_IDACFO]	= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_C1_LGBUF_SPARE]	= { .ghz5 = 0x0001, .ghz2 = 0x0001, UPLOAD, },
+  [B2055_C1_RX_RFSPC1]		= { .ghz5 = 0x008A, .ghz2 = 0x008A, NOUPLOAD, },
+  [B2055_C1_RX_RFR1]		= { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, },
+  [B2055_C1_RX_RFR2]		= { .ghz5 = 0x0083, .ghz2 = 0x0083, NOUPLOAD, },
+  [B2055_C1_RX_RFRCAL]		= { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
+  [B2055_C1_RX_BB_BLCMP]	= { .ghz5 = 0x00A0, .ghz2 = 0x00A0, NOUPLOAD, },
+  [B2055_C1_RX_BB_LPF]		= { .ghz5 = 0x000A, .ghz2 = 0x000A, NOUPLOAD, },
+  [B2055_C1_RX_BB_MIDACHP]	= { .ghz5 = 0x0087, .ghz2 = 0x0087, UPLOAD, },
+  [B2055_C1_RX_BB_VGA1IDAC]	= { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, },
+  [B2055_C1_RX_BB_VGA2IDAC]	= { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, },
+  [B2055_C1_RX_BB_VGA3IDAC]	= { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, },
+  [B2055_C1_RX_BB_BUFOCTL]	= { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, },
+  [B2055_C1_RX_BB_RCCALCTL]	= { .ghz5 = 0x0018, .ghz2 = 0x0018, NOUPLOAD, },
+  [B2055_C1_RX_BB_RSSICTL1]	= { .ghz5 = 0x006A, .ghz2 = 0x006A, UPLOAD, },
+  [B2055_C1_RX_BB_RSSICTL2]	= { .ghz5 = 0x00AB, .ghz2 = 0x00AB, UPLOAD, },
+  [B2055_C1_RX_BB_RSSICTL3]	= { .ghz5 = 0x0013, .ghz2 = 0x0013, UPLOAD, },
+  [B2055_C1_RX_BB_RSSICTL4]	= { .ghz5 = 0x00C1, .ghz2 = 0x00C1, UPLOAD, },
+  [B2055_C1_RX_BB_RSSICTL5]	= { .ghz5 = 0x00AA, .ghz2 = 0x00AA, UPLOAD, },
+  [B2055_C1_RX_BB_REG]		= { .ghz5 = 0x0087, .ghz2 = 0x0087, UPLOAD, },
+  [B2055_C1_RX_BB_SPARE1]	= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_C1_RX_TXBBRCAL]	= { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
+  [B2055_C1_TX_RF_SPGA]		= { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, },
+  [B2055_C1_TX_RF_SPAD]		= { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, },
+  [B2055_C1_TX_RF_CNTPGA1]	= { .ghz5 = 0x0015, .ghz2 = 0x0015, NOUPLOAD, },
+  [B2055_C1_TX_RF_CNTPAD1]	= { .ghz5 = 0x0055, .ghz2 = 0x0055, NOUPLOAD, },
+  [B2055_C1_TX_RF_PGAIDAC]	= { .ghz5 = 0x0097, .ghz2 = 0x0097, UPLOAD, },
+  [B2055_C1_TX_PGAPADTN]	= { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, },
+  [B2055_C1_TX_PADIDAC1]	= { .ghz5 = 0x0014, .ghz2 = 0x0014, UPLOAD, },
+  [B2055_C1_TX_PADIDAC2]	= { .ghz5 = 0x0033, .ghz2 = 0x0033, NOUPLOAD, },
+  [B2055_C1_TX_MXBGTRIM]	= { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
+  [B2055_C1_TX_RF_RCAL]		= { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
+  [B2055_C1_TX_RF_PADTSSI1]	= { .ghz5 = 0x0003, .ghz2 = 0x0003, UPLOAD, },
+  [B2055_C1_TX_RF_PADTSSI2]	= { .ghz5 = 0x000A, .ghz2 = 0x000A, NOUPLOAD, },
+  [B2055_C1_TX_RF_SPARE]	= { .ghz5 = 0x0003, .ghz2 = 0x0003, UPLOAD, },
+  [B2055_C1_TX_RF_IQCAL1]	= { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, },
+  [B2055_C1_TX_RF_IQCAL2]	= { .ghz5 = 0x00A4, .ghz2 = 0x00A4, NOUPLOAD, },
+  [B2055_C1_TXBB_RCCAL]		= { .ghz5 = 0x0018, .ghz2 = 0x0018, NOUPLOAD, },
+  [B2055_C1_TXBB_LPF1]		= { .ghz5 = 0x0028, .ghz2 = 0x0028, NOUPLOAD, },
+  [B2055_C1_TX_VOSCNCL]		= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_C1_TX_LPF_MXGMIDAC]	= { .ghz5 = 0x004A, .ghz2 = 0x004A, NOUPLOAD, },
+  [B2055_C1_TX_BB_MXGM]		= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_C2_LGBUF_ATUNE]	= { .ghz5 = 0x00F8, .ghz2 = 0x00F8, NOUPLOAD, },
+  [B2055_C2_LGBUF_GTUNE]	= { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
+  [B2055_C2_LGBUF_DIV]		= { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
+  [B2055_C2_LGBUF_AIDAC]	= { .ghz5 = 0x0088, .ghz2 = 0x0008, UPLOAD, },
+  [B2055_C2_LGBUF_GIDAC]	= { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
+  [B2055_C2_LGBUF_IDACFO]	= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_C2_LGBUF_SPARE]	= { .ghz5 = 0x0001, .ghz2 = 0x0001, UPLOAD, },
+  [B2055_C2_RX_RFSPC1]		= { .ghz5 = 0x008A, .ghz2 = 0x008A, NOUPLOAD, },
+  [B2055_C2_RX_RFR1]		= { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, },
+  [B2055_C2_RX_RFR2]		= { .ghz5 = 0x0083, .ghz2 = 0x0083, NOUPLOAD, },
+  [B2055_C2_RX_RFRCAL]		= { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
+  [B2055_C2_RX_BB_BLCMP]	= { .ghz5 = 0x00A0, .ghz2 = 0x00A0, NOUPLOAD, },
+  [B2055_C2_RX_BB_LPF]		= { .ghz5 = 0x000A, .ghz2 = 0x000A, NOUPLOAD, },
+  [B2055_C2_RX_BB_MIDACHP]	= { .ghz5 = 0x0087, .ghz2 = 0x0087, UPLOAD, },
+  [B2055_C2_RX_BB_VGA1IDAC]	= { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, },
+  [B2055_C2_RX_BB_VGA2IDAC]	= { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, },
+  [B2055_C2_RX_BB_VGA3IDAC]	= { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, },
+  [B2055_C2_RX_BB_BUFOCTL]	= { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, },
+  [B2055_C2_RX_BB_RCCALCTL]	= { .ghz5 = 0x0018, .ghz2 = 0x0018, NOUPLOAD, },
+  [B2055_C2_RX_BB_RSSICTL1]	= { .ghz5 = 0x006A, .ghz2 = 0x006A, UPLOAD, },
+  [B2055_C2_RX_BB_RSSICTL2]	= { .ghz5 = 0x00AB, .ghz2 = 0x00AB, UPLOAD, },
+  [B2055_C2_RX_BB_RSSICTL3]	= { .ghz5 = 0x0013, .ghz2 = 0x0013, UPLOAD, },
+  [B2055_C2_RX_BB_RSSICTL4]	= { .ghz5 = 0x00C1, .ghz2 = 0x00C1, UPLOAD, },
+  [B2055_C2_RX_BB_RSSICTL5]	= { .ghz5 = 0x00AA, .ghz2 = 0x00AA, UPLOAD, },
+  [B2055_C2_RX_BB_REG]		= { .ghz5 = 0x0087, .ghz2 = 0x0087, UPLOAD, },
+  [B2055_C2_RX_BB_SPARE1]	= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_C2_RX_TXBBRCAL]	= { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
+  [B2055_C2_TX_RF_SPGA]		= { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, },
+  [B2055_C2_TX_RF_SPAD]		= { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, },
+  [B2055_C2_TX_RF_CNTPGA1]	= { .ghz5 = 0x0015, .ghz2 = 0x0015, NOUPLOAD, },
+  [B2055_C2_TX_RF_CNTPAD1]	= { .ghz5 = 0x0055, .ghz2 = 0x0055, NOUPLOAD, },
+  [B2055_C2_TX_RF_PGAIDAC]	= { .ghz5 = 0x0097, .ghz2 = 0x0097, UPLOAD, },
+  [B2055_C2_TX_PGAPADTN]	= { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, },
+  [B2055_C2_TX_PADIDAC1]	= { .ghz5 = 0x0014, .ghz2 = 0x0014, UPLOAD, },
+  [B2055_C2_TX_PADIDAC2]	= { .ghz5 = 0x0033, .ghz2 = 0x0033, NOUPLOAD, },
+  [B2055_C2_TX_MXBGTRIM]	= { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
+  [B2055_C2_TX_RF_RCAL]		= { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
+  [B2055_C2_TX_RF_PADTSSI1]	= { .ghz5 = 0x0003, .ghz2 = 0x0003, UPLOAD, },
+  [B2055_C2_TX_RF_PADTSSI2]	= { .ghz5 = 0x000A, .ghz2 = 0x000A, NOUPLOAD, },
+  [B2055_C2_TX_RF_SPARE]	= { .ghz5 = 0x0003, .ghz2 = 0x0003, UPLOAD, },
+  [B2055_C2_TX_RF_IQCAL1]	= { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, },
+  [B2055_C2_TX_RF_IQCAL2]	= { .ghz5 = 0x00A4, .ghz2 = 0x00A4, NOUPLOAD, },
+  [B2055_C2_TXBB_RCCAL]		= { .ghz5 = 0x0018, .ghz2 = 0x0018, NOUPLOAD, },
+  [B2055_C2_TXBB_LPF1]		= { .ghz5 = 0x0028, .ghz2 = 0x0028, NOUPLOAD, },
+  [B2055_C2_TX_VOSCNCL]		= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_C2_TX_LPF_MXGMIDAC]	= { .ghz5 = 0x004A, .ghz2 = 0x004A, NOUPLOAD, },
+  [B2055_C2_TX_BB_MXGM]		= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_PRG_GCHP21]		= { .ghz5 = 0x0071, .ghz2 = 0x0071, NOUPLOAD, },
+  [B2055_PRG_GCHP22]		= { .ghz5 = 0x0072, .ghz2 = 0x0072, NOUPLOAD, },
+  [B2055_PRG_GCHP23]		= { .ghz5 = 0x0073, .ghz2 = 0x0073, NOUPLOAD, },
+  [B2055_PRG_GCHP24]		= { .ghz5 = 0x0074, .ghz2 = 0x0074, NOUPLOAD, },
+  [B2055_PRG_GCHP25]		= { .ghz5 = 0x0075, .ghz2 = 0x0075, NOUPLOAD, },
+  [B2055_PRG_GCHP26]		= { .ghz5 = 0x0076, .ghz2 = 0x0076, NOUPLOAD, },
+  [B2055_PRG_GCHP27]		= { .ghz5 = 0x0077, .ghz2 = 0x0077, NOUPLOAD, },
+  [B2055_PRG_GCHP28]		= { .ghz5 = 0x0078, .ghz2 = 0x0078, NOUPLOAD, },
+  [B2055_PRG_GCHP29]		= { .ghz5 = 0x0079, .ghz2 = 0x0079, NOUPLOAD, },
+  [B2055_PRG_GCHP30]		= { .ghz5 = 0x007A, .ghz2 = 0x007A, NOUPLOAD, },
+  [0xC7]			= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [0xC8]			= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [0xC9]			= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [0xCA]			= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [0xCB]			= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [0xCC]			= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_C1_LNA_GAINBST]	= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [0xCE]			= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [0xCF]			= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [0xD0]			= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [0xD1]			= { .ghz5 = 0x0018, .ghz2 = 0x0018, NOUPLOAD, },
+  [B2055_C1_B0NB_RSSIVCM]	= { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
+  [0xD3]			= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [0xD4]			= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [0xD5]			= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_C1_GENSPARE2]		= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [0xD7]			= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [0xD8]			= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_C2_LNA_GAINBST]	= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [0xDA]			= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [0xDB]			= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [0xDC]			= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [0xDD]			= { .ghz5 = 0x0018, .ghz2 = 0x0018, NOUPLOAD, },
+  [B2055_C2_B0NB_RSSIVCM]	= { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
+  [0xDF]			= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [0xE0]			= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [0xE1]			= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_C2_GENSPARE2]		= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+};
+
+#define RADIOREGS(r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, \
+		  r12, r13, r14, r15, r16, r17, r18, r19, r20, r21) \
+	.radio_pll_ref		= r0,	\
+	.radio_rf_pllmod0	= r1,	\
+	.radio_rf_pllmod1	= r2,	\
+	.radio_vco_captail	= r3,	\
+	.radio_vco_cal1		= r4,	\
+	.radio_vco_cal2		= r5,	\
+	.radio_pll_lfc1		= r6,	\
+	.radio_pll_lfr1		= r7,	\
+	.radio_pll_lfc2		= r8,	\
+	.radio_lgbuf_cenbuf	= r9,	\
+	.radio_lgen_tune1	= r10,	\
+	.radio_lgen_tune2	= r11,	\
+	.radio_c1_lgbuf_atune	= r12,	\
+	.radio_c1_lgbuf_gtune	= r13,	\
+	.radio_c1_rx_rfr1	= r14,	\
+	.radio_c1_tx_pgapadtn	= r15,	\
+	.radio_c1_tx_mxbgtrim	= r16,	\
+	.radio_c2_lgbuf_atune	= r17,	\
+	.radio_c2_lgbuf_gtune	= r18,	\
+	.radio_c2_rx_rfr1	= r19,	\
+	.radio_c2_tx_pgapadtn	= r20,	\
+	.radio_c2_tx_mxbgtrim	= r21
+
+#define PHYREGS(r0, r1, r2, r3, r4, r5)	\
+	.phy_regs.phy_bw1a	= r0,	\
+	.phy_regs.phy_bw2	= r1,	\
+	.phy_regs.phy_bw3	= r2,	\
+	.phy_regs.phy_bw4	= r3,	\
+	.phy_regs.phy_bw5	= r4,	\
+	.phy_regs.phy_bw6	= r5
+
+static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = {
+  {	.channel		= 184,
+	.freq			= 4920, /* MHz */
+	.unk2			= 3280,
+	RADIOREGS(0x71, 0x01, 0xEC, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
+		  0x00, 0x8F, 0xFF, 0xFF, 0xFF, 0x00, 0x0F, 0x0F,
+		  0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
+	PHYREGS(0xB407, 0xB007, 0xAC07, 0x1402, 0x1502, 0x1602),
+  },
+  {	.channel		= 186,
+	.freq			= 4930, /* MHz */
+	.unk2			= 3287,
+	RADIOREGS(0x71, 0x01, 0xED, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
+		  0x00, 0x8F, 0xFF, 0xFF, 0xFF, 0x00, 0x0F, 0x0F,
+		  0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
+	PHYREGS(0xB807, 0xB407, 0xB007, 0x1302, 0x1402, 0x1502),
+  },
+  {	.channel		= 188,
+	.freq			= 4940, /* MHz */
+	.unk2			= 3293,
+	RADIOREGS(0x71, 0x01, 0xEE, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
+		  0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F,
+		  0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
+	PHYREGS(0xBC07, 0xB807, 0xB407, 0x1202, 0x1302, 0x1402),
+  },
+  {	.channel		= 190,
+	.freq			= 4950, /* MHz */
+	.unk2			= 3300,
+	RADIOREGS(0x71, 0x01, 0xEF, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
+		  0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F,
+		  0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
+	PHYREGS(0xC007, 0xBC07, 0xB807, 0x1102, 0x1202, 0x1302),
+  },
+  {	.channel		= 192,
+	.freq			= 4960, /* MHz */
+	.unk2			= 3307,
+	RADIOREGS(0x71, 0x01, 0xF0, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
+		  0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F,
+		  0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
+	PHYREGS(0xC407, 0xC007, 0xBC07, 0x0F02, 0x1102, 0x1202),
+  },
+  {	.channel		= 194,
+	.freq			= 4970, /* MHz */
+	.unk2			= 3313,
+	RADIOREGS(0x71, 0x01, 0xF1, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
+		  0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F,
+		  0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
+	PHYREGS(0xC807, 0xC407, 0xC007, 0x0E02, 0x0F02, 0x1102),
+  },
+  {	.channel		= 196,
+	.freq			= 4980, /* MHz */
+	.unk2			= 3320,
+	RADIOREGS(0x71, 0x01, 0xF2, 0x0E, 0xFF, 0x01, 0x04, 0x0A,
+		  0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F,
+		  0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
+	PHYREGS(0xCC07, 0xC807, 0xC407, 0x0D02, 0x0E02, 0x0F02),
+  },
+  {	.channel		= 198,
+	.freq			= 4990, /* MHz */
+	.unk2			= 3327,
+	RADIOREGS(0x71, 0x01, 0xF3, 0x0E, 0xFF, 0x01, 0x04, 0x0A,
+		  0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F,
+		  0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
+	PHYREGS(0xD007, 0xCC07, 0xC807, 0x0C02, 0x0D02, 0x0E02),
+  },
+  {	.channel		= 200,
+	.freq			= 5000, /* MHz */
+	.unk2			= 3333,
+	RADIOREGS(0x71, 0x01, 0xF4, 0x0E, 0xFF, 0x01, 0x04, 0x0A,
+		  0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F,
+		  0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
+	PHYREGS(0xD407, 0xD007, 0xCC07, 0x0B02, 0x0C02, 0x0D02),
+  },
+  {	.channel		= 202,
+	.freq			= 5010, /* MHz */
+	.unk2			= 3340,
+	RADIOREGS(0x71, 0x01, 0xF5, 0x0E, 0xFF, 0x01, 0x04, 0x0A,
+		  0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F,
+		  0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
+	PHYREGS(0xD807, 0xD407, 0xD007, 0x0A02, 0x0B02, 0x0C02),
+  },
+  {	.channel		= 204,
+	.freq			= 5020, /* MHz */
+	.unk2			= 3347,
+	RADIOREGS(0x71, 0x01, 0xF6, 0x0E, 0xF7, 0x01, 0x04, 0x0A,
+		  0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F,
+		  0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
+	PHYREGS(0xDC07, 0xD807, 0xD407, 0x0902, 0x0A02, 0x0B02),
+  },
+  {	.channel		= 206,
+	.freq			= 5030, /* MHz */
+	.unk2			= 3353,
+	RADIOREGS(0x71, 0x01, 0xF7, 0x0E, 0xF7, 0x01, 0x04, 0x0A,
+		  0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F,
+		  0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
+	PHYREGS(0xE007, 0xDC07, 0xD807, 0x0802, 0x0902, 0x0A02),
+  },
+  {	.channel		= 208,
+	.freq			= 5040, /* MHz */
+	.unk2			= 3360,
+	RADIOREGS(0x71, 0x01, 0xF8, 0x0D, 0xEF, 0x01, 0x04, 0x0A,
+		  0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F,
+		  0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
+	PHYREGS(0xE407, 0xE007, 0xDC07, 0x0702, 0x0802, 0x0902),
+  },
+  {	.channel		= 210,
+	.freq			= 5050, /* MHz */
+	.unk2			= 3367,
+	RADIOREGS(0x71, 0x01, 0xF9, 0x0D, 0xEF, 0x01, 0x04, 0x0A,
+		  0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F,
+		  0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
+	PHYREGS(0xE807, 0xE407, 0xE007, 0x0602, 0x0702, 0x0802),
+  },
+  {	.channel		= 212,
+	.freq			= 5060, /* MHz */
+	.unk2			= 3373,
+	RADIOREGS(0x71, 0x01, 0xFA, 0x0D, 0xE6, 0x01, 0x04, 0x0A,
+		  0x00, 0x8F, 0xBB, 0xBB, 0xFF, 0x00, 0x0E, 0x0F,
+		  0x8E, 0xFF, 0x00, 0x0E, 0x0F, 0x8E),
+	PHYREGS(0xEC07, 0xE807, 0xE407, 0x0502, 0x0602, 0x0702),
+  },
+  {	.channel		= 214,
+	.freq			= 5070, /* MHz */
+	.unk2			= 3380,
+	RADIOREGS(0x71, 0x01, 0xFB, 0x0D, 0xE6, 0x01, 0x04, 0x0A,
+		  0x00, 0x8F, 0xBB, 0xBB, 0xFF, 0x00, 0x0E, 0x0F,
+		  0x8E, 0xFF, 0x00, 0x0E, 0x0F, 0x8E),
+	PHYREGS(0xF007, 0xEC07, 0xE807, 0x0402, 0x0502, 0x0602),
+  },
+  {	.channel		= 216,
+	.freq			= 5080, /* MHz */
+	.unk2			= 3387,
+	RADIOREGS(0x71, 0x01, 0xFC, 0x0D, 0xDE, 0x01, 0x04, 0x0A,
+		  0x00, 0x8E, 0xBB, 0xBB, 0xEE, 0x00, 0x0E, 0x0F,
+		  0x8D, 0xEE, 0x00, 0x0E, 0x0F, 0x8D),
+	PHYREGS(0xF407, 0xF007, 0xEC07, 0x0302, 0x0402, 0x0502),
+  },
+  {	.channel		= 218,
+	.freq			= 5090, /* MHz */
+	.unk2			= 3393,
+	RADIOREGS(0x71, 0x01, 0xFD, 0x0D, 0xDE, 0x01, 0x04, 0x0A,
+		  0x00, 0x8E, 0xBB, 0xBB, 0xEE, 0x00, 0x0E, 0x0F,
+		  0x8D, 0xEE, 0x00, 0x0E, 0x0F, 0x8D),
+	PHYREGS(0xF807, 0xF407, 0xF007, 0x0202, 0x0302, 0x0402),
+  },
+  {	.channel		= 220,
+	.freq			= 5100, /* MHz */
+	.unk2			= 3400,
+	RADIOREGS(0x71, 0x01, 0xFE, 0x0C, 0xD6, 0x01, 0x04, 0x0A,
+		  0x00, 0x8E, 0xAA, 0xAA, 0xEE, 0x00, 0x0D, 0x0F,
+		  0x8D, 0xEE, 0x00, 0x0D, 0x0F, 0x8D),
+	PHYREGS(0xFC07, 0xF807, 0xF407, 0x0102, 0x0202, 0x0302),
+  },
+  {	.channel		= 222,
+	.freq			= 5110, /* MHz */
+	.unk2			= 3407,
+	RADIOREGS(0x71, 0x01, 0xFF, 0x0C, 0xD6, 0x01, 0x04, 0x0A,
+		  0x00, 0x8E, 0xAA, 0xAA, 0xEE, 0x00, 0x0D, 0x0F,
+		  0x8D, 0xEE, 0x00, 0x0D, 0x0F, 0x8D),
+	PHYREGS(0x0008, 0xFC07, 0xF807, 0x0002, 0x0102, 0x0202),
+  },
+  {	.channel		= 224,
+	.freq			= 5120, /* MHz */
+	.unk2			= 3413,
+	RADIOREGS(0x71, 0x02, 0x00, 0x0C, 0xCE, 0x01, 0x04, 0x0A,
+		  0x00, 0x8D, 0xAA, 0xAA, 0xDD, 0x00, 0x0D, 0x0F,
+		  0x8C, 0xDD, 0x00, 0x0D, 0x0F, 0x8C),
+	PHYREGS(0x0408, 0x0008, 0xFC07, 0xFF01, 0x0002, 0x0102),
+  },
+  {	.channel		= 226,
+	.freq			= 5130, /* MHz */
+	.unk2			= 3420,
+	RADIOREGS(0x71, 0x02, 0x01, 0x0C, 0xCE, 0x01, 0x04, 0x0A,
+		  0x00, 0x8D, 0xAA, 0xAA, 0xDD, 0x00, 0x0D, 0x0F,
+		  0x8C, 0xDD, 0x00, 0x0D, 0x0F, 0x8C),
+	PHYREGS(0x0808, 0x0408, 0x0008, 0xFE01, 0xFF01, 0x0002),
+  },
+  {	.channel		= 228,
+	.freq			= 5140, /* MHz */
+	.unk2			= 3427,
+	RADIOREGS(0x71, 0x02, 0x02, 0x0C, 0xC6, 0x01, 0x04, 0x0A,
+		  0x00, 0x8D, 0x99, 0x99, 0xDD, 0x00, 0x0C, 0x0E,
+		  0x8B, 0xDD, 0x00, 0x0C, 0x0E, 0x8B),
+	PHYREGS(0x0C08, 0x0808, 0x0408, 0xFD01, 0xFE01, 0xFF01),
+  },
+  {	.channel		= 32,
+	.freq			= 5160, /* MHz */
+	.unk2			= 3440,
+	RADIOREGS(0x71, 0x02, 0x04, 0x0B, 0xBE, 0x01, 0x04, 0x0A,
+		  0x00, 0x8C, 0x99, 0x99, 0xCC, 0x00, 0x0B, 0x0D,
+		  0x8A, 0xCC, 0x00, 0x0B, 0x0D, 0x8A),
+	PHYREGS(0x1408, 0x1008, 0x0C08, 0xFB01, 0xFC01, 0xFD01),
+  },
+  {	.channel		= 34,
+	.freq			= 5170, /* MHz */
+	.unk2			= 3447,
+	RADIOREGS(0x71, 0x02, 0x05, 0x0B, 0xBE, 0x01, 0x04, 0x0A,
+		  0x00, 0x8C, 0x99, 0x99, 0xCC, 0x00, 0x0B, 0x0D,
+		  0x8A, 0xCC, 0x00, 0x0B, 0x0D, 0x8A),
+	PHYREGS(0x1808, 0x1408, 0x1008, 0xFA01, 0xFB01, 0xFC01),
+  },
+  {	.channel		= 36,
+	.freq			= 5180, /* MHz */
+	.unk2			= 3453,
+	RADIOREGS(0x71, 0x02, 0x06, 0x0B, 0xB6, 0x01, 0x04, 0x0A,
+		  0x00, 0x8C, 0x88, 0x88, 0xCC, 0x00, 0x0B, 0x0C,
+		  0x89, 0xCC, 0x00, 0x0B, 0x0C, 0x89),
+	PHYREGS(0x1C08, 0x1808, 0x1408, 0xF901, 0xFA01, 0xFB01),
+  },
+  {	.channel		= 38,
+	.freq			= 5190, /* MHz */
+	.unk2			= 3460,
+	RADIOREGS(0x71, 0x02, 0x07, 0x0B, 0xB6, 0x01, 0x04, 0x0A,
+		  0x00, 0x8C, 0x88, 0x88, 0xCC, 0x00, 0x0B, 0x0C,
+		  0x89, 0xCC, 0x00, 0x0B, 0x0C, 0x89),
+	PHYREGS(0x2008, 0x1C08, 0x1808, 0xF801, 0xF901, 0xFA01),
+  },
+  {	.channel		= 40,
+	.freq			= 5200, /* MHz */
+	.unk2			= 3467,
+	RADIOREGS(0x71, 0x02, 0x08, 0x0B, 0xAF, 0x01, 0x04, 0x0A,
+		  0x00, 0x8B, 0x88, 0x88, 0xBB, 0x00, 0x0A, 0x0B,
+		  0x89, 0xBB, 0x00, 0x0A, 0x0B, 0x89),
+	PHYREGS(0x2408, 0x2008, 0x1C08, 0xF701, 0xF801, 0xF901),
+  },
+  {	.channel		= 42,
+	.freq			= 5210, /* MHz */
+	.unk2			= 3473,
+	RADIOREGS(0x71, 0x02, 0x09, 0x0B, 0xAF, 0x01, 0x04, 0x0A,
+		  0x00, 0x8B, 0x88, 0x88, 0xBB, 0x00, 0x0A, 0x0B,
+		  0x89, 0xBB, 0x00, 0x0A, 0x0B, 0x89),
+	PHYREGS(0x2808, 0x2408, 0x2008, 0xF601, 0xF701, 0xF801),
+  },
+  {	.channel		= 44,
+	.freq			= 5220, /* MHz */
+	.unk2			= 3480,
+	RADIOREGS(0x71, 0x02, 0x0A, 0x0A, 0xA7, 0x01, 0x04, 0x0A,
+		  0x00, 0x8B, 0x77, 0x77, 0xBB, 0x00, 0x09, 0x0A,
+		  0x88, 0xBB, 0x00, 0x09, 0x0A, 0x88),
+	PHYREGS(0x2C08, 0x2808, 0x2408, 0xF501, 0xF601, 0xF701),
+  },
+  {	.channel		= 46,
+	.freq			= 5230, /* MHz */
+	.unk2			= 3487,
+	RADIOREGS(0x71, 0x02, 0x0B, 0x0A, 0xA7, 0x01, 0x04, 0x0A,
+		  0x00, 0x8B, 0x77, 0x77, 0xBB, 0x00, 0x09, 0x0A,
+		  0x88, 0xBB, 0x00, 0x09, 0x0A, 0x88),
+	PHYREGS(0x3008, 0x2C08, 0x2808, 0xF401, 0xF501, 0xF601),
+  },
+  {	.channel		= 48,
+	.freq			= 5240, /* MHz */
+	.unk2			= 3493,
+	RADIOREGS(0x71, 0x02, 0x0C, 0x0A, 0xA0, 0x01, 0x04, 0x0A,
+		  0x00, 0x8A, 0x77, 0x77, 0xAA, 0x00, 0x09, 0x0A,
+		  0x87, 0xAA, 0x00, 0x09, 0x0A, 0x87),
+	PHYREGS(0x3408, 0x3008, 0x2C08, 0xF301, 0xF401, 0xF501),
+  },
+  {	.channel		= 50,
+	.freq			= 5250, /* MHz */
+	.unk2			= 3500,
+	RADIOREGS(0x71, 0x02, 0x0D, 0x0A, 0xA0, 0x01, 0x04, 0x0A,
+		  0x00, 0x8A, 0x77, 0x77, 0xAA, 0x00, 0x09, 0x0A,
+		  0x87, 0xAA, 0x00, 0x09, 0x0A, 0x87),
+	PHYREGS(0x3808, 0x3408, 0x3008, 0xF201, 0xF301, 0xF401),
+  },
+  {	.channel		= 52,
+	.freq			= 5260, /* MHz */
+	.unk2			= 3507,
+	RADIOREGS(0x71, 0x02, 0x0E, 0x0A, 0x98, 0x01, 0x04, 0x0A,
+		  0x00, 0x8A, 0x66, 0x66, 0xAA, 0x00, 0x08, 0x09,
+		  0x87, 0xAA, 0x00, 0x08, 0x09, 0x87),
+	PHYREGS(0x3C08, 0x3808, 0x3408, 0xF101, 0xF201, 0xF301),
+  },
+  {	.channel		= 54,
+	.freq			= 5270, /* MHz */
+	.unk2			= 3513,
+	RADIOREGS(0x71, 0x02, 0x0F, 0x0A, 0x98, 0x01, 0x04, 0x0A,
+		  0x00, 0x8A, 0x66, 0x66, 0xAA, 0x00, 0x08, 0x09,
+		  0x87, 0xAA, 0x00, 0x08, 0x09, 0x87),
+	PHYREGS(0x4008, 0x3C08, 0x3808, 0xF001, 0xF101, 0xF201),
+  },
+  {	.channel		= 56,
+	.freq			= 5280, /* MHz */
+	.unk2			= 3520,
+	RADIOREGS(0x71, 0x02, 0x10, 0x09, 0x91, 0x01, 0x04, 0x0A,
+		  0x00, 0x89, 0x66, 0x66, 0x99, 0x00, 0x08, 0x08,
+		  0x86, 0x99, 0x00, 0x08, 0x08, 0x86),
+	PHYREGS(0x4408, 0x4008, 0x3C08, 0xF001, 0xF001, 0xF101),
+  },
+  {	.channel		= 58,
+	.freq			= 5290, /* MHz */
+	.unk2			= 3527,
+	RADIOREGS(0x71, 0x02, 0x11, 0x09, 0x91, 0x01, 0x04, 0x0A,
+		  0x00, 0x89, 0x66, 0x66, 0x99, 0x00, 0x08, 0x08,
+		  0x86, 0x99, 0x00, 0x08, 0x08, 0x86),
+	PHYREGS(0x4808, 0x4408, 0x4008, 0xEF01, 0xF001, 0xF001),
+  },
+  {	.channel		= 60,
+	.freq			= 5300, /* MHz */
+	.unk2			= 3533,
+	RADIOREGS(0x71, 0x02, 0x12, 0x09, 0x8A, 0x01, 0x04, 0x0A,
+		  0x00, 0x89, 0x55, 0x55, 0x99, 0x00, 0x08, 0x07,
+		  0x85, 0x99, 0x00, 0x08, 0x07, 0x85),
+	PHYREGS(0x4C08, 0x4808, 0x4408, 0xEE01, 0xEF01, 0xF001),
+  },
+  {	.channel		= 62,
+	.freq			= 5310, /* MHz */
+	.unk2			= 3540,
+	RADIOREGS(0x71, 0x02, 0x13, 0x09, 0x8A, 0x01, 0x04, 0x0A,
+		  0x00, 0x89, 0x55, 0x55, 0x99, 0x00, 0x08, 0x07,
+		  0x85, 0x99, 0x00, 0x08, 0x07, 0x85),
+	PHYREGS(0x5008, 0x4C08, 0x4808, 0xED01, 0xEE01, 0xEF01),
+  },
+  {	.channel		= 64,
+	.freq			= 5320, /* MHz */
+	.unk2			= 3547,
+	RADIOREGS(0x71, 0x02, 0x14, 0x09, 0x83, 0x01, 0x04, 0x0A,
+		  0x00, 0x88, 0x55, 0x55, 0x88, 0x00, 0x07, 0x07,
+		  0x84, 0x88, 0x00, 0x07, 0x07, 0x84),
+	PHYREGS(0x5408, 0x5008, 0x4C08, 0xEC01, 0xED01, 0xEE01),
+  },
+  {	.channel		= 66,
+	.freq			= 5330, /* MHz */
+	.unk2			= 3553,
+	RADIOREGS(0x71, 0x02, 0x15, 0x09, 0x83, 0x01, 0x04, 0x0A,
+		  0x00, 0x88, 0x55, 0x55, 0x88, 0x00, 0x07, 0x07,
+		  0x84, 0x88, 0x00, 0x07, 0x07, 0x84),
+	PHYREGS(0x5808, 0x5408, 0x5008, 0xEB01, 0xEC01, 0xED01),
+  },
+  {	.channel		= 68,
+	.freq			= 5340, /* MHz */
+	.unk2			= 3560,
+	RADIOREGS(0x71, 0x02, 0x16, 0x08, 0x7C, 0x01, 0x04, 0x0A,
+		  0x00, 0x88, 0x44, 0x44, 0x88, 0x00, 0x07, 0x06,
+		  0x84, 0x88, 0x00, 0x07, 0x06, 0x84),
+	PHYREGS(0x5C08, 0x5808, 0x5408, 0xEA01, 0xEB01, 0xEC01),
+  },
+  {	.channel		= 70,
+	.freq			= 5350, /* MHz */
+	.unk2			= 3567,
+	RADIOREGS(0x71, 0x02, 0x17, 0x08, 0x7C, 0x01, 0x04, 0x0A,
+		  0x00, 0x88, 0x44, 0x44, 0x88, 0x00, 0x07, 0x06,
+		  0x84, 0x88, 0x00, 0x07, 0x06, 0x84),
+	PHYREGS(0x6008, 0x5C08, 0x5808, 0xE901, 0xEA01, 0xEB01),
+  },
+  {	.channel		= 72,
+	.freq			= 5360, /* MHz */
+	.unk2			= 3573,
+	RADIOREGS(0x71, 0x02, 0x18, 0x08, 0x75, 0x01, 0x04, 0x0A,
+		  0x00, 0x87, 0x44, 0x44, 0x77, 0x00, 0x06, 0x05,
+		  0x83, 0x77, 0x00, 0x06, 0x05, 0x83),
+	PHYREGS(0x6408, 0x6008, 0x5C08, 0xE801, 0xE901, 0xEA01),
+  },
+  {	.channel		= 74,
+	.freq			= 5370, /* MHz */
+	.unk2			= 3580,
+	RADIOREGS(0x71, 0x02, 0x19, 0x08, 0x75, 0x01, 0x04, 0x0A,
+		  0x00, 0x87, 0x44, 0x44, 0x77, 0x00, 0x06, 0x05,
+		  0x83, 0x77, 0x00, 0x06, 0x05, 0x83),
+	PHYREGS(0x6808, 0x6408, 0x6008, 0xE701, 0xE801, 0xE901),
+  },
+  {	.channel		= 76,
+	.freq			= 5380, /* MHz */
+	.unk2			= 3587,
+	RADIOREGS(0x71, 0x02, 0x1A, 0x08, 0x6E, 0x01, 0x04, 0x0A,
+		  0x00, 0x87, 0x33, 0x33, 0x77, 0x00, 0x06, 0x04,
+		  0x82, 0x77, 0x00, 0x06, 0x04, 0x82),
+	PHYREGS(0x6C08, 0x6808, 0x6408, 0xE601, 0xE701, 0xE801),
+  },
+  {	.channel		= 78,
+	.freq			= 5390, /* MHz */
+	.unk2			= 3593,
+	RADIOREGS(0x71, 0x02, 0x1B, 0x08, 0x6E, 0x01, 0x04, 0x0A,
+		  0x00, 0x87, 0x33, 0x33, 0x77, 0x00, 0x06, 0x04,
+		  0x82, 0x77, 0x00, 0x06, 0x04, 0x82),
+	PHYREGS(0x7008, 0x6C08, 0x6808, 0xE501, 0xE601, 0xE701),
+  },
+  {	.channel		= 80,
+	.freq			= 5400, /* MHz */
+	.unk2			= 3600,
+	RADIOREGS(0x71, 0x02, 0x1C, 0x07, 0x67, 0x01, 0x04, 0x0A,
+		  0x00, 0x86, 0x33, 0x33, 0x66, 0x00, 0x05, 0x04,
+		  0x81, 0x66, 0x00, 0x05, 0x04, 0x81),
+	PHYREGS(0x7408, 0x7008, 0x6C08, 0xE501, 0xE501, 0xE601),
+  },
+  {	.channel		= 82,
+	.freq			= 5410, /* MHz */
+	.unk2			= 3607,
+	RADIOREGS(0x71, 0x02, 0x1D, 0x07, 0x67, 0x01, 0x04, 0x0A,
+		  0x00, 0x86, 0x33, 0x33, 0x66, 0x00, 0x05, 0x04,
+		  0x81, 0x66, 0x00, 0x05, 0x04, 0x81),
+	PHYREGS(0x7808, 0x7408, 0x7008, 0xE401, 0xE501, 0xE501),
+  },
+  {	.channel		= 84,
+	.freq			= 5420, /* MHz */
+	.unk2			= 3613,
+	RADIOREGS(0x71, 0x02, 0x1E, 0x07, 0x61, 0x01, 0x04, 0x0A,
+		  0x00, 0x86, 0x22, 0x22, 0x66, 0x00, 0x05, 0x03,
+		  0x80, 0x66, 0x00, 0x05, 0x03, 0x80),
+	PHYREGS(0x7C08, 0x7808, 0x7408, 0xE301, 0xE401, 0xE501),
+  },
+  {	.channel		= 86,
+	.freq			= 5430, /* MHz */
+	.unk2			= 3620,
+	RADIOREGS(0x71, 0x02, 0x1F, 0x07, 0x61, 0x01, 0x04, 0x0A,
+		  0x00, 0x86, 0x22, 0x22, 0x66, 0x00, 0x05, 0x03,
+		  0x80, 0x66, 0x00, 0x05, 0x03, 0x80),
+	PHYREGS(0x8008, 0x7C08, 0x7808, 0xE201, 0xE301, 0xE401),
+  },
+  {	.channel		= 88,
+	.freq			= 5440, /* MHz */
+	.unk2			= 3627,
+	RADIOREGS(0x71, 0x02, 0x20, 0x07, 0x5A, 0x01, 0x04, 0x0A,
+		  0x00, 0x85, 0x22, 0x22, 0x55, 0x00, 0x04, 0x02,
+		  0x80, 0x55, 0x00, 0x04, 0x02, 0x80),
+	PHYREGS(0x8408, 0x8008, 0x7C08, 0xE101, 0xE201, 0xE301),
+  },
+  {	.channel		= 90,
+	.freq			= 5450, /* MHz */
+	.unk2			= 3633,
+	RADIOREGS(0x71, 0x02, 0x21, 0x07, 0x5A, 0x01, 0x04, 0x0A,
+		  0x00, 0x85, 0x22, 0x22, 0x55, 0x00, 0x04, 0x02,
+		  0x80, 0x55, 0x00, 0x04, 0x02, 0x80),
+	PHYREGS(0x8808, 0x8408, 0x8008, 0xE001, 0xE101, 0xE201),
+  },
+  {	.channel		= 92,
+	.freq			= 5460, /* MHz */
+	.unk2			= 3640,
+	RADIOREGS(0x71, 0x02, 0x22, 0x06, 0x53, 0x01, 0x04, 0x0A,
+		  0x00, 0x85, 0x11, 0x11, 0x55, 0x00, 0x04, 0x01,
+		  0x80, 0x55, 0x00, 0x04, 0x01, 0x80),
+	PHYREGS(0x8C08, 0x8808, 0x8408, 0xDF01, 0xE001, 0xE101),
+  },
+  {	.channel		= 94,
+	.freq			= 5470, /* MHz */
+	.unk2			= 3647,
+	RADIOREGS(0x71, 0x02, 0x23, 0x06, 0x53, 0x01, 0x04, 0x0A,
+		  0x00, 0x85, 0x11, 0x11, 0x55, 0x00, 0x04, 0x01,
+		  0x80, 0x55, 0x00, 0x04, 0x01, 0x80),
+	PHYREGS(0x9008, 0x8C08, 0x8808, 0xDE01, 0xDF01, 0xE001),
+  },
+  {	.channel		= 96,
+	.freq			= 5480, /* MHz */
+	.unk2			= 3653,
+	RADIOREGS(0x71, 0x02, 0x24, 0x06, 0x4D, 0x01, 0x04, 0x0A,
+		  0x00, 0x84, 0x11, 0x11, 0x44, 0x00, 0x03, 0x00,
+		  0x80, 0x44, 0x00, 0x03, 0x00, 0x80),
+	PHYREGS(0x9408, 0x9008, 0x8C08, 0xDD01, 0xDE01, 0xDF01),
+  },
+  {	.channel		= 98,
+	.freq			= 5490, /* MHz */
+	.unk2			= 3660,
+	RADIOREGS(0x71, 0x02, 0x25, 0x06, 0x4D, 0x01, 0x04, 0x0A,
+		  0x00, 0x84, 0x11, 0x11, 0x44, 0x00, 0x03, 0x00,
+		  0x80, 0x44, 0x00, 0x03, 0x00, 0x80),
+	PHYREGS(0x9808, 0x9408, 0x9008, 0xDD01, 0xDD01, 0xDE01),
+  },
+  {	.channel		= 100,
+	.freq			= 5500, /* MHz */
+	.unk2			= 3667,
+	RADIOREGS(0x71, 0x02, 0x26, 0x06, 0x47, 0x01, 0x04, 0x0A,
+		  0x00, 0x84, 0x00, 0x00, 0x44, 0x00, 0x03, 0x00,
+		  0x80, 0x44, 0x00, 0x03, 0x00, 0x80),
+	PHYREGS(0x9C08, 0x9808, 0x9408, 0xDC01, 0xDD01, 0xDD01),
+  },
+  {	.channel		= 102,
+	.freq			= 5510, /* MHz */
+	.unk2			= 3673,
+	RADIOREGS(0x71, 0x02, 0x27, 0x06, 0x47, 0x01, 0x04, 0x0A,
+		  0x00, 0x84, 0x00, 0x00, 0x44, 0x00, 0x03, 0x00,
+		  0x80, 0x44, 0x00, 0x03, 0x00, 0x80),
+	PHYREGS(0xA008, 0x9C08, 0x9808, 0xDB01, 0xDC01, 0xDD01),
+  },
+  {	.channel		= 104,
+	.freq			= 5520, /* MHz */
+	.unk2			= 3680,
+	RADIOREGS(0x71, 0x02, 0x28, 0x05, 0x40, 0x01, 0x04, 0x0A,
+		  0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00,
+		  0x80, 0x33, 0x00, 0x02, 0x00, 0x80),
+	PHYREGS(0xA408, 0xA008, 0x9C08, 0xDA01, 0xDB01, 0xDC01),
+  },
+  {	.channel		= 106,
+	.freq			= 5530, /* MHz */
+	.unk2			= 3687,
+	RADIOREGS(0x71, 0x02, 0x29, 0x05, 0x40, 0x01, 0x04, 0x0A,
+		  0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00,
+		  0x80, 0x33, 0x00, 0x02, 0x00, 0x80),
+	PHYREGS(0xA808, 0xA408, 0xA008, 0xD901, 0xDA01, 0xDB01),
+  },
+  {	.channel		= 108,
+	.freq			= 5540, /* MHz */
+	.unk2			= 3693,
+	RADIOREGS(0x71, 0x02, 0x2A, 0x05, 0x3A, 0x01, 0x04, 0x0A,
+		  0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00,
+		  0x80, 0x33, 0x00, 0x02, 0x00, 0x80),
+	PHYREGS(0xAC08, 0xA808, 0xA408, 0xD801, 0xD901, 0xDA01),
+  },
+  {	.channel		= 110,
+	.freq			= 5550, /* MHz */
+	.unk2			= 3700,
+	RADIOREGS(0x71, 0x02, 0x2B, 0x05, 0x3A, 0x01, 0x04, 0x0A,
+		  0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00,
+		  0x80, 0x33, 0x00, 0x02, 0x00, 0x80),
+	PHYREGS(0xB008, 0xAC08, 0xA808, 0xD701, 0xD801, 0xD901),
+  },
+  {	.channel		= 112,
+	.freq			= 5560, /* MHz */
+	.unk2			= 3707,
+	RADIOREGS(0x71, 0x02, 0x2C, 0x05, 0x34, 0x01, 0x04, 0x0A,
+		  0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00,
+		  0x80, 0x22, 0x00, 0x01, 0x00, 0x80),
+	PHYREGS(0xB408, 0xB008, 0xAC08, 0xD701, 0xD701, 0xD801),
+  },
+  {	.channel		= 114,
+	.freq			= 5570, /* MHz */
+	.unk2			= 3713,
+	RADIOREGS(0x71, 0x02, 0x2D, 0x05, 0x34, 0x01, 0x04, 0x0A,
+		  0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00,
+		  0x80, 0x22, 0x00, 0x01, 0x00, 0x80),
+	PHYREGS(0xB808, 0xB408, 0xB008, 0xD601, 0xD701, 0xD701),
+  },
+  {	.channel		= 116,
+	.freq			= 5580, /* MHz */
+	.unk2			= 3720,
+	RADIOREGS(0x71, 0x02, 0x2E, 0x04, 0x2E, 0x01, 0x04, 0x0A,
+		  0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00,
+		  0x80, 0x22, 0x00, 0x01, 0x00, 0x80),
+	PHYREGS(0xBC08, 0xB808, 0xB408, 0xD501, 0xD601, 0xD701),
+  },
+  {	.channel		= 118,
+	.freq			= 5590, /* MHz */
+	.unk2			= 3727,
+	RADIOREGS(0x71, 0x02, 0x2F, 0x04, 0x2E, 0x01, 0x04, 0x0A,
+		  0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00,
+		  0x80, 0x22, 0x00, 0x01, 0x00, 0x80),
+	PHYREGS(0xC008, 0xBC08, 0xB808, 0xD401, 0xD501, 0xD601),
+  },
+  {	.channel		= 120,
+	.freq			= 5600, /* MHz */
+	.unk2			= 3733,
+	RADIOREGS(0x71, 0x02, 0x30, 0x04, 0x28, 0x01, 0x04, 0x0A,
+		  0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x01, 0x00,
+		  0x80, 0x11, 0x00, 0x01, 0x00, 0x80),
+	PHYREGS(0xC408, 0xC008, 0xBC08, 0xD301, 0xD401, 0xD501),
+  },
+  {	.channel		= 122,
+	.freq			= 5610, /* MHz */
+	.unk2			= 3740,
+	RADIOREGS(0x71, 0x02, 0x31, 0x04, 0x28, 0x01, 0x04, 0x0A,
+		  0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x01, 0x00,
+		  0x80, 0x11, 0x00, 0x01, 0x00, 0x80),
+	PHYREGS(0xC808, 0xC408, 0xC008, 0xD201, 0xD301, 0xD401),
+  },
+  {	.channel		= 124,
+	.freq			= 5620, /* MHz */
+	.unk2			= 3747,
+	RADIOREGS(0x71, 0x02, 0x32, 0x04, 0x21, 0x01, 0x04, 0x0A,
+		  0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00,
+		  0x80, 0x11, 0x00, 0x00, 0x00, 0x80),
+	PHYREGS(0xCC08, 0xC808, 0xC408, 0xD201, 0xD201, 0xD301),
+  },
+  {	.channel		= 126,
+	.freq			= 5630, /* MHz */
+	.unk2			= 3753,
+	RADIOREGS(0x71, 0x02, 0x33, 0x04, 0x21, 0x01, 0x04, 0x0A,
+		  0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00,
+		  0x80, 0x11, 0x00, 0x00, 0x00, 0x80),
+	PHYREGS(0xD008, 0xCC08, 0xC808, 0xD101, 0xD201, 0xD201),
+  },
+  {	.channel		= 128,
+	.freq			= 5640, /* MHz */
+	.unk2			= 3760,
+	RADIOREGS(0x71, 0x02, 0x34, 0x03, 0x1C, 0x01, 0x04, 0x0A,
+		  0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+	PHYREGS(0xD408, 0xD008, 0xCC08, 0xD001, 0xD101, 0xD201),
+  },
+  {	.channel		= 130,
+	.freq			= 5650, /* MHz */
+	.unk2			= 3767,
+	RADIOREGS(0x71, 0x02, 0x35, 0x03, 0x1C, 0x01, 0x04, 0x0A,
+		  0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+	PHYREGS(0xD808, 0xD408, 0xD008, 0xCF01, 0xD001, 0xD101),
+  },
+  {	.channel		= 132,
+	.freq			= 5660, /* MHz */
+	.unk2			= 3773,
+	RADIOREGS(0x71, 0x02, 0x36, 0x03, 0x16, 0x01, 0x04, 0x0A,
+		  0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+	PHYREGS(0xDC08, 0xD808, 0xD408, 0xCE01, 0xCF01, 0xD001),
+  },
+  {	.channel		= 134,
+	.freq			= 5670, /* MHz */
+	.unk2			= 3780,
+	RADIOREGS(0x71, 0x02, 0x37, 0x03, 0x16, 0x01, 0x04, 0x0A,
+		  0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+	PHYREGS(0xE008, 0xDC08, 0xD808, 0xCE01, 0xCE01, 0xCF01),
+  },
+  {	.channel		= 136,
+	.freq			= 5680, /* MHz */
+	.unk2			= 3787,
+	RADIOREGS(0x71, 0x02, 0x38, 0x03, 0x10, 0x01, 0x04, 0x0A,
+		  0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+	PHYREGS(0xE408, 0xE008, 0xDC08, 0xCD01, 0xCE01, 0xCE01),
+  },
+  {	.channel		= 138,
+	.freq			= 5690, /* MHz */
+	.unk2			= 3793,
+	RADIOREGS(0x71, 0x02, 0x39, 0x03, 0x10, 0x01, 0x04, 0x0A,
+		  0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+	PHYREGS(0xE808, 0xE408, 0xE008, 0xCC01, 0xCD01, 0xCE01),
+  },
+  {	.channel		= 140,
+	.freq			= 5700, /* MHz */
+	.unk2			= 3800,
+	RADIOREGS(0x71, 0x02, 0x3A, 0x02, 0x0A, 0x01, 0x04, 0x0A,
+		  0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+	PHYREGS(0xEC08, 0xE808, 0xE408, 0xCB01, 0xCC01, 0xCD01),
+  },
+  {	.channel		= 142,
+	.freq			= 5710, /* MHz */
+	.unk2			= 3807,
+	RADIOREGS(0x71, 0x02, 0x3B, 0x02, 0x0A, 0x01, 0x04, 0x0A,
+		  0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+	PHYREGS(0xF008, 0xEC08, 0xE808, 0xCA01, 0xCB01, 0xCC01),
+  },
+  {	.channel		= 144,
+	.freq			= 5720, /* MHz */
+	.unk2			= 3813,
+	RADIOREGS(0x71, 0x02, 0x3C, 0x02, 0x0A, 0x01, 0x04, 0x0A,
+		  0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+	PHYREGS(0xF408, 0xF008, 0xEC08, 0xC901, 0xCA01, 0xCB01),
+  },
+  {	.channel		= 145,
+	.freq			= 5725, /* MHz */
+	.unk2			= 3817,
+	RADIOREGS(0x72, 0x04, 0x79, 0x02, 0x03, 0x01, 0x03, 0x14,
+		  0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+	PHYREGS(0xF608, 0xF208, 0xEE08, 0xC901, 0xCA01, 0xCB01),
+  },
+  {	.channel		= 146,
+	.freq			= 5730, /* MHz */
+	.unk2			= 3820,
+	RADIOREGS(0x71, 0x02, 0x3D, 0x02, 0x0A, 0x01, 0x04, 0x0A,
+		  0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+	PHYREGS(0xF808, 0xF408, 0xF008, 0xC901, 0xC901, 0xCA01),
+  },
+  {	.channel		= 147,
+	.freq			= 5735, /* MHz */
+	.unk2			= 3823,
+	RADIOREGS(0x72, 0x04, 0x7B, 0x02, 0x03, 0x01, 0x03, 0x14,
+		  0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+	PHYREGS(0xFA08, 0xF608, 0xF208, 0xC801, 0xC901, 0xCA01),
+  },
+  {	.channel		= 148,
+	.freq			= 5740, /* MHz */
+	.unk2			= 3827,
+	RADIOREGS(0x71, 0x02, 0x3E, 0x02, 0x0A, 0x01, 0x04, 0x0A,
+		  0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+	PHYREGS(0xFC08, 0xF808, 0xF408, 0xC801, 0xC901, 0xC901),
+  },
+  {	.channel		= 149,
+	.freq			= 5745, /* MHz */
+	.unk2			= 3830,
+	RADIOREGS(0x72, 0x04, 0x7D, 0x02, 0xFE, 0x00, 0x03, 0x14,
+		  0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+	PHYREGS(0xFE08, 0xFA08, 0xF608, 0xC801, 0xC801, 0xC901),
+  },
+  {	.channel		= 150,
+	.freq			= 5750, /* MHz */
+	.unk2			= 3833,
+	RADIOREGS(0x71, 0x02, 0x3F, 0x02, 0x0A, 0x01, 0x04, 0x0A,
+		  0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+	PHYREGS(0x0009, 0xFC08, 0xF808, 0xC701, 0xC801, 0xC901),
+  },
+  {	.channel		= 151,
+	.freq			= 5755, /* MHz */
+	.unk2			= 3837,
+	RADIOREGS(0x72, 0x04, 0x7F, 0x02, 0xFE, 0x00, 0x03, 0x14,
+		  0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+	PHYREGS(0x0209, 0xFE08, 0xFA08, 0xC701, 0xC801, 0xC801),
+  },
+  {	.channel		= 152,
+	.freq			= 5760, /* MHz */
+	.unk2			= 3840,
+	RADIOREGS(0x71, 0x02, 0x40, 0x02, 0x0A, 0x01, 0x04, 0x0A,
+		  0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+	PHYREGS(0x0409, 0x0009, 0xFC08, 0xC601, 0xC701, 0xC801),
+  },
+  {	.channel		= 153,
+	.freq			= 5765, /* MHz */
+	.unk2			= 3843,
+	RADIOREGS(0x72, 0x04, 0x81, 0x02, 0xF8, 0x00, 0x03, 0x14,
+		  0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+	PHYREGS(0x0609, 0x0209, 0xFE08, 0xC601, 0xC701, 0xC801),
+  },
+  {	.channel		= 154,
+	.freq			= 5770, /* MHz */
+	.unk2			= 3847,
+	RADIOREGS(0x71, 0x02, 0x41, 0x02, 0x0A, 0x01, 0x04, 0x0A,
+		  0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+	PHYREGS(0x0809, 0x0409, 0x0009, 0xC601, 0xC601, 0xC701),
+  },
+  {	.channel		= 155,
+	.freq			= 5775, /* MHz */
+	.unk2			= 3850,
+	RADIOREGS(0x72, 0x04, 0x83, 0x02, 0xF8, 0x00, 0x03, 0x14,
+		  0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+	PHYREGS(0x0A09, 0x0609, 0x0209, 0xC501, 0xC601, 0xC701),
+  },
+  {	.channel		= 156,
+	.freq			= 5780, /* MHz */
+	.unk2			= 3853,
+	RADIOREGS(0x71, 0x02, 0x42, 0x02, 0x0A, 0x01, 0x04, 0x0A,
+		  0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+	PHYREGS(0x0C09, 0x0809, 0x0409, 0xC501, 0xC601, 0xC601),
+  },
+  {	.channel		= 157,
+	.freq			= 5785, /* MHz */
+	.unk2			= 3857,
+	RADIOREGS(0x72, 0x04, 0x85, 0x02, 0xF2, 0x00, 0x03, 0x14,
+		  0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+	PHYREGS(0x0E09, 0x0A09, 0x0609, 0xC401, 0xC501, 0xC601),
+  },
+  {	.channel		= 158,
+	.freq			= 5790, /* MHz */
+	.unk2			= 3860,
+	RADIOREGS(0x71, 0x02, 0x43, 0x02, 0x0A, 0x01, 0x04, 0x0A,
+		  0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+	PHYREGS(0x1009, 0x0C09, 0x0809, 0xC401, 0xC501, 0xC601),
+  },
+  {	.channel		= 159,
+	.freq			= 5795, /* MHz */
+	.unk2			= 3863,
+	RADIOREGS(0x72, 0x04, 0x87, 0x02, 0xF2, 0x00, 0x03, 0x14,
+		  0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+	PHYREGS(0x1209, 0x0E09, 0x0A09, 0xC401, 0xC401, 0xC501),
+  },
+  {	.channel		= 160,
+	.freq			= 5800, /* MHz */
+	.unk2			= 3867,
+	RADIOREGS(0x71, 0x02, 0x44, 0x01, 0x0A, 0x01, 0x04, 0x0A,
+		  0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+	PHYREGS(0x1409, 0x1009, 0x0C09, 0xC301, 0xC401, 0xC501),
+  },
+  {	.channel		= 161,
+	.freq			= 5805, /* MHz */
+	.unk2			= 3870,
+	RADIOREGS(0x72, 0x04, 0x89, 0x01, 0xED, 0x00, 0x03, 0x14,
+		  0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+	PHYREGS(0x1609, 0x1209, 0x0E09, 0xC301, 0xC401, 0xC401),
+  },
+  {	.channel		= 162,
+	.freq			= 5810, /* MHz */
+	.unk2			= 3873,
+	RADIOREGS(0x71, 0x02, 0x45, 0x01, 0x0A, 0x01, 0x04, 0x0A,
+		  0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+	PHYREGS(0x1809, 0x1409, 0x1009, 0xC201, 0xC301, 0xC401),
+  },
+  {	.channel		= 163,
+	.freq			= 5815, /* MHz */
+	.unk2			= 3877,
+	RADIOREGS(0x72, 0x04, 0x8B, 0x01, 0xED, 0x00, 0x03, 0x14,
+		  0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+	PHYREGS(0x1A09, 0x1609, 0x1209, 0xC201, 0xC301, 0xC401),
+  },
+  {	.channel		= 164,
+	.freq			= 5820, /* MHz */
+	.unk2			= 3880,
+	RADIOREGS(0x71, 0x02, 0x46, 0x01, 0x0A, 0x01, 0x04, 0x0A,
+		  0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+	PHYREGS(0x1C09, 0x1809, 0x1409, 0xC201, 0xC201, 0xC301),
+  },
+  {	.channel		= 165,
+	.freq			= 5825, /* MHz */
+	.unk2			= 3883,
+	RADIOREGS(0x72, 0x04, 0x8D, 0x01, 0xED, 0x00, 0x03, 0x14,
+		  0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+	PHYREGS(0x1E09, 0x1A09, 0x1609, 0xC101, 0xC201, 0xC301),
+  },
+  {	.channel		= 166,
+	.freq			= 5830, /* MHz */
+	.unk2			= 3887,
+	RADIOREGS(0x71, 0x02, 0x47, 0x01, 0x0A, 0x01, 0x04, 0x0A,
+		  0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+	PHYREGS(0x2009, 0x1C09, 0x1809, 0xC101, 0xC201, 0xC201),
+  },
+  {	.channel		= 168,
+	.freq			= 5840, /* MHz */
+	.unk2			= 3893,
+	RADIOREGS(0x71, 0x02, 0x48, 0x01, 0x0A, 0x01, 0x04, 0x0A,
+		  0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+	PHYREGS(0x2409, 0x2009, 0x1C09, 0xC001, 0xC101, 0xC201),
+  },
+  {	.channel		= 170,
+	.freq			= 5850, /* MHz */
+	.unk2			= 3900,
+	RADIOREGS(0x71, 0x02, 0x49, 0x01, 0xE0, 0x00, 0x04, 0x0A,
+		  0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+	PHYREGS(0x2809, 0x2409, 0x2009, 0xBF01, 0xC001, 0xC101),
+  },
+  {	.channel		= 172,
+	.freq			= 5860, /* MHz */
+	.unk2			= 3907,
+	RADIOREGS(0x71, 0x02, 0x4A, 0x01, 0xDE, 0x00, 0x04, 0x0A,
+		  0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+	PHYREGS(0x2C09, 0x2809, 0x2409, 0xBF01, 0xBF01, 0xC001),
+  },
+  {	.channel		= 174,
+	.freq			= 5870, /* MHz */
+	.unk2			= 3913,
+	RADIOREGS(0x71, 0x02, 0x4B, 0x00, 0xDB, 0x00, 0x04, 0x0A,
+		  0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+	PHYREGS(0x3009, 0x2C09, 0x2809, 0xBE01, 0xBF01, 0xBF01),
+  },
+  {	.channel		= 176,
+	.freq			= 5880, /* MHz */
+	.unk2			= 3920,
+	RADIOREGS(0x71, 0x02, 0x4C, 0x00, 0xD8, 0x00, 0x04, 0x0A,
+		  0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+	PHYREGS(0x3409, 0x3009, 0x2C09, 0xBD01, 0xBE01, 0xBF01),
+  },
+  {	.channel		= 178,
+	.freq			= 5890, /* MHz */
+	.unk2			= 3927,
+	RADIOREGS(0x71, 0x02, 0x4D, 0x00, 0xD6, 0x00, 0x04, 0x0A,
+		  0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+	PHYREGS(0x3809, 0x3409, 0x3009, 0xBC01, 0xBD01, 0xBE01),
+  },
+  {	.channel		= 180,
+	.freq			= 5900, /* MHz */
+	.unk2			= 3933,
+	RADIOREGS(0x71, 0x02, 0x4E, 0x00, 0xD3, 0x00, 0x04, 0x0A,
+		  0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+	PHYREGS(0x3C09, 0x3809, 0x3409, 0xBC01, 0xBC01, 0xBD01),
+  },
+  {	.channel		= 182,
+	.freq			= 5910, /* MHz */
+	.unk2			= 3940,
+	RADIOREGS(0x71, 0x02, 0x4F, 0x00, 0xD6, 0x00, 0x04, 0x0A,
+		  0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+	PHYREGS(0x4009, 0x3C09, 0x3809, 0xBB01, 0xBC01, 0xBC01),
+  },
+  {	.channel		= 1,
+	.freq			= 2412, /* MHz */
+	.unk2			= 3216,
+	RADIOREGS(0x73, 0x09, 0x6C, 0x0F, 0x00, 0x01, 0x07, 0x15,
+		  0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0D, 0x0C,
+		  0x80, 0xFF, 0x88, 0x0D, 0x0C, 0x80),
+	PHYREGS(0xC903, 0xC503, 0xC103, 0x3A04, 0x3F04, 0x4304),
+  },
+  {	.channel		= 2,
+	.freq			= 2417, /* MHz */
+	.unk2			= 3223,
+	RADIOREGS(0x73, 0x09, 0x71, 0x0F, 0x00, 0x01, 0x07, 0x15,
+		  0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x0B,
+		  0x80, 0xFF, 0x88, 0x0C, 0x0B, 0x80),
+	PHYREGS(0xCB03, 0xC703, 0xC303, 0x3804, 0x3D04, 0x4104),
+  },
+  {	.channel		= 3,
+	.freq			= 2422, /* MHz */
+	.unk2			= 3229,
+	RADIOREGS(0x73, 0x09, 0x76, 0x0F, 0x00, 0x01, 0x07, 0x15,
+		  0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x0A,
+		  0x80, 0xFF, 0x88, 0x0C, 0x0A, 0x80),
+	PHYREGS(0xCD03, 0xC903, 0xC503, 0x3604, 0x3A04, 0x3F04),
+  },
+  {	.channel		= 4,
+	.freq			= 2427, /* MHz */
+	.unk2			= 3236,
+	RADIOREGS(0x73, 0x09, 0x7B, 0x0F, 0x00, 0x01, 0x07, 0x15,
+		  0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x0A,
+		  0x80, 0xFF, 0x88, 0x0C, 0x0A, 0x80),
+	PHYREGS(0xCF03, 0xCB03, 0xC703, 0x3404, 0x3804, 0x3D04),
+  },
+  {	.channel		= 5,
+	.freq			= 2432, /* MHz */
+	.unk2			= 3243,
+	RADIOREGS(0x73, 0x09, 0x80, 0x0F, 0x00, 0x01, 0x07, 0x15,
+		  0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x09,
+		  0x80, 0xFF, 0x88, 0x0C, 0x09, 0x80),
+	PHYREGS(0xD103, 0xCD03, 0xC903, 0x3104, 0x3604, 0x3A04),
+  },
+  {	.channel		= 6,
+	.freq			= 2437, /* MHz */
+	.unk2			= 3249,
+	RADIOREGS(0x73, 0x09, 0x85, 0x0F, 0x00, 0x01, 0x07, 0x15,
+		  0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0B, 0x08,
+		  0x80, 0xFF, 0x88, 0x0B, 0x08, 0x80),
+	PHYREGS(0xD303, 0xCF03, 0xCB03, 0x2F04, 0x3404, 0x3804),
+  },
+  {	.channel		= 7,
+	.freq			= 2442, /* MHz */
+	.unk2			= 3256,
+	RADIOREGS(0x73, 0x09, 0x8A, 0x0F, 0x00, 0x01, 0x07, 0x15,
+		  0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0A, 0x07,
+		  0x80, 0xFF, 0x88, 0x0A, 0x07, 0x80),
+	PHYREGS(0xD503, 0xD103, 0xCD03, 0x2D04, 0x3104, 0x3604),
+  },
+  {	.channel		= 8,
+	.freq			= 2447, /* MHz */
+	.unk2			= 3263,
+	RADIOREGS(0x73, 0x09, 0x8F, 0x0F, 0x00, 0x01, 0x07, 0x15,
+		  0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0A, 0x06,
+		  0x80, 0xFF, 0x88, 0x0A, 0x06, 0x80),
+	PHYREGS(0xD703, 0xD303, 0xCF03, 0x2B04, 0x2F04, 0x3404),
+  },
+  {	.channel		= 9,
+	.freq			= 2452, /* MHz */
+	.unk2			= 3269,
+	RADIOREGS(0x73, 0x09, 0x94, 0x0F, 0x00, 0x01, 0x07, 0x15,
+		  0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x09, 0x06,
+		  0x80, 0xFF, 0x88, 0x09, 0x06, 0x80),
+	PHYREGS(0xD903, 0xD503, 0xD103, 0x2904, 0x2D04, 0x3104),
+  },
+  {	.channel		= 10,
+	.freq			= 2457, /* MHz */
+	.unk2			= 3276,
+	RADIOREGS(0x73, 0x09, 0x99, 0x0F, 0x00, 0x01, 0x07, 0x15,
+		  0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x08, 0x05,
+		  0x80, 0xFF, 0x88, 0x08, 0x05, 0x80),
+	PHYREGS(0xDB03, 0xD703, 0xD303, 0x2704, 0x2B04, 0x2F04),
+  },
+  {	.channel		= 11,
+	.freq			= 2462, /* MHz */
+	.unk2			= 3283,
+	RADIOREGS(0x73, 0x09, 0x9E, 0x0F, 0x00, 0x01, 0x07, 0x15,
+		  0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x08, 0x04,
+		  0x80, 0xFF, 0x88, 0x08, 0x04, 0x80),
+	PHYREGS(0xDD03, 0xD903, 0xD503, 0x2404, 0x2904, 0x2D04),
+  },
+  {	.channel		= 12,
+	.freq			= 2467, /* MHz */
+	.unk2			= 3289,
+	RADIOREGS(0x73, 0x09, 0xA3, 0x0F, 0x00, 0x01, 0x07, 0x15,
+		  0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x08, 0x03,
+		  0x80, 0xFF, 0x88, 0x08, 0x03, 0x80),
+	PHYREGS(0xDF03, 0xDB03, 0xD703, 0x2204, 0x2704, 0x2B04),
+  },
+  {	.channel		= 13,
+	.freq			= 2472, /* MHz */
+	.unk2			= 3296,
+	RADIOREGS(0x73, 0x09, 0xA8, 0x0F, 0x00, 0x01, 0x07, 0x15,
+		  0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x07, 0x03,
+		  0x80, 0xFF, 0x88, 0x07, 0x03, 0x80),
+	PHYREGS(0xE103, 0xDD03, 0xD903, 0x2004, 0x2404, 0x2904),
+  },
+  {	.channel		= 14,
+	.freq			= 2484, /* MHz */
+	.unk2			= 3312,
+	RADIOREGS(0x73, 0x09, 0xB4, 0x0F, 0xFF, 0x01, 0x07, 0x15,
+		  0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x07, 0x01,
+		  0x80, 0xFF, 0x88, 0x07, 0x01, 0x80),
+	PHYREGS(0xE603, 0xE203, 0xDE03, 0x1B04, 0x1F04, 0x2404),
+  },
+};
+
+void b2055_upload_inittab(struct b43_wldev *dev,
+			  bool ghz5, bool ignore_uploadflag)
+{
+	const struct b2055_inittab_entry *e;
+	unsigned int i;
+	u16 value;
+
+	for (i = 0; i < ARRAY_SIZE(b2055_inittab); i++) {
+		e = &(b2055_inittab[i]);
+		if (!(e->flags & B2055_INITTAB_ENTRY_OK))
+			continue;
+		if ((e->flags & B2055_INITTAB_UPLOAD) || ignore_uploadflag) {
+			if (ghz5)
+				value = e->ghz5;
+			else
+				value = e->ghz2;
+			b43_radio_write16(dev, i, value);
+		}
+	}
+}
+
+const struct b43_nphy_channeltab_entry_rev2 *
+b43_nphy_get_chantabent_rev2(struct b43_wldev *dev, u8 channel)
+{
+	const struct b43_nphy_channeltab_entry_rev2 *e;
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(b43_nphy_channeltab_rev2); i++) {
+		e = &(b43_nphy_channeltab_rev2[i]);
+		if (e->channel == channel)
+			return e;
+	}
+
+	return NULL;
+}
diff --git a/drivers/net/wireless/b43/radio_2055.h b/drivers/net/wireless/b43/radio_2055.h
new file mode 100644
index 000000000000..d9bfa0f21b72
--- /dev/null
+++ b/drivers/net/wireless/b43/radio_2055.h
@@ -0,0 +1,254 @@
+#ifndef B43_RADIO_2055_H_
+#define B43_RADIO_2055_H_
+
+#include <linux/types.h>
+
+#include "tables_nphy.h"
+
+#define B2055_GEN_SPARE			0x00 /* GEN spare */
+#define B2055_SP_PINPD			0x02 /* SP PIN PD */
+#define B2055_C1_SP_RSSI		0x03 /* SP RSSI Core 1 */
+#define B2055_C1_SP_PDMISC		0x04 /* SP PD MISC Core 1 */
+#define B2055_C2_SP_RSSI		0x05 /* SP RSSI Core 2 */
+#define B2055_C2_SP_PDMISC		0x06 /* SP PD MISC Core 2 */
+#define B2055_C1_SP_RXGC1		0x07 /* SP RX GC1 Core 1 */
+#define B2055_C1_SP_RXGC2		0x08 /* SP RX GC2 Core 1 */
+#define B2055_C2_SP_RXGC1		0x09 /* SP RX GC1 Core 2 */
+#define B2055_C2_SP_RXGC2		0x0A /* SP RX GC2 Core 2 */
+#define B2055_C1_SP_LPFBWSEL		0x0B /* SP LPF BW select Core 1 */
+#define B2055_C2_SP_LPFBWSEL		0x0C /* SP LPF BW select Core 2 */
+#define B2055_C1_SP_TXGC1		0x0D /* SP TX GC1 Core 1 */
+#define B2055_C1_SP_TXGC2		0x0E /* SP TX GC2 Core 1 */
+#define B2055_C2_SP_TXGC1		0x0F /* SP TX GC1 Core 2 */
+#define B2055_C2_SP_TXGC2		0x10 /* SP TX GC2 Core 2 */
+#define B2055_MASTER1			0x11 /* Master control 1 */
+#define B2055_MASTER2			0x12 /* Master control 2 */
+#define B2055_PD_LGEN			0x13 /* PD LGEN */
+#define B2055_PD_PLLTS			0x14 /* PD PLL TS */
+#define B2055_C1_PD_LGBUF		0x15 /* PD Core 1 LGBUF */
+#define B2055_C1_PD_TX			0x16 /* PD Core 1 TX */
+#define B2055_C1_PD_RXTX		0x17 /* PD Core 1 RXTX */
+#define B2055_C1_PD_RSSIMISC		0x18 /* PD Core 1 RSSI MISC */
+#define B2055_C2_PD_LGBUF		0x19 /* PD Core 2 LGBUF */
+#define B2055_C2_PD_TX			0x1A /* PD Core 2 TX */
+#define B2055_C2_PD_RXTX		0x1B /* PD Core 2 RXTX */
+#define B2055_C2_PD_RSSIMISC		0x1C /* PD Core 2 RSSI MISC */
+#define B2055_PWRDET_LGEN		0x1D /* PWRDET LGEN */
+#define B2055_C1_PWRDET_LGBUF		0x1E /* PWRDET LGBUF Core 1 */
+#define B2055_C1_PWRDET_RXTX		0x1F /* PWRDET RXTX Core 1 */
+#define B2055_C2_PWRDET_LGBUF		0x20 /* PWRDET LGBUF Core 2 */
+#define B2055_C2_PWRDET_RXTX		0x21 /* PWRDET RXTX Core 2 */
+#define B2055_RRCCAL_CS			0x22 /* RRCCAL Control spare */
+#define B2055_RRCCAL_NOPTSEL		0x23 /* RRCCAL N OPT SEL */
+#define B2055_CAL_MISC			0x24 /* CAL MISC */
+#define B2055_CAL_COUT			0x25 /* CAL Counter out */
+#define B2055_CAL_COUT2			0x26 /* CAL Counter out 2 */
+#define B2055_CAL_CVARCTL		0x27 /* CAL CVAR Control */
+#define B2055_CAL_RVARCTL		0x28 /* CAL RVAR Control */
+#define B2055_CAL_LPOCTL		0x29 /* CAL LPO Control */
+#define B2055_CAL_TS			0x2A /* CAL TS */
+#define B2055_CAL_RCCALRTS		0x2B /* CAL RCCAL READ TS */
+#define B2055_CAL_RCALRTS		0x2C /* CAL RCAL READ TS */
+#define B2055_PADDRV			0x2D /* PAD driver */
+#define B2055_XOCTL1			0x2E /* XO Control 1 */
+#define B2055_XOCTL2			0x2F /* XO Control 2 */
+#define B2055_XOREGUL			0x30 /* XO Regulator */
+#define B2055_XOMISC			0x31 /* XO misc */
+#define B2055_PLL_LFC1			0x32 /* PLL LF C1 */
+#define B2055_PLL_CALVTH		0x33 /* PLL CAL VTH */
+#define B2055_PLL_LFC2			0x34 /* PLL LF C2 */
+#define B2055_PLL_REF			0x35 /* PLL reference */
+#define B2055_PLL_LFR1			0x36 /* PLL LF R1 */
+#define B2055_PLL_PFDCP			0x37 /* PLL PFD CP */
+#define B2055_PLL_IDAC_CPOPAMP		0x38 /* PLL IDAC CPOPAMP */
+#define B2055_PLL_CPREG			0x39 /* PLL CP Regulator */
+#define B2055_PLL_RCAL			0x3A /* PLL RCAL */
+#define B2055_RF_PLLMOD0		0x3B /* RF PLL MOD0 */
+#define B2055_RF_PLLMOD1		0x3C /* RF PLL MOD1 */
+#define B2055_RF_MMDIDAC1		0x3D /* RF MMD IDAC 1 */
+#define B2055_RF_MMDIDAC0		0x3E /* RF MMD IDAC 0 */
+#define B2055_RF_MMDSP			0x3F /* RF MMD spare */
+#define B2055_VCO_CAL1			0x40 /* VCO cal 1 */
+#define B2055_VCO_CAL2			0x41 /* VCO cal 2 */
+#define B2055_VCO_CAL3			0x42 /* VCO cal 3 */
+#define B2055_VCO_CAL4			0x43 /* VCO cal 4 */
+#define B2055_VCO_CAL5			0x44 /* VCO cal 5 */
+#define B2055_VCO_CAL6			0x45 /* VCO cal 6 */
+#define B2055_VCO_CAL7			0x46 /* VCO cal 7 */
+#define B2055_VCO_CAL8			0x47 /* VCO cal 8 */
+#define B2055_VCO_CAL9			0x48 /* VCO cal 9 */
+#define B2055_VCO_CAL10			0x49 /* VCO cal 10 */
+#define B2055_VCO_CAL11			0x4A /* VCO cal 11 */
+#define B2055_VCO_CAL12			0x4B /* VCO cal 12 */
+#define B2055_VCO_CAL13			0x4C /* VCO cal 13 */
+#define B2055_VCO_CAL14			0x4D /* VCO cal 14 */
+#define B2055_VCO_CAL15			0x4E /* VCO cal 15 */
+#define B2055_VCO_CAL16			0x4F /* VCO cal 16 */
+#define B2055_VCO_KVCO			0x50 /* VCO KVCO */
+#define B2055_VCO_CAPTAIL		0x51 /* VCO CAP TAIL */
+#define B2055_VCO_IDACVCO		0x52 /* VCO IDAC VCO */
+#define B2055_VCO_REG			0x53 /* VCO Regulator */
+#define B2055_PLL_RFVTH			0x54 /* PLL RF VTH */
+#define B2055_LGBUF_CENBUF		0x55 /* LGBUF CEN BUF */
+#define B2055_LGEN_TUNE1		0x56 /* LGEN tune 1 */
+#define B2055_LGEN_TUNE2		0x57 /* LGEN tune 2 */
+#define B2055_LGEN_IDAC1		0x58 /* LGEN IDAC 1 */
+#define B2055_LGEN_IDAC2		0x59 /* LGEN IDAC 2 */
+#define B2055_LGEN_BIASC		0x5A /* LGEN BIAS counter */
+#define B2055_LGEN_BIASIDAC		0x5B /* LGEN BIAS IDAC */
+#define B2055_LGEN_RCAL			0x5C /* LGEN RCAL */
+#define B2055_LGEN_DIV			0x5D /* LGEN div */
+#define B2055_LGEN_SPARE2		0x5E /* LGEN spare 2 */
+#define B2055_C1_LGBUF_ATUNE		0x5F /* Core 1 LGBUF A tune */
+#define B2055_C1_LGBUF_GTUNE		0x60 /* Core 1 LGBUF G tune */
+#define B2055_C1_LGBUF_DIV		0x61 /* Core 1 LGBUF div */
+#define B2055_C1_LGBUF_AIDAC		0x62 /* Core 1 LGBUF A IDAC */
+#define B2055_C1_LGBUF_GIDAC		0x63 /* Core 1 LGBUF G IDAC */
+#define B2055_C1_LGBUF_IDACFO		0x64 /* Core 1 LGBUF IDAC filter override */
+#define B2055_C1_LGBUF_SPARE		0x65 /* Core 1 LGBUF spare */
+#define B2055_C1_RX_RFSPC1		0x66 /* Core 1 RX RF SPC1 */
+#define B2055_C1_RX_RFR1		0x67 /* Core 1 RX RF reg 1 */
+#define B2055_C1_RX_RFR2		0x68 /* Core 1 RX RF reg 2 */
+#define B2055_C1_RX_RFRCAL		0x69 /* Core 1 RX RF RCAL */
+#define B2055_C1_RX_BB_BLCMP		0x6A /* Core 1 RX Baseband BUFI LPF CMP */
+#define B2055_C1_RX_BB_LPF		0x6B /* Core 1 RX Baseband LPF */
+#define B2055_C1_RX_BB_MIDACHP		0x6C /* Core 1 RX Baseband MIDAC High-pass */
+#define B2055_C1_RX_BB_VGA1IDAC		0x6D /* Core 1 RX Baseband VGA1 IDAC */
+#define B2055_C1_RX_BB_VGA2IDAC		0x6E /* Core 1 RX Baseband VGA2 IDAC */
+#define B2055_C1_RX_BB_VGA3IDAC		0x6F /* Core 1 RX Baseband VGA3 IDAC */
+#define B2055_C1_RX_BB_BUFOCTL		0x70 /* Core 1 RX Baseband BUFO Control */
+#define B2055_C1_RX_BB_RCCALCTL		0x71 /* Core 1 RX Baseband RCCAL Control */
+#define B2055_C1_RX_BB_RSSICTL1		0x72 /* Core 1 RX Baseband RSSI Control 1 */
+#define B2055_C1_RX_BB_RSSICTL2		0x73 /* Core 1 RX Baseband RSSI Control 2 */
+#define B2055_C1_RX_BB_RSSICTL3		0x74 /* Core 1 RX Baseband RSSI Control 3 */
+#define B2055_C1_RX_BB_RSSICTL4		0x75 /* Core 1 RX Baseband RSSI Control 4 */
+#define B2055_C1_RX_BB_RSSICTL5		0x76 /* Core 1 RX Baseband RSSI Control 5 */
+#define B2055_C1_RX_BB_REG		0x77 /* Core 1 RX Baseband Regulator */
+#define B2055_C1_RX_BB_SPARE1		0x78 /* Core 1 RX Baseband spare 1 */
+#define B2055_C1_RX_TXBBRCAL		0x79 /* Core 1 RX TX BB RCAL */
+#define B2055_C1_TX_RF_SPGA		0x7A /* Core 1 TX RF SGM PGA */
+#define B2055_C1_TX_RF_SPAD		0x7B /* Core 1 TX RF SGM PAD */
+#define B2055_C1_TX_RF_CNTPGA1		0x7C /* Core 1 TX RF counter PGA 1 */
+#define B2055_C1_TX_RF_CNTPAD1		0x7D /* Core 1 TX RF counter PAD 1 */
+#define B2055_C1_TX_RF_PGAIDAC		0x7E /* Core 1 TX RF PGA IDAC */
+#define B2055_C1_TX_PGAPADTN		0x7F /* Core 1 TX PGA PAD TN */
+#define B2055_C1_TX_PADIDAC1		0x80 /* Core 1 TX PAD IDAC 1 */
+#define B2055_C1_TX_PADIDAC2		0x81 /* Core 1 TX PAD IDAC 2 */
+#define B2055_C1_TX_MXBGTRIM		0x82 /* Core 1 TX MX B/G TRIM */
+#define B2055_C1_TX_RF_RCAL		0x83 /* Core 1 TX RF RCAL */
+#define B2055_C1_TX_RF_PADTSSI1		0x84 /* Core 1 TX RF PAD TSSI1 */
+#define B2055_C1_TX_RF_PADTSSI2		0x85 /* Core 1 TX RF PAD TSSI2 */
+#define B2055_C1_TX_RF_SPARE		0x86 /* Core 1 TX RF spare */
+#define B2055_C1_TX_RF_IQCAL1		0x87 /* Core 1 TX RF I/Q CAL 1 */
+#define B2055_C1_TX_RF_IQCAL2		0x88 /* Core 1 TX RF I/Q CAL 2 */
+#define B2055_C1_TXBB_RCCAL		0x89 /* Core 1 TXBB RC CAL Control */
+#define B2055_C1_TXBB_LPF1		0x8A /* Core 1 TXBB LPF 1 */
+#define B2055_C1_TX_VOSCNCL		0x8B /* Core 1 TX VOS CNCL */
+#define B2055_C1_TX_LPF_MXGMIDAC	0x8C /* Core 1 TX LPF MXGM IDAC */
+#define B2055_C1_TX_BB_MXGM		0x8D /* Core 1 TX BB MXGM */
+#define B2055_C2_LGBUF_ATUNE		0x8E /* Core 2 LGBUF A tune */
+#define B2055_C2_LGBUF_GTUNE		0x8F /* Core 2 LGBUF G tune */
+#define B2055_C2_LGBUF_DIV		0x90 /* Core 2 LGBUF div */
+#define B2055_C2_LGBUF_AIDAC		0x91 /* Core 2 LGBUF A IDAC */
+#define B2055_C2_LGBUF_GIDAC		0x92 /* Core 2 LGBUF G IDAC */
+#define B2055_C2_LGBUF_IDACFO		0x93 /* Core 2 LGBUF IDAC filter override */
+#define B2055_C2_LGBUF_SPARE		0x94 /* Core 2 LGBUF spare */
+#define B2055_C2_RX_RFSPC1		0x95 /* Core 2 RX RF SPC1 */
+#define B2055_C2_RX_RFR1		0x96 /* Core 2 RX RF reg 1 */
+#define B2055_C2_RX_RFR2		0x97 /* Core 2 RX RF reg 2 */
+#define B2055_C2_RX_RFRCAL		0x98 /* Core 2 RX RF RCAL */
+#define B2055_C2_RX_BB_BLCMP		0x99 /* Core 2 RX Baseband BUFI LPF CMP */
+#define B2055_C2_RX_BB_LPF		0x9A /* Core 2 RX Baseband LPF */
+#define B2055_C2_RX_BB_MIDACHP		0x9B /* Core 2 RX Baseband MIDAC High-pass */
+#define B2055_C2_RX_BB_VGA1IDAC		0x9C /* Core 2 RX Baseband VGA1 IDAC */
+#define B2055_C2_RX_BB_VGA2IDAC		0x9D /* Core 2 RX Baseband VGA2 IDAC */
+#define B2055_C2_RX_BB_VGA3IDAC		0x9E /* Core 2 RX Baseband VGA3 IDAC */
+#define B2055_C2_RX_BB_BUFOCTL		0x9F /* Core 2 RX Baseband BUFO Control */
+#define B2055_C2_RX_BB_RCCALCTL		0xA0 /* Core 2 RX Baseband RCCAL Control */
+#define B2055_C2_RX_BB_RSSICTL1		0xA1 /* Core 2 RX Baseband RSSI Control 1 */
+#define B2055_C2_RX_BB_RSSICTL2		0xA2 /* Core 2 RX Baseband RSSI Control 2 */
+#define B2055_C2_RX_BB_RSSICTL3		0xA3 /* Core 2 RX Baseband RSSI Control 3 */
+#define B2055_C2_RX_BB_RSSICTL4		0xA4 /* Core 2 RX Baseband RSSI Control 4 */
+#define B2055_C2_RX_BB_RSSICTL5		0xA5 /* Core 2 RX Baseband RSSI Control 5 */
+#define B2055_C2_RX_BB_REG		0xA6 /* Core 2 RX Baseband Regulator */
+#define B2055_C2_RX_BB_SPARE1		0xA7 /* Core 2 RX Baseband spare 1 */
+#define B2055_C2_RX_TXBBRCAL		0xA8 /* Core 2 RX TX BB RCAL */
+#define B2055_C2_TX_RF_SPGA		0xA9 /* Core 2 TX RF SGM PGA */
+#define B2055_C2_TX_RF_SPAD		0xAA /* Core 2 TX RF SGM PAD */
+#define B2055_C2_TX_RF_CNTPGA1		0xAB /* Core 2 TX RF counter PGA 1 */
+#define B2055_C2_TX_RF_CNTPAD1		0xAC /* Core 2 TX RF counter PAD 1 */
+#define B2055_C2_TX_RF_PGAIDAC		0xAD /* Core 2 TX RF PGA IDAC */
+#define B2055_C2_TX_PGAPADTN		0xAE /* Core 2 TX PGA PAD TN */
+#define B2055_C2_TX_PADIDAC1		0xAF /* Core 2 TX PAD IDAC 1 */
+#define B2055_C2_TX_PADIDAC2		0xB0 /* Core 2 TX PAD IDAC 2 */
+#define B2055_C2_TX_MXBGTRIM		0xB1 /* Core 2 TX MX B/G TRIM */
+#define B2055_C2_TX_RF_RCAL		0xB2 /* Core 2 TX RF RCAL */
+#define B2055_C2_TX_RF_PADTSSI1		0xB3 /* Core 2 TX RF PAD TSSI1 */
+#define B2055_C2_TX_RF_PADTSSI2		0xB4 /* Core 2 TX RF PAD TSSI2 */
+#define B2055_C2_TX_RF_SPARE		0xB5 /* Core 2 TX RF spare */
+#define B2055_C2_TX_RF_IQCAL1		0xB6 /* Core 2 TX RF I/Q CAL 1 */
+#define B2055_C2_TX_RF_IQCAL2		0xB7 /* Core 2 TX RF I/Q CAL 2 */
+#define B2055_C2_TXBB_RCCAL		0xB8 /* Core 2 TXBB RC CAL Control */
+#define B2055_C2_TXBB_LPF1		0xB9 /* Core 2 TXBB LPF 1 */
+#define B2055_C2_TX_VOSCNCL		0xBA /* Core 2 TX VOS CNCL */
+#define B2055_C2_TX_LPF_MXGMIDAC	0xBB /* Core 2 TX LPF MXGM IDAC */
+#define B2055_C2_TX_BB_MXGM		0xBC /* Core 2 TX BB MXGM */
+#define B2055_PRG_GCHP21		0xBD /* PRG GC HPVGA23 21 */
+#define B2055_PRG_GCHP22		0xBE /* PRG GC HPVGA23 22 */
+#define B2055_PRG_GCHP23		0xBF /* PRG GC HPVGA23 23 */
+#define B2055_PRG_GCHP24		0xC0 /* PRG GC HPVGA23 24 */
+#define B2055_PRG_GCHP25		0xC1 /* PRG GC HPVGA23 25 */
+#define B2055_PRG_GCHP26		0xC2 /* PRG GC HPVGA23 26 */
+#define B2055_PRG_GCHP27		0xC3 /* PRG GC HPVGA23 27 */
+#define B2055_PRG_GCHP28		0xC4 /* PRG GC HPVGA23 28 */
+#define B2055_PRG_GCHP29		0xC5 /* PRG GC HPVGA23 29 */
+#define B2055_PRG_GCHP30		0xC6 /* PRG GC HPVGA23 30 */
+#define B2055_C1_LNA_GAINBST		0xCD /* Core 1 LNA GAINBST */
+#define B2055_C1_B0NB_RSSIVCM		0xD2 /* Core 1 B0 narrow-band RSSI VCM */
+#define B2055_C1_GENSPARE2		0xD6 /* Core 1 GEN spare 2 */
+#define B2055_C2_LNA_GAINBST		0xD9 /* Core 2 LNA GAINBST */
+#define B2055_C2_B0NB_RSSIVCM		0xDE /* Core 2 B0 narrow-band RSSI VCM */
+#define B2055_C2_GENSPARE2		0xE2 /* Core 2 GEN spare 2 */
+
+struct b43_nphy_channeltab_entry_rev2 {
+	/* The channel number */
+	u8 channel;
+	/* The channel frequency in MHz */
+	u16 freq;
+	/* An unknown value */
+	u16 unk2;
+	/* Radio register values on channelswitch */
+	u8 radio_pll_ref;
+	u8 radio_rf_pllmod0;
+	u8 radio_rf_pllmod1;
+	u8 radio_vco_captail;
+	u8 radio_vco_cal1;
+	u8 radio_vco_cal2;
+	u8 radio_pll_lfc1;
+	u8 radio_pll_lfr1;
+	u8 radio_pll_lfc2;
+	u8 radio_lgbuf_cenbuf;
+	u8 radio_lgen_tune1;
+	u8 radio_lgen_tune2;
+	u8 radio_c1_lgbuf_atune;
+	u8 radio_c1_lgbuf_gtune;
+	u8 radio_c1_rx_rfr1;
+	u8 radio_c1_tx_pgapadtn;
+	u8 radio_c1_tx_mxbgtrim;
+	u8 radio_c2_lgbuf_atune;
+	u8 radio_c2_lgbuf_gtune;
+	u8 radio_c2_rx_rfr1;
+	u8 radio_c2_tx_pgapadtn;
+	u8 radio_c2_tx_mxbgtrim;
+	/* PHY register values on channelswitch */
+	struct b43_phy_n_sfo_cfg phy_regs;
+};
+
+/* Upload the default register value table.
+ * If "ghz5" is true, we upload the 5Ghz table. Otherwise the 2.4Ghz
+ * table is uploaded. If "ignore_uploadflag" is true, we upload any value
+ * and ignore the "UPLOAD" flag. */
+void b2055_upload_inittab(struct b43_wldev *dev,
+			  bool ghz5, bool ignore_uploadflag);
+
+#endif /* B43_RADIO_2055_H_ */
diff --git a/drivers/net/wireless/b43/radio_2056.c b/drivers/net/wireless/b43/radio_2056.c
new file mode 100644
index 000000000000..d8563192ce56
--- /dev/null
+++ b/drivers/net/wireless/b43/radio_2056.c
@@ -0,0 +1,43 @@
+/*
+
+  Broadcom B43 wireless driver
+  IEEE 802.11n 2056 radio device data tables
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; see the file COPYING.  If not, write to
+  the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
+  Boston, MA 02110-1301, USA.
+
+*/
+
+#include "b43.h"
+#include "radio_2056.h"
+#include "phy_common.h"
+
+static const struct b43_nphy_channeltab_entry_rev3 b43_nphy_channeltab_rev3[] = {
+};
+
+const struct b43_nphy_channeltab_entry_rev3 *
+b43_nphy_get_chantabent_rev3(struct b43_wldev *dev, u16 freq)
+{
+	const struct b43_nphy_channeltab_entry_rev3 *e;
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(b43_nphy_channeltab_rev3); i++) {
+		e = &(b43_nphy_channeltab_rev3[i]);
+		if (e->freq == freq)
+			return e;
+	}
+
+	return NULL;
+}
diff --git a/drivers/net/wireless/b43/radio_2056.h b/drivers/net/wireless/b43/radio_2056.h
new file mode 100644
index 000000000000..fda6dafecb8c
--- /dev/null
+++ b/drivers/net/wireless/b43/radio_2056.h
@@ -0,0 +1,42 @@
+/*
+
+  Broadcom B43 wireless driver
+
+  Copyright (c) 2010 Rafał Miłecki <zajec5@gmail.com>
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; see the file COPYING.  If not, write to
+  the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
+  Boston, MA 02110-1301, USA.
+
+*/
+
+#ifndef B43_RADIO_2056_H_
+#define B43_RADIO_2056_H_
+
+#include <linux/types.h>
+
+#include "tables_nphy.h"
+
+struct b43_nphy_channeltab_entry_rev3 {
+	/* The channel number */
+	u8 channel;
+	/* The channel frequency in MHz */
+	u16 freq;
+	/* Radio register values on channelswitch */
+	/* TODO */
+	/* PHY register values on channelswitch */
+	struct b43_phy_n_sfo_cfg phy_regs;
+};
+
+#endif /* B43_RADIO_2056_H_ */
diff --git a/drivers/net/wireless/b43/tables_nphy.c b/drivers/net/wireless/b43/tables_nphy.c
index d96e870ab8fe..d60db078eae2 100644
--- a/drivers/net/wireless/b43/tables_nphy.c
+++ b/drivers/net/wireless/b43/tables_nphy.c
@@ -1,7 +1,7 @@
 /*
 
   Broadcom B43 wireless driver
-  IEEE 802.11n PHY and radio device data tables
+  IEEE 802.11n PHY data tables
 
   Copyright (c) 2008 Michael Buesch <mb@bu3sch.de>
 
@@ -27,1315 +27,6 @@
 #include "phy_common.h"
 #include "phy_n.h"
 
-
-struct b2055_inittab_entry {
-	/* Value to write if we use the 5GHz band. */
-	u16 ghz5;
-	/* Value to write if we use the 2.4GHz band. */
-	u16 ghz2;
-	/* Flags */
-	u8 flags;
-#define B2055_INITTAB_ENTRY_OK	0x01
-#define B2055_INITTAB_UPLOAD	0x02
-};
-#define UPLOAD		.flags = B2055_INITTAB_ENTRY_OK | B2055_INITTAB_UPLOAD
-#define NOUPLOAD	.flags = B2055_INITTAB_ENTRY_OK
-
-static const struct b2055_inittab_entry b2055_inittab [] = {
-  [B2055_SP_PINPD]		= { .ghz5 = 0x0080, .ghz2 = 0x0080, NOUPLOAD, },
-  [B2055_C1_SP_RSSI]		= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [B2055_C1_SP_PDMISC]		= { .ghz5 = 0x0027, .ghz2 = 0x0027, NOUPLOAD, },
-  [B2055_C2_SP_RSSI]		= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [B2055_C2_SP_PDMISC]		= { .ghz5 = 0x0027, .ghz2 = 0x0027, NOUPLOAD, },
-  [B2055_C1_SP_RXGC1]		= { .ghz5 = 0x007F, .ghz2 = 0x007F, UPLOAD, },
-  [B2055_C1_SP_RXGC2]		= { .ghz5 = 0x0007, .ghz2 = 0x0007, UPLOAD, },
-  [B2055_C2_SP_RXGC1]		= { .ghz5 = 0x007F, .ghz2 = 0x007F, UPLOAD, },
-  [B2055_C2_SP_RXGC2]		= { .ghz5 = 0x0007, .ghz2 = 0x0007, UPLOAD, },
-  [B2055_C1_SP_LPFBWSEL]	= { .ghz5 = 0x0015, .ghz2 = 0x0015, NOUPLOAD, },
-  [B2055_C2_SP_LPFBWSEL]	= { .ghz5 = 0x0015, .ghz2 = 0x0015, NOUPLOAD, },
-  [B2055_C1_SP_TXGC1]		= { .ghz5 = 0x004F, .ghz2 = 0x004F, UPLOAD, },
-  [B2055_C1_SP_TXGC2]		= { .ghz5 = 0x0005, .ghz2 = 0x0005, UPLOAD, },
-  [B2055_C2_SP_TXGC1]		= { .ghz5 = 0x004F, .ghz2 = 0x004F, UPLOAD, },
-  [B2055_C2_SP_TXGC2]		= { .ghz5 = 0x0005, .ghz2 = 0x0005, UPLOAD, },
-  [B2055_MASTER1]		= { .ghz5 = 0x00D0, .ghz2 = 0x00D0, NOUPLOAD, },
-  [B2055_MASTER2]		= { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, },
-  [B2055_PD_LGEN]		= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [B2055_PD_PLLTS]		= { .ghz5 = 0x0040, .ghz2 = 0x0040, NOUPLOAD, },
-  [B2055_C1_PD_LGBUF]		= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [B2055_C1_PD_TX]		= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [B2055_C1_PD_RXTX]		= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [B2055_C1_PD_RSSIMISC]	= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [B2055_C2_PD_LGBUF]		= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [B2055_C2_PD_TX]		= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [B2055_C2_PD_RXTX]		= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [B2055_C2_PD_RSSIMISC]	= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [B2055_PWRDET_LGEN]		= { .ghz5 = 0x00C0, .ghz2 = 0x00C0, NOUPLOAD, },
-  [B2055_C1_PWRDET_LGBUF]	= { .ghz5 = 0x00FF, .ghz2 = 0x00FF, NOUPLOAD, },
-  [B2055_C1_PWRDET_RXTX]	= { .ghz5 = 0x00C0, .ghz2 = 0x00C0, NOUPLOAD, },
-  [B2055_C2_PWRDET_LGBUF]	= { .ghz5 = 0x00FF, .ghz2 = 0x00FF, NOUPLOAD, },
-  [B2055_C2_PWRDET_RXTX]	= { .ghz5 = 0x00C0, .ghz2 = 0x00C0, NOUPLOAD, },
-  [B2055_RRCCAL_CS]		= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [B2055_RRCCAL_NOPTSEL]	= { .ghz5 = 0x002C, .ghz2 = 0x002C, NOUPLOAD, },
-  [B2055_CAL_MISC]		= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [B2055_CAL_COUT]		= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [B2055_CAL_COUT2]		= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [B2055_CAL_CVARCTL]		= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [B2055_CAL_RVARCTL]		= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [B2055_CAL_LPOCTL]		= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [B2055_CAL_TS]		= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [B2055_CAL_RCCALRTS]		= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [B2055_CAL_RCALRTS]		= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [B2055_PADDRV]		= { .ghz5 = 0x00A4, .ghz2 = 0x00A4, NOUPLOAD, },
-  [B2055_XOCTL1]		= { .ghz5 = 0x0038, .ghz2 = 0x0038, NOUPLOAD, },
-  [B2055_XOCTL2]		= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [B2055_XOREGUL]		= { .ghz5 = 0x0004, .ghz2 = 0x0004, UPLOAD, },
-  [B2055_XOMISC]		= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [B2055_PLL_LFC1]		= { .ghz5 = 0x000A, .ghz2 = 0x000A, NOUPLOAD, },
-  [B2055_PLL_CALVTH]		= { .ghz5 = 0x0087, .ghz2 = 0x0087, NOUPLOAD, },
-  [B2055_PLL_LFC2]		= { .ghz5 = 0x0009, .ghz2 = 0x0009, NOUPLOAD, },
-  [B2055_PLL_REF]		= { .ghz5 = 0x0070, .ghz2 = 0x0070, NOUPLOAD, },
-  [B2055_PLL_LFR1]		= { .ghz5 = 0x0011, .ghz2 = 0x0011, NOUPLOAD, },
-  [B2055_PLL_PFDCP]		= { .ghz5 = 0x0018, .ghz2 = 0x0018, UPLOAD, },
-  [B2055_PLL_IDAC_CPOPAMP]	= { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
-  [B2055_PLL_CPREG]		= { .ghz5 = 0x0004, .ghz2 = 0x0004, UPLOAD, },
-  [B2055_PLL_RCAL]		= { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
-  [B2055_RF_PLLMOD0]		= { .ghz5 = 0x009E, .ghz2 = 0x009E, NOUPLOAD, },
-  [B2055_RF_PLLMOD1]		= { .ghz5 = 0x0009, .ghz2 = 0x0009, NOUPLOAD, },
-  [B2055_RF_MMDIDAC1]		= { .ghz5 = 0x00C8, .ghz2 = 0x00C8, UPLOAD, },
-  [B2055_RF_MMDIDAC0]		= { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
-  [B2055_RF_MMDSP]		= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [B2055_VCO_CAL1]		= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [B2055_VCO_CAL2]		= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [B2055_VCO_CAL3]		= { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, },
-  [B2055_VCO_CAL4]		= { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, },
-  [B2055_VCO_CAL5]		= { .ghz5 = 0x0096, .ghz2 = 0x0096, NOUPLOAD, },
-  [B2055_VCO_CAL6]		= { .ghz5 = 0x003E, .ghz2 = 0x003E, NOUPLOAD, },
-  [B2055_VCO_CAL7]		= { .ghz5 = 0x003E, .ghz2 = 0x003E, NOUPLOAD, },
-  [B2055_VCO_CAL8]		= { .ghz5 = 0x0013, .ghz2 = 0x0013, NOUPLOAD, },
-  [B2055_VCO_CAL9]		= { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, },
-  [B2055_VCO_CAL10]		= { .ghz5 = 0x0015, .ghz2 = 0x0015, NOUPLOAD, },
-  [B2055_VCO_CAL11]		= { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, },
-  [B2055_VCO_CAL12]		= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [B2055_VCO_CAL13]		= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [B2055_VCO_CAL14]		= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [B2055_VCO_CAL15]		= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [B2055_VCO_CAL16]		= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [B2055_VCO_KVCO]		= { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, },
-  [B2055_VCO_CAPTAIL]		= { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, },
-  [B2055_VCO_IDACVCO]		= { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
-  [B2055_VCO_REG]		= { .ghz5 = 0x0084, .ghz2 = 0x0084, UPLOAD, },
-  [B2055_PLL_RFVTH]		= { .ghz5 = 0x00C3, .ghz2 = 0x00C3, NOUPLOAD, },
-  [B2055_LGBUF_CENBUF]		= { .ghz5 = 0x008F, .ghz2 = 0x008F, NOUPLOAD, },
-  [B2055_LGEN_TUNE1]		= { .ghz5 = 0x00FF, .ghz2 = 0x00FF, NOUPLOAD, },
-  [B2055_LGEN_TUNE2]		= { .ghz5 = 0x00FF, .ghz2 = 0x00FF, NOUPLOAD, },
-  [B2055_LGEN_IDAC1]		= { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
-  [B2055_LGEN_IDAC2]		= { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
-  [B2055_LGEN_BIASC]		= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [B2055_LGEN_BIASIDAC]		= { .ghz5 = 0x00CC, .ghz2 = 0x00CC, NOUPLOAD, },
-  [B2055_LGEN_RCAL]		= { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
-  [B2055_LGEN_DIV]		= { .ghz5 = 0x0080, .ghz2 = 0x0080, NOUPLOAD, },
-  [B2055_LGEN_SPARE2]		= { .ghz5 = 0x0080, .ghz2 = 0x0080, NOUPLOAD, },
-  [B2055_C1_LGBUF_ATUNE]	= { .ghz5 = 0x00F8, .ghz2 = 0x00F8, NOUPLOAD, },
-  [B2055_C1_LGBUF_GTUNE]	= { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
-  [B2055_C1_LGBUF_DIV]		= { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
-  [B2055_C1_LGBUF_AIDAC]	= { .ghz5 = 0x0088, .ghz2 = 0x0008, UPLOAD, },
-  [B2055_C1_LGBUF_GIDAC]	= { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
-  [B2055_C1_LGBUF_IDACFO]	= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [B2055_C1_LGBUF_SPARE]	= { .ghz5 = 0x0001, .ghz2 = 0x0001, UPLOAD, },
-  [B2055_C1_RX_RFSPC1]		= { .ghz5 = 0x008A, .ghz2 = 0x008A, NOUPLOAD, },
-  [B2055_C1_RX_RFR1]		= { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, },
-  [B2055_C1_RX_RFR2]		= { .ghz5 = 0x0083, .ghz2 = 0x0083, NOUPLOAD, },
-  [B2055_C1_RX_RFRCAL]		= { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
-  [B2055_C1_RX_BB_BLCMP]	= { .ghz5 = 0x00A0, .ghz2 = 0x00A0, NOUPLOAD, },
-  [B2055_C1_RX_BB_LPF]		= { .ghz5 = 0x000A, .ghz2 = 0x000A, NOUPLOAD, },
-  [B2055_C1_RX_BB_MIDACHP]	= { .ghz5 = 0x0087, .ghz2 = 0x0087, UPLOAD, },
-  [B2055_C1_RX_BB_VGA1IDAC]	= { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, },
-  [B2055_C1_RX_BB_VGA2IDAC]	= { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, },
-  [B2055_C1_RX_BB_VGA3IDAC]	= { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, },
-  [B2055_C1_RX_BB_BUFOCTL]	= { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, },
-  [B2055_C1_RX_BB_RCCALCTL]	= { .ghz5 = 0x0018, .ghz2 = 0x0018, NOUPLOAD, },
-  [B2055_C1_RX_BB_RSSICTL1]	= { .ghz5 = 0x006A, .ghz2 = 0x006A, UPLOAD, },
-  [B2055_C1_RX_BB_RSSICTL2]	= { .ghz5 = 0x00AB, .ghz2 = 0x00AB, UPLOAD, },
-  [B2055_C1_RX_BB_RSSICTL3]	= { .ghz5 = 0x0013, .ghz2 = 0x0013, UPLOAD, },
-  [B2055_C1_RX_BB_RSSICTL4]	= { .ghz5 = 0x00C1, .ghz2 = 0x00C1, UPLOAD, },
-  [B2055_C1_RX_BB_RSSICTL5]	= { .ghz5 = 0x00AA, .ghz2 = 0x00AA, UPLOAD, },
-  [B2055_C1_RX_BB_REG]		= { .ghz5 = 0x0087, .ghz2 = 0x0087, UPLOAD, },
-  [B2055_C1_RX_BB_SPARE1]	= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [B2055_C1_RX_TXBBRCAL]	= { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
-  [B2055_C1_TX_RF_SPGA]		= { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, },
-  [B2055_C1_TX_RF_SPAD]		= { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, },
-  [B2055_C1_TX_RF_CNTPGA1]	= { .ghz5 = 0x0015, .ghz2 = 0x0015, NOUPLOAD, },
-  [B2055_C1_TX_RF_CNTPAD1]	= { .ghz5 = 0x0055, .ghz2 = 0x0055, NOUPLOAD, },
-  [B2055_C1_TX_RF_PGAIDAC]	= { .ghz5 = 0x0097, .ghz2 = 0x0097, UPLOAD, },
-  [B2055_C1_TX_PGAPADTN]	= { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, },
-  [B2055_C1_TX_PADIDAC1]	= { .ghz5 = 0x0014, .ghz2 = 0x0014, UPLOAD, },
-  [B2055_C1_TX_PADIDAC2]	= { .ghz5 = 0x0033, .ghz2 = 0x0033, NOUPLOAD, },
-  [B2055_C1_TX_MXBGTRIM]	= { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
-  [B2055_C1_TX_RF_RCAL]		= { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
-  [B2055_C1_TX_RF_PADTSSI1]	= { .ghz5 = 0x0003, .ghz2 = 0x0003, UPLOAD, },
-  [B2055_C1_TX_RF_PADTSSI2]	= { .ghz5 = 0x000A, .ghz2 = 0x000A, NOUPLOAD, },
-  [B2055_C1_TX_RF_SPARE]	= { .ghz5 = 0x0003, .ghz2 = 0x0003, UPLOAD, },
-  [B2055_C1_TX_RF_IQCAL1]	= { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, },
-  [B2055_C1_TX_RF_IQCAL2]	= { .ghz5 = 0x00A4, .ghz2 = 0x00A4, NOUPLOAD, },
-  [B2055_C1_TXBB_RCCAL]		= { .ghz5 = 0x0018, .ghz2 = 0x0018, NOUPLOAD, },
-  [B2055_C1_TXBB_LPF1]		= { .ghz5 = 0x0028, .ghz2 = 0x0028, NOUPLOAD, },
-  [B2055_C1_TX_VOSCNCL]		= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [B2055_C1_TX_LPF_MXGMIDAC]	= { .ghz5 = 0x004A, .ghz2 = 0x004A, NOUPLOAD, },
-  [B2055_C1_TX_BB_MXGM]		= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [B2055_C2_LGBUF_ATUNE]	= { .ghz5 = 0x00F8, .ghz2 = 0x00F8, NOUPLOAD, },
-  [B2055_C2_LGBUF_GTUNE]	= { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
-  [B2055_C2_LGBUF_DIV]		= { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
-  [B2055_C2_LGBUF_AIDAC]	= { .ghz5 = 0x0088, .ghz2 = 0x0008, UPLOAD, },
-  [B2055_C2_LGBUF_GIDAC]	= { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
-  [B2055_C2_LGBUF_IDACFO]	= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [B2055_C2_LGBUF_SPARE]	= { .ghz5 = 0x0001, .ghz2 = 0x0001, UPLOAD, },
-  [B2055_C2_RX_RFSPC1]		= { .ghz5 = 0x008A, .ghz2 = 0x008A, NOUPLOAD, },
-  [B2055_C2_RX_RFR1]		= { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, },
-  [B2055_C2_RX_RFR2]		= { .ghz5 = 0x0083, .ghz2 = 0x0083, NOUPLOAD, },
-  [B2055_C2_RX_RFRCAL]		= { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
-  [B2055_C2_RX_BB_BLCMP]	= { .ghz5 = 0x00A0, .ghz2 = 0x00A0, NOUPLOAD, },
-  [B2055_C2_RX_BB_LPF]		= { .ghz5 = 0x000A, .ghz2 = 0x000A, NOUPLOAD, },
-  [B2055_C2_RX_BB_MIDACHP]	= { .ghz5 = 0x0087, .ghz2 = 0x0087, UPLOAD, },
-  [B2055_C2_RX_BB_VGA1IDAC]	= { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, },
-  [B2055_C2_RX_BB_VGA2IDAC]	= { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, },
-  [B2055_C2_RX_BB_VGA3IDAC]	= { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, },
-  [B2055_C2_RX_BB_BUFOCTL]	= { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, },
-  [B2055_C2_RX_BB_RCCALCTL]	= { .ghz5 = 0x0018, .ghz2 = 0x0018, NOUPLOAD, },
-  [B2055_C2_RX_BB_RSSICTL1]	= { .ghz5 = 0x006A, .ghz2 = 0x006A, UPLOAD, },
-  [B2055_C2_RX_BB_RSSICTL2]	= { .ghz5 = 0x00AB, .ghz2 = 0x00AB, UPLOAD, },
-  [B2055_C2_RX_BB_RSSICTL3]	= { .ghz5 = 0x0013, .ghz2 = 0x0013, UPLOAD, },
-  [B2055_C2_RX_BB_RSSICTL4]	= { .ghz5 = 0x00C1, .ghz2 = 0x00C1, UPLOAD, },
-  [B2055_C2_RX_BB_RSSICTL5]	= { .ghz5 = 0x00AA, .ghz2 = 0x00AA, UPLOAD, },
-  [B2055_C2_RX_BB_REG]		= { .ghz5 = 0x0087, .ghz2 = 0x0087, UPLOAD, },
-  [B2055_C2_RX_BB_SPARE1]	= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [B2055_C2_RX_TXBBRCAL]	= { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
-  [B2055_C2_TX_RF_SPGA]		= { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, },
-  [B2055_C2_TX_RF_SPAD]		= { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, },
-  [B2055_C2_TX_RF_CNTPGA1]	= { .ghz5 = 0x0015, .ghz2 = 0x0015, NOUPLOAD, },
-  [B2055_C2_TX_RF_CNTPAD1]	= { .ghz5 = 0x0055, .ghz2 = 0x0055, NOUPLOAD, },
-  [B2055_C2_TX_RF_PGAIDAC]	= { .ghz5 = 0x0097, .ghz2 = 0x0097, UPLOAD, },
-  [B2055_C2_TX_PGAPADTN]	= { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, },
-  [B2055_C2_TX_PADIDAC1]	= { .ghz5 = 0x0014, .ghz2 = 0x0014, UPLOAD, },
-  [B2055_C2_TX_PADIDAC2]	= { .ghz5 = 0x0033, .ghz2 = 0x0033, NOUPLOAD, },
-  [B2055_C2_TX_MXBGTRIM]	= { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
-  [B2055_C2_TX_RF_RCAL]		= { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
-  [B2055_C2_TX_RF_PADTSSI1]	= { .ghz5 = 0x0003, .ghz2 = 0x0003, UPLOAD, },
-  [B2055_C2_TX_RF_PADTSSI2]	= { .ghz5 = 0x000A, .ghz2 = 0x000A, NOUPLOAD, },
-  [B2055_C2_TX_RF_SPARE]	= { .ghz5 = 0x0003, .ghz2 = 0x0003, UPLOAD, },
-  [B2055_C2_TX_RF_IQCAL1]	= { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, },
-  [B2055_C2_TX_RF_IQCAL2]	= { .ghz5 = 0x00A4, .ghz2 = 0x00A4, NOUPLOAD, },
-  [B2055_C2_TXBB_RCCAL]		= { .ghz5 = 0x0018, .ghz2 = 0x0018, NOUPLOAD, },
-  [B2055_C2_TXBB_LPF1]		= { .ghz5 = 0x0028, .ghz2 = 0x0028, NOUPLOAD, },
-  [B2055_C2_TX_VOSCNCL]		= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [B2055_C2_TX_LPF_MXGMIDAC]	= { .ghz5 = 0x004A, .ghz2 = 0x004A, NOUPLOAD, },
-  [B2055_C2_TX_BB_MXGM]		= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [B2055_PRG_GCHP21]		= { .ghz5 = 0x0071, .ghz2 = 0x0071, NOUPLOAD, },
-  [B2055_PRG_GCHP22]		= { .ghz5 = 0x0072, .ghz2 = 0x0072, NOUPLOAD, },
-  [B2055_PRG_GCHP23]		= { .ghz5 = 0x0073, .ghz2 = 0x0073, NOUPLOAD, },
-  [B2055_PRG_GCHP24]		= { .ghz5 = 0x0074, .ghz2 = 0x0074, NOUPLOAD, },
-  [B2055_PRG_GCHP25]		= { .ghz5 = 0x0075, .ghz2 = 0x0075, NOUPLOAD, },
-  [B2055_PRG_GCHP26]		= { .ghz5 = 0x0076, .ghz2 = 0x0076, NOUPLOAD, },
-  [B2055_PRG_GCHP27]		= { .ghz5 = 0x0077, .ghz2 = 0x0077, NOUPLOAD, },
-  [B2055_PRG_GCHP28]		= { .ghz5 = 0x0078, .ghz2 = 0x0078, NOUPLOAD, },
-  [B2055_PRG_GCHP29]		= { .ghz5 = 0x0079, .ghz2 = 0x0079, NOUPLOAD, },
-  [B2055_PRG_GCHP30]		= { .ghz5 = 0x007A, .ghz2 = 0x007A, NOUPLOAD, },
-  [0xC7]			= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [0xC8]			= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [0xC9]			= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [0xCA]			= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [0xCB]			= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [0xCC]			= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [B2055_C1_LNA_GAINBST]	= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [0xCE]			= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [0xCF]			= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [0xD0]			= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [0xD1]			= { .ghz5 = 0x0018, .ghz2 = 0x0018, NOUPLOAD, },
-  [B2055_C1_B0NB_RSSIVCM]	= { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
-  [0xD3]			= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [0xD4]			= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [0xD5]			= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [B2055_C1_GENSPARE2]		= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [0xD7]			= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [0xD8]			= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [B2055_C2_LNA_GAINBST]	= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [0xDA]			= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [0xDB]			= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [0xDC]			= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [0xDD]			= { .ghz5 = 0x0018, .ghz2 = 0x0018, NOUPLOAD, },
-  [B2055_C2_B0NB_RSSIVCM]	= { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
-  [0xDF]			= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [0xE0]			= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [0xE1]			= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [B2055_C2_GENSPARE2]		= { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-};
-
-
-void b2055_upload_inittab(struct b43_wldev *dev,
-			  bool ghz5, bool ignore_uploadflag)
-{
-	const struct b2055_inittab_entry *e;
-	unsigned int i;
-	u16 value;
-
-	for (i = 0; i < ARRAY_SIZE(b2055_inittab); i++) {
-		e = &(b2055_inittab[i]);
-		if (!(e->flags & B2055_INITTAB_ENTRY_OK))
-			continue;
-		if ((e->flags & B2055_INITTAB_UPLOAD) || ignore_uploadflag) {
-			if (ghz5)
-				value = e->ghz5;
-			else
-				value = e->ghz2;
-			b43_radio_write16(dev, i, value);
-		}
-	}
-}
-
-
-#define RADIOREGS(r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, \
-		  r12, r13, r14, r15, r16, r17, r18, r19, r20, r21) \
-	.radio_pll_ref		= r0,	\
-	.radio_rf_pllmod0	= r1,	\
-	.radio_rf_pllmod1	= r2,	\
-	.radio_vco_captail	= r3,	\
-	.radio_vco_cal1		= r4,	\
-	.radio_vco_cal2		= r5,	\
-	.radio_pll_lfc1		= r6,	\
-	.radio_pll_lfr1		= r7,	\
-	.radio_pll_lfc2		= r8,	\
-	.radio_lgbuf_cenbuf	= r9,	\
-	.radio_lgen_tune1	= r10,	\
-	.radio_lgen_tune2	= r11,	\
-	.radio_c1_lgbuf_atune	= r12,	\
-	.radio_c1_lgbuf_gtune	= r13,	\
-	.radio_c1_rx_rfr1	= r14,	\
-	.radio_c1_tx_pgapadtn	= r15,	\
-	.radio_c1_tx_mxbgtrim	= r16,	\
-	.radio_c2_lgbuf_atune	= r17,	\
-	.radio_c2_lgbuf_gtune	= r18,	\
-	.radio_c2_rx_rfr1	= r19,	\
-	.radio_c2_tx_pgapadtn	= r20,	\
-	.radio_c2_tx_mxbgtrim	= r21
-
-#define PHYREGS(r0, r1, r2, r3, r4, r5)	\
-	.phy_regs.phy_bw1a	= r0,	\
-	.phy_regs.phy_bw2	= r1,	\
-	.phy_regs.phy_bw3	= r2,	\
-	.phy_regs.phy_bw4	= r3,	\
-	.phy_regs.phy_bw5	= r4,	\
-	.phy_regs.phy_bw6	= r5
-
-static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab[] = {
-  {	.channel		= 184,
-	.freq			= 4920, /* MHz */
-	.unk2			= 3280,
-	RADIOREGS(0x71, 0x01, 0xEC, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
-		  0x00, 0x8F, 0xFF, 0xFF, 0xFF, 0x00, 0x0F, 0x0F,
-		  0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
-	PHYREGS(0xB407, 0xB007, 0xAC07, 0x1402, 0x1502, 0x1602),
-  },
-  {	.channel		= 186,
-	.freq			= 4930, /* MHz */
-	.unk2			= 3287,
-	RADIOREGS(0x71, 0x01, 0xED, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
-		  0x00, 0x8F, 0xFF, 0xFF, 0xFF, 0x00, 0x0F, 0x0F,
-		  0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
-	PHYREGS(0xB807, 0xB407, 0xB007, 0x1302, 0x1402, 0x1502),
-  },
-  {	.channel		= 188,
-	.freq			= 4940, /* MHz */
-	.unk2			= 3293,
-	RADIOREGS(0x71, 0x01, 0xEE, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
-		  0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F,
-		  0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
-	PHYREGS(0xBC07, 0xB807, 0xB407, 0x1202, 0x1302, 0x1402),
-  },
-  {	.channel		= 190,
-	.freq			= 4950, /* MHz */
-	.unk2			= 3300,
-	RADIOREGS(0x71, 0x01, 0xEF, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
-		  0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F,
-		  0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
-	PHYREGS(0xC007, 0xBC07, 0xB807, 0x1102, 0x1202, 0x1302),
-  },
-  {	.channel		= 192,
-	.freq			= 4960, /* MHz */
-	.unk2			= 3307,
-	RADIOREGS(0x71, 0x01, 0xF0, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
-		  0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F,
-		  0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
-	PHYREGS(0xC407, 0xC007, 0xBC07, 0x0F02, 0x1102, 0x1202),
-  },
-  {	.channel		= 194,
-	.freq			= 4970, /* MHz */
-	.unk2			= 3313,
-	RADIOREGS(0x71, 0x01, 0xF1, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
-		  0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F,
-		  0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
-	PHYREGS(0xC807, 0xC407, 0xC007, 0x0E02, 0x0F02, 0x1102),
-  },
-  {	.channel		= 196,
-	.freq			= 4980, /* MHz */
-	.unk2			= 3320,
-	RADIOREGS(0x71, 0x01, 0xF2, 0x0E, 0xFF, 0x01, 0x04, 0x0A,
-		  0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F,
-		  0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
-	PHYREGS(0xCC07, 0xC807, 0xC407, 0x0D02, 0x0E02, 0x0F02),
-  },
-  {	.channel		= 198,
-	.freq			= 4990, /* MHz */
-	.unk2			= 3327,
-	RADIOREGS(0x71, 0x01, 0xF3, 0x0E, 0xFF, 0x01, 0x04, 0x0A,
-		  0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F,
-		  0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
-	PHYREGS(0xD007, 0xCC07, 0xC807, 0x0C02, 0x0D02, 0x0E02),
-  },
-  {	.channel		= 200,
-	.freq			= 5000, /* MHz */
-	.unk2			= 3333,
-	RADIOREGS(0x71, 0x01, 0xF4, 0x0E, 0xFF, 0x01, 0x04, 0x0A,
-		  0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F,
-		  0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
-	PHYREGS(0xD407, 0xD007, 0xCC07, 0x0B02, 0x0C02, 0x0D02),
-  },
-  {	.channel		= 202,
-	.freq			= 5010, /* MHz */
-	.unk2			= 3340,
-	RADIOREGS(0x71, 0x01, 0xF5, 0x0E, 0xFF, 0x01, 0x04, 0x0A,
-		  0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F,
-		  0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
-	PHYREGS(0xD807, 0xD407, 0xD007, 0x0A02, 0x0B02, 0x0C02),
-  },
-  {	.channel		= 204,
-	.freq			= 5020, /* MHz */
-	.unk2			= 3347,
-	RADIOREGS(0x71, 0x01, 0xF6, 0x0E, 0xF7, 0x01, 0x04, 0x0A,
-		  0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F,
-		  0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
-	PHYREGS(0xDC07, 0xD807, 0xD407, 0x0902, 0x0A02, 0x0B02),
-  },
-  {	.channel		= 206,
-	.freq			= 5030, /* MHz */
-	.unk2			= 3353,
-	RADIOREGS(0x71, 0x01, 0xF7, 0x0E, 0xF7, 0x01, 0x04, 0x0A,
-		  0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F,
-		  0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
-	PHYREGS(0xE007, 0xDC07, 0xD807, 0x0802, 0x0902, 0x0A02),
-  },
-  {	.channel		= 208,
-	.freq			= 5040, /* MHz */
-	.unk2			= 3360,
-	RADIOREGS(0x71, 0x01, 0xF8, 0x0D, 0xEF, 0x01, 0x04, 0x0A,
-		  0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F,
-		  0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
-	PHYREGS(0xE407, 0xE007, 0xDC07, 0x0702, 0x0802, 0x0902),
-  },
-  {	.channel		= 210,
-	.freq			= 5050, /* MHz */
-	.unk2			= 3367,
-	RADIOREGS(0x71, 0x01, 0xF9, 0x0D, 0xEF, 0x01, 0x04, 0x0A,
-		  0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F,
-		  0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
-	PHYREGS(0xE807, 0xE407, 0xE007, 0x0602, 0x0702, 0x0802),
-  },
-  {	.channel		= 212,
-	.freq			= 5060, /* MHz */
-	.unk2			= 3373,
-	RADIOREGS(0x71, 0x01, 0xFA, 0x0D, 0xE6, 0x01, 0x04, 0x0A,
-		  0x00, 0x8F, 0xBB, 0xBB, 0xFF, 0x00, 0x0E, 0x0F,
-		  0x8E, 0xFF, 0x00, 0x0E, 0x0F, 0x8E),
-	PHYREGS(0xEC07, 0xE807, 0xE407, 0x0502, 0x0602, 0x0702),
-  },
-  {	.channel		= 214,
-	.freq			= 5070, /* MHz */
-	.unk2			= 3380,
-	RADIOREGS(0x71, 0x01, 0xFB, 0x0D, 0xE6, 0x01, 0x04, 0x0A,
-		  0x00, 0x8F, 0xBB, 0xBB, 0xFF, 0x00, 0x0E, 0x0F,
-		  0x8E, 0xFF, 0x00, 0x0E, 0x0F, 0x8E),
-	PHYREGS(0xF007, 0xEC07, 0xE807, 0x0402, 0x0502, 0x0602),
-  },
-  {	.channel		= 216,
-	.freq			= 5080, /* MHz */
-	.unk2			= 3387,
-	RADIOREGS(0x71, 0x01, 0xFC, 0x0D, 0xDE, 0x01, 0x04, 0x0A,
-		  0x00, 0x8E, 0xBB, 0xBB, 0xEE, 0x00, 0x0E, 0x0F,
-		  0x8D, 0xEE, 0x00, 0x0E, 0x0F, 0x8D),
-	PHYREGS(0xF407, 0xF007, 0xEC07, 0x0302, 0x0402, 0x0502),
-  },
-  {	.channel		= 218,
-	.freq			= 5090, /* MHz */
-	.unk2			= 3393,
-	RADIOREGS(0x71, 0x01, 0xFD, 0x0D, 0xDE, 0x01, 0x04, 0x0A,
-		  0x00, 0x8E, 0xBB, 0xBB, 0xEE, 0x00, 0x0E, 0x0F,
-		  0x8D, 0xEE, 0x00, 0x0E, 0x0F, 0x8D),
-	PHYREGS(0xF807, 0xF407, 0xF007, 0x0202, 0x0302, 0x0402),
-  },
-  {	.channel		= 220,
-	.freq			= 5100, /* MHz */
-	.unk2			= 3400,
-	RADIOREGS(0x71, 0x01, 0xFE, 0x0C, 0xD6, 0x01, 0x04, 0x0A,
-		  0x00, 0x8E, 0xAA, 0xAA, 0xEE, 0x00, 0x0D, 0x0F,
-		  0x8D, 0xEE, 0x00, 0x0D, 0x0F, 0x8D),
-	PHYREGS(0xFC07, 0xF807, 0xF407, 0x0102, 0x0202, 0x0302),
-  },
-  {	.channel		= 222,
-	.freq			= 5110, /* MHz */
-	.unk2			= 3407,
-	RADIOREGS(0x71, 0x01, 0xFF, 0x0C, 0xD6, 0x01, 0x04, 0x0A,
-		  0x00, 0x8E, 0xAA, 0xAA, 0xEE, 0x00, 0x0D, 0x0F,
-		  0x8D, 0xEE, 0x00, 0x0D, 0x0F, 0x8D),
-	PHYREGS(0x0008, 0xFC07, 0xF807, 0x0002, 0x0102, 0x0202),
-  },
-  {	.channel		= 224,
-	.freq			= 5120, /* MHz */
-	.unk2			= 3413,
-	RADIOREGS(0x71, 0x02, 0x00, 0x0C, 0xCE, 0x01, 0x04, 0x0A,
-		  0x00, 0x8D, 0xAA, 0xAA, 0xDD, 0x00, 0x0D, 0x0F,
-		  0x8C, 0xDD, 0x00, 0x0D, 0x0F, 0x8C),
-	PHYREGS(0x0408, 0x0008, 0xFC07, 0xFF01, 0x0002, 0x0102),
-  },
-  {	.channel		= 226,
-	.freq			= 5130, /* MHz */
-	.unk2			= 3420,
-	RADIOREGS(0x71, 0x02, 0x01, 0x0C, 0xCE, 0x01, 0x04, 0x0A,
-		  0x00, 0x8D, 0xAA, 0xAA, 0xDD, 0x00, 0x0D, 0x0F,
-		  0x8C, 0xDD, 0x00, 0x0D, 0x0F, 0x8C),
-	PHYREGS(0x0808, 0x0408, 0x0008, 0xFE01, 0xFF01, 0x0002),
-  },
-  {	.channel		= 228,
-	.freq			= 5140, /* MHz */
-	.unk2			= 3427,
-	RADIOREGS(0x71, 0x02, 0x02, 0x0C, 0xC6, 0x01, 0x04, 0x0A,
-		  0x00, 0x8D, 0x99, 0x99, 0xDD, 0x00, 0x0C, 0x0E,
-		  0x8B, 0xDD, 0x00, 0x0C, 0x0E, 0x8B),
-	PHYREGS(0x0C08, 0x0808, 0x0408, 0xFD01, 0xFE01, 0xFF01),
-  },
-  {	.channel		= 32,
-	.freq			= 5160, /* MHz */
-	.unk2			= 3440,
-	RADIOREGS(0x71, 0x02, 0x04, 0x0B, 0xBE, 0x01, 0x04, 0x0A,
-		  0x00, 0x8C, 0x99, 0x99, 0xCC, 0x00, 0x0B, 0x0D,
-		  0x8A, 0xCC, 0x00, 0x0B, 0x0D, 0x8A),
-	PHYREGS(0x1408, 0x1008, 0x0C08, 0xFB01, 0xFC01, 0xFD01),
-  },
-  {	.channel		= 34,
-	.freq			= 5170, /* MHz */
-	.unk2			= 3447,
-	RADIOREGS(0x71, 0x02, 0x05, 0x0B, 0xBE, 0x01, 0x04, 0x0A,
-		  0x00, 0x8C, 0x99, 0x99, 0xCC, 0x00, 0x0B, 0x0D,
-		  0x8A, 0xCC, 0x00, 0x0B, 0x0D, 0x8A),
-	PHYREGS(0x1808, 0x1408, 0x1008, 0xFA01, 0xFB01, 0xFC01),
-  },
-  {	.channel		= 36,
-	.freq			= 5180, /* MHz */
-	.unk2			= 3453,
-	RADIOREGS(0x71, 0x02, 0x06, 0x0B, 0xB6, 0x01, 0x04, 0x0A,
-		  0x00, 0x8C, 0x88, 0x88, 0xCC, 0x00, 0x0B, 0x0C,
-		  0x89, 0xCC, 0x00, 0x0B, 0x0C, 0x89),
-	PHYREGS(0x1C08, 0x1808, 0x1408, 0xF901, 0xFA01, 0xFB01),
-  },
-  {	.channel		= 38,
-	.freq			= 5190, /* MHz */
-	.unk2			= 3460,
-	RADIOREGS(0x71, 0x02, 0x07, 0x0B, 0xB6, 0x01, 0x04, 0x0A,
-		  0x00, 0x8C, 0x88, 0x88, 0xCC, 0x00, 0x0B, 0x0C,
-		  0x89, 0xCC, 0x00, 0x0B, 0x0C, 0x89),
-	PHYREGS(0x2008, 0x1C08, 0x1808, 0xF801, 0xF901, 0xFA01),
-  },
-  {	.channel		= 40,
-	.freq			= 5200, /* MHz */
-	.unk2			= 3467,
-	RADIOREGS(0x71, 0x02, 0x08, 0x0B, 0xAF, 0x01, 0x04, 0x0A,
-		  0x00, 0x8B, 0x88, 0x88, 0xBB, 0x00, 0x0A, 0x0B,
-		  0x89, 0xBB, 0x00, 0x0A, 0x0B, 0x89),
-	PHYREGS(0x2408, 0x2008, 0x1C08, 0xF701, 0xF801, 0xF901),
-  },
-  {	.channel		= 42,
-	.freq			= 5210, /* MHz */
-	.unk2			= 3473,
-	RADIOREGS(0x71, 0x02, 0x09, 0x0B, 0xAF, 0x01, 0x04, 0x0A,
-		  0x00, 0x8B, 0x88, 0x88, 0xBB, 0x00, 0x0A, 0x0B,
-		  0x89, 0xBB, 0x00, 0x0A, 0x0B, 0x89),
-	PHYREGS(0x2808, 0x2408, 0x2008, 0xF601, 0xF701, 0xF801),
-  },
-  {	.channel		= 44,
-	.freq			= 5220, /* MHz */
-	.unk2			= 3480,
-	RADIOREGS(0x71, 0x02, 0x0A, 0x0A, 0xA7, 0x01, 0x04, 0x0A,
-		  0x00, 0x8B, 0x77, 0x77, 0xBB, 0x00, 0x09, 0x0A,
-		  0x88, 0xBB, 0x00, 0x09, 0x0A, 0x88),
-	PHYREGS(0x2C08, 0x2808, 0x2408, 0xF501, 0xF601, 0xF701),
-  },
-  {	.channel		= 46,
-	.freq			= 5230, /* MHz */
-	.unk2			= 3487,
-	RADIOREGS(0x71, 0x02, 0x0B, 0x0A, 0xA7, 0x01, 0x04, 0x0A,
-		  0x00, 0x8B, 0x77, 0x77, 0xBB, 0x00, 0x09, 0x0A,
-		  0x88, 0xBB, 0x00, 0x09, 0x0A, 0x88),
-	PHYREGS(0x3008, 0x2C08, 0x2808, 0xF401, 0xF501, 0xF601),
-  },
-  {	.channel		= 48,
-	.freq			= 5240, /* MHz */
-	.unk2			= 3493,
-	RADIOREGS(0x71, 0x02, 0x0C, 0x0A, 0xA0, 0x01, 0x04, 0x0A,
-		  0x00, 0x8A, 0x77, 0x77, 0xAA, 0x00, 0x09, 0x0A,
-		  0x87, 0xAA, 0x00, 0x09, 0x0A, 0x87),
-	PHYREGS(0x3408, 0x3008, 0x2C08, 0xF301, 0xF401, 0xF501),
-  },
-  {	.channel		= 50,
-	.freq			= 5250, /* MHz */
-	.unk2			= 3500,
-	RADIOREGS(0x71, 0x02, 0x0D, 0x0A, 0xA0, 0x01, 0x04, 0x0A,
-		  0x00, 0x8A, 0x77, 0x77, 0xAA, 0x00, 0x09, 0x0A,
-		  0x87, 0xAA, 0x00, 0x09, 0x0A, 0x87),
-	PHYREGS(0x3808, 0x3408, 0x3008, 0xF201, 0xF301, 0xF401),
-  },
-  {	.channel		= 52,
-	.freq			= 5260, /* MHz */
-	.unk2			= 3507,
-	RADIOREGS(0x71, 0x02, 0x0E, 0x0A, 0x98, 0x01, 0x04, 0x0A,
-		  0x00, 0x8A, 0x66, 0x66, 0xAA, 0x00, 0x08, 0x09,
-		  0x87, 0xAA, 0x00, 0x08, 0x09, 0x87),
-	PHYREGS(0x3C08, 0x3808, 0x3408, 0xF101, 0xF201, 0xF301),
-  },
-  {	.channel		= 54,
-	.freq			= 5270, /* MHz */
-	.unk2			= 3513,
-	RADIOREGS(0x71, 0x02, 0x0F, 0x0A, 0x98, 0x01, 0x04, 0x0A,
-		  0x00, 0x8A, 0x66, 0x66, 0xAA, 0x00, 0x08, 0x09,
-		  0x87, 0xAA, 0x00, 0x08, 0x09, 0x87),
-	PHYREGS(0x4008, 0x3C08, 0x3808, 0xF001, 0xF101, 0xF201),
-  },
-  {	.channel		= 56,
-	.freq			= 5280, /* MHz */
-	.unk2			= 3520,
-	RADIOREGS(0x71, 0x02, 0x10, 0x09, 0x91, 0x01, 0x04, 0x0A,
-		  0x00, 0x89, 0x66, 0x66, 0x99, 0x00, 0x08, 0x08,
-		  0x86, 0x99, 0x00, 0x08, 0x08, 0x86),
-	PHYREGS(0x4408, 0x4008, 0x3C08, 0xF001, 0xF001, 0xF101),
-  },
-  {	.channel		= 58,
-	.freq			= 5290, /* MHz */
-	.unk2			= 3527,
-	RADIOREGS(0x71, 0x02, 0x11, 0x09, 0x91, 0x01, 0x04, 0x0A,
-		  0x00, 0x89, 0x66, 0x66, 0x99, 0x00, 0x08, 0x08,
-		  0x86, 0x99, 0x00, 0x08, 0x08, 0x86),
-	PHYREGS(0x4808, 0x4408, 0x4008, 0xEF01, 0xF001, 0xF001),
-  },
-  {	.channel		= 60,
-	.freq			= 5300, /* MHz */
-	.unk2			= 3533,
-	RADIOREGS(0x71, 0x02, 0x12, 0x09, 0x8A, 0x01, 0x04, 0x0A,
-		  0x00, 0x89, 0x55, 0x55, 0x99, 0x00, 0x08, 0x07,
-		  0x85, 0x99, 0x00, 0x08, 0x07, 0x85),
-	PHYREGS(0x4C08, 0x4808, 0x4408, 0xEE01, 0xEF01, 0xF001),
-  },
-  {	.channel		= 62,
-	.freq			= 5310, /* MHz */
-	.unk2			= 3540,
-	RADIOREGS(0x71, 0x02, 0x13, 0x09, 0x8A, 0x01, 0x04, 0x0A,
-		  0x00, 0x89, 0x55, 0x55, 0x99, 0x00, 0x08, 0x07,
-		  0x85, 0x99, 0x00, 0x08, 0x07, 0x85),
-	PHYREGS(0x5008, 0x4C08, 0x4808, 0xED01, 0xEE01, 0xEF01),
-  },
-  {	.channel		= 64,
-	.freq			= 5320, /* MHz */
-	.unk2			= 3547,
-	RADIOREGS(0x71, 0x02, 0x14, 0x09, 0x83, 0x01, 0x04, 0x0A,
-		  0x00, 0x88, 0x55, 0x55, 0x88, 0x00, 0x07, 0x07,
-		  0x84, 0x88, 0x00, 0x07, 0x07, 0x84),
-	PHYREGS(0x5408, 0x5008, 0x4C08, 0xEC01, 0xED01, 0xEE01),
-  },
-  {	.channel		= 66,
-	.freq			= 5330, /* MHz */
-	.unk2			= 3553,
-	RADIOREGS(0x71, 0x02, 0x15, 0x09, 0x83, 0x01, 0x04, 0x0A,
-		  0x00, 0x88, 0x55, 0x55, 0x88, 0x00, 0x07, 0x07,
-		  0x84, 0x88, 0x00, 0x07, 0x07, 0x84),
-	PHYREGS(0x5808, 0x5408, 0x5008, 0xEB01, 0xEC01, 0xED01),
-  },
-  {	.channel		= 68,
-	.freq			= 5340, /* MHz */
-	.unk2			= 3560,
-	RADIOREGS(0x71, 0x02, 0x16, 0x08, 0x7C, 0x01, 0x04, 0x0A,
-		  0x00, 0x88, 0x44, 0x44, 0x88, 0x00, 0x07, 0x06,
-		  0x84, 0x88, 0x00, 0x07, 0x06, 0x84),
-	PHYREGS(0x5C08, 0x5808, 0x5408, 0xEA01, 0xEB01, 0xEC01),
-  },
-  {	.channel		= 70,
-	.freq			= 5350, /* MHz */
-	.unk2			= 3567,
-	RADIOREGS(0x71, 0x02, 0x17, 0x08, 0x7C, 0x01, 0x04, 0x0A,
-		  0x00, 0x88, 0x44, 0x44, 0x88, 0x00, 0x07, 0x06,
-		  0x84, 0x88, 0x00, 0x07, 0x06, 0x84),
-	PHYREGS(0x6008, 0x5C08, 0x5808, 0xE901, 0xEA01, 0xEB01),
-  },
-  {	.channel		= 72,
-	.freq			= 5360, /* MHz */
-	.unk2			= 3573,
-	RADIOREGS(0x71, 0x02, 0x18, 0x08, 0x75, 0x01, 0x04, 0x0A,
-		  0x00, 0x87, 0x44, 0x44, 0x77, 0x00, 0x06, 0x05,
-		  0x83, 0x77, 0x00, 0x06, 0x05, 0x83),
-	PHYREGS(0x6408, 0x6008, 0x5C08, 0xE801, 0xE901, 0xEA01),
-  },
-  {	.channel		= 74,
-	.freq			= 5370, /* MHz */
-	.unk2			= 3580,
-	RADIOREGS(0x71, 0x02, 0x19, 0x08, 0x75, 0x01, 0x04, 0x0A,
-		  0x00, 0x87, 0x44, 0x44, 0x77, 0x00, 0x06, 0x05,
-		  0x83, 0x77, 0x00, 0x06, 0x05, 0x83),
-	PHYREGS(0x6808, 0x6408, 0x6008, 0xE701, 0xE801, 0xE901),
-  },
-  {	.channel		= 76,
-	.freq			= 5380, /* MHz */
-	.unk2			= 3587,
-	RADIOREGS(0x71, 0x02, 0x1A, 0x08, 0x6E, 0x01, 0x04, 0x0A,
-		  0x00, 0x87, 0x33, 0x33, 0x77, 0x00, 0x06, 0x04,
-		  0x82, 0x77, 0x00, 0x06, 0x04, 0x82),
-	PHYREGS(0x6C08, 0x6808, 0x6408, 0xE601, 0xE701, 0xE801),
-  },
-  {	.channel		= 78,
-	.freq			= 5390, /* MHz */
-	.unk2			= 3593,
-	RADIOREGS(0x71, 0x02, 0x1B, 0x08, 0x6E, 0x01, 0x04, 0x0A,
-		  0x00, 0x87, 0x33, 0x33, 0x77, 0x00, 0x06, 0x04,
-		  0x82, 0x77, 0x00, 0x06, 0x04, 0x82),
-	PHYREGS(0x7008, 0x6C08, 0x6808, 0xE501, 0xE601, 0xE701),
-  },
-  {	.channel		= 80,
-	.freq			= 5400, /* MHz */
-	.unk2			= 3600,
-	RADIOREGS(0x71, 0x02, 0x1C, 0x07, 0x67, 0x01, 0x04, 0x0A,
-		  0x00, 0x86, 0x33, 0x33, 0x66, 0x00, 0x05, 0x04,
-		  0x81, 0x66, 0x00, 0x05, 0x04, 0x81),
-	PHYREGS(0x7408, 0x7008, 0x6C08, 0xE501, 0xE501, 0xE601),
-  },
-  {	.channel		= 82,
-	.freq			= 5410, /* MHz */
-	.unk2			= 3607,
-	RADIOREGS(0x71, 0x02, 0x1D, 0x07, 0x67, 0x01, 0x04, 0x0A,
-		  0x00, 0x86, 0x33, 0x33, 0x66, 0x00, 0x05, 0x04,
-		  0x81, 0x66, 0x00, 0x05, 0x04, 0x81),
-	PHYREGS(0x7808, 0x7408, 0x7008, 0xE401, 0xE501, 0xE501),
-  },
-  {	.channel		= 84,
-	.freq			= 5420, /* MHz */
-	.unk2			= 3613,
-	RADIOREGS(0x71, 0x02, 0x1E, 0x07, 0x61, 0x01, 0x04, 0x0A,
-		  0x00, 0x86, 0x22, 0x22, 0x66, 0x00, 0x05, 0x03,
-		  0x80, 0x66, 0x00, 0x05, 0x03, 0x80),
-	PHYREGS(0x7C08, 0x7808, 0x7408, 0xE301, 0xE401, 0xE501),
-  },
-  {	.channel		= 86,
-	.freq			= 5430, /* MHz */
-	.unk2			= 3620,
-	RADIOREGS(0x71, 0x02, 0x1F, 0x07, 0x61, 0x01, 0x04, 0x0A,
-		  0x00, 0x86, 0x22, 0x22, 0x66, 0x00, 0x05, 0x03,
-		  0x80, 0x66, 0x00, 0x05, 0x03, 0x80),
-	PHYREGS(0x8008, 0x7C08, 0x7808, 0xE201, 0xE301, 0xE401),
-  },
-  {	.channel		= 88,
-	.freq			= 5440, /* MHz */
-	.unk2			= 3627,
-	RADIOREGS(0x71, 0x02, 0x20, 0x07, 0x5A, 0x01, 0x04, 0x0A,
-		  0x00, 0x85, 0x22, 0x22, 0x55, 0x00, 0x04, 0x02,
-		  0x80, 0x55, 0x00, 0x04, 0x02, 0x80),
-	PHYREGS(0x8408, 0x8008, 0x7C08, 0xE101, 0xE201, 0xE301),
-  },
-  {	.channel		= 90,
-	.freq			= 5450, /* MHz */
-	.unk2			= 3633,
-	RADIOREGS(0x71, 0x02, 0x21, 0x07, 0x5A, 0x01, 0x04, 0x0A,
-		  0x00, 0x85, 0x22, 0x22, 0x55, 0x00, 0x04, 0x02,
-		  0x80, 0x55, 0x00, 0x04, 0x02, 0x80),
-	PHYREGS(0x8808, 0x8408, 0x8008, 0xE001, 0xE101, 0xE201),
-  },
-  {	.channel		= 92,
-	.freq			= 5460, /* MHz */
-	.unk2			= 3640,
-	RADIOREGS(0x71, 0x02, 0x22, 0x06, 0x53, 0x01, 0x04, 0x0A,
-		  0x00, 0x85, 0x11, 0x11, 0x55, 0x00, 0x04, 0x01,
-		  0x80, 0x55, 0x00, 0x04, 0x01, 0x80),
-	PHYREGS(0x8C08, 0x8808, 0x8408, 0xDF01, 0xE001, 0xE101),
-  },
-  {	.channel		= 94,
-	.freq			= 5470, /* MHz */
-	.unk2			= 3647,
-	RADIOREGS(0x71, 0x02, 0x23, 0x06, 0x53, 0x01, 0x04, 0x0A,
-		  0x00, 0x85, 0x11, 0x11, 0x55, 0x00, 0x04, 0x01,
-		  0x80, 0x55, 0x00, 0x04, 0x01, 0x80),
-	PHYREGS(0x9008, 0x8C08, 0x8808, 0xDE01, 0xDF01, 0xE001),
-  },
-  {	.channel		= 96,
-	.freq			= 5480, /* MHz */
-	.unk2			= 3653,
-	RADIOREGS(0x71, 0x02, 0x24, 0x06, 0x4D, 0x01, 0x04, 0x0A,
-		  0x00, 0x84, 0x11, 0x11, 0x44, 0x00, 0x03, 0x00,
-		  0x80, 0x44, 0x00, 0x03, 0x00, 0x80),
-	PHYREGS(0x9408, 0x9008, 0x8C08, 0xDD01, 0xDE01, 0xDF01),
-  },
-  {	.channel		= 98,
-	.freq			= 5490, /* MHz */
-	.unk2			= 3660,
-	RADIOREGS(0x71, 0x02, 0x25, 0x06, 0x4D, 0x01, 0x04, 0x0A,
-		  0x00, 0x84, 0x11, 0x11, 0x44, 0x00, 0x03, 0x00,
-		  0x80, 0x44, 0x00, 0x03, 0x00, 0x80),
-	PHYREGS(0x9808, 0x9408, 0x9008, 0xDD01, 0xDD01, 0xDE01),
-  },
-  {	.channel		= 100,
-	.freq			= 5500, /* MHz */
-	.unk2			= 3667,
-	RADIOREGS(0x71, 0x02, 0x26, 0x06, 0x47, 0x01, 0x04, 0x0A,
-		  0x00, 0x84, 0x00, 0x00, 0x44, 0x00, 0x03, 0x00,
-		  0x80, 0x44, 0x00, 0x03, 0x00, 0x80),
-	PHYREGS(0x9C08, 0x9808, 0x9408, 0xDC01, 0xDD01, 0xDD01),
-  },
-  {	.channel		= 102,
-	.freq			= 5510, /* MHz */
-	.unk2			= 3673,
-	RADIOREGS(0x71, 0x02, 0x27, 0x06, 0x47, 0x01, 0x04, 0x0A,
-		  0x00, 0x84, 0x00, 0x00, 0x44, 0x00, 0x03, 0x00,
-		  0x80, 0x44, 0x00, 0x03, 0x00, 0x80),
-	PHYREGS(0xA008, 0x9C08, 0x9808, 0xDB01, 0xDC01, 0xDD01),
-  },
-  {	.channel		= 104,
-	.freq			= 5520, /* MHz */
-	.unk2			= 3680,
-	RADIOREGS(0x71, 0x02, 0x28, 0x05, 0x40, 0x01, 0x04, 0x0A,
-		  0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00,
-		  0x80, 0x33, 0x00, 0x02, 0x00, 0x80),
-	PHYREGS(0xA408, 0xA008, 0x9C08, 0xDA01, 0xDB01, 0xDC01),
-  },
-  {	.channel		= 106,
-	.freq			= 5530, /* MHz */
-	.unk2			= 3687,
-	RADIOREGS(0x71, 0x02, 0x29, 0x05, 0x40, 0x01, 0x04, 0x0A,
-		  0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00,
-		  0x80, 0x33, 0x00, 0x02, 0x00, 0x80),
-	PHYREGS(0xA808, 0xA408, 0xA008, 0xD901, 0xDA01, 0xDB01),
-  },
-  {	.channel		= 108,
-	.freq			= 5540, /* MHz */
-	.unk2			= 3693,
-	RADIOREGS(0x71, 0x02, 0x2A, 0x05, 0x3A, 0x01, 0x04, 0x0A,
-		  0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00,
-		  0x80, 0x33, 0x00, 0x02, 0x00, 0x80),
-	PHYREGS(0xAC08, 0xA808, 0xA408, 0xD801, 0xD901, 0xDA01),
-  },
-  {	.channel		= 110,
-	.freq			= 5550, /* MHz */
-	.unk2			= 3700,
-	RADIOREGS(0x71, 0x02, 0x2B, 0x05, 0x3A, 0x01, 0x04, 0x0A,
-		  0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00,
-		  0x80, 0x33, 0x00, 0x02, 0x00, 0x80),
-	PHYREGS(0xB008, 0xAC08, 0xA808, 0xD701, 0xD801, 0xD901),
-  },
-  {	.channel		= 112,
-	.freq			= 5560, /* MHz */
-	.unk2			= 3707,
-	RADIOREGS(0x71, 0x02, 0x2C, 0x05, 0x34, 0x01, 0x04, 0x0A,
-		  0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00,
-		  0x80, 0x22, 0x00, 0x01, 0x00, 0x80),
-	PHYREGS(0xB408, 0xB008, 0xAC08, 0xD701, 0xD701, 0xD801),
-  },
-  {	.channel		= 114,
-	.freq			= 5570, /* MHz */
-	.unk2			= 3713,
-	RADIOREGS(0x71, 0x02, 0x2D, 0x05, 0x34, 0x01, 0x04, 0x0A,
-		  0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00,
-		  0x80, 0x22, 0x00, 0x01, 0x00, 0x80),
-	PHYREGS(0xB808, 0xB408, 0xB008, 0xD601, 0xD701, 0xD701),
-  },
-  {	.channel		= 116,
-	.freq			= 5580, /* MHz */
-	.unk2			= 3720,
-	RADIOREGS(0x71, 0x02, 0x2E, 0x04, 0x2E, 0x01, 0x04, 0x0A,
-		  0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00,
-		  0x80, 0x22, 0x00, 0x01, 0x00, 0x80),
-	PHYREGS(0xBC08, 0xB808, 0xB408, 0xD501, 0xD601, 0xD701),
-  },
-  {	.channel		= 118,
-	.freq			= 5590, /* MHz */
-	.unk2			= 3727,
-	RADIOREGS(0x71, 0x02, 0x2F, 0x04, 0x2E, 0x01, 0x04, 0x0A,
-		  0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00,
-		  0x80, 0x22, 0x00, 0x01, 0x00, 0x80),
-	PHYREGS(0xC008, 0xBC08, 0xB808, 0xD401, 0xD501, 0xD601),
-  },
-  {	.channel		= 120,
-	.freq			= 5600, /* MHz */
-	.unk2			= 3733,
-	RADIOREGS(0x71, 0x02, 0x30, 0x04, 0x28, 0x01, 0x04, 0x0A,
-		  0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x01, 0x00,
-		  0x80, 0x11, 0x00, 0x01, 0x00, 0x80),
-	PHYREGS(0xC408, 0xC008, 0xBC08, 0xD301, 0xD401, 0xD501),
-  },
-  {	.channel		= 122,
-	.freq			= 5610, /* MHz */
-	.unk2			= 3740,
-	RADIOREGS(0x71, 0x02, 0x31, 0x04, 0x28, 0x01, 0x04, 0x0A,
-		  0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x01, 0x00,
-		  0x80, 0x11, 0x00, 0x01, 0x00, 0x80),
-	PHYREGS(0xC808, 0xC408, 0xC008, 0xD201, 0xD301, 0xD401),
-  },
-  {	.channel		= 124,
-	.freq			= 5620, /* MHz */
-	.unk2			= 3747,
-	RADIOREGS(0x71, 0x02, 0x32, 0x04, 0x21, 0x01, 0x04, 0x0A,
-		  0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00,
-		  0x80, 0x11, 0x00, 0x00, 0x00, 0x80),
-	PHYREGS(0xCC08, 0xC808, 0xC408, 0xD201, 0xD201, 0xD301),
-  },
-  {	.channel		= 126,
-	.freq			= 5630, /* MHz */
-	.unk2			= 3753,
-	RADIOREGS(0x71, 0x02, 0x33, 0x04, 0x21, 0x01, 0x04, 0x0A,
-		  0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00,
-		  0x80, 0x11, 0x00, 0x00, 0x00, 0x80),
-	PHYREGS(0xD008, 0xCC08, 0xC808, 0xD101, 0xD201, 0xD201),
-  },
-  {	.channel		= 128,
-	.freq			= 5640, /* MHz */
-	.unk2			= 3760,
-	RADIOREGS(0x71, 0x02, 0x34, 0x03, 0x1C, 0x01, 0x04, 0x0A,
-		  0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
-	PHYREGS(0xD408, 0xD008, 0xCC08, 0xD001, 0xD101, 0xD201),
-  },
-  {	.channel		= 130,
-	.freq			= 5650, /* MHz */
-	.unk2			= 3767,
-	RADIOREGS(0x71, 0x02, 0x35, 0x03, 0x1C, 0x01, 0x04, 0x0A,
-		  0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
-	PHYREGS(0xD808, 0xD408, 0xD008, 0xCF01, 0xD001, 0xD101),
-  },
-  {	.channel		= 132,
-	.freq			= 5660, /* MHz */
-	.unk2			= 3773,
-	RADIOREGS(0x71, 0x02, 0x36, 0x03, 0x16, 0x01, 0x04, 0x0A,
-		  0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
-	PHYREGS(0xDC08, 0xD808, 0xD408, 0xCE01, 0xCF01, 0xD001),
-  },
-  {	.channel		= 134,
-	.freq			= 5670, /* MHz */
-	.unk2			= 3780,
-	RADIOREGS(0x71, 0x02, 0x37, 0x03, 0x16, 0x01, 0x04, 0x0A,
-		  0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
-	PHYREGS(0xE008, 0xDC08, 0xD808, 0xCE01, 0xCE01, 0xCF01),
-  },
-  {	.channel		= 136,
-	.freq			= 5680, /* MHz */
-	.unk2			= 3787,
-	RADIOREGS(0x71, 0x02, 0x38, 0x03, 0x10, 0x01, 0x04, 0x0A,
-		  0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
-	PHYREGS(0xE408, 0xE008, 0xDC08, 0xCD01, 0xCE01, 0xCE01),
-  },
-  {	.channel		= 138,
-	.freq			= 5690, /* MHz */
-	.unk2			= 3793,
-	RADIOREGS(0x71, 0x02, 0x39, 0x03, 0x10, 0x01, 0x04, 0x0A,
-		  0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
-	PHYREGS(0xE808, 0xE408, 0xE008, 0xCC01, 0xCD01, 0xCE01),
-  },
-  {	.channel		= 140,
-	.freq			= 5700, /* MHz */
-	.unk2			= 3800,
-	RADIOREGS(0x71, 0x02, 0x3A, 0x02, 0x0A, 0x01, 0x04, 0x0A,
-		  0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
-	PHYREGS(0xEC08, 0xE808, 0xE408, 0xCB01, 0xCC01, 0xCD01),
-  },
-  {	.channel		= 142,
-	.freq			= 5710, /* MHz */
-	.unk2			= 3807,
-	RADIOREGS(0x71, 0x02, 0x3B, 0x02, 0x0A, 0x01, 0x04, 0x0A,
-		  0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
-	PHYREGS(0xF008, 0xEC08, 0xE808, 0xCA01, 0xCB01, 0xCC01),
-  },
-  {	.channel		= 144,
-	.freq			= 5720, /* MHz */
-	.unk2			= 3813,
-	RADIOREGS(0x71, 0x02, 0x3C, 0x02, 0x0A, 0x01, 0x04, 0x0A,
-		  0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
-	PHYREGS(0xF408, 0xF008, 0xEC08, 0xC901, 0xCA01, 0xCB01),
-  },
-  {	.channel		= 145,
-	.freq			= 5725, /* MHz */
-	.unk2			= 3817,
-	RADIOREGS(0x72, 0x04, 0x79, 0x02, 0x03, 0x01, 0x03, 0x14,
-		  0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
-	PHYREGS(0xF608, 0xF208, 0xEE08, 0xC901, 0xCA01, 0xCB01),
-  },
-  {	.channel		= 146,
-	.freq			= 5730, /* MHz */
-	.unk2			= 3820,
-	RADIOREGS(0x71, 0x02, 0x3D, 0x02, 0x0A, 0x01, 0x04, 0x0A,
-		  0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
-	PHYREGS(0xF808, 0xF408, 0xF008, 0xC901, 0xC901, 0xCA01),
-  },
-  {	.channel		= 147,
-	.freq			= 5735, /* MHz */
-	.unk2			= 3823,
-	RADIOREGS(0x72, 0x04, 0x7B, 0x02, 0x03, 0x01, 0x03, 0x14,
-		  0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
-	PHYREGS(0xFA08, 0xF608, 0xF208, 0xC801, 0xC901, 0xCA01),
-  },
-  {	.channel		= 148,
-	.freq			= 5740, /* MHz */
-	.unk2			= 3827,
-	RADIOREGS(0x71, 0x02, 0x3E, 0x02, 0x0A, 0x01, 0x04, 0x0A,
-		  0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
-	PHYREGS(0xFC08, 0xF808, 0xF408, 0xC801, 0xC901, 0xC901),
-  },
-  {	.channel		= 149,
-	.freq			= 5745, /* MHz */
-	.unk2			= 3830,
-	RADIOREGS(0x72, 0x04, 0x7D, 0x02, 0xFE, 0x00, 0x03, 0x14,
-		  0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
-	PHYREGS(0xFE08, 0xFA08, 0xF608, 0xC801, 0xC801, 0xC901),
-  },
-  {	.channel		= 150,
-	.freq			= 5750, /* MHz */
-	.unk2			= 3833,
-	RADIOREGS(0x71, 0x02, 0x3F, 0x02, 0x0A, 0x01, 0x04, 0x0A,
-		  0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
-	PHYREGS(0x0009, 0xFC08, 0xF808, 0xC701, 0xC801, 0xC901),
-  },
-  {	.channel		= 151,
-	.freq			= 5755, /* MHz */
-	.unk2			= 3837,
-	RADIOREGS(0x72, 0x04, 0x7F, 0x02, 0xFE, 0x00, 0x03, 0x14,
-		  0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
-	PHYREGS(0x0209, 0xFE08, 0xFA08, 0xC701, 0xC801, 0xC801),
-  },
-  {	.channel		= 152,
-	.freq			= 5760, /* MHz */
-	.unk2			= 3840,
-	RADIOREGS(0x71, 0x02, 0x40, 0x02, 0x0A, 0x01, 0x04, 0x0A,
-		  0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
-	PHYREGS(0x0409, 0x0009, 0xFC08, 0xC601, 0xC701, 0xC801),
-  },
-  {	.channel		= 153,
-	.freq			= 5765, /* MHz */
-	.unk2			= 3843,
-	RADIOREGS(0x72, 0x04, 0x81, 0x02, 0xF8, 0x00, 0x03, 0x14,
-		  0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
-	PHYREGS(0x0609, 0x0209, 0xFE08, 0xC601, 0xC701, 0xC801),
-  },
-  {	.channel		= 154,
-	.freq			= 5770, /* MHz */
-	.unk2			= 3847,
-	RADIOREGS(0x71, 0x02, 0x41, 0x02, 0x0A, 0x01, 0x04, 0x0A,
-		  0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
-	PHYREGS(0x0809, 0x0409, 0x0009, 0xC601, 0xC601, 0xC701),
-  },
-  {	.channel		= 155,
-	.freq			= 5775, /* MHz */
-	.unk2			= 3850,
-	RADIOREGS(0x72, 0x04, 0x83, 0x02, 0xF8, 0x00, 0x03, 0x14,
-		  0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
-	PHYREGS(0x0A09, 0x0609, 0x0209, 0xC501, 0xC601, 0xC701),
-  },
-  {	.channel		= 156,
-	.freq			= 5780, /* MHz */
-	.unk2			= 3853,
-	RADIOREGS(0x71, 0x02, 0x42, 0x02, 0x0A, 0x01, 0x04, 0x0A,
-		  0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
-	PHYREGS(0x0C09, 0x0809, 0x0409, 0xC501, 0xC601, 0xC601),
-  },
-  {	.channel		= 157,
-	.freq			= 5785, /* MHz */
-	.unk2			= 3857,
-	RADIOREGS(0x72, 0x04, 0x85, 0x02, 0xF2, 0x00, 0x03, 0x14,
-		  0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
-	PHYREGS(0x0E09, 0x0A09, 0x0609, 0xC401, 0xC501, 0xC601),
-  },
-  {	.channel		= 158,
-	.freq			= 5790, /* MHz */
-	.unk2			= 3860,
-	RADIOREGS(0x71, 0x02, 0x43, 0x02, 0x0A, 0x01, 0x04, 0x0A,
-		  0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
-	PHYREGS(0x1009, 0x0C09, 0x0809, 0xC401, 0xC501, 0xC601),
-  },
-  {	.channel		= 159,
-	.freq			= 5795, /* MHz */
-	.unk2			= 3863,
-	RADIOREGS(0x72, 0x04, 0x87, 0x02, 0xF2, 0x00, 0x03, 0x14,
-		  0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
-	PHYREGS(0x1209, 0x0E09, 0x0A09, 0xC401, 0xC401, 0xC501),
-  },
-  {	.channel		= 160,
-	.freq			= 5800, /* MHz */
-	.unk2			= 3867,
-	RADIOREGS(0x71, 0x02, 0x44, 0x01, 0x0A, 0x01, 0x04, 0x0A,
-		  0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
-	PHYREGS(0x1409, 0x1009, 0x0C09, 0xC301, 0xC401, 0xC501),
-  },
-  {	.channel		= 161,
-	.freq			= 5805, /* MHz */
-	.unk2			= 3870,
-	RADIOREGS(0x72, 0x04, 0x89, 0x01, 0xED, 0x00, 0x03, 0x14,
-		  0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
-	PHYREGS(0x1609, 0x1209, 0x0E09, 0xC301, 0xC401, 0xC401),
-  },
-  {	.channel		= 162,
-	.freq			= 5810, /* MHz */
-	.unk2			= 3873,
-	RADIOREGS(0x71, 0x02, 0x45, 0x01, 0x0A, 0x01, 0x04, 0x0A,
-		  0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
-	PHYREGS(0x1809, 0x1409, 0x1009, 0xC201, 0xC301, 0xC401),
-  },
-  {	.channel		= 163,
-	.freq			= 5815, /* MHz */
-	.unk2			= 3877,
-	RADIOREGS(0x72, 0x04, 0x8B, 0x01, 0xED, 0x00, 0x03, 0x14,
-		  0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
-	PHYREGS(0x1A09, 0x1609, 0x1209, 0xC201, 0xC301, 0xC401),
-  },
-  {	.channel		= 164,
-	.freq			= 5820, /* MHz */
-	.unk2			= 3880,
-	RADIOREGS(0x71, 0x02, 0x46, 0x01, 0x0A, 0x01, 0x04, 0x0A,
-		  0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
-	PHYREGS(0x1C09, 0x1809, 0x1409, 0xC201, 0xC201, 0xC301),
-  },
-  {	.channel		= 165,
-	.freq			= 5825, /* MHz */
-	.unk2			= 3883,
-	RADIOREGS(0x72, 0x04, 0x8D, 0x01, 0xED, 0x00, 0x03, 0x14,
-		  0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
-	PHYREGS(0x1E09, 0x1A09, 0x1609, 0xC101, 0xC201, 0xC301),
-  },
-  {	.channel		= 166,
-	.freq			= 5830, /* MHz */
-	.unk2			= 3887,
-	RADIOREGS(0x71, 0x02, 0x47, 0x01, 0x0A, 0x01, 0x04, 0x0A,
-		  0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
-	PHYREGS(0x2009, 0x1C09, 0x1809, 0xC101, 0xC201, 0xC201),
-  },
-  {	.channel		= 168,
-	.freq			= 5840, /* MHz */
-	.unk2			= 3893,
-	RADIOREGS(0x71, 0x02, 0x48, 0x01, 0x0A, 0x01, 0x04, 0x0A,
-		  0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
-	PHYREGS(0x2409, 0x2009, 0x1C09, 0xC001, 0xC101, 0xC201),
-  },
-  {	.channel		= 170,
-	.freq			= 5850, /* MHz */
-	.unk2			= 3900,
-	RADIOREGS(0x71, 0x02, 0x49, 0x01, 0xE0, 0x00, 0x04, 0x0A,
-		  0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
-	PHYREGS(0x2809, 0x2409, 0x2009, 0xBF01, 0xC001, 0xC101),
-  },
-  {	.channel		= 172,
-	.freq			= 5860, /* MHz */
-	.unk2			= 3907,
-	RADIOREGS(0x71, 0x02, 0x4A, 0x01, 0xDE, 0x00, 0x04, 0x0A,
-		  0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
-	PHYREGS(0x2C09, 0x2809, 0x2409, 0xBF01, 0xBF01, 0xC001),
-  },
-  {	.channel		= 174,
-	.freq			= 5870, /* MHz */
-	.unk2			= 3913,
-	RADIOREGS(0x71, 0x02, 0x4B, 0x00, 0xDB, 0x00, 0x04, 0x0A,
-		  0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
-	PHYREGS(0x3009, 0x2C09, 0x2809, 0xBE01, 0xBF01, 0xBF01),
-  },
-  {	.channel		= 176,
-	.freq			= 5880, /* MHz */
-	.unk2			= 3920,
-	RADIOREGS(0x71, 0x02, 0x4C, 0x00, 0xD8, 0x00, 0x04, 0x0A,
-		  0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
-	PHYREGS(0x3409, 0x3009, 0x2C09, 0xBD01, 0xBE01, 0xBF01),
-  },
-  {	.channel		= 178,
-	.freq			= 5890, /* MHz */
-	.unk2			= 3927,
-	RADIOREGS(0x71, 0x02, 0x4D, 0x00, 0xD6, 0x00, 0x04, 0x0A,
-		  0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
-	PHYREGS(0x3809, 0x3409, 0x3009, 0xBC01, 0xBD01, 0xBE01),
-  },
-  {	.channel		= 180,
-	.freq			= 5900, /* MHz */
-	.unk2			= 3933,
-	RADIOREGS(0x71, 0x02, 0x4E, 0x00, 0xD3, 0x00, 0x04, 0x0A,
-		  0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
-	PHYREGS(0x3C09, 0x3809, 0x3409, 0xBC01, 0xBC01, 0xBD01),
-  },
-  {	.channel		= 182,
-	.freq			= 5910, /* MHz */
-	.unk2			= 3940,
-	RADIOREGS(0x71, 0x02, 0x4F, 0x00, 0xD6, 0x00, 0x04, 0x0A,
-		  0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
-	PHYREGS(0x4009, 0x3C09, 0x3809, 0xBB01, 0xBC01, 0xBC01),
-  },
-  {	.channel		= 1,
-	.freq			= 2412, /* MHz */
-	.unk2			= 3216,
-	RADIOREGS(0x73, 0x09, 0x6C, 0x0F, 0x00, 0x01, 0x07, 0x15,
-		  0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0D, 0x0C,
-		  0x80, 0xFF, 0x88, 0x0D, 0x0C, 0x80),
-	PHYREGS(0xC903, 0xC503, 0xC103, 0x3A04, 0x3F04, 0x4304),
-  },
-  {	.channel		= 2,
-	.freq			= 2417, /* MHz */
-	.unk2			= 3223,
-	RADIOREGS(0x73, 0x09, 0x71, 0x0F, 0x00, 0x01, 0x07, 0x15,
-		  0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x0B,
-		  0x80, 0xFF, 0x88, 0x0C, 0x0B, 0x80),
-	PHYREGS(0xCB03, 0xC703, 0xC303, 0x3804, 0x3D04, 0x4104),
-  },
-  {	.channel		= 3,
-	.freq			= 2422, /* MHz */
-	.unk2			= 3229,
-	RADIOREGS(0x73, 0x09, 0x76, 0x0F, 0x00, 0x01, 0x07, 0x15,
-		  0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x0A,
-		  0x80, 0xFF, 0x88, 0x0C, 0x0A, 0x80),
-	PHYREGS(0xCD03, 0xC903, 0xC503, 0x3604, 0x3A04, 0x3F04),
-  },
-  {	.channel		= 4,
-	.freq			= 2427, /* MHz */
-	.unk2			= 3236,
-	RADIOREGS(0x73, 0x09, 0x7B, 0x0F, 0x00, 0x01, 0x07, 0x15,
-		  0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x0A,
-		  0x80, 0xFF, 0x88, 0x0C, 0x0A, 0x80),
-	PHYREGS(0xCF03, 0xCB03, 0xC703, 0x3404, 0x3804, 0x3D04),
-  },
-  {	.channel		= 5,
-	.freq			= 2432, /* MHz */
-	.unk2			= 3243,
-	RADIOREGS(0x73, 0x09, 0x80, 0x0F, 0x00, 0x01, 0x07, 0x15,
-		  0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x09,
-		  0x80, 0xFF, 0x88, 0x0C, 0x09, 0x80),
-	PHYREGS(0xD103, 0xCD03, 0xC903, 0x3104, 0x3604, 0x3A04),
-  },
-  {	.channel		= 6,
-	.freq			= 2437, /* MHz */
-	.unk2			= 3249,
-	RADIOREGS(0x73, 0x09, 0x85, 0x0F, 0x00, 0x01, 0x07, 0x15,
-		  0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0B, 0x08,
-		  0x80, 0xFF, 0x88, 0x0B, 0x08, 0x80),
-	PHYREGS(0xD303, 0xCF03, 0xCB03, 0x2F04, 0x3404, 0x3804),
-  },
-  {	.channel		= 7,
-	.freq			= 2442, /* MHz */
-	.unk2			= 3256,
-	RADIOREGS(0x73, 0x09, 0x8A, 0x0F, 0x00, 0x01, 0x07, 0x15,
-		  0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0A, 0x07,
-		  0x80, 0xFF, 0x88, 0x0A, 0x07, 0x80),
-	PHYREGS(0xD503, 0xD103, 0xCD03, 0x2D04, 0x3104, 0x3604),
-  },
-  {	.channel		= 8,
-	.freq			= 2447, /* MHz */
-	.unk2			= 3263,
-	RADIOREGS(0x73, 0x09, 0x8F, 0x0F, 0x00, 0x01, 0x07, 0x15,
-		  0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0A, 0x06,
-		  0x80, 0xFF, 0x88, 0x0A, 0x06, 0x80),
-	PHYREGS(0xD703, 0xD303, 0xCF03, 0x2B04, 0x2F04, 0x3404),
-  },
-  {	.channel		= 9,
-	.freq			= 2452, /* MHz */
-	.unk2			= 3269,
-	RADIOREGS(0x73, 0x09, 0x94, 0x0F, 0x00, 0x01, 0x07, 0x15,
-		  0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x09, 0x06,
-		  0x80, 0xFF, 0x88, 0x09, 0x06, 0x80),
-	PHYREGS(0xD903, 0xD503, 0xD103, 0x2904, 0x2D04, 0x3104),
-  },
-  {	.channel		= 10,
-	.freq			= 2457, /* MHz */
-	.unk2			= 3276,
-	RADIOREGS(0x73, 0x09, 0x99, 0x0F, 0x00, 0x01, 0x07, 0x15,
-		  0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x08, 0x05,
-		  0x80, 0xFF, 0x88, 0x08, 0x05, 0x80),
-	PHYREGS(0xDB03, 0xD703, 0xD303, 0x2704, 0x2B04, 0x2F04),
-  },
-  {	.channel		= 11,
-	.freq			= 2462, /* MHz */
-	.unk2			= 3283,
-	RADIOREGS(0x73, 0x09, 0x9E, 0x0F, 0x00, 0x01, 0x07, 0x15,
-		  0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x08, 0x04,
-		  0x80, 0xFF, 0x88, 0x08, 0x04, 0x80),
-	PHYREGS(0xDD03, 0xD903, 0xD503, 0x2404, 0x2904, 0x2D04),
-  },
-  {	.channel		= 12,
-	.freq			= 2467, /* MHz */
-	.unk2			= 3289,
-	RADIOREGS(0x73, 0x09, 0xA3, 0x0F, 0x00, 0x01, 0x07, 0x15,
-		  0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x08, 0x03,
-		  0x80, 0xFF, 0x88, 0x08, 0x03, 0x80),
-	PHYREGS(0xDF03, 0xDB03, 0xD703, 0x2204, 0x2704, 0x2B04),
-  },
-  {	.channel		= 13,
-	.freq			= 2472, /* MHz */
-	.unk2			= 3296,
-	RADIOREGS(0x73, 0x09, 0xA8, 0x0F, 0x00, 0x01, 0x07, 0x15,
-		  0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x07, 0x03,
-		  0x80, 0xFF, 0x88, 0x07, 0x03, 0x80),
-	PHYREGS(0xE103, 0xDD03, 0xD903, 0x2004, 0x2404, 0x2904),
-  },
-  {	.channel		= 14,
-	.freq			= 2484, /* MHz */
-	.unk2			= 3312,
-	RADIOREGS(0x73, 0x09, 0xB4, 0x0F, 0xFF, 0x01, 0x07, 0x15,
-		  0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x07, 0x01,
-		  0x80, 0xFF, 0x88, 0x07, 0x01, 0x80),
-	PHYREGS(0xE603, 0xE203, 0xDE03, 0x1B04, 0x1F04, 0x2404),
-  },
-};
-
-const struct b43_nphy_channeltab_entry_rev2 *
-b43_nphy_get_chantabent_rev2(struct b43_wldev *dev, u8 channel)
-{
-	const struct b43_nphy_channeltab_entry_rev2 *e;
-	unsigned int i;
-
-	for (i = 0; i < ARRAY_SIZE(b43_nphy_channeltab); i++) {
-		e = &(b43_nphy_channeltab[i]);
-		if (e->channel == channel)
-			return e;
-	}
-
-	return NULL;
-}
-
-
 static const u8 b43_ntab_adjustpower0[] = {
 	0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
 	0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03,
diff --git a/drivers/net/wireless/b43/tables_nphy.h b/drivers/net/wireless/b43/tables_nphy.h
index 8fc1da9f8fe5..4ec593ba3eef 100644
--- a/drivers/net/wireless/b43/tables_nphy.h
+++ b/drivers/net/wireless/b43/tables_nphy.h
@@ -3,7 +3,6 @@
 
 #include <linux/types.h>
 
-
 struct b43_phy_n_sfo_cfg {
 	u16 phy_bw1a;
 	u16 phy_bw2;
@@ -13,52 +12,6 @@ struct b43_phy_n_sfo_cfg {
 	u16 phy_bw6;
 };
 
-struct b43_nphy_channeltab_entry_rev2 {
-	/* The channel number */
-	u8 channel;
-	/* The channel frequency in MHz */
-	u16 freq;
-	/* An unknown value */
-	u16 unk2;
-	/* Radio register values on channelswitch */
-	u8 radio_pll_ref;
-	u8 radio_rf_pllmod0;
-	u8 radio_rf_pllmod1;
-	u8 radio_vco_captail;
-	u8 radio_vco_cal1;
-	u8 radio_vco_cal2;
-	u8 radio_pll_lfc1;
-	u8 radio_pll_lfr1;
-	u8 radio_pll_lfc2;
-	u8 radio_lgbuf_cenbuf;
-	u8 radio_lgen_tune1;
-	u8 radio_lgen_tune2;
-	u8 radio_c1_lgbuf_atune;
-	u8 radio_c1_lgbuf_gtune;
-	u8 radio_c1_rx_rfr1;
-	u8 radio_c1_tx_pgapadtn;
-	u8 radio_c1_tx_mxbgtrim;
-	u8 radio_c2_lgbuf_atune;
-	u8 radio_c2_lgbuf_gtune;
-	u8 radio_c2_rx_rfr1;
-	u8 radio_c2_tx_pgapadtn;
-	u8 radio_c2_tx_mxbgtrim;
-	/* PHY register values on channelswitch */
-	struct b43_phy_n_sfo_cfg phy_regs;
-};
-
-struct b43_nphy_channeltab_entry_rev3 {
-	/* The channel number */
-	u8 channel;
-	/* The channel frequency in MHz */
-	u16 freq;
-	/* Radio register values on channelswitch */
-	/* TODO */
-	/* PHY register values on channelswitch */
-	struct b43_phy_n_sfo_cfg phy_regs;
-};
-
-
 struct b43_wldev;
 
 struct nphy_txiqcal_ladder {
@@ -82,18 +35,12 @@ struct nphy_rf_control_override_rev3 {
 	u8 val_addr1;
 };
 
-/* Upload the default register value table.
- * If "ghz5" is true, we upload the 5Ghz table. Otherwise the 2.4Ghz
- * table is uploaded. If "ignore_uploadflag" is true, we upload any value
- * and ignore the "UPLOAD" flag. */
-void b2055_upload_inittab(struct b43_wldev *dev,
-			  bool ghz5, bool ignore_uploadflag);
-
-
-/* Get the NPHY Channel Switch Table entry for a channel number.
+/* Get the NPHY Channel Switch Table entry for a channel.
  * Returns NULL on failure to find an entry. */
 const struct b43_nphy_channeltab_entry_rev2 *
 b43_nphy_get_chantabent_rev2(struct b43_wldev *dev, u8 channel);
+const struct b43_nphy_channeltab_entry_rev3 *
+b43_nphy_get_chantabent_rev3(struct b43_wldev *dev, u16 freq);
 
 
 /* The N-PHY tables. */
diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile
index 493163925a45..63edbe2e557f 100644
--- a/drivers/net/wireless/iwlwifi/Makefile
+++ b/drivers/net/wireless/iwlwifi/Makefile
@@ -12,7 +12,7 @@ obj-$(CONFIG_IWLAGN)	+= iwlagn.o
 iwlagn-objs		:= iwl-agn.o iwl-agn-rs.o iwl-agn-led.o iwl-agn-ict.o
 iwlagn-objs		+= iwl-agn-ucode.o iwl-agn-hcmd.o iwl-agn-tx.o
 iwlagn-objs		+= iwl-agn-lib.o iwl-agn-rx.o iwl-agn-calib.o
-iwlagn-objs		+= iwl-agn-tt.o
+iwlagn-objs		+= iwl-agn-tt.o iwl-agn-sta.o iwl-agn-eeprom.o
 iwlagn-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-agn-debugfs.o
 
 iwlagn-$(CONFIG_IWL4965) += iwl-4965.o
diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c
index 134f54541330..db540910b110 100644
--- a/drivers/net/wireless/iwlwifi/iwl-1000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-1000.c
@@ -151,8 +151,7 @@ static int iwl1000_hw_set_hw_params(struct iwl_priv *priv)
 	priv->hw_params.valid_tx_ant = priv->cfg->valid_tx_ant;
 	priv->hw_params.valid_rx_ant = priv->cfg->valid_rx_ant;
 
-	if (priv->cfg->ops->lib->temp_ops.set_ct_kill)
-		priv->cfg->ops->lib->temp_ops.set_ct_kill(priv);
+	iwl1000_set_ct_threshold(priv);
 
 	/* Set initial sensitivity parameters */
 	/* Set initial calibration set */
@@ -195,9 +194,7 @@ static struct iwl_lib_ops iwl1000_lib = {
 	.update_chain_flags = iwl_update_chain_flags,
 	.apm_ops = {
 		.init = iwl_apm_init,
-		.stop = iwl_apm_stop,
 		.config = iwl1000_nic_config,
-		.set_pwr_src = iwl_set_pwr_src,
 	},
 	.eeprom_ops = {
 		.regulatory_bands = {
@@ -209,7 +206,6 @@ static struct iwl_lib_ops iwl1000_lib = {
 			EEPROM_REG_BAND_24_HT40_CHANNELS,
 			EEPROM_REG_BAND_52_HT40_CHANNELS
 		},
-		.verify_signature  = iwlcore_eeprom_verify_signature,
 		.acquire_semaphore = iwlcore_eeprom_acquire_semaphore,
 		.release_semaphore = iwlcore_eeprom_release_semaphore,
 		.calib_version	= iwlagn_eeprom_calib_version,
@@ -220,7 +216,6 @@ static struct iwl_lib_ops iwl1000_lib = {
 	.config_ap = iwl_config_ap,
 	.temp_ops = {
 		.temperature = iwlagn_temperature,
-		.set_ct_kill = iwl1000_set_ct_threshold,
 	 },
 	.manage_ibss_station = iwlagn_manage_ibss_station,
 	.update_bcast_stations = iwl_update_bcast_stations,
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index cfdff5487e3c..176e52577673 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -87,6 +87,15 @@ const struct iwl3945_rate_info iwl3945_rates[IWL_RATE_COUNT_3945] = {
 	IWL_DECLARE_RATE_INFO(54, 48, INV, 48, INV, 48, INV),/* 54mbps */
 };
 
+static inline u8 iwl3945_get_prev_ieee_rate(u8 rate_index)
+{
+	u8 rate = iwl3945_rates[rate_index].prev_ieee;
+
+	if (rate == IWL_RATE_INVALID)
+		rate = rate_index;
+	return rate;
+}
+
 /* 1 = enable the iwl3945_disable_events() function */
 #define IWL_EVT_DISABLE (0)
 #define IWL_EVT_DISABLE_SIZE (1532/32)
@@ -339,7 +348,7 @@ static void iwl3945_rx_reply_tx(struct iwl_priv *priv,
 	IWL_DEBUG_TX_REPLY(priv, "Tx queue reclaim %d\n", index);
 	iwl3945_tx_queue_reclaim(priv, txq_id, index);
 
-	if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK))
+	if (status & TX_ABORT_REQUIRED_MSK)
 		IWL_ERR(priv, "TODO:  Implement Tx ABORT REQUIRED!!!\n");
 }
 
@@ -807,9 +816,12 @@ static u8 iwl3945_sync_sta(struct iwl_priv *priv, int sta_id, u16 tx_rate)
 	return sta_id;
 }
 
-static int iwl3945_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src)
+static void iwl3945_set_pwr_vmain(struct iwl_priv *priv)
 {
-	if (src == IWL_PWR_SRC_VAUX) {
+/*
+ * (for documentation purposes)
+ * to set power to V_AUX, do
+
 		if (pci_pme_capable(priv->pci_dev, PCI_D3cold)) {
 			iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG,
 					APMG_PS_CTRL_VAL_PWR_SRC_VAUX,
@@ -819,16 +831,14 @@ static int iwl3945_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src)
 				     CSR_GPIO_IN_VAL_VAUX_PWR_SRC,
 				     CSR_GPIO_IN_BIT_AUX_POWER, 5000);
 		}
-	} else {
-		iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG,
-				APMG_PS_CTRL_VAL_PWR_SRC_VMAIN,
-				~APMG_PS_CTRL_MSK_PWR_SRC);
+ */
 
-		iwl_poll_bit(priv, CSR_GPIO_IN, CSR_GPIO_IN_VAL_VMAIN_PWR_SRC,
-			     CSR_GPIO_IN_BIT_AUX_POWER, 5000);	/* uS */
-	}
+	iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG,
+			APMG_PS_CTRL_VAL_PWR_SRC_VMAIN,
+			~APMG_PS_CTRL_MSK_PWR_SRC);
 
-	return 0;
+	iwl_poll_bit(priv, CSR_GPIO_IN, CSR_GPIO_IN_VAL_VMAIN_PWR_SRC,
+		     CSR_GPIO_IN_BIT_AUX_POWER, 5000);	/* uS */
 }
 
 static int iwl3945_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
@@ -1022,9 +1032,7 @@ int iwl3945_hw_nic_init(struct iwl_priv *priv)
 	priv->cfg->ops->lib->apm_ops.init(priv);
 	spin_unlock_irqrestore(&priv->lock, flags);
 
-	rc = priv->cfg->ops->lib->apm_ops.set_pwr_src(priv, IWL_PWR_SRC_VMAIN);
-	if (rc)
-		return rc;
+	iwl3945_set_pwr_vmain(priv);
 
 	priv->cfg->ops->lib->apm_ops.config(priv);
 
@@ -1763,8 +1771,7 @@ static int iwl3945_send_rxon_assoc(struct iwl_priv *priv,
  * function correctly transitions out of the RXON_ASSOC_MSK state if
  * a HW tune is required based on the RXON structure changes.
  */
-static int iwl3945_commit_rxon(struct iwl_priv *priv,
-			       struct iwl_rxon_context *ctx)
+int iwl3945_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
 {
 	/* cast away the const for active_rxon in this function */
 	struct iwl3945_rxon_cmd *active_rxon = (void *)&ctx->active;
@@ -2300,6 +2307,32 @@ static u16 iwl3945_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data)
 	return (u16)sizeof(struct iwl3945_addsta_cmd);
 }
 
+static int iwl3945_add_bssid_station(struct iwl_priv *priv,
+				     const u8 *addr, u8 *sta_id_r)
+{
+	struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
+	int ret;
+	u8 sta_id;
+	unsigned long flags;
+
+	if (sta_id_r)
+		*sta_id_r = IWL_INVALID_STATION;
+
+	ret = iwl_add_station_common(priv, ctx, addr, 0, NULL, &sta_id);
+	if (ret) {
+		IWL_ERR(priv, "Unable to add station %pM\n", addr);
+		return ret;
+	}
+
+	if (sta_id_r)
+		*sta_id_r = sta_id;
+
+	spin_lock_irqsave(&priv->sta_lock, flags);
+	priv->stations[sta_id].used |= IWL_STA_LOCAL;
+	spin_unlock_irqrestore(&priv->sta_lock, flags);
+
+	return 0;
+}
 static int iwl3945_manage_ibss_station(struct iwl_priv *priv,
 				       struct ieee80211_vif *vif, bool add)
 {
@@ -2307,10 +2340,8 @@ static int iwl3945_manage_ibss_station(struct iwl_priv *priv,
 	int ret;
 
 	if (add) {
-		ret = iwl_add_bssid_station(
-				priv, &priv->contexts[IWL_RXON_CTX_BSS],
-				vif->bss_conf.bssid, false,
-				&vif_priv->ibss_bssid_sta_id);
+		ret = iwl3945_add_bssid_station(priv, vif->bss_conf.bssid,
+						&vif_priv->ibss_bssid_sta_id);
 		if (ret)
 			return ret;
 
@@ -2673,9 +2704,7 @@ static struct iwl_lib_ops iwl3945_lib = {
 	.dump_nic_error_log = iwl3945_dump_nic_error_log,
 	.apm_ops = {
 		.init = iwl3945_apm_init,
-		.stop = iwl_apm_stop,
 		.config = iwl3945_nic_config,
-		.set_pwr_src = iwl3945_set_pwr_src,
 	},
 	.eeprom_ops = {
 		.regulatory_bands = {
@@ -2687,7 +2716,6 @@ static struct iwl_lib_ops iwl3945_lib = {
 			EEPROM_REGULATORY_BAND_NO_HT40,
 			EEPROM_REGULATORY_BAND_NO_HT40,
 		},
-		.verify_signature  = iwlcore_eeprom_verify_signature,
 		.acquire_semaphore = iwl3945_eeprom_acquire_semaphore,
 		.release_semaphore = iwl3945_eeprom_release_semaphore,
 		.query_addr = iwlcore_eeprom_query_addr,
@@ -2713,6 +2741,7 @@ static struct iwl_hcmd_utils_ops iwl3945_hcmd_utils = {
 	.build_addsta_hcmd = iwl3945_build_addsta_hcmd,
 	.tx_cmd_protection = iwlcore_tx_cmd_protection,
 	.request_scan = iwl3945_request_scan,
+	.post_scan = iwl3945_post_scan,
 };
 
 static const struct iwl_ops iwl3945_ops = {
@@ -2724,6 +2753,7 @@ static const struct iwl_ops iwl3945_ops = {
 
 static struct iwl_base_params iwl3945_base_params = {
 	.eeprom_size = IWL3945_EEPROM_IMG_SIZE,
+	.num_of_queues = IWL39_NUM_QUEUES,
 	.pll_cfg_val = CSR39_ANA_PLL_CFG_VAL,
 	.set_l0s = false,
 	.use_bsm = true,
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h
index 98509c5e708d..09391f0ee61f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.h
@@ -138,8 +138,6 @@ enum iwl3945_antenna {
 #define	DEFAULT_SHORT_RETRY_LIMIT 7U
 #define	DEFAULT_LONG_RETRY_LIMIT  4U
 
-#include "iwl-agn-rs.h"
-
 #define IWL_TX_FIFO_AC0	0
 #define IWL_TX_FIFO_AC1	1
 #define IWL_TX_FIFO_AC2	2
@@ -271,6 +269,9 @@ extern void iwl3945_post_associate(struct iwl_priv *priv,
 extern void iwl3945_config_ap(struct iwl_priv *priv,
 			      struct ieee80211_vif *vif);
 
+extern int iwl3945_commit_rxon(struct iwl_priv *priv,
+			       struct iwl_rxon_context *ctx);
+
 /**
  * iwl3945_hw_find_station - Find station id for a given BSSID
  * @bssid: MAC address of station ID to find
@@ -296,6 +297,10 @@ extern int iwl3945_rs_next_rate(struct iwl_priv *priv, int rate);
 
 /* scanning */
 int iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif);
+void iwl3945_post_scan(struct iwl_priv *priv);
+
+/* rates */
+extern const struct iwl3945_rate_info iwl3945_rates[IWL_RATE_COUNT_3945];
 
 /* Requires full declaration of iwl_priv before including */
 #include "iwl-io.h"
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index 834c2f9c15d7..b207e3e9299f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -43,7 +43,7 @@
 #include "iwl-core.h"
 #include "iwl-io.h"
 #include "iwl-helpers.h"
-#include "iwl-calib.h"
+#include "iwl-agn-calib.h"
 #include "iwl-sta.h"
 #include "iwl-agn-led.h"
 #include "iwl-agn.h"
@@ -669,8 +669,8 @@ static int iwl4965_hw_set_hw_params(struct iwl_priv *priv)
 	priv->hw_params.rx_chains_num = num_of_ant(priv->cfg->valid_rx_ant);
 	priv->hw_params.valid_tx_ant = priv->cfg->valid_tx_ant;
 	priv->hw_params.valid_rx_ant = priv->cfg->valid_rx_ant;
-	if (priv->cfg->ops->lib->temp_ops.set_ct_kill)
-		priv->cfg->ops->lib->temp_ops.set_ct_kill(priv);
+
+	iwl4965_set_ct_threshold(priv);
 
 	priv->hw_params.sens = &iwl4965_sensitivity;
 	priv->hw_params.beacon_time_tsf_bits = IWLAGN_EXT_BEACON_TIME_POS;
@@ -2216,11 +2216,23 @@ static void iwl4965_cancel_deferred_work(struct iwl_priv *priv)
 
 static struct iwl_hcmd_ops iwl4965_hcmd = {
 	.rxon_assoc = iwl4965_send_rxon_assoc,
-	.commit_rxon = iwl_commit_rxon,
-	.set_rxon_chain = iwl_set_rxon_chain,
+	.commit_rxon = iwlagn_commit_rxon,
+	.set_rxon_chain = iwlagn_set_rxon_chain,
 	.send_bt_config = iwl_send_bt_config,
 };
 
+static void iwl4965_post_scan(struct iwl_priv *priv)
+{
+	struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
+
+	/*
+	 * Since setting the RXON may have been deferred while
+	 * performing the scan, fire one off if needed
+	 */
+	if (memcmp(&ctx->staging, &ctx->active, sizeof(ctx->staging)))
+		iwlcore_commit_rxon(priv, ctx);
+}
+
 static struct iwl_hcmd_utils_ops iwl4965_hcmd_utils = {
 	.get_hcmd_size = iwl4965_get_hcmd_size,
 	.build_addsta_hcmd = iwl4965_build_addsta_hcmd,
@@ -2229,6 +2241,7 @@ static struct iwl_hcmd_utils_ops iwl4965_hcmd_utils = {
 	.tx_cmd_protection = iwlcore_tx_cmd_protection,
 	.calc_rssi = iwl4965_calc_rssi,
 	.request_scan = iwlagn_request_scan,
+	.post_scan = iwl4965_post_scan,
 };
 
 static struct iwl_lib_ops iwl4965_lib = {
@@ -2253,9 +2266,7 @@ static struct iwl_lib_ops iwl4965_lib = {
 	.set_channel_switch = iwl4965_hw_channel_switch,
 	.apm_ops = {
 		.init = iwl_apm_init,
-		.stop = iwl_apm_stop,
 		.config = iwl4965_nic_config,
-		.set_pwr_src = iwl_set_pwr_src,
 	},
 	.eeprom_ops = {
 		.regulatory_bands = {
@@ -2267,7 +2278,6 @@ static struct iwl_lib_ops iwl4965_lib = {
 			EEPROM_4965_REGULATORY_BAND_24_HT40_CHANNELS,
 			EEPROM_4965_REGULATORY_BAND_52_HT40_CHANNELS
 		},
-		.verify_signature  = iwlcore_eeprom_verify_signature,
 		.acquire_semaphore = iwlcore_eeprom_acquire_semaphore,
 		.release_semaphore = iwlcore_eeprom_release_semaphore,
 		.calib_version = iwl4965_eeprom_calib_version,
@@ -2280,7 +2290,6 @@ static struct iwl_lib_ops iwl4965_lib = {
 	.isr = iwl_isr_legacy,
 	.temp_ops = {
 		.temperature = iwl4965_temperature_calib,
-		.set_ct_kill = iwl4965_set_ct_threshold,
 	},
 	.manage_ibss_station = iwlagn_manage_ibss_station,
 	.update_bcast_stations = iwl_update_bcast_stations,
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index 1b25ad63b5c1..fd9fbc93ea1b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -195,8 +195,7 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
 	priv->hw_params.valid_tx_ant = priv->cfg->valid_tx_ant;
 	priv->hw_params.valid_rx_ant = priv->cfg->valid_rx_ant;
 
-	if (priv->cfg->ops->lib->temp_ops.set_ct_kill)
-		priv->cfg->ops->lib->temp_ops.set_ct_kill(priv);
+	iwl5000_set_ct_threshold(priv);
 
 	/* Set initial sensitivity parameters */
 	/* Set initial calibration set */
@@ -242,8 +241,7 @@ static int iwl5150_hw_set_hw_params(struct iwl_priv *priv)
 	priv->hw_params.valid_tx_ant = priv->cfg->valid_tx_ant;
 	priv->hw_params.valid_rx_ant = priv->cfg->valid_rx_ant;
 
-	if (priv->cfg->ops->lib->temp_ops.set_ct_kill)
-		priv->cfg->ops->lib->temp_ops.set_ct_kill(priv);
+	iwl5150_set_ct_threshold(priv);
 
 	/* Set initial sensitivity parameters */
 	/* Set initial calibration set */
@@ -370,9 +368,7 @@ static struct iwl_lib_ops iwl5000_lib = {
 	.set_channel_switch = iwl5000_hw_channel_switch,
 	.apm_ops = {
 		.init = iwl_apm_init,
-		.stop = iwl_apm_stop,
 		.config = iwl5000_nic_config,
-		.set_pwr_src = iwl_set_pwr_src,
 	},
 	.eeprom_ops = {
 		.regulatory_bands = {
@@ -384,7 +380,6 @@ static struct iwl_lib_ops iwl5000_lib = {
 			EEPROM_REG_BAND_24_HT40_CHANNELS,
 			EEPROM_REG_BAND_52_HT40_CHANNELS
 		},
-		.verify_signature  = iwlcore_eeprom_verify_signature,
 		.acquire_semaphore = iwlcore_eeprom_acquire_semaphore,
 		.release_semaphore = iwlcore_eeprom_release_semaphore,
 		.calib_version	= iwlagn_eeprom_calib_version,
@@ -395,7 +390,6 @@ static struct iwl_lib_ops iwl5000_lib = {
 	.config_ap = iwl_config_ap,
 	.temp_ops = {
 		.temperature = iwlagn_temperature,
-		.set_ct_kill = iwl5000_set_ct_threshold,
 	 },
 	.manage_ibss_station = iwlagn_manage_ibss_station,
 	.update_bcast_stations = iwl_update_bcast_stations,
@@ -442,9 +436,7 @@ static struct iwl_lib_ops iwl5150_lib = {
 	.set_channel_switch = iwl5000_hw_channel_switch,
 	.apm_ops = {
 		.init = iwl_apm_init,
-		.stop = iwl_apm_stop,
 		.config = iwl5000_nic_config,
-		.set_pwr_src = iwl_set_pwr_src,
 	},
 	.eeprom_ops = {
 		.regulatory_bands = {
@@ -456,7 +448,6 @@ static struct iwl_lib_ops iwl5150_lib = {
 			EEPROM_REG_BAND_24_HT40_CHANNELS,
 			EEPROM_REG_BAND_52_HT40_CHANNELS
 		},
-		.verify_signature  = iwlcore_eeprom_verify_signature,
 		.acquire_semaphore = iwlcore_eeprom_acquire_semaphore,
 		.release_semaphore = iwlcore_eeprom_release_semaphore,
 		.calib_version	= iwlagn_eeprom_calib_version,
@@ -467,7 +458,6 @@ static struct iwl_lib_ops iwl5150_lib = {
 	.config_ap = iwl_config_ap,
 	.temp_ops = {
 		.temperature = iwl5150_temperature,
-		.set_ct_kill = iwl5150_set_ct_threshold,
 	 },
 	.manage_ibss_station = iwlagn_manage_ibss_station,
 	.update_bcast_stations = iwl_update_bcast_stations,
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c
index 6261aec5ebdc..11e6532fc573 100644
--- a/drivers/net/wireless/iwlwifi/iwl-6000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-6000.c
@@ -192,8 +192,7 @@ static int iwl6000_hw_set_hw_params(struct iwl_priv *priv)
 	priv->hw_params.valid_tx_ant = priv->cfg->valid_tx_ant;
 	priv->hw_params.valid_rx_ant = priv->cfg->valid_rx_ant;
 
-	if (priv->cfg->ops->lib->temp_ops.set_ct_kill)
-		priv->cfg->ops->lib->temp_ops.set_ct_kill(priv);
+	iwl6000_set_ct_threshold(priv);
 
 	/* Set initial sensitivity parameters */
 	/* Set initial calibration set */
@@ -205,6 +204,8 @@ static int iwl6000_hw_set_hw_params(struct iwl_priv *priv)
 		BIT(IWL_CALIB_BASE_BAND);
 	if (priv->cfg->need_dc_calib)
 		priv->hw_params.calib_rt_cfg |= BIT(IWL_CALIB_CFG_DC_IDX);
+	if (priv->cfg->need_temp_offset_calib)
+		priv->hw_params.calib_init_cfg |= BIT(IWL_CALIB_TEMP_OFFSET);
 
 	priv->hw_params.beacon_time_tsf_bits = IWLAGN_EXT_BEACON_TIME_POS;
 
@@ -309,9 +310,7 @@ static struct iwl_lib_ops iwl6000_lib = {
 	.set_channel_switch = iwl6000_hw_channel_switch,
 	.apm_ops = {
 		.init = iwl_apm_init,
-		.stop = iwl_apm_stop,
 		.config = iwl6000_nic_config,
-		.set_pwr_src = iwl_set_pwr_src,
 	},
 	.eeprom_ops = {
 		.regulatory_bands = {
@@ -323,7 +322,6 @@ static struct iwl_lib_ops iwl6000_lib = {
 			EEPROM_6000_REG_BAND_24_HT40_CHANNELS,
 			EEPROM_REG_BAND_52_HT40_CHANNELS
 		},
-		.verify_signature  = iwlcore_eeprom_verify_signature,
 		.acquire_semaphore = iwlcore_eeprom_acquire_semaphore,
 		.release_semaphore = iwlcore_eeprom_release_semaphore,
 		.calib_version	= iwlagn_eeprom_calib_version,
@@ -335,7 +333,6 @@ static struct iwl_lib_ops iwl6000_lib = {
 	.config_ap = iwl_config_ap,
 	.temp_ops = {
 		.temperature = iwlagn_temperature,
-		.set_ct_kill = iwl6000_set_ct_threshold,
 	 },
 	.manage_ibss_station = iwlagn_manage_ibss_station,
 	.update_bcast_stations = iwl_update_bcast_stations,
@@ -384,9 +381,7 @@ static struct iwl_lib_ops iwl6000g2b_lib = {
 	.set_channel_switch = iwl6000_hw_channel_switch,
 	.apm_ops = {
 		.init = iwl_apm_init,
-		.stop = iwl_apm_stop,
 		.config = iwl6000_nic_config,
-		.set_pwr_src = iwl_set_pwr_src,
 	},
 	.eeprom_ops = {
 		.regulatory_bands = {
@@ -398,7 +393,6 @@ static struct iwl_lib_ops iwl6000g2b_lib = {
 			EEPROM_6000_REG_BAND_24_HT40_CHANNELS,
 			EEPROM_REG_BAND_52_HT40_CHANNELS
 		},
-		.verify_signature  = iwlcore_eeprom_verify_signature,
 		.acquire_semaphore = iwlcore_eeprom_acquire_semaphore,
 		.release_semaphore = iwlcore_eeprom_release_semaphore,
 		.calib_version	= iwlagn_eeprom_calib_version,
@@ -410,7 +404,6 @@ static struct iwl_lib_ops iwl6000g2b_lib = {
 	.config_ap = iwl_config_ap,
 	.temp_ops = {
 		.temperature = iwlagn_temperature,
-		.set_ct_kill = iwl6000_set_ct_threshold,
 	 },
 	.manage_ibss_station = iwlagn_manage_ibss_station,
 	.update_bcast_stations = iwl_update_bcast_stations,
@@ -516,6 +509,28 @@ static struct iwl_base_params iwl6050_base_params = {
 	.sensitivity_calib_by_driver = true,
 	.chain_noise_calib_by_driver = true,
 };
+static struct iwl_base_params iwl6000_coex_base_params = {
+	.eeprom_size = OTP_LOW_IMAGE_SIZE,
+	.num_of_queues = IWLAGN_NUM_QUEUES,
+	.num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
+	.pll_cfg_val = 0,
+	.set_l0s = true,
+	.use_bsm = false,
+	.max_ll_items = OTP_MAX_LL_ITEMS_6x00,
+	.shadow_ram_support = true,
+	.led_compensation = 51,
+	.chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
+	.supports_idle = true,
+	.adv_thermal_throttle = true,
+	.support_ct_kill_exit = true,
+	.plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
+	.chain_noise_scale = 1000,
+	.monitor_recover_period = IWL_LONG_MONITORING_PERIOD,
+	.max_event_log_size = 512,
+	.ucode_tracing = true,
+	.sensitivity_calib_by_driver = true,
+	.chain_noise_calib_by_driver = true,
+};
 
 static struct iwl_ht_params iwl6000_ht_params = {
 	.ht_greenfield_support = true,
@@ -545,6 +560,7 @@ struct iwl_cfg iwl6000g2a_2agn_cfg = {
 	.base_params = &iwl6000_base_params,
 	.ht_params = &iwl6000_ht_params,
 	.need_dc_calib = true,
+	.need_temp_offset_calib = true,
 };
 
 struct iwl_cfg iwl6000g2a_2abg_cfg = {
@@ -561,6 +577,7 @@ struct iwl_cfg iwl6000g2a_2abg_cfg = {
 	.mod_params = &iwlagn_mod_params,
 	.base_params = &iwl6000_base_params,
 	.need_dc_calib = true,
+	.need_temp_offset_calib = true,
 };
 
 struct iwl_cfg iwl6000g2a_2bg_cfg = {
@@ -577,6 +594,7 @@ struct iwl_cfg iwl6000g2a_2bg_cfg = {
 	.mod_params = &iwlagn_mod_params,
 	.base_params = &iwl6000_base_params,
 	.need_dc_calib = true,
+	.need_temp_offset_calib = true,
 };
 
 struct iwl_cfg iwl6000g2b_2agn_cfg = {
@@ -591,10 +609,11 @@ struct iwl_cfg iwl6000g2b_2agn_cfg = {
 	.eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
 	.ops = &iwl6000g2b_ops,
 	.mod_params = &iwlagn_mod_params,
-	.base_params = &iwl6000_base_params,
+	.base_params = &iwl6000_coex_base_params,
 	.bt_params = &iwl6000_bt_params,
 	.ht_params = &iwl6000_ht_params,
 	.need_dc_calib = true,
+	.need_temp_offset_calib = true,
 	/* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
 	.scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A,
 };
@@ -611,9 +630,10 @@ struct iwl_cfg iwl6000g2b_2abg_cfg = {
 	.eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
 	.ops = &iwl6000g2b_ops,
 	.mod_params = &iwlagn_mod_params,
-	.base_params = &iwl6000_base_params,
+	.base_params = &iwl6000_coex_base_params,
 	.bt_params = &iwl6000_bt_params,
 	.need_dc_calib = true,
+	.need_temp_offset_calib = true,
 	/* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
 	.scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A,
 };
@@ -630,10 +650,11 @@ struct iwl_cfg iwl6000g2b_2bgn_cfg = {
 	.eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
 	.ops = &iwl6000g2b_ops,
 	.mod_params = &iwlagn_mod_params,
-	.base_params = &iwl6000_base_params,
+	.base_params = &iwl6000_coex_base_params,
 	.bt_params = &iwl6000_bt_params,
 	.ht_params = &iwl6000_ht_params,
 	.need_dc_calib = true,
+	.need_temp_offset_calib = true,
 	/* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
 	.scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A,
 };
@@ -650,9 +671,10 @@ struct iwl_cfg iwl6000g2b_2bg_cfg = {
 	.eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
 	.ops = &iwl6000g2b_ops,
 	.mod_params = &iwlagn_mod_params,
-	.base_params = &iwl6000_base_params,
+	.base_params = &iwl6000_coex_base_params,
 	.bt_params = &iwl6000_bt_params,
 	.need_dc_calib = true,
+	.need_temp_offset_calib = true,
 	/* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
 	.scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A,
 };
@@ -669,10 +691,11 @@ struct iwl_cfg iwl6000g2b_bgn_cfg = {
 	.eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
 	.ops = &iwl6000g2b_ops,
 	.mod_params = &iwlagn_mod_params,
-	.base_params = &iwl6000_base_params,
+	.base_params = &iwl6000_coex_base_params,
 	.bt_params = &iwl6000_bt_params,
 	.ht_params = &iwl6000_ht_params,
 	.need_dc_calib = true,
+	.need_temp_offset_calib = true,
 	/* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
 	.scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A,
 };
@@ -689,9 +712,10 @@ struct iwl_cfg iwl6000g2b_bg_cfg = {
 	.eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
 	.ops = &iwl6000g2b_ops,
 	.mod_params = &iwlagn_mod_params,
-	.base_params = &iwl6000_base_params,
+	.base_params = &iwl6000_coex_base_params,
 	.bt_params = &iwl6000_bt_params,
 	.need_dc_calib = true,
+	.need_temp_offset_calib = true,
 	/* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
 	.scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A,
 };
@@ -756,7 +780,7 @@ struct iwl_cfg iwl6050_2agn_cfg = {
 	.sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
 	.valid_tx_ant = ANT_AB,
 	.valid_rx_ant = ANT_AB,
-	.ops = &iwl6000_ops,
+	.ops = &iwl6050_ops,
 	.eeprom_ver = EEPROM_6050_EEPROM_VERSION,
 	.eeprom_calib_ver = EEPROM_6050_TX_POWER_VERSION,
 	.mod_params = &iwlagn_mod_params,
@@ -827,7 +851,7 @@ struct iwl_cfg iwl130_bgn_cfg = {
 	.eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
 	.ops = &iwl6000g2b_ops,
 	.mod_params = &iwlagn_mod_params,
-	.base_params = &iwl6000_base_params,
+	.base_params = &iwl6000_coex_base_params,
 	.bt_params = &iwl6000_bt_params,
 	.ht_params = &iwl6000_ht_params,
 	.need_dc_calib = true,
@@ -847,7 +871,7 @@ struct iwl_cfg iwl130_bg_cfg = {
 	.eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
 	.ops = &iwl6000g2b_ops,
 	.mod_params = &iwlagn_mod_params,
-	.base_params = &iwl6000_base_params,
+	.base_params = &iwl6000_coex_base_params,
 	.bt_params = &iwl6000_bt_params,
 	.need_dc_calib = true,
 	/* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c
index 4c5ab783737f..e2019e756936 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c
@@ -65,7 +65,7 @@
 
 #include "iwl-dev.h"
 #include "iwl-core.h"
-#include "iwl-calib.h"
+#include "iwl-agn-calib.h"
 
 /*****************************************************************************
  * INIT calibrations framework
diff --git a/drivers/net/wireless/iwlwifi/iwl-calib.h b/drivers/net/wireless/iwlwifi/iwl-agn-calib.h
index ba9523fbb300..e37ae7261630 100644
--- a/drivers/net/wireless/iwlwifi/iwl-calib.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-calib.h
@@ -79,4 +79,8 @@ static inline void iwl_chain_noise_reset(struct iwl_priv *priv)
 		priv->cfg->ops->utils->chain_noise_reset(priv);
 }
 
+int iwl_send_calib_results(struct iwl_priv *priv);
+int iwl_calib_set(struct iwl_calib_result *res, const u8 *buf, int len);
+void iwl_calib_free_results(struct iwl_priv *priv);
+
 #endif /* __iwl_calib_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c
new file mode 100644
index 000000000000..a650baba0809
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c
@@ -0,0 +1,454 @@
+/******************************************************************************
+ *
+ * This file is provided under a dual BSD/GPLv2 license.  When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
+ * USA
+ *
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * Contact Information:
+ *  Intel Linux Wireless <ilw@linux.intel.com>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *  * Neither the name Intel Corporation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *****************************************************************************/
+
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+
+#include <net/mac80211.h>
+
+#include "iwl-commands.h"
+#include "iwl-dev.h"
+#include "iwl-core.h"
+#include "iwl-debug.h"
+#include "iwl-agn.h"
+#include "iwl-io.h"
+
+/************************** EEPROM BANDS ****************************
+ *
+ * The iwl_eeprom_band definitions below provide the mapping from the
+ * EEPROM contents to the specific channel number supported for each
+ * band.
+ *
+ * For example, iwl_priv->eeprom.band_3_channels[4] from the band_3
+ * definition below maps to physical channel 42 in the 5.2GHz spectrum.
+ * The specific geography and calibration information for that channel
+ * is contained in the eeprom map itself.
+ *
+ * During init, we copy the eeprom information and channel map
+ * information into priv->channel_info_24/52 and priv->channel_map_24/52
+ *
+ * channel_map_24/52 provides the index in the channel_info array for a
+ * given channel.  We have to have two separate maps as there is channel
+ * overlap with the 2.4GHz and 5.2GHz spectrum as seen in band_1 and
+ * band_2
+ *
+ * A value of 0xff stored in the channel_map indicates that the channel
+ * is not supported by the hardware at all.
+ *
+ * A value of 0xfe in the channel_map indicates that the channel is not
+ * valid for Tx with the current hardware.  This means that
+ * while the system can tune and receive on a given channel, it may not
+ * be able to associate or transmit any frames on that
+ * channel.  There is no corresponding channel information for that
+ * entry.
+ *
+ *********************************************************************/
+
+/**
+ * struct iwl_txpwr_section: eeprom section information
+ * @offset: indirect address into eeprom image
+ * @count: number of "struct iwl_eeprom_enhanced_txpwr" in this section
+ * @band: band type for the section
+ * @is_common - true: common section, false: channel section
+ * @is_cck - true: cck section, false: not cck section
+ * @is_ht_40 - true: all channel in the section are HT40 channel,
+ *	       false: legacy or HT 20 MHz
+ *	       ignore if it is common section
+ * @iwl_eeprom_section_channel: channel array in the section,
+ *	       ignore if common section
+ */
+struct iwl_txpwr_section {
+	u32 offset;
+	u8 count;
+	enum ieee80211_band band;
+	bool is_common;
+	bool is_cck;
+	bool is_ht40;
+	u8 iwl_eeprom_section_channel[EEPROM_MAX_TXPOWER_SECTION_ELEMENTS];
+};
+
+/**
+ * section 1 - 3 are regulatory tx power apply to all channels based on
+ *    modulation: CCK, OFDM
+ *    Band: 2.4GHz, 5.2GHz
+ * section 4 - 10 are regulatory tx power apply to specified channels
+ *    For example:
+ *	1L - Channel 1 Legacy
+ *	1HT - Channel 1 HT
+ *	(1,+1) - Channel 1 HT40 "_above_"
+ *
+ * Section 1: all CCK channels
+ * Section 2: all 2.4 GHz OFDM (Legacy, HT and HT40) channels
+ * Section 3: all 5.2 GHz OFDM (Legacy, HT and HT40) channels
+ * Section 4: 2.4 GHz 20MHz channels: 1L, 1HT, 2L, 2HT, 10L, 10HT, 11L, 11HT
+ * Section 5: 2.4 GHz 40MHz channels: (1,+1) (2,+1) (6,+1) (7,+1) (9,+1)
+ * Section 6: 5.2 GHz 20MHz channels: 36L, 64L, 100L, 36HT, 64HT, 100HT
+ * Section 7: 5.2 GHz 40MHz channels: (36,+1) (60,+1) (100,+1)
+ * Section 8: 2.4 GHz channel: 13L, 13HT
+ * Section 9: 2.4 GHz channel: 140L, 140HT
+ * Section 10: 2.4 GHz 40MHz channels: (132,+1)  (44,+1)
+ *
+ */
+static const struct iwl_txpwr_section enhinfo[] = {
+	{ EEPROM_LB_CCK_20_COMMON, 1, IEEE80211_BAND_2GHZ, true, true, false },
+	{ EEPROM_LB_OFDM_COMMON, 3, IEEE80211_BAND_2GHZ, true, false, false },
+	{ EEPROM_HB_OFDM_COMMON, 3, IEEE80211_BAND_5GHZ, true, false, false },
+	{ EEPROM_LB_OFDM_20_BAND, 8, IEEE80211_BAND_2GHZ,
+		false, false, false,
+		{1, 1, 2, 2, 10, 10, 11, 11 } },
+	{ EEPROM_LB_OFDM_HT40_BAND, 5, IEEE80211_BAND_2GHZ,
+		false, false, true,
+		{ 1, 2, 6, 7, 9 } },
+	{ EEPROM_HB_OFDM_20_BAND, 6, IEEE80211_BAND_5GHZ,
+		false, false, false,
+		{ 36, 64, 100, 36, 64, 100 } },
+	{ EEPROM_HB_OFDM_HT40_BAND, 3, IEEE80211_BAND_5GHZ,
+		false, false, true,
+		{ 36, 60, 100 } },
+	{ EEPROM_LB_OFDM_20_CHANNEL_13, 2, IEEE80211_BAND_2GHZ,
+		false, false, false,
+		{ 13, 13 } },
+	{ EEPROM_HB_OFDM_20_CHANNEL_140, 2, IEEE80211_BAND_5GHZ,
+		false, false, false,
+		{ 140, 140 } },
+	{ EEPROM_HB_OFDM_HT40_BAND_1, 2, IEEE80211_BAND_5GHZ,
+		false, false, true,
+		{ 132, 44 } },
+};
+
+/******************************************************************************
+ *
+ * EEPROM related functions
+ *
+******************************************************************************/
+
+/*
+ * The device's EEPROM semaphore prevents conflicts between driver and uCode
+ * when accessing the EEPROM; each access is a series of pulses to/from the
+ * EEPROM chip, not a single event, so even reads could conflict if they
+ * weren't arbitrated by the semaphore.
+ */
+int iwlcore_eeprom_acquire_semaphore(struct iwl_priv *priv)
+{
+	u16 count;
+	int ret;
+
+	for (count = 0; count < EEPROM_SEM_RETRY_LIMIT; count++) {
+		/* Request semaphore */
+		iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
+			    CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM);
+
+		/* See if we got it */
+		ret = iwl_poll_bit(priv, CSR_HW_IF_CONFIG_REG,
+				CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM,
+				CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM,
+				EEPROM_SEM_TIMEOUT);
+		if (ret >= 0) {
+			IWL_DEBUG_IO(priv,
+				"Acquired semaphore after %d tries.\n",
+				count+1);
+			return ret;
+		}
+	}
+
+	return ret;
+}
+
+void iwlcore_eeprom_release_semaphore(struct iwl_priv *priv)
+{
+	iwl_clear_bit(priv, CSR_HW_IF_CONFIG_REG,
+		CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM);
+
+}
+
+int iwl_eeprom_check_version(struct iwl_priv *priv)
+{
+	u16 eeprom_ver;
+	u16 calib_ver;
+
+	eeprom_ver = iwl_eeprom_query16(priv, EEPROM_VERSION);
+	calib_ver = priv->cfg->ops->lib->eeprom_ops.calib_version(priv);
+
+	if (eeprom_ver < priv->cfg->eeprom_ver ||
+	    calib_ver < priv->cfg->eeprom_calib_ver)
+		goto err;
+
+	IWL_INFO(priv, "device EEPROM VER=0x%x, CALIB=0x%x\n",
+		 eeprom_ver, calib_ver);
+
+	return 0;
+err:
+	IWL_ERR(priv, "Unsupported (too old) EEPROM VER=0x%x < 0x%x "
+		  "CALIB=0x%x < 0x%x\n",
+		  eeprom_ver, priv->cfg->eeprom_ver,
+		  calib_ver,  priv->cfg->eeprom_calib_ver);
+	return -EINVAL;
+
+}
+
+void iwl_eeprom_get_mac(const struct iwl_priv *priv, u8 *mac)
+{
+	const u8 *addr = priv->cfg->ops->lib->eeprom_ops.query_addr(priv,
+					EEPROM_MAC_ADDRESS);
+	memcpy(mac, addr, ETH_ALEN);
+}
+
+/**
+ * iwl_get_max_txpower_avg - get the highest tx power from all chains.
+ *     find the highest tx power from all chains for the channel
+ */
+static s8 iwl_get_max_txpower_avg(struct iwl_priv *priv,
+		struct iwl_eeprom_enhanced_txpwr *enhanced_txpower,
+		int element, s8 *max_txpower_in_half_dbm)
+{
+	s8 max_txpower_avg = 0; /* (dBm) */
+
+	IWL_DEBUG_INFO(priv, "%d - "
+			"chain_a: %d dB chain_b: %d dB "
+			"chain_c: %d dB mimo2: %d dB mimo3: %d dB\n",
+			element,
+			enhanced_txpower[element].chain_a_max >> 1,
+			enhanced_txpower[element].chain_b_max >> 1,
+			enhanced_txpower[element].chain_c_max >> 1,
+			enhanced_txpower[element].mimo2_max >> 1,
+			enhanced_txpower[element].mimo3_max >> 1);
+	/* Take the highest tx power from any valid chains */
+	if ((priv->cfg->valid_tx_ant & ANT_A) &&
+	    (enhanced_txpower[element].chain_a_max > max_txpower_avg))
+		max_txpower_avg = enhanced_txpower[element].chain_a_max;
+	if ((priv->cfg->valid_tx_ant & ANT_B) &&
+	    (enhanced_txpower[element].chain_b_max > max_txpower_avg))
+		max_txpower_avg = enhanced_txpower[element].chain_b_max;
+	if ((priv->cfg->valid_tx_ant & ANT_C) &&
+	    (enhanced_txpower[element].chain_c_max > max_txpower_avg))
+		max_txpower_avg = enhanced_txpower[element].chain_c_max;
+	if (((priv->cfg->valid_tx_ant == ANT_AB) |
+	    (priv->cfg->valid_tx_ant == ANT_BC) |
+	    (priv->cfg->valid_tx_ant == ANT_AC)) &&
+	    (enhanced_txpower[element].mimo2_max > max_txpower_avg))
+		max_txpower_avg =  enhanced_txpower[element].mimo2_max;
+	if ((priv->cfg->valid_tx_ant == ANT_ABC) &&
+	    (enhanced_txpower[element].mimo3_max > max_txpower_avg))
+		max_txpower_avg = enhanced_txpower[element].mimo3_max;
+
+	/*
+	 * max. tx power in EEPROM is in 1/2 dBm format
+	 * convert from 1/2 dBm to dBm (round-up convert)
+	 * but we also do not want to loss 1/2 dBm resolution which
+	 * will impact performance
+	 */
+	*max_txpower_in_half_dbm = max_txpower_avg;
+	return (max_txpower_avg & 0x01) + (max_txpower_avg >> 1);
+}
+
+/**
+ * iwl_update_common_txpower: update channel tx power
+ *     update tx power per band based on EEPROM enhanced tx power info.
+ */
+static s8 iwl_update_common_txpower(struct iwl_priv *priv,
+		struct iwl_eeprom_enhanced_txpwr *enhanced_txpower,
+		int section, int element, s8 *max_txpower_in_half_dbm)
+{
+	struct iwl_channel_info *ch_info;
+	int ch;
+	bool is_ht40 = false;
+	s8 max_txpower_avg; /* (dBm) */
+
+	/* it is common section, contain all type (Legacy, HT and HT40)
+	 * based on the element in the section to determine
+	 * is it HT 40 or not
+	 */
+	if (element == EEPROM_TXPOWER_COMMON_HT40_INDEX)
+		is_ht40 = true;
+	max_txpower_avg =
+		iwl_get_max_txpower_avg(priv, enhanced_txpower,
+					element, max_txpower_in_half_dbm);
+
+	ch_info = priv->channel_info;
+
+	for (ch = 0; ch < priv->channel_count; ch++) {
+		/* find matching band and update tx power if needed */
+		if ((ch_info->band == enhinfo[section].band) &&
+		    (ch_info->max_power_avg < max_txpower_avg) &&
+		    (!is_ht40)) {
+			/* Update regulatory-based run-time data */
+			ch_info->max_power_avg = ch_info->curr_txpow =
+				max_txpower_avg;
+			ch_info->scan_power = max_txpower_avg;
+		}
+		if ((ch_info->band == enhinfo[section].band) && is_ht40 &&
+		    (ch_info->ht40_max_power_avg < max_txpower_avg)) {
+			/* Update regulatory-based run-time data */
+			ch_info->ht40_max_power_avg = max_txpower_avg;
+		}
+		ch_info++;
+	}
+	return max_txpower_avg;
+}
+
+/**
+ * iwl_update_channel_txpower: update channel tx power
+ *      update channel tx power based on EEPROM enhanced tx power info.
+ */
+static s8 iwl_update_channel_txpower(struct iwl_priv *priv,
+		struct iwl_eeprom_enhanced_txpwr *enhanced_txpower,
+		int section, int element, s8 *max_txpower_in_half_dbm)
+{
+	struct iwl_channel_info *ch_info;
+	int ch;
+	u8 channel;
+	s8 max_txpower_avg; /* (dBm) */
+
+	channel = enhinfo[section].iwl_eeprom_section_channel[element];
+	max_txpower_avg =
+		iwl_get_max_txpower_avg(priv, enhanced_txpower,
+					element, max_txpower_in_half_dbm);
+
+	ch_info = priv->channel_info;
+	for (ch = 0; ch < priv->channel_count; ch++) {
+		/* find matching channel and update tx power if needed */
+		if (ch_info->channel == channel) {
+			if ((ch_info->max_power_avg < max_txpower_avg) &&
+			    (!enhinfo[section].is_ht40)) {
+				/* Update regulatory-based run-time data */
+				ch_info->max_power_avg = max_txpower_avg;
+				ch_info->curr_txpow = max_txpower_avg;
+				ch_info->scan_power = max_txpower_avg;
+			}
+			if ((enhinfo[section].is_ht40) &&
+			    (ch_info->ht40_max_power_avg < max_txpower_avg)) {
+				/* Update regulatory-based run-time data */
+				ch_info->ht40_max_power_avg = max_txpower_avg;
+			}
+			break;
+		}
+		ch_info++;
+	}
+	return max_txpower_avg;
+}
+
+/**
+ * iwlcore_eeprom_enhanced_txpower: process enhanced tx power info
+ */
+void iwlcore_eeprom_enhanced_txpower(struct iwl_priv *priv)
+{
+	int eeprom_section_count = 0;
+	int section, element;
+	struct iwl_eeprom_enhanced_txpwr *enhanced_txpower;
+	u32 offset;
+	s8 max_txpower_avg; /* (dBm) */
+	s8 max_txpower_in_half_dbm; /* (half-dBm) */
+
+	/* Loop through all the sections
+	 * adjust bands and channel's max tx power
+	 * Set the tx_power_user_lmt to the highest power
+	 * supported by any channels and chains
+	 */
+	for (section = 0; section < ARRAY_SIZE(enhinfo); section++) {
+		eeprom_section_count = enhinfo[section].count;
+		offset = enhinfo[section].offset;
+		enhanced_txpower = (struct iwl_eeprom_enhanced_txpwr *)
+				iwl_eeprom_query_addr(priv, offset);
+
+		/*
+		 * check for valid entry -
+		 * different version of EEPROM might contain different set
+		 * of enhanced tx power table
+		 * always check for valid entry before process
+		 * the information
+		 */
+		if (!enhanced_txpower->common || enhanced_txpower->reserved)
+			continue;
+
+		for (element = 0; element < eeprom_section_count; element++) {
+			if (enhinfo[section].is_common)
+				max_txpower_avg =
+					iwl_update_common_txpower(priv,
+						enhanced_txpower, section,
+						element,
+						&max_txpower_in_half_dbm);
+			else
+				max_txpower_avg =
+					iwl_update_channel_txpower(priv,
+						enhanced_txpower, section,
+						element,
+						&max_txpower_in_half_dbm);
+
+			/* Update the tx_power_user_lmt to the highest power
+			 * supported by any channel */
+			if (max_txpower_avg > priv->tx_power_user_lmt)
+				priv->tx_power_user_lmt = max_txpower_avg;
+
+			/*
+			 * Update the tx_power_lmt_in_half_dbm to
+			 * the highest power supported by any channel
+			 */
+			if (max_txpower_in_half_dbm >
+			    priv->tx_power_lmt_in_half_dbm)
+				priv->tx_power_lmt_in_half_dbm =
+					max_txpower_in_half_dbm;
+		}
+	}
+}
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c
index 9ca6c91eaae6..ffb2f4111ad0 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c
@@ -360,8 +360,8 @@ static int iwlagn_set_pan_params(struct iwl_priv *priv)
 
 struct iwl_hcmd_ops iwlagn_hcmd = {
 	.rxon_assoc = iwlagn_send_rxon_assoc,
-	.commit_rxon = iwl_commit_rxon,
-	.set_rxon_chain = iwl_set_rxon_chain,
+	.commit_rxon = iwlagn_commit_rxon,
+	.set_rxon_chain = iwlagn_set_rxon_chain,
 	.set_tx_ant = iwlagn_send_tx_ant_config,
 	.send_bt_config = iwl_send_bt_config,
 	.set_pan_params = iwlagn_set_pan_params,
@@ -369,8 +369,8 @@ struct iwl_hcmd_ops iwlagn_hcmd = {
 
 struct iwl_hcmd_ops iwlagn_bt_hcmd = {
 	.rxon_assoc = iwlagn_send_rxon_assoc,
-	.commit_rxon = iwl_commit_rxon,
-	.set_rxon_chain = iwl_set_rxon_chain,
+	.commit_rxon = iwlagn_commit_rxon,
+	.set_rxon_chain = iwlagn_set_rxon_chain,
 	.set_tx_ant = iwlagn_send_tx_ant_config,
 	.send_bt_config = iwlagn_send_advance_bt_config,
 	.set_pan_params = iwlagn_set_pan_params,
@@ -384,4 +384,5 @@ struct iwl_hcmd_utils_ops iwlagn_hcmd_utils = {
 	.tx_cmd_protection = iwlagn_tx_cmd_protection,
 	.calc_rssi = iwlagn_calc_rssi,
 	.request_scan = iwlagn_request_scan,
+	.post_scan = iwlagn_post_scan,
 };
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
index f5445d575fec..b555edd53354 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
@@ -685,6 +685,23 @@ int iwlagn_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
 	return 0;
 }
 
+static void iwlagn_set_pwr_vmain(struct iwl_priv *priv)
+{
+/*
+ * (for documentation purposes)
+ * to set power to V_AUX, do:
+
+		if (pci_pme_capable(priv->pci_dev, PCI_D3cold))
+			iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG,
+					       APMG_PS_CTRL_VAL_PWR_SRC_VAUX,
+					       ~APMG_PS_CTRL_MSK_PWR_SRC);
+ */
+
+	iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG,
+			       APMG_PS_CTRL_VAL_PWR_SRC_VMAIN,
+			       ~APMG_PS_CTRL_MSK_PWR_SRC);
+}
+
 int iwlagn_hw_nic_init(struct iwl_priv *priv)
 {
 	unsigned long flags;
@@ -700,7 +717,7 @@ int iwlagn_hw_nic_init(struct iwl_priv *priv)
 
 	spin_unlock_irqrestore(&priv->lock, flags);
 
-	ret = priv->cfg->ops->lib->apm_ops.set_pwr_src(priv, IWL_PWR_SRC_VMAIN);
+	iwlagn_set_pwr_vmain(priv);
 
 	priv->cfg->ops->lib->apm_ops.config(priv);
 
@@ -1430,35 +1447,35 @@ int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
 		if (priv->cfg->bt_params &&
 		    priv->cfg->bt_params->advanced_bt_coexist)
 			scan->tx_cmd.tx_flags |= TX_CMD_FLG_IGNORE_BT;
-		scan->good_CRC_th = IWL_GOOD_CRC_TH_DISABLED;
 		break;
 	case IEEE80211_BAND_5GHZ:
 		rate = IWL_RATE_6M_PLCP;
-		/*
-		 * If active scanning is requested but a certain channel is
-		 * marked passive, we can do active scanning if we detect
-		 * transmissions.
-		 *
-		 * There is an issue with some firmware versions that triggers
-		 * a sysassert on a "good CRC threshold" of zero (== disabled),
-		 * on a radar channel even though this means that we should NOT
-		 * send probes.
-		 *
-		 * The "good CRC threshold" is the number of frames that we
-		 * need to receive during our dwell time on a channel before
-		 * sending out probes -- setting this to a huge value will
-		 * mean we never reach it, but at the same time work around
-		 * the aforementioned issue. Thus use IWL_GOOD_CRC_TH_NEVER
-		 * here instead of IWL_GOOD_CRC_TH_DISABLED.
-		 */
-		scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH_DEFAULT :
-						IWL_GOOD_CRC_TH_NEVER;
 		break;
 	default:
 		IWL_WARN(priv, "Invalid scan band\n");
 		return -EIO;
 	}
 
+	/*
+	 * If active scanning is requested but a certain channel is
+	 * marked passive, we can do active scanning if we detect
+	 * transmissions.
+	 *
+	 * There is an issue with some firmware versions that triggers
+	 * a sysassert on a "good CRC threshold" of zero (== disabled),
+	 * on a radar channel even though this means that we should NOT
+	 * send probes.
+	 *
+	 * The "good CRC threshold" is the number of frames that we
+	 * need to receive during our dwell time on a channel before
+	 * sending out probes -- setting this to a huge value will
+	 * mean we never reach it, but at the same time work around
+	 * the aforementioned issue. Thus use IWL_GOOD_CRC_TH_NEVER
+	 * here instead of IWL_GOOD_CRC_TH_DISABLED.
+	 */
+	scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH_DEFAULT :
+					IWL_GOOD_CRC_TH_NEVER;
+
 	band = priv->scan_band;
 
 	if (priv->cfg->scan_rx_antennas[band])
@@ -1548,13 +1565,15 @@ int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
 	cmd.data = scan;
 	scan->len = cpu_to_le16(cmd.len);
 
+	/* set scan bit here for PAN params */
+	set_bit(STATUS_SCAN_HW, &priv->status);
+
 	if (priv->cfg->ops->hcmd->set_pan_params) {
 		ret = priv->cfg->ops->hcmd->set_pan_params(priv);
 		if (ret)
 			return ret;
 	}
 
-	set_bit(STATUS_SCAN_HW, &priv->status);
 	ret = iwl_send_cmd_sync(priv, &cmd);
 	if (ret) {
 		clear_bit(STATUS_SCAN_HW, &priv->status);
@@ -1565,15 +1584,31 @@ int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
 	return ret;
 }
 
+void iwlagn_post_scan(struct iwl_priv *priv)
+{
+	struct iwl_rxon_context *ctx;
+
+	/*
+	 * Since setting the RXON may have been deferred while
+	 * performing the scan, fire one off if needed
+	 */
+	for_each_context(priv, ctx)
+		if (memcmp(&ctx->staging, &ctx->active, sizeof(ctx->staging)))
+			iwlagn_commit_rxon(priv, ctx);
+
+	if (priv->cfg->ops->hcmd->set_pan_params)
+		priv->cfg->ops->hcmd->set_pan_params(priv);
+}
+
 int iwlagn_manage_ibss_station(struct iwl_priv *priv,
 			       struct ieee80211_vif *vif, bool add)
 {
 	struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv;
 
 	if (add)
-		return iwl_add_bssid_station(priv, vif_priv->ctx,
-					     vif->bss_conf.bssid, true,
-					     &vif_priv->ibss_bssid_sta_id);
+		return iwlagn_add_bssid_station(priv, vif_priv->ctx,
+						vif->bss_conf.bssid,
+						&vif_priv->ibss_bssid_sta_id);
 	return iwl_remove_station(priv, vif_priv->ibss_bssid_sta_id,
 				  vif->bss_conf.bssid);
 }
@@ -2049,3 +2084,290 @@ void iwlagn_bt_cancel_deferred_work(struct iwl_priv *priv)
 {
 	cancel_work_sync(&priv->bt_traffic_change_work);
 }
+
+static bool is_single_rx_stream(struct iwl_priv *priv)
+{
+	return priv->current_ht_config.smps == IEEE80211_SMPS_STATIC ||
+	       priv->current_ht_config.single_chain_sufficient;
+}
+
+#define IWL_NUM_RX_CHAINS_MULTIPLE	3
+#define IWL_NUM_RX_CHAINS_SINGLE	2
+#define IWL_NUM_IDLE_CHAINS_DUAL	2
+#define IWL_NUM_IDLE_CHAINS_SINGLE	1
+
+/*
+ * Determine how many receiver/antenna chains to use.
+ *
+ * More provides better reception via diversity.  Fewer saves power
+ * at the expense of throughput, but only when not in powersave to
+ * start with.
+ *
+ * MIMO (dual stream) requires at least 2, but works better with 3.
+ * This does not determine *which* chains to use, just how many.
+ */
+static int iwl_get_active_rx_chain_count(struct iwl_priv *priv)
+{
+	if (priv->cfg->bt_params &&
+	    priv->cfg->bt_params->advanced_bt_coexist &&
+	    (priv->bt_full_concurrent ||
+	     priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH)) {
+		/*
+		 * only use chain 'A' in bt high traffic load or
+		 * full concurrency mode
+		 */
+		return IWL_NUM_RX_CHAINS_SINGLE;
+	}
+	/* # of Rx chains to use when expecting MIMO. */
+	if (is_single_rx_stream(priv))
+		return IWL_NUM_RX_CHAINS_SINGLE;
+	else
+		return IWL_NUM_RX_CHAINS_MULTIPLE;
+}
+
+/*
+ * When we are in power saving mode, unless device support spatial
+ * multiplexing power save, use the active count for rx chain count.
+ */
+static int iwl_get_idle_rx_chain_count(struct iwl_priv *priv, int active_cnt)
+{
+	/* # Rx chains when idling, depending on SMPS mode */
+	switch (priv->current_ht_config.smps) {
+	case IEEE80211_SMPS_STATIC:
+	case IEEE80211_SMPS_DYNAMIC:
+		return IWL_NUM_IDLE_CHAINS_SINGLE;
+	case IEEE80211_SMPS_OFF:
+		return active_cnt;
+	default:
+		WARN(1, "invalid SMPS mode %d",
+		     priv->current_ht_config.smps);
+		return active_cnt;
+	}
+}
+
+/* up to 4 chains */
+static u8 iwl_count_chain_bitmap(u32 chain_bitmap)
+{
+	u8 res;
+	res = (chain_bitmap & BIT(0)) >> 0;
+	res += (chain_bitmap & BIT(1)) >> 1;
+	res += (chain_bitmap & BIT(2)) >> 2;
+	res += (chain_bitmap & BIT(3)) >> 3;
+	return res;
+}
+
+/**
+ * iwlagn_set_rxon_chain - Set up Rx chain usage in "staging" RXON image
+ *
+ * Selects how many and which Rx receivers/antennas/chains to use.
+ * This should not be used for scan command ... it puts data in wrong place.
+ */
+void iwlagn_set_rxon_chain(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
+{
+	bool is_single = is_single_rx_stream(priv);
+	bool is_cam = !test_bit(STATUS_POWER_PMI, &priv->status);
+	u8 idle_rx_cnt, active_rx_cnt, valid_rx_cnt;
+	u32 active_chains;
+	u16 rx_chain;
+
+	/* Tell uCode which antennas are actually connected.
+	 * Before first association, we assume all antennas are connected.
+	 * Just after first association, iwl_chain_noise_calibration()
+	 *    checks which antennas actually *are* connected. */
+	if (priv->chain_noise_data.active_chains)
+		active_chains = priv->chain_noise_data.active_chains;
+	else
+		active_chains = priv->hw_params.valid_rx_ant;
+
+	if (priv->cfg->bt_params &&
+	    priv->cfg->bt_params->advanced_bt_coexist &&
+	    (priv->bt_full_concurrent ||
+	     priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH)) {
+		/*
+		 * only use chain 'A' in bt high traffic load or
+		 * full concurrency mode
+		 */
+		active_chains = first_antenna(active_chains);
+	}
+
+	rx_chain = active_chains << RXON_RX_CHAIN_VALID_POS;
+
+	/* How many receivers should we use? */
+	active_rx_cnt = iwl_get_active_rx_chain_count(priv);
+	idle_rx_cnt = iwl_get_idle_rx_chain_count(priv, active_rx_cnt);
+
+
+	/* correct rx chain count according hw settings
+	 * and chain noise calibration
+	 */
+	valid_rx_cnt = iwl_count_chain_bitmap(active_chains);
+	if (valid_rx_cnt < active_rx_cnt)
+		active_rx_cnt = valid_rx_cnt;
+
+	if (valid_rx_cnt < idle_rx_cnt)
+		idle_rx_cnt = valid_rx_cnt;
+
+	rx_chain |= active_rx_cnt << RXON_RX_CHAIN_MIMO_CNT_POS;
+	rx_chain |= idle_rx_cnt  << RXON_RX_CHAIN_CNT_POS;
+
+	ctx->staging.rx_chain = cpu_to_le16(rx_chain);
+
+	if (!is_single && (active_rx_cnt >= IWL_NUM_RX_CHAINS_SINGLE) && is_cam)
+		ctx->staging.rx_chain |= RXON_RX_CHAIN_MIMO_FORCE_MSK;
+	else
+		ctx->staging.rx_chain &= ~RXON_RX_CHAIN_MIMO_FORCE_MSK;
+
+	IWL_DEBUG_ASSOC(priv, "rx_chain=0x%X active=%d idle=%d\n",
+			ctx->staging.rx_chain,
+			active_rx_cnt, idle_rx_cnt);
+
+	WARN_ON(active_rx_cnt == 0 || idle_rx_cnt == 0 ||
+		active_rx_cnt < idle_rx_cnt);
+}
+
+u8 iwl_toggle_tx_ant(struct iwl_priv *priv, u8 ant, u8 valid)
+{
+	int i;
+	u8 ind = ant;
+
+	if (priv->band == IEEE80211_BAND_2GHZ &&
+	    priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH)
+		return 0;
+
+	for (i = 0; i < RATE_ANT_NUM - 1; i++) {
+		ind = (ind + 1) < RATE_ANT_NUM ?  ind + 1 : 0;
+		if (valid & BIT(ind))
+			return ind;
+	}
+	return ant;
+}
+
+static const char *get_csr_string(int cmd)
+{
+	switch (cmd) {
+	IWL_CMD(CSR_HW_IF_CONFIG_REG);
+	IWL_CMD(CSR_INT_COALESCING);
+	IWL_CMD(CSR_INT);
+	IWL_CMD(CSR_INT_MASK);
+	IWL_CMD(CSR_FH_INT_STATUS);
+	IWL_CMD(CSR_GPIO_IN);
+	IWL_CMD(CSR_RESET);
+	IWL_CMD(CSR_GP_CNTRL);
+	IWL_CMD(CSR_HW_REV);
+	IWL_CMD(CSR_EEPROM_REG);
+	IWL_CMD(CSR_EEPROM_GP);
+	IWL_CMD(CSR_OTP_GP_REG);
+	IWL_CMD(CSR_GIO_REG);
+	IWL_CMD(CSR_GP_UCODE_REG);
+	IWL_CMD(CSR_GP_DRIVER_REG);
+	IWL_CMD(CSR_UCODE_DRV_GP1);
+	IWL_CMD(CSR_UCODE_DRV_GP2);
+	IWL_CMD(CSR_LED_REG);
+	IWL_CMD(CSR_DRAM_INT_TBL_REG);
+	IWL_CMD(CSR_GIO_CHICKEN_BITS);
+	IWL_CMD(CSR_ANA_PLL_CFG);
+	IWL_CMD(CSR_HW_REV_WA_REG);
+	IWL_CMD(CSR_DBG_HPET_MEM_REG);
+	default:
+		return "UNKNOWN";
+	}
+}
+
+void iwl_dump_csr(struct iwl_priv *priv)
+{
+	int i;
+	u32 csr_tbl[] = {
+		CSR_HW_IF_CONFIG_REG,
+		CSR_INT_COALESCING,
+		CSR_INT,
+		CSR_INT_MASK,
+		CSR_FH_INT_STATUS,
+		CSR_GPIO_IN,
+		CSR_RESET,
+		CSR_GP_CNTRL,
+		CSR_HW_REV,
+		CSR_EEPROM_REG,
+		CSR_EEPROM_GP,
+		CSR_OTP_GP_REG,
+		CSR_GIO_REG,
+		CSR_GP_UCODE_REG,
+		CSR_GP_DRIVER_REG,
+		CSR_UCODE_DRV_GP1,
+		CSR_UCODE_DRV_GP2,
+		CSR_LED_REG,
+		CSR_DRAM_INT_TBL_REG,
+		CSR_GIO_CHICKEN_BITS,
+		CSR_ANA_PLL_CFG,
+		CSR_HW_REV_WA_REG,
+		CSR_DBG_HPET_MEM_REG
+	};
+	IWL_ERR(priv, "CSR values:\n");
+	IWL_ERR(priv, "(2nd byte of CSR_INT_COALESCING is "
+		"CSR_INT_PERIODIC_REG)\n");
+	for (i = 0; i <  ARRAY_SIZE(csr_tbl); i++) {
+		IWL_ERR(priv, "  %25s: 0X%08x\n",
+			get_csr_string(csr_tbl[i]),
+			iwl_read32(priv, csr_tbl[i]));
+	}
+}
+
+static const char *get_fh_string(int cmd)
+{
+	switch (cmd) {
+	IWL_CMD(FH_RSCSR_CHNL0_STTS_WPTR_REG);
+	IWL_CMD(FH_RSCSR_CHNL0_RBDCB_BASE_REG);
+	IWL_CMD(FH_RSCSR_CHNL0_WPTR);
+	IWL_CMD(FH_MEM_RCSR_CHNL0_CONFIG_REG);
+	IWL_CMD(FH_MEM_RSSR_SHARED_CTRL_REG);
+	IWL_CMD(FH_MEM_RSSR_RX_STATUS_REG);
+	IWL_CMD(FH_MEM_RSSR_RX_ENABLE_ERR_IRQ2DRV);
+	IWL_CMD(FH_TSSR_TX_STATUS_REG);
+	IWL_CMD(FH_TSSR_TX_ERROR_REG);
+	default:
+		return "UNKNOWN";
+	}
+}
+
+int iwl_dump_fh(struct iwl_priv *priv, char **buf, bool display)
+{
+	int i;
+#ifdef CONFIG_IWLWIFI_DEBUG
+	int pos = 0;
+	size_t bufsz = 0;
+#endif
+	u32 fh_tbl[] = {
+		FH_RSCSR_CHNL0_STTS_WPTR_REG,
+		FH_RSCSR_CHNL0_RBDCB_BASE_REG,
+		FH_RSCSR_CHNL0_WPTR,
+		FH_MEM_RCSR_CHNL0_CONFIG_REG,
+		FH_MEM_RSSR_SHARED_CTRL_REG,
+		FH_MEM_RSSR_RX_STATUS_REG,
+		FH_MEM_RSSR_RX_ENABLE_ERR_IRQ2DRV,
+		FH_TSSR_TX_STATUS_REG,
+		FH_TSSR_TX_ERROR_REG
+	};
+#ifdef CONFIG_IWLWIFI_DEBUG
+	if (display) {
+		bufsz = ARRAY_SIZE(fh_tbl) * 48 + 40;
+		*buf = kmalloc(bufsz, GFP_KERNEL);
+		if (!*buf)
+			return -ENOMEM;
+		pos += scnprintf(*buf + pos, bufsz - pos,
+				"FH register values:\n");
+		for (i = 0; i < ARRAY_SIZE(fh_tbl); i++) {
+			pos += scnprintf(*buf + pos, bufsz - pos,
+				"  %34s: 0X%08x\n",
+				get_fh_string(fh_tbl[i]),
+				iwl_read_direct32(priv, fh_tbl[i]));
+		}
+		return pos;
+	}
+#endif
+	IWL_ERR(priv, "FH register values:\n");
+	for (i = 0; i <  ARRAY_SIZE(fh_tbl); i++) {
+		IWL_ERR(priv, "  %34s: 0X%08x\n",
+			get_fh_string(fh_tbl[i]),
+			iwl_read_direct32(priv, fh_tbl[i]));
+	}
+	return 0;
+}
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
index f865685fd5f5..5abe2e9ff0d2 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
@@ -39,6 +39,7 @@
 #include "iwl-dev.h"
 #include "iwl-sta.h"
 #include "iwl-core.h"
+#include "iwl-agn.h"
 
 #define RS_NAME "iwl-agn-rs"
 
@@ -76,6 +77,74 @@ static const u8 ant_toggle_lookup[] = {
 	/*ANT_ABC  -> */ ANT_ABC,
 };
 
+#define IWL_DECLARE_RATE_INFO(r, s, ip, in, rp, rn, pp, np)    \
+	[IWL_RATE_##r##M_INDEX] = { IWL_RATE_##r##M_PLCP,      \
+				    IWL_RATE_SISO_##s##M_PLCP, \
+				    IWL_RATE_MIMO2_##s##M_PLCP,\
+				    IWL_RATE_MIMO3_##s##M_PLCP,\
+				    IWL_RATE_##r##M_IEEE,      \
+				    IWL_RATE_##ip##M_INDEX,    \
+				    IWL_RATE_##in##M_INDEX,    \
+				    IWL_RATE_##rp##M_INDEX,    \
+				    IWL_RATE_##rn##M_INDEX,    \
+				    IWL_RATE_##pp##M_INDEX,    \
+				    IWL_RATE_##np##M_INDEX }
+
+/*
+ * Parameter order:
+ *   rate, ht rate, prev rate, next rate, prev tgg rate, next tgg rate
+ *
+ * If there isn't a valid next or previous rate then INV is used which
+ * maps to IWL_RATE_INVALID
+ *
+ */
+const struct iwl_rate_info iwl_rates[IWL_RATE_COUNT] = {
+	IWL_DECLARE_RATE_INFO(1, INV, INV, 2, INV, 2, INV, 2),    /*  1mbps */
+	IWL_DECLARE_RATE_INFO(2, INV, 1, 5, 1, 5, 1, 5),          /*  2mbps */
+	IWL_DECLARE_RATE_INFO(5, INV, 2, 6, 2, 11, 2, 11),        /*5.5mbps */
+	IWL_DECLARE_RATE_INFO(11, INV, 9, 12, 9, 12, 5, 18),      /* 11mbps */
+	IWL_DECLARE_RATE_INFO(6, 6, 5, 9, 5, 11, 5, 11),        /*  6mbps */
+	IWL_DECLARE_RATE_INFO(9, 6, 6, 11, 6, 11, 5, 11),       /*  9mbps */
+	IWL_DECLARE_RATE_INFO(12, 12, 11, 18, 11, 18, 11, 18),   /* 12mbps */
+	IWL_DECLARE_RATE_INFO(18, 18, 12, 24, 12, 24, 11, 24),   /* 18mbps */
+	IWL_DECLARE_RATE_INFO(24, 24, 18, 36, 18, 36, 18, 36),   /* 24mbps */
+	IWL_DECLARE_RATE_INFO(36, 36, 24, 48, 24, 48, 24, 48),   /* 36mbps */
+	IWL_DECLARE_RATE_INFO(48, 48, 36, 54, 36, 54, 36, 54),   /* 48mbps */
+	IWL_DECLARE_RATE_INFO(54, 54, 48, INV, 48, INV, 48, INV),/* 54mbps */
+	IWL_DECLARE_RATE_INFO(60, 60, 48, INV, 48, INV, 48, INV),/* 60mbps */
+	/* FIXME:RS:          ^^    should be INV (legacy) */
+};
+
+static int iwl_hwrate_to_plcp_idx(u32 rate_n_flags)
+{
+	int idx = 0;
+
+	/* HT rate format */
+	if (rate_n_flags & RATE_MCS_HT_MSK) {
+		idx = (rate_n_flags & 0xff);
+
+		if (idx >= IWL_RATE_MIMO3_6M_PLCP)
+			idx = idx - IWL_RATE_MIMO3_6M_PLCP;
+		else if (idx >= IWL_RATE_MIMO2_6M_PLCP)
+			idx = idx - IWL_RATE_MIMO2_6M_PLCP;
+
+		idx += IWL_FIRST_OFDM_RATE;
+		/* skip 9M not supported in ht*/
+		if (idx >= IWL_RATE_9M_INDEX)
+			idx += 1;
+		if ((idx >= IWL_FIRST_OFDM_RATE) && (idx <= IWL_LAST_OFDM_RATE))
+			return idx;
+
+	/* legacy rate format, search for match in table */
+	} else {
+		for (idx = 0; idx < ARRAY_SIZE(iwl_rates); idx++)
+			if (iwl_rates[idx].plcp == (rate_n_flags & 0xFF))
+				return idx;
+	}
+
+	return -1;
+}
+
 static void rs_rate_scale_perform(struct iwl_priv *priv,
 				   struct sk_buff *skb,
 				   struct ieee80211_sta *sta,
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h
index 357cdb26f16d..75e50d33ecb3 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h
@@ -299,7 +299,6 @@ enum {
 #define TIME_WRAP_AROUND(x, y) (((y) > (x)) ? (y) - (x) : (0-(x)) + (y))
 
 extern const struct iwl_rate_info iwl_rates[IWL_RATE_COUNT];
-extern const struct iwl3945_rate_info iwl3945_rates[IWL_RATE_COUNT_3945];
 
 enum iwl_table_type {
 	LQ_NONE,
@@ -453,15 +452,6 @@ static inline u8 first_antenna(u8 mask)
 }
 
 
-static inline u8 iwl3945_get_prev_ieee_rate(u8 rate_index)
-{
-	u8 rate = iwl3945_rates[rate_index].prev_ieee;
-
-	if (rate == IWL_RATE_INVALID)
-		rate = rate_index;
-	return rate;
-}
-
 /**
  * iwl3945_rate_scale_init - Initialize the rate scale table based on assoc info
  *
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c
index 1e08eb455474..bbd40b7dd597 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c
@@ -34,7 +34,7 @@
 
 #include "iwl-dev.h"
 #include "iwl-core.h"
-#include "iwl-calib.h"
+#include "iwl-agn-calib.h"
 #include "iwl-sta.h"
 #include "iwl-io.h"
 #include "iwl-helpers.h"
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c
new file mode 100644
index 000000000000..35a30d2e0734
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c
@@ -0,0 +1,716 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
+ *
+ * Portions of this file are derived from the ipw3945 project, as well
+ * as portions of the ieee80211 subsystem header files.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ *  Intel Linux Wireless <ilw@linux.intel.com>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *
+ *****************************************************************************/
+
+#include <net/mac80211.h>
+
+#include "iwl-dev.h"
+#include "iwl-core.h"
+#include "iwl-sta.h"
+#include "iwl-agn.h"
+
+static struct iwl_link_quality_cmd *
+iwl_sta_alloc_lq(struct iwl_priv *priv, u8 sta_id)
+{
+	int i, r;
+	struct iwl_link_quality_cmd *link_cmd;
+	u32 rate_flags = 0;
+	__le32 rate_n_flags;
+
+	link_cmd = kzalloc(sizeof(struct iwl_link_quality_cmd), GFP_KERNEL);
+	if (!link_cmd) {
+		IWL_ERR(priv, "Unable to allocate memory for LQ cmd.\n");
+		return NULL;
+	}
+	/* Set up the rate scaling to start at selected rate, fall back
+	 * all the way down to 1M in IEEE order, and then spin on 1M */
+	if (priv->band == IEEE80211_BAND_5GHZ)
+		r = IWL_RATE_6M_INDEX;
+	else
+		r = IWL_RATE_1M_INDEX;
+
+	if (r >= IWL_FIRST_CCK_RATE && r <= IWL_LAST_CCK_RATE)
+		rate_flags |= RATE_MCS_CCK_MSK;
+
+	rate_flags |= first_antenna(priv->hw_params.valid_tx_ant) <<
+				RATE_MCS_ANT_POS;
+	rate_n_flags = iwl_hw_set_rate_n_flags(iwl_rates[r].plcp, rate_flags);
+	for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++)
+		link_cmd->rs_table[i].rate_n_flags = rate_n_flags;
+
+	link_cmd->general_params.single_stream_ant_msk =
+				first_antenna(priv->hw_params.valid_tx_ant);
+
+	link_cmd->general_params.dual_stream_ant_msk =
+		priv->hw_params.valid_tx_ant &
+		~first_antenna(priv->hw_params.valid_tx_ant);
+	if (!link_cmd->general_params.dual_stream_ant_msk) {
+		link_cmd->general_params.dual_stream_ant_msk = ANT_AB;
+	} else if (num_of_ant(priv->hw_params.valid_tx_ant) == 2) {
+		link_cmd->general_params.dual_stream_ant_msk =
+			priv->hw_params.valid_tx_ant;
+	}
+
+	link_cmd->agg_params.agg_dis_start_th = LINK_QUAL_AGG_DISABLE_START_DEF;
+	link_cmd->agg_params.agg_time_limit =
+		cpu_to_le16(LINK_QUAL_AGG_TIME_LIMIT_DEF);
+
+	link_cmd->sta_id = sta_id;
+
+	return link_cmd;
+}
+
+/*
+ * iwlagn_add_bssid_station - Add the special IBSS BSSID station
+ *
+ * Function sleeps.
+ */
+int iwlagn_add_bssid_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
+			     const u8 *addr, u8 *sta_id_r)
+{
+	int ret;
+	u8 sta_id;
+	struct iwl_link_quality_cmd *link_cmd;
+	unsigned long flags;
+
+	if (sta_id_r)
+		*sta_id_r = IWL_INVALID_STATION;
+
+	ret = iwl_add_station_common(priv, ctx, addr, 0, NULL, &sta_id);
+	if (ret) {
+		IWL_ERR(priv, "Unable to add station %pM\n", addr);
+		return ret;
+	}
+
+	if (sta_id_r)
+		*sta_id_r = sta_id;
+
+	spin_lock_irqsave(&priv->sta_lock, flags);
+	priv->stations[sta_id].used |= IWL_STA_LOCAL;
+	spin_unlock_irqrestore(&priv->sta_lock, flags);
+
+	/* Set up default rate scaling table in device's station table */
+	link_cmd = iwl_sta_alloc_lq(priv, sta_id);
+	if (!link_cmd) {
+		IWL_ERR(priv, "Unable to initialize rate scaling for station %pM.\n",
+			addr);
+		return -ENOMEM;
+	}
+
+	ret = iwl_send_lq_cmd(priv, ctx, link_cmd, CMD_SYNC, true);
+	if (ret)
+		IWL_ERR(priv, "Link quality command failed (%d)\n", ret);
+
+	spin_lock_irqsave(&priv->sta_lock, flags);
+	priv->stations[sta_id].lq = link_cmd;
+	spin_unlock_irqrestore(&priv->sta_lock, flags);
+
+	return 0;
+}
+
+static int iwl_send_static_wepkey_cmd(struct iwl_priv *priv,
+				      struct iwl_rxon_context *ctx,
+				      bool send_if_empty)
+{
+	int i, not_empty = 0;
+	u8 buff[sizeof(struct iwl_wep_cmd) +
+		sizeof(struct iwl_wep_key) * WEP_KEYS_MAX];
+	struct iwl_wep_cmd *wep_cmd = (struct iwl_wep_cmd *)buff;
+	size_t cmd_size  = sizeof(struct iwl_wep_cmd);
+	struct iwl_host_cmd cmd = {
+		.id = ctx->wep_key_cmd,
+		.data = wep_cmd,
+		.flags = CMD_SYNC,
+	};
+
+	might_sleep();
+
+	memset(wep_cmd, 0, cmd_size +
+			(sizeof(struct iwl_wep_key) * WEP_KEYS_MAX));
+
+	for (i = 0; i < WEP_KEYS_MAX ; i++) {
+		wep_cmd->key[i].key_index = i;
+		if (ctx->wep_keys[i].key_size) {
+			wep_cmd->key[i].key_offset = i;
+			not_empty = 1;
+		} else {
+			wep_cmd->key[i].key_offset = WEP_INVALID_OFFSET;
+		}
+
+		wep_cmd->key[i].key_size = ctx->wep_keys[i].key_size;
+		memcpy(&wep_cmd->key[i].key[3], ctx->wep_keys[i].key,
+				ctx->wep_keys[i].key_size);
+	}
+
+	wep_cmd->global_key_type = WEP_KEY_WEP_TYPE;
+	wep_cmd->num_keys = WEP_KEYS_MAX;
+
+	cmd_size += sizeof(struct iwl_wep_key) * WEP_KEYS_MAX;
+
+	cmd.len = cmd_size;
+
+	if (not_empty || send_if_empty)
+		return iwl_send_cmd(priv, &cmd);
+	else
+		return 0;
+}
+
+int iwl_restore_default_wep_keys(struct iwl_priv *priv,
+				 struct iwl_rxon_context *ctx)
+{
+	lockdep_assert_held(&priv->mutex);
+
+	return iwl_send_static_wepkey_cmd(priv, ctx, false);
+}
+
+int iwl_remove_default_wep_key(struct iwl_priv *priv,
+			       struct iwl_rxon_context *ctx,
+			       struct ieee80211_key_conf *keyconf)
+{
+	int ret;
+
+	lockdep_assert_held(&priv->mutex);
+
+	IWL_DEBUG_WEP(priv, "Removing default WEP key: idx=%d\n",
+		      keyconf->keyidx);
+
+	memset(&ctx->wep_keys[keyconf->keyidx], 0, sizeof(ctx->wep_keys[0]));
+	if (iwl_is_rfkill(priv)) {
+		IWL_DEBUG_WEP(priv, "Not sending REPLY_WEPKEY command due to RFKILL.\n");
+		/* but keys in device are clear anyway so return success */
+		return 0;
+	}
+	ret = iwl_send_static_wepkey_cmd(priv, ctx, 1);
+	IWL_DEBUG_WEP(priv, "Remove default WEP key: idx=%d ret=%d\n",
+		      keyconf->keyidx, ret);
+
+	return ret;
+}
+
+int iwl_set_default_wep_key(struct iwl_priv *priv,
+			    struct iwl_rxon_context *ctx,
+			    struct ieee80211_key_conf *keyconf)
+{
+	int ret;
+
+	lockdep_assert_held(&priv->mutex);
+
+	if (keyconf->keylen != WEP_KEY_LEN_128 &&
+	    keyconf->keylen != WEP_KEY_LEN_64) {
+		IWL_DEBUG_WEP(priv, "Bad WEP key length %d\n", keyconf->keylen);
+		return -EINVAL;
+	}
+
+	keyconf->flags &= ~IEEE80211_KEY_FLAG_GENERATE_IV;
+	keyconf->hw_key_idx = HW_KEY_DEFAULT;
+	priv->stations[ctx->ap_sta_id].keyinfo.cipher = keyconf->cipher;
+
+	ctx->wep_keys[keyconf->keyidx].key_size = keyconf->keylen;
+	memcpy(&ctx->wep_keys[keyconf->keyidx].key, &keyconf->key,
+							keyconf->keylen);
+
+	ret = iwl_send_static_wepkey_cmd(priv, ctx, false);
+	IWL_DEBUG_WEP(priv, "Set default WEP key: len=%d idx=%d ret=%d\n",
+		keyconf->keylen, keyconf->keyidx, ret);
+
+	return ret;
+}
+
+static int iwl_set_wep_dynamic_key_info(struct iwl_priv *priv,
+					struct iwl_rxon_context *ctx,
+					struct ieee80211_key_conf *keyconf,
+					u8 sta_id)
+{
+	unsigned long flags;
+	__le16 key_flags = 0;
+	struct iwl_addsta_cmd sta_cmd;
+
+	lockdep_assert_held(&priv->mutex);
+
+	keyconf->flags &= ~IEEE80211_KEY_FLAG_GENERATE_IV;
+
+	key_flags |= (STA_KEY_FLG_WEP | STA_KEY_FLG_MAP_KEY_MSK);
+	key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS);
+	key_flags &= ~STA_KEY_FLG_INVALID;
+
+	if (keyconf->keylen == WEP_KEY_LEN_128)
+		key_flags |= STA_KEY_FLG_KEY_SIZE_MSK;
+
+	if (sta_id == ctx->bcast_sta_id)
+		key_flags |= STA_KEY_MULTICAST_MSK;
+
+	spin_lock_irqsave(&priv->sta_lock, flags);
+
+	priv->stations[sta_id].keyinfo.cipher = keyconf->cipher;
+	priv->stations[sta_id].keyinfo.keylen = keyconf->keylen;
+	priv->stations[sta_id].keyinfo.keyidx = keyconf->keyidx;
+
+	memcpy(priv->stations[sta_id].keyinfo.key,
+				keyconf->key, keyconf->keylen);
+
+	memcpy(&priv->stations[sta_id].sta.key.key[3],
+				keyconf->key, keyconf->keylen);
+
+	if ((priv->stations[sta_id].sta.key.key_flags & STA_KEY_FLG_ENCRYPT_MSK)
+			== STA_KEY_FLG_NO_ENC)
+		priv->stations[sta_id].sta.key.key_offset =
+				 iwl_get_free_ucode_key_index(priv);
+	/* else, we are overriding an existing key => no need to allocated room
+	 * in uCode. */
+
+	WARN(priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET,
+		"no space for a new key");
+
+	priv->stations[sta_id].sta.key.key_flags = key_flags;
+	priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
+	priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
+
+	memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd));
+	spin_unlock_irqrestore(&priv->sta_lock, flags);
+
+	return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
+}
+
+static int iwl_set_ccmp_dynamic_key_info(struct iwl_priv *priv,
+					 struct iwl_rxon_context *ctx,
+					 struct ieee80211_key_conf *keyconf,
+					 u8 sta_id)
+{
+	unsigned long flags;
+	__le16 key_flags = 0;
+	struct iwl_addsta_cmd sta_cmd;
+
+	lockdep_assert_held(&priv->mutex);
+
+	key_flags |= (STA_KEY_FLG_CCMP | STA_KEY_FLG_MAP_KEY_MSK);
+	key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS);
+	key_flags &= ~STA_KEY_FLG_INVALID;
+
+	if (sta_id == ctx->bcast_sta_id)
+		key_flags |= STA_KEY_MULTICAST_MSK;
+
+	keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
+
+	spin_lock_irqsave(&priv->sta_lock, flags);
+	priv->stations[sta_id].keyinfo.cipher = keyconf->cipher;
+	priv->stations[sta_id].keyinfo.keylen = keyconf->keylen;
+
+	memcpy(priv->stations[sta_id].keyinfo.key, keyconf->key,
+	       keyconf->keylen);
+
+	memcpy(priv->stations[sta_id].sta.key.key, keyconf->key,
+	       keyconf->keylen);
+
+	if ((priv->stations[sta_id].sta.key.key_flags & STA_KEY_FLG_ENCRYPT_MSK)
+			== STA_KEY_FLG_NO_ENC)
+		priv->stations[sta_id].sta.key.key_offset =
+				 iwl_get_free_ucode_key_index(priv);
+	/* else, we are overriding an existing key => no need to allocated room
+	 * in uCode. */
+
+	WARN(priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET,
+		"no space for a new key");
+
+	priv->stations[sta_id].sta.key.key_flags = key_flags;
+	priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
+	priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
+
+	memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd));
+	spin_unlock_irqrestore(&priv->sta_lock, flags);
+
+	return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
+}
+
+static int iwl_set_tkip_dynamic_key_info(struct iwl_priv *priv,
+					 struct iwl_rxon_context *ctx,
+					 struct ieee80211_key_conf *keyconf,
+					 u8 sta_id)
+{
+	unsigned long flags;
+	int ret = 0;
+	__le16 key_flags = 0;
+
+	key_flags |= (STA_KEY_FLG_TKIP | STA_KEY_FLG_MAP_KEY_MSK);
+	key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS);
+	key_flags &= ~STA_KEY_FLG_INVALID;
+
+	if (sta_id == ctx->bcast_sta_id)
+		key_flags |= STA_KEY_MULTICAST_MSK;
+
+	keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
+	keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
+
+	spin_lock_irqsave(&priv->sta_lock, flags);
+
+	priv->stations[sta_id].keyinfo.cipher = keyconf->cipher;
+	priv->stations[sta_id].keyinfo.keylen = 16;
+
+	if ((priv->stations[sta_id].sta.key.key_flags & STA_KEY_FLG_ENCRYPT_MSK)
+			== STA_KEY_FLG_NO_ENC)
+		priv->stations[sta_id].sta.key.key_offset =
+				 iwl_get_free_ucode_key_index(priv);
+	/* else, we are overriding an existing key => no need to allocated room
+	 * in uCode. */
+
+	WARN(priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET,
+		"no space for a new key");
+
+	priv->stations[sta_id].sta.key.key_flags = key_flags;
+
+
+	/* This copy is acutally not needed: we get the key with each TX */
+	memcpy(priv->stations[sta_id].keyinfo.key, keyconf->key, 16);
+
+	memcpy(priv->stations[sta_id].sta.key.key, keyconf->key, 16);
+
+	spin_unlock_irqrestore(&priv->sta_lock, flags);
+
+	return ret;
+}
+
+void iwl_update_tkip_key(struct iwl_priv *priv,
+			 struct iwl_rxon_context *ctx,
+			 struct ieee80211_key_conf *keyconf,
+			 struct ieee80211_sta *sta, u32 iv32, u16 *phase1key)
+{
+	u8 sta_id;
+	unsigned long flags;
+	int i;
+
+	if (iwl_scan_cancel(priv)) {
+		/* cancel scan failed, just live w/ bad key and rely
+		   briefly on SW decryption */
+		return;
+	}
+
+	sta_id = iwl_sta_id_or_broadcast(priv, ctx, sta);
+	if (sta_id == IWL_INVALID_STATION)
+		return;
+
+	spin_lock_irqsave(&priv->sta_lock, flags);
+
+	priv->stations[sta_id].sta.key.tkip_rx_tsc_byte2 = (u8) iv32;
+
+	for (i = 0; i < 5; i++)
+		priv->stations[sta_id].sta.key.tkip_rx_ttak[i] =
+			cpu_to_le16(phase1key[i]);
+
+	priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
+	priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
+
+	iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
+
+	spin_unlock_irqrestore(&priv->sta_lock, flags);
+
+}
+
+int iwl_remove_dynamic_key(struct iwl_priv *priv,
+			   struct iwl_rxon_context *ctx,
+			   struct ieee80211_key_conf *keyconf,
+			   u8 sta_id)
+{
+	unsigned long flags;
+	u16 key_flags;
+	u8 keyidx;
+	struct iwl_addsta_cmd sta_cmd;
+
+	lockdep_assert_held(&priv->mutex);
+
+	ctx->key_mapping_keys--;
+
+	spin_lock_irqsave(&priv->sta_lock, flags);
+	key_flags = le16_to_cpu(priv->stations[sta_id].sta.key.key_flags);
+	keyidx = (key_flags >> STA_KEY_FLG_KEYID_POS) & 0x3;
+
+	IWL_DEBUG_WEP(priv, "Remove dynamic key: idx=%d sta=%d\n",
+		      keyconf->keyidx, sta_id);
+
+	if (keyconf->keyidx != keyidx) {
+		/* We need to remove a key with index different that the one
+		 * in the uCode. This means that the key we need to remove has
+		 * been replaced by another one with different index.
+		 * Don't do anything and return ok
+		 */
+		spin_unlock_irqrestore(&priv->sta_lock, flags);
+		return 0;
+	}
+
+	if (priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET) {
+		IWL_WARN(priv, "Removing wrong key %d 0x%x\n",
+			    keyconf->keyidx, key_flags);
+		spin_unlock_irqrestore(&priv->sta_lock, flags);
+		return 0;
+	}
+
+	if (!test_and_clear_bit(priv->stations[sta_id].sta.key.key_offset,
+		&priv->ucode_key_table))
+		IWL_ERR(priv, "index %d not used in uCode key table.\n",
+			priv->stations[sta_id].sta.key.key_offset);
+	memset(&priv->stations[sta_id].keyinfo, 0,
+					sizeof(struct iwl_hw_key));
+	memset(&priv->stations[sta_id].sta.key, 0,
+					sizeof(struct iwl4965_keyinfo));
+	priv->stations[sta_id].sta.key.key_flags =
+			STA_KEY_FLG_NO_ENC | STA_KEY_FLG_INVALID;
+	priv->stations[sta_id].sta.key.key_offset = WEP_INVALID_OFFSET;
+	priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
+	priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
+
+	if (iwl_is_rfkill(priv)) {
+		IWL_DEBUG_WEP(priv, "Not sending REPLY_ADD_STA command because RFKILL enabled.\n");
+		spin_unlock_irqrestore(&priv->sta_lock, flags);
+		return 0;
+	}
+	memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd));
+	spin_unlock_irqrestore(&priv->sta_lock, flags);
+
+	return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
+}
+
+int iwl_set_dynamic_key(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
+			struct ieee80211_key_conf *keyconf, u8 sta_id)
+{
+	int ret;
+
+	lockdep_assert_held(&priv->mutex);
+
+	ctx->key_mapping_keys++;
+	keyconf->hw_key_idx = HW_KEY_DYNAMIC;
+
+	switch (keyconf->cipher) {
+	case WLAN_CIPHER_SUITE_CCMP:
+		ret = iwl_set_ccmp_dynamic_key_info(priv, ctx, keyconf, sta_id);
+		break;
+	case WLAN_CIPHER_SUITE_TKIP:
+		ret = iwl_set_tkip_dynamic_key_info(priv, ctx, keyconf, sta_id);
+		break;
+	case WLAN_CIPHER_SUITE_WEP40:
+	case WLAN_CIPHER_SUITE_WEP104:
+		ret = iwl_set_wep_dynamic_key_info(priv, ctx, keyconf, sta_id);
+		break;
+	default:
+		IWL_ERR(priv,
+			"Unknown alg: %s cipher = %x\n", __func__,
+			keyconf->cipher);
+		ret = -EINVAL;
+	}
+
+	IWL_DEBUG_WEP(priv, "Set dynamic key: cipher=%x len=%d idx=%d sta=%d ret=%d\n",
+		      keyconf->cipher, keyconf->keylen, keyconf->keyidx,
+		      sta_id, ret);
+
+	return ret;
+}
+
+/**
+ * iwlagn_alloc_bcast_station - add broadcast station into driver's station table.
+ *
+ * This adds the broadcast station into the driver's station table
+ * and marks it driver active, so that it will be restored to the
+ * device at the next best time.
+ */
+int iwlagn_alloc_bcast_station(struct iwl_priv *priv,
+			       struct iwl_rxon_context *ctx)
+{
+	struct iwl_link_quality_cmd *link_cmd;
+	unsigned long flags;
+	u8 sta_id;
+
+	spin_lock_irqsave(&priv->sta_lock, flags);
+	sta_id = iwl_prep_station(priv, ctx, iwl_bcast_addr, false, NULL);
+	if (sta_id == IWL_INVALID_STATION) {
+		IWL_ERR(priv, "Unable to prepare broadcast station\n");
+		spin_unlock_irqrestore(&priv->sta_lock, flags);
+
+		return -EINVAL;
+	}
+
+	priv->stations[sta_id].used |= IWL_STA_DRIVER_ACTIVE;
+	priv->stations[sta_id].used |= IWL_STA_BCAST;
+	spin_unlock_irqrestore(&priv->sta_lock, flags);
+
+	link_cmd = iwl_sta_alloc_lq(priv, sta_id);
+	if (!link_cmd) {
+		IWL_ERR(priv,
+			"Unable to initialize rate scaling for bcast station.\n");
+		return -ENOMEM;
+	}
+
+	spin_lock_irqsave(&priv->sta_lock, flags);
+	priv->stations[sta_id].lq = link_cmd;
+	spin_unlock_irqrestore(&priv->sta_lock, flags);
+
+	return 0;
+}
+
+/**
+ * iwl_update_bcast_station - update broadcast station's LQ command
+ *
+ * Only used by iwlagn. Placed here to have all bcast station management
+ * code together.
+ */
+static int iwl_update_bcast_station(struct iwl_priv *priv,
+				    struct iwl_rxon_context *ctx)
+{
+	unsigned long flags;
+	struct iwl_link_quality_cmd *link_cmd;
+	u8 sta_id = ctx->bcast_sta_id;
+
+	link_cmd = iwl_sta_alloc_lq(priv, sta_id);
+	if (!link_cmd) {
+		IWL_ERR(priv, "Unable to initialize rate scaling for bcast station.\n");
+		return -ENOMEM;
+	}
+
+	spin_lock_irqsave(&priv->sta_lock, flags);
+	if (priv->stations[sta_id].lq)
+		kfree(priv->stations[sta_id].lq);
+	else
+		IWL_DEBUG_INFO(priv, "Bcast station rate scaling has not been initialized yet.\n");
+	priv->stations[sta_id].lq = link_cmd;
+	spin_unlock_irqrestore(&priv->sta_lock, flags);
+
+	return 0;
+}
+
+int iwl_update_bcast_stations(struct iwl_priv *priv)
+{
+	struct iwl_rxon_context *ctx;
+	int ret = 0;
+
+	for_each_context(priv, ctx) {
+		ret = iwl_update_bcast_station(priv, ctx);
+		if (ret)
+			break;
+	}
+
+	return ret;
+}
+
+/**
+ * iwl_sta_tx_modify_enable_tid - Enable Tx for this TID in station table
+ */
+int iwl_sta_tx_modify_enable_tid(struct iwl_priv *priv, int sta_id, int tid)
+{
+	unsigned long flags;
+	struct iwl_addsta_cmd sta_cmd;
+
+	lockdep_assert_held(&priv->mutex);
+
+	/* Remove "disable" flag, to enable Tx for this TID */
+	spin_lock_irqsave(&priv->sta_lock, flags);
+	priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_TID_DISABLE_TX;
+	priv->stations[sta_id].sta.tid_disable_tx &= cpu_to_le16(~(1 << tid));
+	priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
+	memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd));
+	spin_unlock_irqrestore(&priv->sta_lock, flags);
+
+	return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
+}
+
+int iwl_sta_rx_agg_start(struct iwl_priv *priv, struct ieee80211_sta *sta,
+			 int tid, u16 ssn)
+{
+	unsigned long flags;
+	int sta_id;
+	struct iwl_addsta_cmd sta_cmd;
+
+	lockdep_assert_held(&priv->mutex);
+
+	sta_id = iwl_sta_id(sta);
+	if (sta_id == IWL_INVALID_STATION)
+		return -ENXIO;
+
+	spin_lock_irqsave(&priv->sta_lock, flags);
+	priv->stations[sta_id].sta.station_flags_msk = 0;
+	priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_ADDBA_TID_MSK;
+	priv->stations[sta_id].sta.add_immediate_ba_tid = (u8)tid;
+	priv->stations[sta_id].sta.add_immediate_ba_ssn = cpu_to_le16(ssn);
+	priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
+	memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd));
+	spin_unlock_irqrestore(&priv->sta_lock, flags);
+
+	return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
+}
+
+int iwl_sta_rx_agg_stop(struct iwl_priv *priv, struct ieee80211_sta *sta,
+			int tid)
+{
+	unsigned long flags;
+	int sta_id;
+	struct iwl_addsta_cmd sta_cmd;
+
+	lockdep_assert_held(&priv->mutex);
+
+	sta_id = iwl_sta_id(sta);
+	if (sta_id == IWL_INVALID_STATION) {
+		IWL_ERR(priv, "Invalid station for AGG tid %d\n", tid);
+		return -ENXIO;
+	}
+
+	spin_lock_irqsave(&priv->sta_lock, flags);
+	priv->stations[sta_id].sta.station_flags_msk = 0;
+	priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_DELBA_TID_MSK;
+	priv->stations[sta_id].sta.remove_immediate_ba_tid = (u8)tid;
+	priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
+	memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd));
+	spin_unlock_irqrestore(&priv->sta_lock, flags);
+
+	return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
+}
+
+void iwl_sta_modify_ps_wake(struct iwl_priv *priv, int sta_id)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&priv->sta_lock, flags);
+	priv->stations[sta_id].sta.station_flags &= ~STA_FLG_PWR_SAVE_MSK;
+	priv->stations[sta_id].sta.station_flags_msk = STA_FLG_PWR_SAVE_MSK;
+	priv->stations[sta_id].sta.sta.modify_mask = 0;
+	priv->stations[sta_id].sta.sleep_tx_count = 0;
+	priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
+	iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
+	spin_unlock_irqrestore(&priv->sta_lock, flags);
+
+}
+
+void iwl_sta_modify_sleep_tx_count(struct iwl_priv *priv, int sta_id, int cnt)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&priv->sta_lock, flags);
+	priv->stations[sta_id].sta.station_flags |= STA_FLG_PWR_SAVE_MSK;
+	priv->stations[sta_id].sta.station_flags_msk = STA_FLG_PWR_SAVE_MSK;
+	priv->stations[sta_id].sta.sta.modify_mask =
+					STA_MODIFY_SLEEP_TX_COUNT_MSK;
+	priv->stations[sta_id].sta.sleep_tx_count = cpu_to_le16(cnt);
+	priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
+	iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
+	spin_unlock_irqrestore(&priv->sta_lock, flags);
+
+}
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tt.c b/drivers/net/wireless/iwlwifi/iwl-agn-tt.c
index 0c6c4d969706..e3a8216a033c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-tt.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-tt.c
@@ -571,7 +571,6 @@ void iwl_tt_enter_ct_kill(struct iwl_priv *priv)
 	IWL_DEBUG_POWER(priv, "Queueing critical temperature enter.\n");
 	queue_work(priv->workqueue, &priv->ct_enter);
 }
-EXPORT_SYMBOL(iwl_tt_enter_ct_kill);
 
 void iwl_tt_exit_ct_kill(struct iwl_priv *priv)
 {
@@ -581,7 +580,6 @@ void iwl_tt_exit_ct_kill(struct iwl_priv *priv)
 	IWL_DEBUG_POWER(priv, "Queueing critical temperature exit.\n");
 	queue_work(priv->workqueue, &priv->ct_exit);
 }
-EXPORT_SYMBOL(iwl_tt_exit_ct_kill);
 
 static void iwl_bg_tt_work(struct work_struct *work)
 {
@@ -608,7 +606,6 @@ void iwl_tt_handler(struct iwl_priv *priv)
 	IWL_DEBUG_POWER(priv, "Queueing thermal throttling work.\n");
 	queue_work(priv->workqueue, &priv->tt_work);
 }
-EXPORT_SYMBOL(iwl_tt_handler);
 
 /* Thermal throttling initialization
  * For advance thermal throttling:
@@ -678,7 +675,6 @@ void iwl_tt_initialize(struct iwl_priv *priv)
 		priv->thermal_throttle.advanced_tt = false;
 	}
 }
-EXPORT_SYMBOL(iwl_tt_initialize);
 
 /* cleanup thermal throttling management related memory and timer */
 void iwl_tt_exit(struct iwl_priv *priv)
@@ -701,4 +697,3 @@ void iwl_tt_exit(struct iwl_priv *priv)
 		tt->transaction = NULL;
 	}
 }
-EXPORT_SYMBOL(iwl_tt_exit);
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
index 77753b72f236..db57aea629d9 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
@@ -1391,3 +1391,43 @@ void iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv,
 
 	spin_unlock_irqrestore(&priv->sta_lock, flags);
 }
+
+#ifdef CONFIG_IWLWIFI_DEBUG
+const char *iwl_get_tx_fail_reason(u32 status)
+{
+#define TX_STATUS_FAIL(x) case TX_STATUS_FAIL_ ## x: return #x
+#define TX_STATUS_POSTPONE(x) case TX_STATUS_POSTPONE_ ## x: return #x
+
+	switch (status & TX_STATUS_MSK) {
+	case TX_STATUS_SUCCESS:
+		return "SUCCESS";
+	TX_STATUS_POSTPONE(DELAY);
+	TX_STATUS_POSTPONE(FEW_BYTES);
+	TX_STATUS_POSTPONE(BT_PRIO);
+	TX_STATUS_POSTPONE(QUIET_PERIOD);
+	TX_STATUS_POSTPONE(CALC_TTAK);
+	TX_STATUS_FAIL(INTERNAL_CROSSED_RETRY);
+	TX_STATUS_FAIL(SHORT_LIMIT);
+	TX_STATUS_FAIL(LONG_LIMIT);
+	TX_STATUS_FAIL(FIFO_UNDERRUN);
+	TX_STATUS_FAIL(DRAIN_FLOW);
+	TX_STATUS_FAIL(RFKILL_FLUSH);
+	TX_STATUS_FAIL(LIFE_EXPIRE);
+	TX_STATUS_FAIL(DEST_PS);
+	TX_STATUS_FAIL(HOST_ABORTED);
+	TX_STATUS_FAIL(BT_RETRY);
+	TX_STATUS_FAIL(STA_INVALID);
+	TX_STATUS_FAIL(FRAG_DROPPED);
+	TX_STATUS_FAIL(TID_DISABLE);
+	TX_STATUS_FAIL(FIFO_FLUSHED);
+	TX_STATUS_FAIL(INSUFFICIENT_CF_POLL);
+	TX_STATUS_FAIL(PASSIVE_NO_RX);
+	TX_STATUS_FAIL(NO_BEACON_ON_RADAR);
+	}
+
+	return "UNKNOWN";
+
+#undef TX_STATUS_FAIL
+#undef TX_STATUS_POSTPONE
+}
+#endif /* CONFIG_IWLWIFI_DEBUG */
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c
index e1dd76267dca..703621107dac 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c
@@ -38,6 +38,7 @@
 #include "iwl-helpers.h"
 #include "iwl-agn-hw.h"
 #include "iwl-agn.h"
+#include "iwl-agn-calib.h"
 
 static const s8 iwlagn_default_queue_to_tx_fifo[] = {
 	IWL_TX_FIFO_VO,
@@ -214,6 +215,25 @@ static int iwlagn_set_Xtal_calib(struct iwl_priv *priv)
 			     (u8 *)&cmd, sizeof(cmd));
 }
 
+static int iwlagn_set_temperature_offset_calib(struct iwl_priv *priv)
+{
+	struct iwl_calib_temperature_offset_cmd cmd;
+	__le16 *offset_calib =
+		(__le16 *)iwl_eeprom_query_addr(priv, EEPROM_5000_TEMPERATURE);
+	cmd.hdr.op_code = IWL_PHY_CALIBRATE_TEMP_OFFSET_CMD;
+	cmd.hdr.first_group = 0;
+	cmd.hdr.groups_num = 1;
+	cmd.hdr.data_valid = 1;
+	cmd.radio_sensor_offset = le16_to_cpu(offset_calib[1]);
+	if (!(cmd.radio_sensor_offset))
+		cmd.radio_sensor_offset = DEFAULT_RADIO_SENSOR_OFFSET;
+	cmd.reserved = 0;
+	IWL_DEBUG_CALIB(priv, "Radio sensor offset: %d\n",
+			cmd.radio_sensor_offset);
+	return iwl_calib_set(&priv->calib_results[IWL_CALIB_TEMP_OFFSET],
+			     (u8 *)&cmd, sizeof(cmd));
+}
+
 static int iwlagn_send_calib_cfg(struct iwl_priv *priv)
 {
 	struct iwl_calib_cfg_cmd calib_cfg_cmd;
@@ -320,6 +340,14 @@ void iwlagn_init_alive_start(struct iwl_priv *priv)
 
 	}
 	iwlagn_send_calib_cfg(priv);
+
+	/**
+	 * temperature offset calibration is only needed for runtime ucode,
+	 * so prepare the value now.
+	 */
+	if (priv->cfg->need_temp_offset_calib)
+		iwlagn_set_temperature_offset_calib(priv);
+
 	return;
 
 restart:
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index a6dce616ee3c..c2636a7ab9ee 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -57,7 +57,7 @@
 #include "iwl-io.h"
 #include "iwl-helpers.h"
 #include "iwl-sta.h"
-#include "iwl-calib.h"
+#include "iwl-agn-calib.h"
 #include "iwl-agn.h"
 
 
@@ -91,14 +91,14 @@ static int iwlagn_ant_coupling;
 static bool iwlagn_bt_ch_announce = 1;
 
 /**
- * iwl_commit_rxon - commit staging_rxon to hardware
+ * iwlagn_commit_rxon - commit staging_rxon to hardware
  *
  * The RXON command in staging_rxon is committed to the hardware and
  * the active_rxon structure is updated with the new data.  This
  * function correctly transitions out of the RXON_ASSOC_MSK state if
  * a HW tune is required based on the RXON structure changes.
  */
-int iwl_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
+int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
 {
 	/* cast away the const for active_rxon in this function */
 	struct iwl_rxon_cmd *active_rxon = (void *)&ctx->active;
@@ -314,24 +314,26 @@ static void iwl_free_frame(struct iwl_priv *priv, struct iwl_frame *frame)
 }
 
 static u32 iwl_fill_beacon_frame(struct iwl_priv *priv,
-					  struct ieee80211_hdr *hdr,
-					  int left)
+				 struct ieee80211_hdr *hdr,
+				 int left)
 {
-	if (!priv->ibss_beacon)
+	lockdep_assert_held(&priv->mutex);
+
+	if (!priv->beacon_skb)
 		return 0;
 
-	if (priv->ibss_beacon->len > left)
+	if (priv->beacon_skb->len > left)
 		return 0;
 
-	memcpy(hdr, priv->ibss_beacon->data, priv->ibss_beacon->len);
+	memcpy(hdr, priv->beacon_skb->data, priv->beacon_skb->len);
 
-	return priv->ibss_beacon->len;
+	return priv->beacon_skb->len;
 }
 
 /* Parse the beacon frame to find the TIM element and set tim_idx & tim_size */
 static void iwl_set_beacon_tim(struct iwl_priv *priv,
-		struct iwl_tx_beacon_cmd *tx_beacon_cmd,
-		u8 *beacon, u32 frame_size)
+			       struct iwl_tx_beacon_cmd *tx_beacon_cmd,
+			       u8 *beacon, u32 frame_size)
 {
 	u16 tim_idx;
 	struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)beacon;
@@ -383,6 +385,8 @@ static unsigned int iwl_hw_get_beacon_cmd(struct iwl_priv *priv,
 				sizeof(frame->u) - sizeof(*tx_beacon_cmd));
 	if (WARN_ON_ONCE(frame_size > MAX_MPDU_SIZE))
 		return 0;
+	if (!frame_size)
+		return 0;
 
 	/* Set up TX command fields */
 	tx_beacon_cmd->tx.len = cpu_to_le16((u16)frame_size);
@@ -393,7 +397,7 @@ static unsigned int iwl_hw_get_beacon_cmd(struct iwl_priv *priv,
 
 	/* Set up TX beacon command fields */
 	iwl_set_beacon_tim(priv, tx_beacon_cmd, (u8 *)tx_beacon_cmd->frame,
-			frame_size);
+			   frame_size);
 
 	/* Set up packet rate and flags */
 	rate = iwl_rate_get_lowest_plcp(priv, priv->beacon_ctx);
@@ -648,15 +652,14 @@ static void iwl_bg_beacon_update(struct work_struct *work)
 	/* Pull updated AP beacon from mac80211. will fail if not in AP mode */
 	beacon = ieee80211_beacon_get(priv->hw, priv->beacon_ctx->vif);
 	if (!beacon) {
-		IWL_ERR(priv, "update beacon failed\n");
+		IWL_ERR(priv, "update beacon failed -- keeping old\n");
 		goto out;
 	}
 
 	/* new beacon skb is allocated every time; dispose previous.*/
-	if (priv->ibss_beacon)
-		dev_kfree_skb(priv->ibss_beacon);
+	dev_kfree_skb(priv->beacon_skb);
 
-	priv->ibss_beacon = beacon;
+	priv->beacon_skb = beacon;
 
 	iwl_send_beacon_cmd(priv);
  out:
@@ -935,22 +938,6 @@ static void iwl_rx_card_state_notif(struct iwl_priv *priv,
 		wake_up_interruptible(&priv->wait_command_queue);
 }
 
-int iwl_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src)
-{
-	if (src == IWL_PWR_SRC_VAUX) {
-		if (pci_pme_capable(priv->pci_dev, PCI_D3cold))
-			iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG,
-					       APMG_PS_CTRL_VAL_PWR_SRC_VAUX,
-					       ~APMG_PS_CTRL_MSK_PWR_SRC);
-	} else {
-		iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG,
-				       APMG_PS_CTRL_VAL_PWR_SRC_VMAIN,
-				       ~APMG_PS_CTRL_MSK_PWR_SRC);
-	}
-
-	return 0;
-}
-
 static void iwl_bg_tx_flush(struct work_struct *work)
 {
 	struct iwl_priv *priv =
@@ -2078,7 +2065,7 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
 	struct iwlagn_ucode_capabilities ucode_capa = {
 		.max_probe_length = 200,
 		.standard_phy_calibration_size =
-			IWL_MAX_STANDARD_PHY_CALIBRATE_TBL_SIZE,
+			IWL_DEFAULT_STANDARD_PHY_CALIBRATE_TBL_SIZE,
 	};
 
 	memset(&pieces, 0, sizeof(pieces));
@@ -2120,18 +2107,23 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
 	 * firmware filename ... but we don't check for that and only rely
 	 * on the API version read from firmware header from here on forward
 	 */
-	if (api_ver < api_min || api_ver > api_max) {
-		IWL_ERR(priv, "Driver unable to support your firmware API. "
-			  "Driver supports v%u, firmware is v%u.\n",
-			  api_max, api_ver);
-		goto try_again;
-	}
+	/* no api version check required for experimental uCode */
+	if (priv->fw_index != UCODE_EXPERIMENTAL_INDEX) {
+		if (api_ver < api_min || api_ver > api_max) {
+			IWL_ERR(priv,
+				"Driver unable to support your firmware API. "
+				"Driver supports v%u, firmware is v%u.\n",
+				api_max, api_ver);
+			goto try_again;
+		}
 
-	if (api_ver != api_max)
-		IWL_ERR(priv, "Firmware has old API version. Expected v%u, "
-			  "got v%u. New firmware can be obtained "
-			  "from http://www.intellinuxwireless.org.\n",
-			  api_max, api_ver);
+		if (api_ver != api_max)
+			IWL_ERR(priv,
+				"Firmware has old API version. Expected v%u, "
+				"got v%u. New firmware can be obtained "
+				"from http://www.intellinuxwireless.org.\n",
+				api_max, api_ver);
+	}
 
 	if (build)
 		sprintf(buildstr, " build %u%s", build,
@@ -2820,9 +2812,6 @@ static void iwl_alive_start(struct iwl_priv *priv)
 		goto restart;
 	}
 
-	if (priv->hw_params.calib_rt_cfg)
-		iwlagn_send_calib_cfg_rt(priv, priv->hw_params.calib_rt_cfg);
-
 
 	/* After the ALIVE response, we can send host commands to the uCode */
 	set_bit(STATUS_ALIVE, &priv->status);
@@ -2838,6 +2827,7 @@ static void iwl_alive_start(struct iwl_priv *priv)
 	if (iwl_is_rfkill(priv))
 		return;
 
+	/* download priority table before any calibration request */
 	if (priv->cfg->bt_params &&
 	    priv->cfg->bt_params->advanced_bt_coexist) {
 		/* Configure Bluetooth device coexistence support */
@@ -2846,8 +2836,7 @@ static void iwl_alive_start(struct iwl_priv *priv)
 		priv->kill_cts_mask = IWLAGN_BT_KILL_CTS_MASK_DEFAULT;
 		priv->cfg->ops->hcmd->send_bt_config(priv);
 		priv->bt_valid = IWLAGN_BT_VALID_ENABLE_FLAGS;
-		if (bt_coex_active && priv->iw_mode != NL80211_IFTYPE_ADHOC)
-			iwlagn_send_prio_tbl(priv);
+		iwlagn_send_prio_tbl(priv);
 
 		/* FIXME: w/a to force change uCode BT state machine */
 		iwlagn_send_bt_env(priv, IWL_BT_COEX_ENV_OPEN,
@@ -2855,6 +2844,9 @@ static void iwl_alive_start(struct iwl_priv *priv)
 		iwlagn_send_bt_env(priv, IWL_BT_COEX_ENV_CLOSE,
 			BT_COEX_PRIO_TBL_EVT_INIT_CALIB2);
 	}
+	if (priv->hw_params.calib_rt_cfg)
+		iwlagn_send_calib_cfg_rt(priv, priv->hw_params.calib_rt_cfg);
+
 	ieee80211_wake_queues(priv->hw);
 
 	priv->active_rate = IWL_RATES_MASK;
@@ -2999,14 +2991,13 @@ static void __iwl_down(struct iwl_priv *priv)
 	iwl_clear_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
 
 	/* Stop the device, and put it in low power state */
-	priv->cfg->ops->lib->apm_ops.stop(priv);
+	iwl_apm_stop(priv);
 
  exit:
 	memset(&priv->card_alive, 0, sizeof(struct iwl_alive_resp));
 
-	if (priv->ibss_beacon)
-		dev_kfree_skb(priv->ibss_beacon);
-	priv->ibss_beacon = NULL;
+	dev_kfree_skb(priv->beacon_skb);
+	priv->beacon_skb = NULL;
 
 	/* clear out any free frames */
 	iwl_clear_free_frames(priv);
@@ -3089,7 +3080,7 @@ static int __iwl_up(struct iwl_priv *priv)
 	}
 
 	for_each_context(priv, ctx) {
-		ret = iwl_alloc_bcast_station(priv, ctx, true);
+		ret = iwlagn_alloc_bcast_station(priv, ctx);
 		if (ret) {
 			iwl_dealloc_bcast_stations(priv);
 			return ret;
@@ -4142,8 +4133,6 @@ static int iwl_init_drv(struct iwl_priv *priv)
 {
 	int ret;
 
-	priv->ibss_beacon = NULL;
-
 	spin_lock_init(&priv->sta_lock);
 	spin_lock_init(&priv->hcmd_lock);
 
@@ -4613,7 +4602,7 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev)
 	 * paths to avoid running iwl_down() at all before leaving driver.
 	 * This (inexpensive) call *makes sure* device is reset.
 	 */
-	priv->cfg->ops->lib->apm_ops.stop(priv);
+	iwl_apm_stop(priv);
 
 	iwl_tt_exit(priv);
 
@@ -4656,8 +4645,7 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev)
 
 	iwl_free_isr_ict(priv);
 
-	if (priv->ibss_beacon)
-		dev_kfree_skb(priv->ibss_beacon);
+	dev_kfree_skb(priv->beacon_skb);
 
 	ieee80211_free_hw(priv->hw);
 }
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h
index eb3812a35862..f525d55f2c0f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.h
@@ -129,6 +129,10 @@ void iwlagn_txq_set_sched(struct iwl_priv *priv, u32 mask);
 void iwl_free_tfds_in_queue(struct iwl_priv *priv,
 			    int sta_id, int tid, int freed);
 
+/* RXON */
+int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx);
+void iwlagn_set_rxon_chain(struct iwl_priv *priv, struct iwl_rxon_context *ctx);
+
 /* uCode */
 int iwlagn_load_ucode(struct iwl_priv *priv);
 void iwlagn_rx_calib_result(struct iwl_priv *priv,
@@ -158,6 +162,8 @@ int iwlagn_hw_nic_init(struct iwl_priv *priv);
 int iwlagn_wait_tx_queue_empty(struct iwl_priv *priv);
 int iwlagn_txfifo_flush(struct iwl_priv *priv, u16 flush_control);
 void iwlagn_dev_txfifo_flush(struct iwl_priv *priv, u16 flush_control);
+void iwl_dump_csr(struct iwl_priv *priv);
+int iwl_dump_fh(struct iwl_priv *priv, char **buf, bool display);
 
 /* rx */
 void iwlagn_rx_queue_restock(struct iwl_priv *priv);
@@ -171,8 +177,15 @@ void iwlagn_rx_reply_rx(struct iwl_priv *priv,
 		     struct iwl_rx_mem_buffer *rxb);
 void iwlagn_rx_reply_rx_phy(struct iwl_priv *priv,
 			 struct iwl_rx_mem_buffer *rxb);
+void iwl_rx_handle(struct iwl_priv *priv);
 
 /* tx */
+void iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq);
+int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv,
+				 struct iwl_tx_queue *txq,
+				 dma_addr_t addr, u16 len, u8 reset, u8 pad);
+int iwl_hw_tx_queue_init(struct iwl_priv *priv,
+			 struct iwl_tx_queue *txq);
 void iwlagn_hwrate_to_tx_control(struct iwl_priv *priv, u32 rate_n_flags,
 			      struct ieee80211_tx_info *info);
 int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb);
@@ -212,6 +225,8 @@ static inline bool iwl_is_tx_success(u32 status)
 	       (status == TX_STATUS_DIRECT_DONE);
 }
 
+u8 iwl_toggle_tx_ant(struct iwl_priv *priv, u8 ant_idx, u8 valid);
+
 /* rx */
 void iwl_rx_missed_beacon_notif(struct iwl_priv *priv,
 				struct iwl_rx_mem_buffer *rxb);
@@ -224,6 +239,7 @@ void iwl_reply_statistics(struct iwl_priv *priv,
 
 /* scan */
 int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif);
+void iwlagn_post_scan(struct iwl_priv *priv);
 
 /* station mgmt */
 int iwlagn_manage_ibss_station(struct iwl_priv *priv,
@@ -243,8 +259,63 @@ void iwlagn_bt_setup_deferred_work(struct iwl_priv *priv);
 void iwlagn_bt_cancel_deferred_work(struct iwl_priv *priv);
 
 #ifdef CONFIG_IWLWIFI_DEBUG
+const char *iwl_get_tx_fail_reason(u32 status);
 const char *iwl_get_agg_tx_fail_reason(u16 status);
 #else
+static inline const char *iwl_get_tx_fail_reason(u32 status) { return ""; }
 static inline const char *iwl_get_agg_tx_fail_reason(u16 status) { return ""; }
 #endif
+
+/* station management */
+int iwlagn_alloc_bcast_station(struct iwl_priv *priv,
+			       struct iwl_rxon_context *ctx);
+int iwlagn_add_bssid_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
+			     const u8 *addr, u8 *sta_id_r);
+int iwl_remove_default_wep_key(struct iwl_priv *priv,
+			       struct iwl_rxon_context *ctx,
+			       struct ieee80211_key_conf *key);
+int iwl_set_default_wep_key(struct iwl_priv *priv,
+			    struct iwl_rxon_context *ctx,
+			    struct ieee80211_key_conf *key);
+int iwl_restore_default_wep_keys(struct iwl_priv *priv,
+				 struct iwl_rxon_context *ctx);
+int iwl_set_dynamic_key(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
+			struct ieee80211_key_conf *key, u8 sta_id);
+int iwl_remove_dynamic_key(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
+			   struct ieee80211_key_conf *key, u8 sta_id);
+void iwl_update_tkip_key(struct iwl_priv *priv,
+			 struct iwl_rxon_context *ctx,
+			 struct ieee80211_key_conf *keyconf,
+			 struct ieee80211_sta *sta, u32 iv32, u16 *phase1key);
+int iwl_sta_tx_modify_enable_tid(struct iwl_priv *priv, int sta_id, int tid);
+int iwl_sta_rx_agg_start(struct iwl_priv *priv, struct ieee80211_sta *sta,
+			 int tid, u16 ssn);
+int iwl_sta_rx_agg_stop(struct iwl_priv *priv, struct ieee80211_sta *sta,
+			int tid);
+void iwl_sta_modify_ps_wake(struct iwl_priv *priv, int sta_id);
+void iwl_sta_modify_sleep_tx_count(struct iwl_priv *priv, int sta_id, int cnt);
+int iwl_update_bcast_stations(struct iwl_priv *priv);
+
+/* rate */
+static inline u32 iwl_ant_idx_to_flags(u8 ant_idx)
+{
+	return BIT(ant_idx) << RATE_MCS_ANT_POS;
+}
+
+static inline u8 iwl_hw_get_rate(__le32 rate_n_flags)
+{
+	return le32_to_cpu(rate_n_flags) & 0xFF;
+}
+
+static inline __le32 iwl_hw_set_rate_n_flags(u8 rate, u32 flags)
+{
+	return cpu_to_le32(flags|(u32)rate);
+}
+
+/* eeprom */
+void iwlcore_eeprom_enhanced_txpower(struct iwl_priv *priv);
+void iwl_eeprom_get_mac(const struct iwl_priv *priv, u8 *mac);
+int iwlcore_eeprom_acquire_semaphore(struct iwl_priv *priv);
+void iwlcore_eeprom_release_semaphore(struct iwl_priv *priv);
+
 #endif /* __iwl_agn_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h
index fe652568fec7..424801abc80e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-commands.h
+++ b/drivers/net/wireless/iwlwifi/iwl-commands.h
@@ -3784,7 +3784,8 @@ struct iwl_enhance_sensitivity_cmd {
  */
 
 /* Phy calibration command for series */
-
+/* The default calibrate table size if not specified by firmware */
+#define IWL_DEFAULT_STANDARD_PHY_CALIBRATE_TBL_SIZE	18
 enum {
 	IWL_PHY_CALIBRATE_DIFF_GAIN_CMD		= 7,
 	IWL_PHY_CALIBRATE_DC_CMD		= 8,
@@ -3793,7 +3794,8 @@ enum {
 	IWL_PHY_CALIBRATE_CRYSTAL_FRQ_CMD	= 15,
 	IWL_PHY_CALIBRATE_BASE_BAND_CMD		= 16,
 	IWL_PHY_CALIBRATE_TX_IQ_PERD_CMD	= 17,
-	IWL_MAX_STANDARD_PHY_CALIBRATE_TBL_SIZE	= 18,
+	IWL_PHY_CALIBRATE_TEMP_OFFSET_CMD	= 18,
+	IWL_MAX_STANDARD_PHY_CALIBRATE_TBL_SIZE	= 19,
 };
 
 #define IWL_MAX_PHY_CALIBRATE_TBL_SIZE		(253)
@@ -3863,6 +3865,13 @@ struct iwl_calib_xtal_freq_cmd {
 	u8 pad[2];
 } __packed;
 
+#define DEFAULT_RADIO_SENSOR_OFFSET    2700
+struct iwl_calib_temperature_offset_cmd {
+	struct iwl_calib_hdr hdr;
+	s16 radio_sensor_offset;
+	s16 reserved;
+} __packed;
+
 /* IWL_PHY_CALIBRATE_CHAIN_NOISE_RESET_CMD */
 struct iwl_calib_chain_noise_reset_cmd {
 	struct iwl_calib_hdr hdr;
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index 516c55ae38aa..25fb3912342c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -69,97 +69,9 @@ EXPORT_SYMBOL_GPL(bt_coex_active);
 module_param(bt_coex_active, bool, S_IRUGO);
 MODULE_PARM_DESC(bt_coex_active, "enable wifi/bluetooth co-exist");
 
-#define IWL_DECLARE_RATE_INFO(r, s, ip, in, rp, rn, pp, np)    \
-	[IWL_RATE_##r##M_INDEX] = { IWL_RATE_##r##M_PLCP,      \
-				    IWL_RATE_SISO_##s##M_PLCP, \
-				    IWL_RATE_MIMO2_##s##M_PLCP,\
-				    IWL_RATE_MIMO3_##s##M_PLCP,\
-				    IWL_RATE_##r##M_IEEE,      \
-				    IWL_RATE_##ip##M_INDEX,    \
-				    IWL_RATE_##in##M_INDEX,    \
-				    IWL_RATE_##rp##M_INDEX,    \
-				    IWL_RATE_##rn##M_INDEX,    \
-				    IWL_RATE_##pp##M_INDEX,    \
-				    IWL_RATE_##np##M_INDEX }
-
 u32 iwl_debug_level;
 EXPORT_SYMBOL(iwl_debug_level);
 
-/*
- * Parameter order:
- *   rate, ht rate, prev rate, next rate, prev tgg rate, next tgg rate
- *
- * If there isn't a valid next or previous rate then INV is used which
- * maps to IWL_RATE_INVALID
- *
- */
-const struct iwl_rate_info iwl_rates[IWL_RATE_COUNT] = {
-	IWL_DECLARE_RATE_INFO(1, INV, INV, 2, INV, 2, INV, 2),    /*  1mbps */
-	IWL_DECLARE_RATE_INFO(2, INV, 1, 5, 1, 5, 1, 5),          /*  2mbps */
-	IWL_DECLARE_RATE_INFO(5, INV, 2, 6, 2, 11, 2, 11),        /*5.5mbps */
-	IWL_DECLARE_RATE_INFO(11, INV, 9, 12, 9, 12, 5, 18),      /* 11mbps */
-	IWL_DECLARE_RATE_INFO(6, 6, 5, 9, 5, 11, 5, 11),        /*  6mbps */
-	IWL_DECLARE_RATE_INFO(9, 6, 6, 11, 6, 11, 5, 11),       /*  9mbps */
-	IWL_DECLARE_RATE_INFO(12, 12, 11, 18, 11, 18, 11, 18),   /* 12mbps */
-	IWL_DECLARE_RATE_INFO(18, 18, 12, 24, 12, 24, 11, 24),   /* 18mbps */
-	IWL_DECLARE_RATE_INFO(24, 24, 18, 36, 18, 36, 18, 36),   /* 24mbps */
-	IWL_DECLARE_RATE_INFO(36, 36, 24, 48, 24, 48, 24, 48),   /* 36mbps */
-	IWL_DECLARE_RATE_INFO(48, 48, 36, 54, 36, 54, 36, 54),   /* 48mbps */
-	IWL_DECLARE_RATE_INFO(54, 54, 48, INV, 48, INV, 48, INV),/* 54mbps */
-	IWL_DECLARE_RATE_INFO(60, 60, 48, INV, 48, INV, 48, INV),/* 60mbps */
-	/* FIXME:RS:          ^^    should be INV (legacy) */
-};
-EXPORT_SYMBOL(iwl_rates);
-
-int iwl_hwrate_to_plcp_idx(u32 rate_n_flags)
-{
-	int idx = 0;
-
-	/* HT rate format */
-	if (rate_n_flags & RATE_MCS_HT_MSK) {
-		idx = (rate_n_flags & 0xff);
-
-		if (idx >= IWL_RATE_MIMO3_6M_PLCP)
-			idx = idx - IWL_RATE_MIMO3_6M_PLCP;
-		else if (idx >= IWL_RATE_MIMO2_6M_PLCP)
-			idx = idx - IWL_RATE_MIMO2_6M_PLCP;
-
-		idx += IWL_FIRST_OFDM_RATE;
-		/* skip 9M not supported in ht*/
-		if (idx >= IWL_RATE_9M_INDEX)
-			idx += 1;
-		if ((idx >= IWL_FIRST_OFDM_RATE) && (idx <= IWL_LAST_OFDM_RATE))
-			return idx;
-
-	/* legacy rate format, search for match in table */
-	} else {
-		for (idx = 0; idx < ARRAY_SIZE(iwl_rates); idx++)
-			if (iwl_rates[idx].plcp == (rate_n_flags & 0xFF))
-				return idx;
-	}
-
-	return -1;
-}
-EXPORT_SYMBOL(iwl_hwrate_to_plcp_idx);
-
-u8 iwl_toggle_tx_ant(struct iwl_priv *priv, u8 ant, u8 valid)
-{
-	int i;
-	u8 ind = ant;
-
-	if (priv->band == IEEE80211_BAND_2GHZ &&
-	    priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH)
-		return 0;
-
-	for (i = 0; i < RATE_ANT_NUM - 1; i++) {
-		ind = (ind + 1) < RATE_ANT_NUM ?  ind + 1 : 0;
-		if (valid & BIT(ind))
-			return ind;
-	}
-	return ant;
-}
-EXPORT_SYMBOL(iwl_toggle_tx_ant);
-
 const u8 iwl_bcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
 EXPORT_SYMBOL(iwl_bcast_addr);
 
@@ -439,12 +351,6 @@ void iwlcore_tx_cmd_protection(struct iwl_priv *priv,
 EXPORT_SYMBOL(iwlcore_tx_cmd_protection);
 
 
-static bool is_single_rx_stream(struct iwl_priv *priv)
-{
-	return priv->current_ht_config.smps == IEEE80211_SMPS_STATIC ||
-	       priv->current_ht_config.single_chain_sufficient;
-}
-
 static bool iwl_is_channel_extension(struct iwl_priv *priv,
 				     enum ieee80211_band band,
 				     u16 channel, u8 extension_chan_offset)
@@ -604,76 +510,74 @@ void iwl_set_rxon_hwcrypto(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
 }
 EXPORT_SYMBOL(iwl_set_rxon_hwcrypto);
 
-/**
- * iwl_check_rxon_cmd - validate RXON structure is valid
- *
- * NOTE:  This is really only useful during development and can eventually
- * be #ifdef'd out once the driver is stable and folks aren't actively
- * making changes
- */
+/* validate RXON structure is valid */
 int iwl_check_rxon_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
 {
-	int error = 0;
-	int counter = 1;
 	struct iwl_rxon_cmd *rxon = &ctx->staging;
+	bool error = false;
 
 	if (rxon->flags & RXON_FLG_BAND_24G_MSK) {
-		error |= le32_to_cpu(rxon->flags &
-				(RXON_FLG_TGJ_NARROW_BAND_MSK |
-				 RXON_FLG_RADAR_DETECT_MSK));
-		if (error)
-			IWL_WARN(priv, "check 24G fields %d | %d\n",
-				    counter++, error);
+		if (rxon->flags & RXON_FLG_TGJ_NARROW_BAND_MSK) {
+			IWL_WARN(priv, "check 2.4G: wrong narrow\n");
+			error = true;
+		}
+		if (rxon->flags & RXON_FLG_RADAR_DETECT_MSK) {
+			IWL_WARN(priv, "check 2.4G: wrong radar\n");
+			error = true;
+		}
 	} else {
-		error |= (rxon->flags & RXON_FLG_SHORT_SLOT_MSK) ?
-				0 : le32_to_cpu(RXON_FLG_SHORT_SLOT_MSK);
-		if (error)
-			IWL_WARN(priv, "check 52 fields %d | %d\n",
-				    counter++, error);
-		error |= le32_to_cpu(rxon->flags & RXON_FLG_CCK_MSK);
-		if (error)
-			IWL_WARN(priv, "check 52 CCK %d | %d\n",
-				    counter++, error);
-	}
-	error |= (rxon->node_addr[0] | rxon->bssid_addr[0]) & 0x1;
-	if (error)
-		IWL_WARN(priv, "check mac addr %d | %d\n", counter++, error);
+		if (!(rxon->flags & RXON_FLG_SHORT_SLOT_MSK)) {
+			IWL_WARN(priv, "check 5.2G: not short slot!\n");
+			error = true;
+		}
+		if (rxon->flags & RXON_FLG_CCK_MSK) {
+			IWL_WARN(priv, "check 5.2G: CCK!\n");
+			error = true;
+		}
+	}
+	if ((rxon->node_addr[0] | rxon->bssid_addr[0]) & 0x1) {
+		IWL_WARN(priv, "mac/bssid mcast!\n");
+		error = true;
+	}
 
 	/* make sure basic rates 6Mbps and 1Mbps are supported */
-	error |= (((rxon->ofdm_basic_rates & IWL_RATE_6M_MASK) == 0) &&
-		  ((rxon->cck_basic_rates & IWL_RATE_1M_MASK) == 0));
-	if (error)
-		IWL_WARN(priv, "check basic rate %d | %d\n", counter++, error);
+	if ((rxon->ofdm_basic_rates & IWL_RATE_6M_MASK) == 0 &&
+	    (rxon->cck_basic_rates & IWL_RATE_1M_MASK) == 0) {
+		IWL_WARN(priv, "neither 1 nor 6 are basic\n");
+		error = true;
+	}
 
-	error |= (le16_to_cpu(rxon->assoc_id) > 2007);
-	if (error)
-		IWL_WARN(priv, "check assoc id %d | %d\n", counter++, error);
+	if (le16_to_cpu(rxon->assoc_id) > 2007) {
+		IWL_WARN(priv, "aid > 2007\n");
+		error = true;
+	}
 
-	error |= ((rxon->flags & (RXON_FLG_CCK_MSK | RXON_FLG_SHORT_SLOT_MSK))
-			== (RXON_FLG_CCK_MSK | RXON_FLG_SHORT_SLOT_MSK));
-	if (error)
-		IWL_WARN(priv, "check CCK and short slot %d | %d\n",
-			    counter++, error);
+	if ((rxon->flags & (RXON_FLG_CCK_MSK | RXON_FLG_SHORT_SLOT_MSK))
+			== (RXON_FLG_CCK_MSK | RXON_FLG_SHORT_SLOT_MSK)) {
+		IWL_WARN(priv, "CCK and short slot\n");
+		error = true;
+	}
 
-	error |= ((rxon->flags & (RXON_FLG_CCK_MSK | RXON_FLG_AUTO_DETECT_MSK))
-			== (RXON_FLG_CCK_MSK | RXON_FLG_AUTO_DETECT_MSK));
-	if (error)
-		IWL_WARN(priv, "check CCK & auto detect %d | %d\n",
-			    counter++, error);
+	if ((rxon->flags & (RXON_FLG_CCK_MSK | RXON_FLG_AUTO_DETECT_MSK))
+			== (RXON_FLG_CCK_MSK | RXON_FLG_AUTO_DETECT_MSK)) {
+		IWL_WARN(priv, "CCK and auto detect");
+		error = true;
+	}
 
-	error |= ((rxon->flags & (RXON_FLG_AUTO_DETECT_MSK |
-			RXON_FLG_TGG_PROTECT_MSK)) == RXON_FLG_TGG_PROTECT_MSK);
-	if (error)
-		IWL_WARN(priv, "check TGG and auto detect %d | %d\n",
-			    counter++, error);
+	if ((rxon->flags & (RXON_FLG_AUTO_DETECT_MSK |
+			    RXON_FLG_TGG_PROTECT_MSK)) ==
+			    RXON_FLG_TGG_PROTECT_MSK) {
+		IWL_WARN(priv, "TGg but no auto-detect\n");
+		error = true;
+	}
 
 	if (error)
 		IWL_WARN(priv, "Tuning to channel %d\n",
 			    le16_to_cpu(rxon->channel));
 
 	if (error) {
-		IWL_ERR(priv, "Not a valid iwl_rxon_assoc_cmd field values\n");
-		return -1;
+		IWL_ERR(priv, "Invalid RXON\n");
+		return -EINVAL;
 	}
 	return 0;
 }
@@ -834,141 +738,6 @@ void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_config *ht_conf)
 }
 EXPORT_SYMBOL(iwl_set_rxon_ht);
 
-#define IWL_NUM_RX_CHAINS_MULTIPLE	3
-#define IWL_NUM_RX_CHAINS_SINGLE	2
-#define IWL_NUM_IDLE_CHAINS_DUAL	2
-#define IWL_NUM_IDLE_CHAINS_SINGLE	1
-
-/*
- * Determine how many receiver/antenna chains to use.
- *
- * More provides better reception via diversity.  Fewer saves power
- * at the expense of throughput, but only when not in powersave to
- * start with.
- *
- * MIMO (dual stream) requires at least 2, but works better with 3.
- * This does not determine *which* chains to use, just how many.
- */
-static int iwl_get_active_rx_chain_count(struct iwl_priv *priv)
-{
-	if (priv->cfg->bt_params &&
-	    priv->cfg->bt_params->advanced_bt_coexist &&
-	    (priv->bt_full_concurrent ||
-	     priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH)) {
-		/*
-		 * only use chain 'A' in bt high traffic load or
-		 * full concurrency mode
-		 */
-		return IWL_NUM_RX_CHAINS_SINGLE;
-	}
-	/* # of Rx chains to use when expecting MIMO. */
-	if (is_single_rx_stream(priv))
-		return IWL_NUM_RX_CHAINS_SINGLE;
-	else
-		return IWL_NUM_RX_CHAINS_MULTIPLE;
-}
-
-/*
- * When we are in power saving mode, unless device support spatial
- * multiplexing power save, use the active count for rx chain count.
- */
-static int iwl_get_idle_rx_chain_count(struct iwl_priv *priv, int active_cnt)
-{
-	/* # Rx chains when idling, depending on SMPS mode */
-	switch (priv->current_ht_config.smps) {
-	case IEEE80211_SMPS_STATIC:
-	case IEEE80211_SMPS_DYNAMIC:
-		return IWL_NUM_IDLE_CHAINS_SINGLE;
-	case IEEE80211_SMPS_OFF:
-		return active_cnt;
-	default:
-		WARN(1, "invalid SMPS mode %d",
-		     priv->current_ht_config.smps);
-		return active_cnt;
-	}
-}
-
-/* up to 4 chains */
-static u8 iwl_count_chain_bitmap(u32 chain_bitmap)
-{
-	u8 res;
-	res = (chain_bitmap & BIT(0)) >> 0;
-	res += (chain_bitmap & BIT(1)) >> 1;
-	res += (chain_bitmap & BIT(2)) >> 2;
-	res += (chain_bitmap & BIT(3)) >> 3;
-	return res;
-}
-
-/**
- * iwl_set_rxon_chain - Set up Rx chain usage in "staging" RXON image
- *
- * Selects how many and which Rx receivers/antennas/chains to use.
- * This should not be used for scan command ... it puts data in wrong place.
- */
-void iwl_set_rxon_chain(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
-{
-	bool is_single = is_single_rx_stream(priv);
-	bool is_cam = !test_bit(STATUS_POWER_PMI, &priv->status);
-	u8 idle_rx_cnt, active_rx_cnt, valid_rx_cnt;
-	u32 active_chains;
-	u16 rx_chain;
-
-	/* Tell uCode which antennas are actually connected.
-	 * Before first association, we assume all antennas are connected.
-	 * Just after first association, iwl_chain_noise_calibration()
-	 *    checks which antennas actually *are* connected. */
-	if (priv->chain_noise_data.active_chains)
-		active_chains = priv->chain_noise_data.active_chains;
-	else
-		active_chains = priv->hw_params.valid_rx_ant;
-
-	if (priv->cfg->bt_params &&
-	    priv->cfg->bt_params->advanced_bt_coexist &&
-	    (priv->bt_full_concurrent ||
-	     priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH)) {
-		/*
-		 * only use chain 'A' in bt high traffic load or
-		 * full concurrency mode
-		 */
-		active_chains = first_antenna(active_chains);
-	}
-
-	rx_chain = active_chains << RXON_RX_CHAIN_VALID_POS;
-
-	/* How many receivers should we use? */
-	active_rx_cnt = iwl_get_active_rx_chain_count(priv);
-	idle_rx_cnt = iwl_get_idle_rx_chain_count(priv, active_rx_cnt);
-
-
-	/* correct rx chain count according hw settings
-	 * and chain noise calibration
-	 */
-	valid_rx_cnt = iwl_count_chain_bitmap(active_chains);
-	if (valid_rx_cnt < active_rx_cnt)
-		active_rx_cnt = valid_rx_cnt;
-
-	if (valid_rx_cnt < idle_rx_cnt)
-		idle_rx_cnt = valid_rx_cnt;
-
-	rx_chain |= active_rx_cnt << RXON_RX_CHAIN_MIMO_CNT_POS;
-	rx_chain |= idle_rx_cnt  << RXON_RX_CHAIN_CNT_POS;
-
-	ctx->staging.rx_chain = cpu_to_le16(rx_chain);
-
-	if (!is_single && (active_rx_cnt >= IWL_NUM_RX_CHAINS_SINGLE) && is_cam)
-		ctx->staging.rx_chain |= RXON_RX_CHAIN_MIMO_FORCE_MSK;
-	else
-		ctx->staging.rx_chain &= ~RXON_RX_CHAIN_MIMO_FORCE_MSK;
-
-	IWL_DEBUG_ASSOC(priv, "rx_chain=0x%X active=%d idle=%d\n",
-			ctx->staging.rx_chain,
-			active_rx_cnt, idle_rx_cnt);
-
-	WARN_ON(active_rx_cnt == 0 || idle_rx_cnt == 0 ||
-		active_rx_cnt < idle_rx_cnt);
-}
-EXPORT_SYMBOL(iwl_set_rxon_chain);
-
 /* Return valid, unused, channel for a passive scan to reset the RF */
 u8 iwl_get_single_channel_number(struct iwl_priv *priv,
 				 enum ieee80211_band band)
@@ -1758,43 +1527,47 @@ static inline void iwl_set_no_assoc(struct iwl_priv *priv,
 	iwlcore_commit_rxon(priv, ctx);
 }
 
-static int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
+static void iwlcore_beacon_update(struct ieee80211_hw *hw,
+				  struct ieee80211_vif *vif)
 {
 	struct iwl_priv *priv = hw->priv;
 	unsigned long flags;
 	__le64 timestamp;
+	struct sk_buff *skb = ieee80211_beacon_get(hw, vif);
 
-	IWL_DEBUG_MAC80211(priv, "enter\n");
+	if (!skb)
+		return;
+
+	IWL_DEBUG_ASSOC(priv, "enter\n");
 
 	lockdep_assert_held(&priv->mutex);
 
 	if (!priv->beacon_ctx) {
 		IWL_ERR(priv, "update beacon but no beacon context!\n");
 		dev_kfree_skb(skb);
-		return -EINVAL;
-	}
-
-	if (!iwl_is_ready_rf(priv)) {
-		IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n");
-		return -EIO;
+		return;
 	}
 
 	spin_lock_irqsave(&priv->lock, flags);
 
-	if (priv->ibss_beacon)
-		dev_kfree_skb(priv->ibss_beacon);
+	if (priv->beacon_skb)
+		dev_kfree_skb(priv->beacon_skb);
 
-	priv->ibss_beacon = skb;
+	priv->beacon_skb = skb;
 
 	timestamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp;
 	priv->timestamp = le64_to_cpu(timestamp);
 
-	IWL_DEBUG_MAC80211(priv, "leave\n");
+	IWL_DEBUG_ASSOC(priv, "leave\n");
+
 	spin_unlock_irqrestore(&priv->lock, flags);
 
-	priv->cfg->ops->lib->post_associate(priv, priv->beacon_ctx->vif);
+	if (!iwl_is_ready_rf(priv)) {
+		IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n");
+		return;
+	}
 
-	return 0;
+	priv->cfg->ops->lib->post_associate(priv, priv->beacon_ctx->vif);
 }
 
 void iwl_bss_info_changed(struct ieee80211_hw *hw,
@@ -1835,8 +1608,8 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw,
 	}
 
 	if (changes & BSS_CHANGED_BEACON && vif->type == NL80211_IFTYPE_AP) {
-		dev_kfree_skb(priv->ibss_beacon);
-		priv->ibss_beacon = ieee80211_beacon_get(hw, vif);
+		dev_kfree_skb(priv->beacon_skb);
+		priv->beacon_skb = ieee80211_beacon_get(hw, vif);
 	}
 
 	if (changes & BSS_CHANGED_BEACON_INT && vif->type == NL80211_IFTYPE_AP)
@@ -1876,13 +1649,8 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw,
 	 * mac80211 decides to do both changes at once because
 	 * it will invoke post_associate.
 	 */
-	if (vif->type == NL80211_IFTYPE_ADHOC &&
-	    changes & BSS_CHANGED_BEACON) {
-		struct sk_buff *beacon = ieee80211_beacon_get(hw, vif);
-
-		if (beacon)
-			iwl_mac_beacon_update(hw, beacon);
-	}
+	if (vif->type == NL80211_IFTYPE_ADHOC && changes & BSS_CHANGED_BEACON)
+		iwlcore_beacon_update(hw, vif);
 
 	if (changes & BSS_CHANGED_ERP_PREAMBLE) {
 		IWL_DEBUG_MAC80211(priv, "ERP_PREAMBLE %d\n",
@@ -1959,6 +1727,7 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw,
 			memcpy(ctx->staging.bssid_addr,
 			       bss_conf->bssid, ETH_ALEN);
 			memcpy(priv->bssid, bss_conf->bssid, ETH_ALEN);
+			iwl_led_associate(priv);
 			iwlcore_config_ap(priv, vif);
 		} else
 			iwl_set_no_assoc(priv, vif);
@@ -2290,10 +2059,10 @@ void iwl_mac_reset_tsf(struct ieee80211_hw *hw)
 	spin_lock_irqsave(&priv->lock, flags);
 
 	/* new association get rid of ibss beacon skb */
-	if (priv->ibss_beacon)
-		dev_kfree_skb(priv->ibss_beacon);
+	if (priv->beacon_skb)
+		dev_kfree_skb(priv->beacon_skb);
 
-	priv->ibss_beacon = NULL;
+	priv->beacon_skb = NULL;
 
 	priv->timestamp = 0;
 
@@ -2581,140 +2350,6 @@ void iwl_update_stats(struct iwl_priv *priv, bool is_tx, __le16 fc, u16 len)
 EXPORT_SYMBOL(iwl_update_stats);
 #endif
 
-static const char *get_csr_string(int cmd)
-{
-	switch (cmd) {
-		IWL_CMD(CSR_HW_IF_CONFIG_REG);
-		IWL_CMD(CSR_INT_COALESCING);
-		IWL_CMD(CSR_INT);
-		IWL_CMD(CSR_INT_MASK);
-		IWL_CMD(CSR_FH_INT_STATUS);
-		IWL_CMD(CSR_GPIO_IN);
-		IWL_CMD(CSR_RESET);
-		IWL_CMD(CSR_GP_CNTRL);
-		IWL_CMD(CSR_HW_REV);
-		IWL_CMD(CSR_EEPROM_REG);
-		IWL_CMD(CSR_EEPROM_GP);
-		IWL_CMD(CSR_OTP_GP_REG);
-		IWL_CMD(CSR_GIO_REG);
-		IWL_CMD(CSR_GP_UCODE_REG);
-		IWL_CMD(CSR_GP_DRIVER_REG);
-		IWL_CMD(CSR_UCODE_DRV_GP1);
-		IWL_CMD(CSR_UCODE_DRV_GP2);
-		IWL_CMD(CSR_LED_REG);
-		IWL_CMD(CSR_DRAM_INT_TBL_REG);
-		IWL_CMD(CSR_GIO_CHICKEN_BITS);
-		IWL_CMD(CSR_ANA_PLL_CFG);
-		IWL_CMD(CSR_HW_REV_WA_REG);
-		IWL_CMD(CSR_DBG_HPET_MEM_REG);
-	default:
-		return "UNKNOWN";
-
-	}
-}
-
-void iwl_dump_csr(struct iwl_priv *priv)
-{
-	int i;
-	u32 csr_tbl[] = {
-		CSR_HW_IF_CONFIG_REG,
-		CSR_INT_COALESCING,
-		CSR_INT,
-		CSR_INT_MASK,
-		CSR_FH_INT_STATUS,
-		CSR_GPIO_IN,
-		CSR_RESET,
-		CSR_GP_CNTRL,
-		CSR_HW_REV,
-		CSR_EEPROM_REG,
-		CSR_EEPROM_GP,
-		CSR_OTP_GP_REG,
-		CSR_GIO_REG,
-		CSR_GP_UCODE_REG,
-		CSR_GP_DRIVER_REG,
-		CSR_UCODE_DRV_GP1,
-		CSR_UCODE_DRV_GP2,
-		CSR_LED_REG,
-		CSR_DRAM_INT_TBL_REG,
-		CSR_GIO_CHICKEN_BITS,
-		CSR_ANA_PLL_CFG,
-		CSR_HW_REV_WA_REG,
-		CSR_DBG_HPET_MEM_REG
-	};
-	IWL_ERR(priv, "CSR values:\n");
-	IWL_ERR(priv, "(2nd byte of CSR_INT_COALESCING is "
-		"CSR_INT_PERIODIC_REG)\n");
-	for (i = 0; i <  ARRAY_SIZE(csr_tbl); i++) {
-		IWL_ERR(priv, "  %25s: 0X%08x\n",
-			get_csr_string(csr_tbl[i]),
-			iwl_read32(priv, csr_tbl[i]));
-	}
-}
-EXPORT_SYMBOL(iwl_dump_csr);
-
-static const char *get_fh_string(int cmd)
-{
-	switch (cmd) {
-		IWL_CMD(FH_RSCSR_CHNL0_STTS_WPTR_REG);
-		IWL_CMD(FH_RSCSR_CHNL0_RBDCB_BASE_REG);
-		IWL_CMD(FH_RSCSR_CHNL0_WPTR);
-		IWL_CMD(FH_MEM_RCSR_CHNL0_CONFIG_REG);
-		IWL_CMD(FH_MEM_RSSR_SHARED_CTRL_REG);
-		IWL_CMD(FH_MEM_RSSR_RX_STATUS_REG);
-		IWL_CMD(FH_MEM_RSSR_RX_ENABLE_ERR_IRQ2DRV);
-		IWL_CMD(FH_TSSR_TX_STATUS_REG);
-		IWL_CMD(FH_TSSR_TX_ERROR_REG);
-	default:
-		return "UNKNOWN";
-
-	}
-}
-
-int iwl_dump_fh(struct iwl_priv *priv, char **buf, bool display)
-{
-	int i;
-#ifdef CONFIG_IWLWIFI_DEBUG
-	int pos = 0;
-	size_t bufsz = 0;
-#endif
-	u32 fh_tbl[] = {
-		FH_RSCSR_CHNL0_STTS_WPTR_REG,
-		FH_RSCSR_CHNL0_RBDCB_BASE_REG,
-		FH_RSCSR_CHNL0_WPTR,
-		FH_MEM_RCSR_CHNL0_CONFIG_REG,
-		FH_MEM_RSSR_SHARED_CTRL_REG,
-		FH_MEM_RSSR_RX_STATUS_REG,
-		FH_MEM_RSSR_RX_ENABLE_ERR_IRQ2DRV,
-		FH_TSSR_TX_STATUS_REG,
-		FH_TSSR_TX_ERROR_REG
-	};
-#ifdef CONFIG_IWLWIFI_DEBUG
-	if (display) {
-		bufsz = ARRAY_SIZE(fh_tbl) * 48 + 40;
-		*buf = kmalloc(bufsz, GFP_KERNEL);
-		if (!*buf)
-			return -ENOMEM;
-		pos += scnprintf(*buf + pos, bufsz - pos,
-				"FH register values:\n");
-		for (i = 0; i < ARRAY_SIZE(fh_tbl); i++) {
-			pos += scnprintf(*buf + pos, bufsz - pos,
-				"  %34s: 0X%08x\n",
-				get_fh_string(fh_tbl[i]),
-				iwl_read_direct32(priv, fh_tbl[i]));
-		}
-		return pos;
-	}
-#endif
-	IWL_ERR(priv, "FH register values:\n");
-	for (i = 0; i <  ARRAY_SIZE(fh_tbl); i++) {
-		IWL_ERR(priv, "  %34s: 0X%08x\n",
-			get_fh_string(fh_tbl[i]),
-			iwl_read_direct32(priv, fh_tbl[i]));
-	}
-	return 0;
-}
-EXPORT_SYMBOL(iwl_dump_fh);
-
 static void iwl_force_rf_reset(struct iwl_priv *priv)
 {
 	if (test_bit(STATUS_EXIT_PENDING, &priv->status))
@@ -2795,7 +2430,6 @@ int iwl_force_reset(struct iwl_priv *priv, int mode, bool external)
 	}
 	return 0;
 }
-EXPORT_SYMBOL(iwl_force_reset);
 
 /**
  * iwl_bg_monitor_recover - Timer callback to check for stuck queue and recover
@@ -2848,13 +2482,10 @@ static int iwl_check_stuck_queue(struct iwl_priv *priv, int cnt)
 					"queue %d, not read %d time\n",
 					q->id,
 					q->repeat_same_read_ptr);
-			if (priv->cfg->bt_params &&
-			    !priv->cfg->bt_params->advanced_bt_coexist) {
-				mod_timer(&priv->monitor_recover,
-					jiffies + msecs_to_jiffies(
-					IWL_ONE_HUNDRED_MSECS));
-				return 1;
-			}
+			mod_timer(&priv->monitor_recover,
+				jiffies + msecs_to_jiffies(
+				IWL_ONE_HUNDRED_MSECS));
+			return 1;
 		}
 	} else {
 		q->last_read_ptr = q->read_ptr;
@@ -2964,7 +2595,7 @@ int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state)
 	 * it will not call apm_ops.stop() to stop the DMA operation.
 	 * Calling apm_ops.stop here to make sure we stop the DMA.
 	 */
-	priv->cfg->ops->lib->apm_ops.stop(priv);
+	iwl_apm_stop(priv);
 
 	pci_save_state(pdev);
 	pci_disable_device(pdev);
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index 6228b1c2ec96..64527def059f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -112,13 +112,12 @@ struct iwl_hcmd_utils_ops {
 	int  (*calc_rssi)(struct iwl_priv *priv,
 			  struct iwl_rx_phy_res *rx_resp);
 	int (*request_scan)(struct iwl_priv *priv, struct ieee80211_vif *vif);
+	void (*post_scan)(struct iwl_priv *priv);
 };
 
 struct iwl_apm_ops {
 	int (*init)(struct iwl_priv *priv);
-	void (*stop)(struct iwl_priv *priv);
 	void (*config)(struct iwl_priv *priv);
-	int (*set_pwr_src)(struct iwl_priv *priv, enum iwl_pwr_src src);
 };
 
 struct iwl_debugfs_ops {
@@ -136,7 +135,6 @@ struct iwl_debugfs_ops {
 
 struct iwl_temp_ops {
 	void (*temperature)(struct iwl_priv *priv);
-	void (*set_ct_kill)(struct iwl_priv *priv);
 };
 
 struct iwl_tt_ops {
@@ -344,6 +342,7 @@ struct iwl_ht_params {
  * @ucode_api_min: Lowest version of uCode API supported by driver.
  * @pa_type: used by 6000 series only to identify the type of Power Amplifier
  * @need_dc_calib: need to perform init dc calibration
+ * @need_temp_offset_calib: need to perform temperature offset calibration
  * @scan_antennas: available antenna for scan operation
  *
  * We enable the driver to be backward compatible wrt API version. The
@@ -388,6 +387,7 @@ struct iwl_cfg {
 	struct iwl_bt_params *bt_params;
 	enum iwl_pa_type pa_type;	  /* if used set to IWL_PA_SYSTEM */
 	const bool need_dc_calib;	  /* if used set to true */
+	const bool need_temp_offset_calib; /* if used set to true */
 	u8 scan_rx_antennas[IEEE80211_NUM_BANDS];
 	u8 scan_tx_antennas[IEEE80211_NUM_BANDS];
 };
@@ -398,7 +398,6 @@ struct iwl_cfg {
 
 struct ieee80211_hw *iwl_alloc_all(struct iwl_cfg *cfg,
 		struct ieee80211_ops *hw_ops);
-void iwl_activate_qos(struct iwl_priv *priv);
 int iwl_mac_conf_tx(struct ieee80211_hw *hw, u16 queue,
 		    const struct ieee80211_tx_queue_params *params);
 int iwl_mac_tx_last_beacon(struct ieee80211_hw *hw);
@@ -406,7 +405,6 @@ void iwl_set_rxon_hwcrypto(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
 			   int hw_decrypt);
 int iwl_check_rxon_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx);
 int iwl_full_rxon_required(struct iwl_priv *priv, struct iwl_rxon_context *ctx);
-void iwl_set_rxon_chain(struct iwl_priv *priv, struct iwl_rxon_context *ctx);
 int iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch,
 			 struct iwl_rxon_context *ctx);
 void iwl_set_flags_for_band(struct iwl_priv *priv,
@@ -432,7 +430,6 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw,
 				     struct ieee80211_vif *vif,
 				     struct ieee80211_bss_conf *bss_conf,
 				     u32 changes);
-int iwl_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx);
 int iwl_mac_add_interface(struct ieee80211_hw *hw,
 			  struct ieee80211_vif *vif);
 void iwl_mac_remove_interface(struct ieee80211_hw *hw,
@@ -509,7 +506,6 @@ void iwl_rx_reply_error(struct iwl_priv *priv,
 ******************************************************/
 void iwl_cmd_queue_free(struct iwl_priv *priv);
 int iwl_rx_queue_alloc(struct iwl_priv *priv);
-void iwl_rx_handle(struct iwl_priv *priv);
 void iwl_rx_queue_update_write_ptr(struct iwl_priv *priv,
 				  struct iwl_rx_queue *q);
 int iwl_rx_queue_space(const struct iwl_rx_queue *q);
@@ -527,12 +523,6 @@ void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb);
 /*****************************************************
 * TX
 ******************************************************/
-void iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq);
-int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv,
-				 struct iwl_tx_queue *txq,
-				 dma_addr_t addr, u16 len, u8 reset, u8 pad);
-int iwl_hw_tx_queue_init(struct iwl_priv *priv,
-			 struct iwl_tx_queue *txq);
 void iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq);
 int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq,
 		      int slots_num, u32 txq_id);
@@ -548,31 +538,9 @@ int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force);
  * Rate
  ******************************************************************************/
 
-int iwl_hwrate_to_plcp_idx(u32 rate_n_flags);
-
 u8 iwl_rate_get_lowest_plcp(struct iwl_priv *priv,
 			    struct iwl_rxon_context *ctx);
 
-u8 iwl_toggle_tx_ant(struct iwl_priv *priv, u8 ant_idx, u8 valid);
-
-static inline u32 iwl_ant_idx_to_flags(u8 ant_idx)
-{
-	return BIT(ant_idx) << RATE_MCS_ANT_POS;
-}
-
-static inline u8 iwl_hw_get_rate(__le32 rate_n_flags)
-{
-	return le32_to_cpu(rate_n_flags) & 0xFF;
-}
-static inline u32 iwl_hw_get_rate_n_flags(__le32 rate_n_flags)
-{
-	return le32_to_cpu(rate_n_flags) & 0x1FFFF;
-}
-static inline __le32 iwl_hw_set_rate_n_flags(u8 rate, u32 flags)
-{
-	return cpu_to_le32(flags|(u32)rate);
-}
-
 /*******************************************************************************
  * Scanning
  ******************************************************************************/
@@ -608,13 +576,6 @@ void iwl_cancel_scan_deferred_work(struct iwl_priv *priv);
 
 #define IWL_SCAN_CHECK_WATCHDOG		(HZ * 7)
 
-/*******************************************************************************
- * Calibrations - implemented in iwl-calib.c
- ******************************************************************************/
-int iwl_send_calib_results(struct iwl_priv *priv);
-int iwl_calib_set(struct iwl_calib_result *res, const u8 *buf, int len);
-void iwl_calib_free_results(struct iwl_priv *priv);
-
 /*****************************************************
  *   S e n d i n g     H o s t     C o m m a n d s   *
  *****************************************************/
@@ -664,8 +625,6 @@ int iwl_pci_resume(struct pci_dev *pdev);
 void iwl_dump_nic_error_log(struct iwl_priv *priv);
 int iwl_dump_nic_event_log(struct iwl_priv *priv,
 			   bool full_log, char **buf, bool display);
-void iwl_dump_csr(struct iwl_priv *priv);
-int iwl_dump_fh(struct iwl_priv *priv, char **buf, bool display);
 #ifdef CONFIG_IWLWIFI_DEBUG
 void iwl_print_rx_config_cmd(struct iwl_priv *priv,
 			     struct iwl_rxon_context *ctx);
@@ -751,8 +710,6 @@ static inline int iwl_is_ready_rf(struct iwl_priv *priv)
 extern void iwl_send_bt_config(struct iwl_priv *priv);
 extern int iwl_send_statistics_request(struct iwl_priv *priv,
 				       u8 flags, bool clear);
-extern int iwl_send_lq_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
-		struct iwl_link_quality_cmd *lq, u8 flags, bool init);
 void iwl_apm_stop(struct iwl_priv *priv);
 int iwl_apm_init(struct iwl_priv *priv);
 
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
index fc340311ea0a..96d9085639e3 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
@@ -39,7 +39,6 @@
 #include "iwl-debug.h"
 #include "iwl-core.h"
 #include "iwl-io.h"
-#include "iwl-calib.h"
 
 /* create and remove of files */
 #define DEBUGFS_ADD_FILE(name, parent, mode) do {			\
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index 90a37a94c698..70e07fa48405 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -282,13 +282,6 @@ struct iwl_channel_info {
  */
 #define IWL_IPAN_MCAST_QUEUE		8
 
-/* Power management (not Tx power) structures */
-
-enum iwl_pwr_src {
-	IWL_PWR_SRC_VMAIN,
-	IWL_PWR_SRC_VAUX,
-};
-
 #define IEEE80211_DATA_LEN              2304
 #define IEEE80211_4ADDR_LEN             30
 #define IEEE80211_HLEN                  (IEEE80211_4ADDR_LEN)
@@ -732,7 +725,6 @@ struct iwl_hw_params {
  *
  ****************************************************************************/
 extern void iwl_update_chain_flags(struct iwl_priv *priv);
-extern int iwl_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src);
 extern const u8 iwl_bcast_addr[ETH_ALEN];
 extern int iwl_rxq_stop(struct iwl_priv *priv);
 extern void iwl_txq_ctx_stop(struct iwl_priv *priv);
@@ -843,6 +835,7 @@ enum iwl_calib {
 	IWL_CALIB_TX_IQ,
 	IWL_CALIB_TX_IQ_PERD,
 	IWL_CALIB_BASE_BAND,
+	IWL_CALIB_TEMP_OFFSET,
 	IWL_CALIB_MAX
 };
 
@@ -1390,8 +1383,6 @@ struct iwl_priv {
 
 	enum nl80211_iftype iw_mode;
 
-	struct sk_buff *ibss_beacon;
-
 	/* Last Rx'd beacon timestamp */
 	u64 timestamp;
 
@@ -1503,8 +1494,10 @@ struct iwl_priv {
 	struct work_struct scan_completed;
 	struct work_struct rx_replenish;
 	struct work_struct abort_scan;
+
 	struct work_struct beacon_update;
 	struct iwl_rxon_context *beacon_ctx;
+	struct sk_buff *beacon_skb;
 
 	struct work_struct tt_work;
 	struct work_struct ct_enter;
@@ -1566,7 +1559,6 @@ static inline void iwl_txq_ctx_deactivate(struct iwl_priv *priv, int txq_id)
 }
 
 #ifdef CONFIG_IWLWIFI_DEBUG
-const char *iwl_get_tx_fail_reason(u32 status);
 /*
  * iwl_get_debug_level: Return active debug level for device
  *
@@ -1582,8 +1574,6 @@ static inline u32 iwl_get_debug_level(struct iwl_priv *priv)
 		return iwl_debug_level;
 }
 #else
-static inline const char *iwl_get_tx_fail_reason(u32 status) { return ""; }
-
 static inline u32 iwl_get_debug_level(struct iwl_priv *priv)
 {
 	return iwl_debug_level;
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
index 88f4a80d4733..87cd10ff285d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
@@ -136,85 +136,13 @@ static const u8 iwl_eeprom_band_7[] = {       /* 5.2 ht40 channel */
 	36, 44, 52, 60, 100, 108, 116, 124, 132, 149, 157
 };
 
-/**
- * struct iwl_txpwr_section: eeprom section information
- * @offset: indirect address into eeprom image
- * @count: number of "struct iwl_eeprom_enhanced_txpwr" in this section
- * @band: band type for the section
- * @is_common - true: common section, false: channel section
- * @is_cck - true: cck section, false: not cck section
- * @is_ht_40 - true: all channel in the section are HT40 channel,
- * 	       false: legacy or HT 20 MHz
- *	       ignore if it is common section
- * @iwl_eeprom_section_channel: channel array in the section,
- *	       ignore if common section
- */
-struct iwl_txpwr_section {
-	u32 offset;
-	u8 count;
-	enum ieee80211_band band;
-	bool is_common;
-	bool is_cck;
-	bool is_ht40;
-	u8 iwl_eeprom_section_channel[EEPROM_MAX_TXPOWER_SECTION_ELEMENTS];
-};
-
-/**
- * section 1 - 3 are regulatory tx power apply to all channels based on
- *    modulation: CCK, OFDM
- *    Band: 2.4GHz, 5.2GHz
- * section 4 - 10 are regulatory tx power apply to specified channels
- *    For example:
- *	1L - Channel 1 Legacy
- *	1HT - Channel 1 HT
- *	(1,+1) - Channel 1 HT40 "_above_"
- *
- * Section 1: all CCK channels
- * Section 2: all 2.4 GHz OFDM (Legacy, HT and HT40) channels
- * Section 3: all 5.2 GHz OFDM (Legacy, HT and HT40) channels
- * Section 4: 2.4 GHz 20MHz channels: 1L, 1HT, 2L, 2HT, 10L, 10HT, 11L, 11HT
- * Section 5: 2.4 GHz 40MHz channels: (1,+1) (2,+1) (6,+1) (7,+1) (9,+1)
- * Section 6: 5.2 GHz 20MHz channels: 36L, 64L, 100L, 36HT, 64HT, 100HT
- * Section 7: 5.2 GHz 40MHz channels: (36,+1) (60,+1) (100,+1)
- * Section 8: 2.4 GHz channel: 13L, 13HT
- * Section 9: 2.4 GHz channel: 140L, 140HT
- * Section 10: 2.4 GHz 40MHz channels: (132,+1)  (44,+1)
- *
- */
-static const struct iwl_txpwr_section enhinfo[] = {
-	{ EEPROM_LB_CCK_20_COMMON, 1, IEEE80211_BAND_2GHZ, true, true, false },
-	{ EEPROM_LB_OFDM_COMMON, 3, IEEE80211_BAND_2GHZ, true, false, false },
-	{ EEPROM_HB_OFDM_COMMON, 3, IEEE80211_BAND_5GHZ, true, false, false },
-	{ EEPROM_LB_OFDM_20_BAND, 8, IEEE80211_BAND_2GHZ,
-		false, false, false,
-		{1, 1, 2, 2, 10, 10, 11, 11 } },
-	{ EEPROM_LB_OFDM_HT40_BAND, 5, IEEE80211_BAND_2GHZ,
-		false, false, true,
-		{ 1, 2, 6, 7, 9 } },
-	{ EEPROM_HB_OFDM_20_BAND, 6, IEEE80211_BAND_5GHZ,
-		false, false, false,
-		{ 36, 64, 100, 36, 64, 100 } },
-	{ EEPROM_HB_OFDM_HT40_BAND, 3, IEEE80211_BAND_5GHZ,
-		false, false, true,
-		{ 36, 60, 100 } },
-	{ EEPROM_LB_OFDM_20_CHANNEL_13, 2, IEEE80211_BAND_2GHZ,
-		false, false, false,
-		{ 13, 13 } },
-	{ EEPROM_HB_OFDM_20_CHANNEL_140, 2, IEEE80211_BAND_5GHZ,
-		false, false, false,
-		{ 140, 140 } },
-	{ EEPROM_HB_OFDM_HT40_BAND_1, 2, IEEE80211_BAND_5GHZ,
-		false, false, true,
-		{ 132, 44 } },
-};
-
 /******************************************************************************
  *
  * EEPROM related functions
  *
 ******************************************************************************/
 
-int iwlcore_eeprom_verify_signature(struct iwl_priv *priv)
+static int iwl_eeprom_verify_signature(struct iwl_priv *priv)
 {
 	u32 gp = iwl_read32(priv, CSR_EEPROM_GP) & CSR_EEPROM_GP_VALID_MSK;
 	int ret = 0;
@@ -246,7 +174,6 @@ int iwlcore_eeprom_verify_signature(struct iwl_priv *priv)
 	}
 	return ret;
 }
-EXPORT_SYMBOL(iwlcore_eeprom_verify_signature);
 
 static void iwl_set_otp_access(struct iwl_priv *priv, enum iwl_access_mode mode)
 {
@@ -290,46 +217,6 @@ static int iwlcore_get_nvm_type(struct iwl_priv *priv)
 	return  nvm_type;
 }
 
-/*
- * The device's EEPROM semaphore prevents conflicts between driver and uCode
- * when accessing the EEPROM; each access is a series of pulses to/from the
- * EEPROM chip, not a single event, so even reads could conflict if they
- * weren't arbitrated by the semaphore.
- */
-int iwlcore_eeprom_acquire_semaphore(struct iwl_priv *priv)
-{
-	u16 count;
-	int ret;
-
-	for (count = 0; count < EEPROM_SEM_RETRY_LIMIT; count++) {
-		/* Request semaphore */
-		iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
-			    CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM);
-
-		/* See if we got it */
-		ret = iwl_poll_bit(priv, CSR_HW_IF_CONFIG_REG,
-				CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM,
-				CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM,
-				EEPROM_SEM_TIMEOUT);
-		if (ret >= 0) {
-			IWL_DEBUG_IO(priv, "Acquired semaphore after %d tries.\n",
-				count+1);
-			return ret;
-		}
-	}
-
-	return ret;
-}
-EXPORT_SYMBOL(iwlcore_eeprom_acquire_semaphore);
-
-void iwlcore_eeprom_release_semaphore(struct iwl_priv *priv)
-{
-	iwl_clear_bit(priv, CSR_HW_IF_CONFIG_REG,
-		CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM);
-
-}
-EXPORT_SYMBOL(iwlcore_eeprom_release_semaphore);
-
 const u8 *iwlcore_eeprom_query_addr(const struct iwl_priv *priv, size_t offset)
 {
 	BUG_ON(offset >= priv->cfg->base_params->eeprom_size);
@@ -491,6 +378,20 @@ static int iwl_find_otp_image(struct iwl_priv *priv,
 	return -EINVAL;
 }
 
+const u8 *iwl_eeprom_query_addr(const struct iwl_priv *priv, size_t offset)
+{
+	return priv->cfg->ops->lib->eeprom_ops.query_addr(priv, offset);
+}
+EXPORT_SYMBOL(iwl_eeprom_query_addr);
+
+u16 iwl_eeprom_query16(const struct iwl_priv *priv, size_t offset)
+{
+	if (!priv->eeprom)
+		return 0;
+	return (u16)priv->eeprom[offset] | ((u16)priv->eeprom[offset + 1] << 8);
+}
+EXPORT_SYMBOL(iwl_eeprom_query16);
+
 /**
  * iwl_eeprom_init - read EEPROM contents
  *
@@ -523,7 +424,7 @@ int iwl_eeprom_init(struct iwl_priv *priv)
 
 	priv->cfg->ops->lib->apm_ops.init(priv);
 
-	ret = priv->cfg->ops->lib->eeprom_ops.verify_signature(priv);
+	ret = iwl_eeprom_verify_signature(priv);
 	if (ret < 0) {
 		IWL_ERR(priv, "EEPROM not found, EEPROM_GP=0x%08x\n", gp);
 		ret = -ENOENT;
@@ -604,7 +505,7 @@ err:
 	if (ret)
 		iwl_eeprom_free(priv);
 	/* Reset chip to save power until we load uCode during "up". */
-	priv->cfg->ops->lib->apm_ops.stop(priv);
+	iwl_apm_stop(priv);
 alloc_err:
 	return ret;
 }
@@ -617,53 +518,6 @@ void iwl_eeprom_free(struct iwl_priv *priv)
 }
 EXPORT_SYMBOL(iwl_eeprom_free);
 
-int iwl_eeprom_check_version(struct iwl_priv *priv)
-{
-	u16 eeprom_ver;
-	u16 calib_ver;
-
-	eeprom_ver = iwl_eeprom_query16(priv, EEPROM_VERSION);
-	calib_ver = priv->cfg->ops->lib->eeprom_ops.calib_version(priv);
-
-	if (eeprom_ver < priv->cfg->eeprom_ver ||
-	    calib_ver < priv->cfg->eeprom_calib_ver)
-		goto err;
-
-	IWL_INFO(priv, "device EEPROM VER=0x%x, CALIB=0x%x\n",
-		 eeprom_ver, calib_ver);
-
-	return 0;
-err:
-	IWL_ERR(priv, "Unsupported (too old) EEPROM VER=0x%x < 0x%x CALIB=0x%x < 0x%x\n",
-		  eeprom_ver, priv->cfg->eeprom_ver,
-		  calib_ver,  priv->cfg->eeprom_calib_ver);
-	return -EINVAL;
-
-}
-EXPORT_SYMBOL(iwl_eeprom_check_version);
-
-const u8 *iwl_eeprom_query_addr(const struct iwl_priv *priv, size_t offset)
-{
-	return priv->cfg->ops->lib->eeprom_ops.query_addr(priv, offset);
-}
-EXPORT_SYMBOL(iwl_eeprom_query_addr);
-
-u16 iwl_eeprom_query16(const struct iwl_priv *priv, size_t offset)
-{
-	if (!priv->eeprom)
-		return 0;
-	return (u16)priv->eeprom[offset] | ((u16)priv->eeprom[offset + 1] << 8);
-}
-EXPORT_SYMBOL(iwl_eeprom_query16);
-
-void iwl_eeprom_get_mac(const struct iwl_priv *priv, u8 *mac)
-{
-	const u8 *addr = priv->cfg->ops->lib->eeprom_ops.query_addr(priv,
-					EEPROM_MAC_ADDRESS);
-	memcpy(mac, addr, ETH_ALEN);
-}
-EXPORT_SYMBOL(iwl_eeprom_get_mac);
-
 static void iwl_init_band_reference(const struct iwl_priv *priv,
 			int eep_band, int *eeprom_ch_count,
 			const struct iwl_eeprom_channel **eeprom_ch_info,
@@ -722,7 +576,6 @@ static void iwl_init_band_reference(const struct iwl_priv *priv,
 
 #define CHECK_AND_PRINT(x) ((eeprom_ch->flags & EEPROM_CHANNEL_##x) \
 			    ? # x " " : "")
-
 /**
  * iwl_mod_ht40_chan_info - Copy ht40 channel info into driver's priv.
  *
@@ -766,205 +619,6 @@ static int iwl_mod_ht40_chan_info(struct iwl_priv *priv,
 	return 0;
 }
 
-/**
- * iwl_get_max_txpower_avg - get the highest tx power from all chains.
- *     find the highest tx power from all chains for the channel
- */
-static s8 iwl_get_max_txpower_avg(struct iwl_priv *priv,
-		struct iwl_eeprom_enhanced_txpwr *enhanced_txpower,
-		int element, s8 *max_txpower_in_half_dbm)
-{
-	s8 max_txpower_avg = 0; /* (dBm) */
-
-	IWL_DEBUG_INFO(priv, "%d - "
-			"chain_a: %d dB chain_b: %d dB "
-			"chain_c: %d dB mimo2: %d dB mimo3: %d dB\n",
-			element,
-			enhanced_txpower[element].chain_a_max >> 1,
-			enhanced_txpower[element].chain_b_max >> 1,
-			enhanced_txpower[element].chain_c_max >> 1,
-			enhanced_txpower[element].mimo2_max >> 1,
-			enhanced_txpower[element].mimo3_max >> 1);
-	/* Take the highest tx power from any valid chains */
-	if ((priv->cfg->valid_tx_ant & ANT_A) &&
-	    (enhanced_txpower[element].chain_a_max > max_txpower_avg))
-		max_txpower_avg = enhanced_txpower[element].chain_a_max;
-	if ((priv->cfg->valid_tx_ant & ANT_B) &&
-	    (enhanced_txpower[element].chain_b_max > max_txpower_avg))
-		max_txpower_avg = enhanced_txpower[element].chain_b_max;
-	if ((priv->cfg->valid_tx_ant & ANT_C) &&
-	    (enhanced_txpower[element].chain_c_max > max_txpower_avg))
-		max_txpower_avg = enhanced_txpower[element].chain_c_max;
-	if (((priv->cfg->valid_tx_ant == ANT_AB) |
-	    (priv->cfg->valid_tx_ant == ANT_BC) |
-	    (priv->cfg->valid_tx_ant == ANT_AC)) &&
-	    (enhanced_txpower[element].mimo2_max > max_txpower_avg))
-		max_txpower_avg =  enhanced_txpower[element].mimo2_max;
-	if ((priv->cfg->valid_tx_ant == ANT_ABC) &&
-	    (enhanced_txpower[element].mimo3_max > max_txpower_avg))
-		max_txpower_avg = enhanced_txpower[element].mimo3_max;
-
-	/*
-	 * max. tx power in EEPROM is in 1/2 dBm format
-	 * convert from 1/2 dBm to dBm (round-up convert)
-	 * but we also do not want to loss 1/2 dBm resolution which
-	 * will impact performance
-	 */
-	*max_txpower_in_half_dbm = max_txpower_avg;
-	return (max_txpower_avg & 0x01) + (max_txpower_avg >> 1);
-}
-
-/**
- * iwl_update_common_txpower: update channel tx power
- *     update tx power per band based on EEPROM enhanced tx power info.
- */
-static s8 iwl_update_common_txpower(struct iwl_priv *priv,
-		struct iwl_eeprom_enhanced_txpwr *enhanced_txpower,
-		int section, int element, s8 *max_txpower_in_half_dbm)
-{
-	struct iwl_channel_info *ch_info;
-	int ch;
-	bool is_ht40 = false;
-	s8 max_txpower_avg; /* (dBm) */
-
-	/* it is common section, contain all type (Legacy, HT and HT40)
-	 * based on the element in the section to determine
-	 * is it HT 40 or not
-	 */
-	if (element == EEPROM_TXPOWER_COMMON_HT40_INDEX)
-		is_ht40 = true;
-	max_txpower_avg =
-		iwl_get_max_txpower_avg(priv, enhanced_txpower,
-					element, max_txpower_in_half_dbm);
-
-	ch_info = priv->channel_info;
-
-	for (ch = 0; ch < priv->channel_count; ch++) {
-		/* find matching band and update tx power if needed */
-		if ((ch_info->band == enhinfo[section].band) &&
-		    (ch_info->max_power_avg < max_txpower_avg) &&
-		    (!is_ht40)) {
-			/* Update regulatory-based run-time data */
-			ch_info->max_power_avg = ch_info->curr_txpow =
-				max_txpower_avg;
-			ch_info->scan_power = max_txpower_avg;
-		}
-		if ((ch_info->band == enhinfo[section].band) && is_ht40 &&
-		    (ch_info->ht40_max_power_avg < max_txpower_avg)) {
-			/* Update regulatory-based run-time data */
-			ch_info->ht40_max_power_avg = max_txpower_avg;
-		}
-		ch_info++;
-	}
-	return max_txpower_avg;
-}
-
-/**
- * iwl_update_channel_txpower: update channel tx power
- *      update channel tx power based on EEPROM enhanced tx power info.
- */
-static s8 iwl_update_channel_txpower(struct iwl_priv *priv,
-		struct iwl_eeprom_enhanced_txpwr *enhanced_txpower,
-		int section, int element, s8 *max_txpower_in_half_dbm)
-{
-	struct iwl_channel_info *ch_info;
-	int ch;
-	u8 channel;
-	s8 max_txpower_avg; /* (dBm) */
-
-	channel = enhinfo[section].iwl_eeprom_section_channel[element];
-	max_txpower_avg =
-		iwl_get_max_txpower_avg(priv, enhanced_txpower,
-					element, max_txpower_in_half_dbm);
-
-	ch_info = priv->channel_info;
-	for (ch = 0; ch < priv->channel_count; ch++) {
-		/* find matching channel and update tx power if needed */
-		if (ch_info->channel == channel) {
-			if ((ch_info->max_power_avg < max_txpower_avg) &&
-			    (!enhinfo[section].is_ht40)) {
-				/* Update regulatory-based run-time data */
-				ch_info->max_power_avg = max_txpower_avg;
-				ch_info->curr_txpow = max_txpower_avg;
-				ch_info->scan_power = max_txpower_avg;
-			}
-			if ((enhinfo[section].is_ht40) &&
-			    (ch_info->ht40_max_power_avg < max_txpower_avg)) {
-				/* Update regulatory-based run-time data */
-				ch_info->ht40_max_power_avg = max_txpower_avg;
-			}
-			break;
-		}
-		ch_info++;
-	}
-	return max_txpower_avg;
-}
-
-/**
- * iwlcore_eeprom_enhanced_txpower: process enhanced tx power info
- */
-void iwlcore_eeprom_enhanced_txpower(struct iwl_priv *priv)
-{
-	int eeprom_section_count = 0;
-	int section, element;
-	struct iwl_eeprom_enhanced_txpwr *enhanced_txpower;
-	u32 offset;
-	s8 max_txpower_avg; /* (dBm) */
-	s8 max_txpower_in_half_dbm; /* (half-dBm) */
-
-	/* Loop through all the sections
-	 * adjust bands and channel's max tx power
-	 * Set the tx_power_user_lmt to the highest power
-	 * supported by any channels and chains
-	 */
-	for (section = 0; section < ARRAY_SIZE(enhinfo); section++) {
-		eeprom_section_count = enhinfo[section].count;
-		offset = enhinfo[section].offset;
-		enhanced_txpower = (struct iwl_eeprom_enhanced_txpwr *)
-				iwl_eeprom_query_addr(priv, offset);
-
-		/*
-		 * check for valid entry -
-		 * different version of EEPROM might contain different set
-		 * of enhanced tx power table
-		 * always check for valid entry before process
-		 * the information
-		 */
-		if (!enhanced_txpower->common || enhanced_txpower->reserved)
-			continue;
-
-		for (element = 0; element < eeprom_section_count; element++) {
-			if (enhinfo[section].is_common)
-				max_txpower_avg =
-					iwl_update_common_txpower(priv,
-						enhanced_txpower, section,
-						element,
-						&max_txpower_in_half_dbm);
-			else
-				max_txpower_avg =
-					iwl_update_channel_txpower(priv,
-						enhanced_txpower, section,
-						element,
-						&max_txpower_in_half_dbm);
-
-			/* Update the tx_power_user_lmt to the highest power
-			 * supported by any channel */
-			if (max_txpower_avg > priv->tx_power_user_lmt)
-				priv->tx_power_user_lmt = max_txpower_avg;
-
-			/*
-			 * Update the tx_power_lmt_in_half_dbm to
-			 * the highest power supported by any channel
-			 */
-			if (max_txpower_in_half_dbm >
-			    priv->tx_power_lmt_in_half_dbm)
-				priv->tx_power_lmt_in_half_dbm =
-					max_txpower_in_half_dbm;
-		}
-	}
-}
-EXPORT_SYMBOL(iwlcore_eeprom_enhanced_txpower);
-
 #define CHECK_AND_PRINT_I(x) ((eeprom_ch_info[ch].flags & EEPROM_CHANNEL_##x) \
 			    ? # x " " : "")
 
@@ -1162,4 +816,3 @@ const struct iwl_channel_info *iwl_get_channel_info(const struct iwl_priv *priv,
 	return NULL;
 }
 EXPORT_SYMBOL(iwl_get_channel_info);
-
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.h b/drivers/net/wireless/iwlwifi/iwl-eeprom.h
index a4772aff51fe..d9b590625ae4 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom.h
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.h
@@ -493,7 +493,6 @@ struct iwl_eeprom_calib_info {
 
 struct iwl_eeprom_ops {
 	const u32 regulatory_bands[7];
-	int (*verify_signature) (struct iwl_priv *priv);
 	int (*acquire_semaphore) (struct iwl_priv *priv);
 	void (*release_semaphore) (struct iwl_priv *priv);
 	u16 (*calib_version) (struct iwl_priv *priv);
@@ -502,18 +501,13 @@ struct iwl_eeprom_ops {
 };
 
 
-void iwl_eeprom_get_mac(const struct iwl_priv *priv, u8 *mac);
 int iwl_eeprom_init(struct iwl_priv *priv);
 void iwl_eeprom_free(struct iwl_priv *priv);
 int  iwl_eeprom_check_version(struct iwl_priv *priv);
 const u8 *iwl_eeprom_query_addr(const struct iwl_priv *priv, size_t offset);
-u16 iwl_eeprom_query16(const struct iwl_priv *priv, size_t offset);
-
 int iwlcore_eeprom_verify_signature(struct iwl_priv *priv);
-int iwlcore_eeprom_acquire_semaphore(struct iwl_priv *priv);
-void iwlcore_eeprom_release_semaphore(struct iwl_priv *priv);
+u16 iwl_eeprom_query16(const struct iwl_priv *priv, size_t offset);
 const u8 *iwlcore_eeprom_query_addr(const struct iwl_priv *priv, size_t offset);
-void iwlcore_eeprom_enhanced_txpower(struct iwl_priv *priv);
 int iwl_init_channel_map(struct iwl_priv *priv);
 void iwl_free_channel_map(struct iwl_priv *priv);
 const struct iwl_channel_info *iwl_get_channel_info(
diff --git a/drivers/net/wireless/iwlwifi/iwl-helpers.h b/drivers/net/wireless/iwlwifi/iwl-helpers.h
index 621abe3c5afc..1aaef70deaec 100644
--- a/drivers/net/wireless/iwlwifi/iwl-helpers.h
+++ b/drivers/net/wireless/iwlwifi/iwl-helpers.h
@@ -44,11 +44,6 @@ static inline struct ieee80211_conf *ieee80211_get_hw_conf(
 	return &hw->conf;
 }
 
-static inline int iwl_check_bits(unsigned long field, unsigned long mask)
-{
-	return ((field & mask) == mask) ? 1 : 0;
-}
-
 static inline unsigned long elapsed_jiffies(unsigned long start,
 					    unsigned long end)
 {
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c
index 10be197b0f22..f436270ca39a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-rx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-rx.c
@@ -36,7 +36,6 @@
 #include "iwl-core.h"
 #include "iwl-sta.h"
 #include "iwl-io.h"
-#include "iwl-calib.h"
 #include "iwl-helpers.h"
 /************************** RX-FUNCTIONS ****************************/
 /*
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c
index eaae49ee0c60..67da31295781 100644
--- a/drivers/net/wireless/iwlwifi/iwl-scan.c
+++ b/drivers/net/wireless/iwlwifi/iwl-scan.c
@@ -121,7 +121,6 @@ void iwl_force_scan_end(struct iwl_priv *priv)
 	clear_bit(STATUS_SCAN_ABORTING, &priv->status);
 	iwl_complete_scan(priv, true);
 }
-EXPORT_SYMBOL(iwl_force_scan_end);
 
 static void iwl_do_scan_abort(struct iwl_priv *priv)
 {
@@ -559,7 +558,6 @@ static void iwl_bg_scan_completed(struct work_struct *work)
 	struct iwl_priv *priv =
 	    container_of(work, struct iwl_priv, scan_completed);
 	bool aborted;
-	struct iwl_rxon_context *ctx;
 
 	IWL_DEBUG_SCAN(priv, "Completed %sscan.\n",
 		       priv->is_internal_short_scan ? "internal short " : "");
@@ -609,15 +607,7 @@ out_settings:
 	 * performing the scan, fire one off */
 	iwl_set_tx_power(priv, priv->tx_power_user_lmt, true);
 
-	/*
-	 * Since setting the RXON may have been deferred while
-	 * performing the scan, fire one off if needed
-	 */
-	for_each_context(priv, ctx)
-		iwlcore_commit_rxon(priv, ctx);
-
-	if (priv->cfg->ops->hcmd->set_pan_params)
-		priv->cfg->ops->hcmd->set_pan_params(priv);
+	priv->cfg->ops->utils->post_scan(priv);
 
  out:
 	mutex_unlock(&priv->mutex);
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c
index 6edd0341dfe2..7c7f7dcb1b1e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.c
@@ -228,9 +228,8 @@ static void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index,
  *
  * should be called with sta_lock held
  */
-static u8 iwl_prep_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
-			   const u8 *addr, bool is_ap,
-			   struct ieee80211_sta *sta)
+u8 iwl_prep_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
+		    const u8 *addr, bool is_ap, struct ieee80211_sta *sta)
 {
 	struct iwl_station_entry *station;
 	int i;
@@ -317,6 +316,7 @@ static u8 iwl_prep_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
 	return sta_id;
 
 }
+EXPORT_SYMBOL_GPL(iwl_prep_station);
 
 #define STA_WAIT_TIMEOUT (HZ/2)
 
@@ -381,108 +381,6 @@ int iwl_add_station_common(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
 }
 EXPORT_SYMBOL(iwl_add_station_common);
 
-static struct iwl_link_quality_cmd *iwl_sta_alloc_lq(struct iwl_priv *priv,
-						     u8 sta_id)
-{
-	int i, r;
-	struct iwl_link_quality_cmd *link_cmd;
-	u32 rate_flags = 0;
-	__le32 rate_n_flags;
-
-	link_cmd = kzalloc(sizeof(struct iwl_link_quality_cmd), GFP_KERNEL);
-	if (!link_cmd) {
-		IWL_ERR(priv, "Unable to allocate memory for LQ cmd.\n");
-		return NULL;
-	}
-	/* Set up the rate scaling to start at selected rate, fall back
-	 * all the way down to 1M in IEEE order, and then spin on 1M */
-	if (priv->band == IEEE80211_BAND_5GHZ)
-		r = IWL_RATE_6M_INDEX;
-	else
-		r = IWL_RATE_1M_INDEX;
-
-	if (r >= IWL_FIRST_CCK_RATE && r <= IWL_LAST_CCK_RATE)
-		rate_flags |= RATE_MCS_CCK_MSK;
-
-	rate_flags |= first_antenna(priv->hw_params.valid_tx_ant) <<
-				RATE_MCS_ANT_POS;
-	rate_n_flags = iwl_hw_set_rate_n_flags(iwl_rates[r].plcp, rate_flags);
-	for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++)
-		link_cmd->rs_table[i].rate_n_flags = rate_n_flags;
-
-	link_cmd->general_params.single_stream_ant_msk =
-				first_antenna(priv->hw_params.valid_tx_ant);
-
-	link_cmd->general_params.dual_stream_ant_msk =
-		priv->hw_params.valid_tx_ant &
-		~first_antenna(priv->hw_params.valid_tx_ant);
-	if (!link_cmd->general_params.dual_stream_ant_msk) {
-		link_cmd->general_params.dual_stream_ant_msk = ANT_AB;
-	} else if (num_of_ant(priv->hw_params.valid_tx_ant) == 2) {
-		link_cmd->general_params.dual_stream_ant_msk =
-			priv->hw_params.valid_tx_ant;
-	}
-
-	link_cmd->agg_params.agg_dis_start_th = LINK_QUAL_AGG_DISABLE_START_DEF;
-	link_cmd->agg_params.agg_time_limit =
-		cpu_to_le16(LINK_QUAL_AGG_TIME_LIMIT_DEF);
-
-	link_cmd->sta_id = sta_id;
-
-	return link_cmd;
-}
-
-/*
- * iwl_add_bssid_station - Add the special IBSS BSSID station
- *
- * Function sleeps.
- */
-int iwl_add_bssid_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
-			  const u8 *addr, bool init_rs, u8 *sta_id_r)
-{
-	int ret;
-	u8 sta_id;
-	struct iwl_link_quality_cmd *link_cmd;
-	unsigned long flags;
-
-	if (sta_id_r)
-		*sta_id_r = IWL_INVALID_STATION;
-
-	ret = iwl_add_station_common(priv, ctx, addr, 0, NULL, &sta_id);
-	if (ret) {
-		IWL_ERR(priv, "Unable to add station %pM\n", addr);
-		return ret;
-	}
-
-	if (sta_id_r)
-		*sta_id_r = sta_id;
-
-	spin_lock_irqsave(&priv->sta_lock, flags);
-	priv->stations[sta_id].used |= IWL_STA_LOCAL;
-	spin_unlock_irqrestore(&priv->sta_lock, flags);
-
-	if (init_rs) {
-		/* Set up default rate scaling table in device's station table */
-		link_cmd = iwl_sta_alloc_lq(priv, sta_id);
-		if (!link_cmd) {
-			IWL_ERR(priv, "Unable to initialize rate scaling for station %pM.\n",
-				addr);
-			return -ENOMEM;
-		}
-
-		ret = iwl_send_lq_cmd(priv, ctx, link_cmd, CMD_SYNC, true);
-		if (ret)
-			IWL_ERR(priv, "Link quality command failed (%d)\n", ret);
-
-		spin_lock_irqsave(&priv->sta_lock, flags);
-		priv->stations[sta_id].lq = link_cmd;
-		spin_unlock_irqrestore(&priv->sta_lock, flags);
-	}
-
-	return 0;
-}
-EXPORT_SYMBOL(iwl_add_bssid_station);
-
 /**
  * iwl_sta_ucode_deactivate - deactivate ucode status for a station
  *
@@ -738,405 +636,25 @@ int iwl_get_free_ucode_key_index(struct iwl_priv *priv)
 }
 EXPORT_SYMBOL(iwl_get_free_ucode_key_index);
 
-static int iwl_send_static_wepkey_cmd(struct iwl_priv *priv,
-				      struct iwl_rxon_context *ctx,
-				      bool send_if_empty)
-{
-	int i, not_empty = 0;
-	u8 buff[sizeof(struct iwl_wep_cmd) +
-		sizeof(struct iwl_wep_key) * WEP_KEYS_MAX];
-	struct iwl_wep_cmd *wep_cmd = (struct iwl_wep_cmd *)buff;
-	size_t cmd_size  = sizeof(struct iwl_wep_cmd);
-	struct iwl_host_cmd cmd = {
-		.id = ctx->wep_key_cmd,
-		.data = wep_cmd,
-		.flags = CMD_SYNC,
-	};
-
-	might_sleep();
-
-	memset(wep_cmd, 0, cmd_size +
-			(sizeof(struct iwl_wep_key) * WEP_KEYS_MAX));
-
-	for (i = 0; i < WEP_KEYS_MAX ; i++) {
-		wep_cmd->key[i].key_index = i;
-		if (ctx->wep_keys[i].key_size) {
-			wep_cmd->key[i].key_offset = i;
-			not_empty = 1;
-		} else {
-			wep_cmd->key[i].key_offset = WEP_INVALID_OFFSET;
-		}
-
-		wep_cmd->key[i].key_size = ctx->wep_keys[i].key_size;
-		memcpy(&wep_cmd->key[i].key[3], ctx->wep_keys[i].key,
-				ctx->wep_keys[i].key_size);
-	}
-
-	wep_cmd->global_key_type = WEP_KEY_WEP_TYPE;
-	wep_cmd->num_keys = WEP_KEYS_MAX;
-
-	cmd_size += sizeof(struct iwl_wep_key) * WEP_KEYS_MAX;
-
-	cmd.len = cmd_size;
-
-	if (not_empty || send_if_empty)
-		return iwl_send_cmd(priv, &cmd);
-	else
-		return 0;
-}
-
-int iwl_restore_default_wep_keys(struct iwl_priv *priv,
-				 struct iwl_rxon_context *ctx)
-{
-	lockdep_assert_held(&priv->mutex);
-
-	return iwl_send_static_wepkey_cmd(priv, ctx, false);
-}
-EXPORT_SYMBOL(iwl_restore_default_wep_keys);
-
-int iwl_remove_default_wep_key(struct iwl_priv *priv,
-			       struct iwl_rxon_context *ctx,
-			       struct ieee80211_key_conf *keyconf)
-{
-	int ret;
-
-	lockdep_assert_held(&priv->mutex);
-
-	IWL_DEBUG_WEP(priv, "Removing default WEP key: idx=%d\n",
-		      keyconf->keyidx);
-
-	memset(&ctx->wep_keys[keyconf->keyidx], 0, sizeof(ctx->wep_keys[0]));
-	if (iwl_is_rfkill(priv)) {
-		IWL_DEBUG_WEP(priv, "Not sending REPLY_WEPKEY command due to RFKILL.\n");
-		/* but keys in device are clear anyway so return success */
-		return 0;
-	}
-	ret = iwl_send_static_wepkey_cmd(priv, ctx, 1);
-	IWL_DEBUG_WEP(priv, "Remove default WEP key: idx=%d ret=%d\n",
-		      keyconf->keyidx, ret);
-
-	return ret;
-}
-EXPORT_SYMBOL(iwl_remove_default_wep_key);
-
-int iwl_set_default_wep_key(struct iwl_priv *priv,
-			    struct iwl_rxon_context *ctx,
-			    struct ieee80211_key_conf *keyconf)
-{
-	int ret;
-
-	lockdep_assert_held(&priv->mutex);
-
-	if (keyconf->keylen != WEP_KEY_LEN_128 &&
-	    keyconf->keylen != WEP_KEY_LEN_64) {
-		IWL_DEBUG_WEP(priv, "Bad WEP key length %d\n", keyconf->keylen);
-		return -EINVAL;
-	}
-
-	keyconf->flags &= ~IEEE80211_KEY_FLAG_GENERATE_IV;
-	keyconf->hw_key_idx = HW_KEY_DEFAULT;
-	priv->stations[ctx->ap_sta_id].keyinfo.cipher = keyconf->cipher;
-
-	ctx->wep_keys[keyconf->keyidx].key_size = keyconf->keylen;
-	memcpy(&ctx->wep_keys[keyconf->keyidx].key, &keyconf->key,
-							keyconf->keylen);
-
-	ret = iwl_send_static_wepkey_cmd(priv, ctx, false);
-	IWL_DEBUG_WEP(priv, "Set default WEP key: len=%d idx=%d ret=%d\n",
-		keyconf->keylen, keyconf->keyidx, ret);
-
-	return ret;
-}
-EXPORT_SYMBOL(iwl_set_default_wep_key);
-
-static int iwl_set_wep_dynamic_key_info(struct iwl_priv *priv,
-					struct iwl_rxon_context *ctx,
-					struct ieee80211_key_conf *keyconf,
-					u8 sta_id)
-{
-	unsigned long flags;
-	__le16 key_flags = 0;
-	struct iwl_addsta_cmd sta_cmd;
-
-	lockdep_assert_held(&priv->mutex);
-
-	keyconf->flags &= ~IEEE80211_KEY_FLAG_GENERATE_IV;
-
-	key_flags |= (STA_KEY_FLG_WEP | STA_KEY_FLG_MAP_KEY_MSK);
-	key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS);
-	key_flags &= ~STA_KEY_FLG_INVALID;
-
-	if (keyconf->keylen == WEP_KEY_LEN_128)
-		key_flags |= STA_KEY_FLG_KEY_SIZE_MSK;
-
-	if (sta_id == ctx->bcast_sta_id)
-		key_flags |= STA_KEY_MULTICAST_MSK;
-
-	spin_lock_irqsave(&priv->sta_lock, flags);
-
-	priv->stations[sta_id].keyinfo.cipher = keyconf->cipher;
-	priv->stations[sta_id].keyinfo.keylen = keyconf->keylen;
-	priv->stations[sta_id].keyinfo.keyidx = keyconf->keyidx;
-
-	memcpy(priv->stations[sta_id].keyinfo.key,
-				keyconf->key, keyconf->keylen);
-
-	memcpy(&priv->stations[sta_id].sta.key.key[3],
-				keyconf->key, keyconf->keylen);
-
-	if ((priv->stations[sta_id].sta.key.key_flags & STA_KEY_FLG_ENCRYPT_MSK)
-			== STA_KEY_FLG_NO_ENC)
-		priv->stations[sta_id].sta.key.key_offset =
-				 iwl_get_free_ucode_key_index(priv);
-	/* else, we are overriding an existing key => no need to allocated room
-	 * in uCode. */
-
-	WARN(priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET,
-		"no space for a new key");
-
-	priv->stations[sta_id].sta.key.key_flags = key_flags;
-	priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
-	priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
-
-	memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd));
-	spin_unlock_irqrestore(&priv->sta_lock, flags);
-
-	return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
-}
-
-static int iwl_set_ccmp_dynamic_key_info(struct iwl_priv *priv,
-					 struct iwl_rxon_context *ctx,
-					 struct ieee80211_key_conf *keyconf,
-					 u8 sta_id)
-{
-	unsigned long flags;
-	__le16 key_flags = 0;
-	struct iwl_addsta_cmd sta_cmd;
-
-	lockdep_assert_held(&priv->mutex);
-
-	key_flags |= (STA_KEY_FLG_CCMP | STA_KEY_FLG_MAP_KEY_MSK);
-	key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS);
-	key_flags &= ~STA_KEY_FLG_INVALID;
-
-	if (sta_id == ctx->bcast_sta_id)
-		key_flags |= STA_KEY_MULTICAST_MSK;
-
-	keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
-
-	spin_lock_irqsave(&priv->sta_lock, flags);
-	priv->stations[sta_id].keyinfo.cipher = keyconf->cipher;
-	priv->stations[sta_id].keyinfo.keylen = keyconf->keylen;
-
-	memcpy(priv->stations[sta_id].keyinfo.key, keyconf->key,
-	       keyconf->keylen);
-
-	memcpy(priv->stations[sta_id].sta.key.key, keyconf->key,
-	       keyconf->keylen);
-
-	if ((priv->stations[sta_id].sta.key.key_flags & STA_KEY_FLG_ENCRYPT_MSK)
-			== STA_KEY_FLG_NO_ENC)
-		priv->stations[sta_id].sta.key.key_offset =
-				 iwl_get_free_ucode_key_index(priv);
-	/* else, we are overriding an existing key => no need to allocated room
-	 * in uCode. */
-
-	WARN(priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET,
-		"no space for a new key");
-
-	priv->stations[sta_id].sta.key.key_flags = key_flags;
-	priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
-	priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
-
-	memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd));
-	spin_unlock_irqrestore(&priv->sta_lock, flags);
-
-	return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
-}
-
-static int iwl_set_tkip_dynamic_key_info(struct iwl_priv *priv,
-					 struct iwl_rxon_context *ctx,
-					 struct ieee80211_key_conf *keyconf,
-					 u8 sta_id)
-{
-	unsigned long flags;
-	int ret = 0;
-	__le16 key_flags = 0;
-
-	key_flags |= (STA_KEY_FLG_TKIP | STA_KEY_FLG_MAP_KEY_MSK);
-	key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS);
-	key_flags &= ~STA_KEY_FLG_INVALID;
-
-	if (sta_id == ctx->bcast_sta_id)
-		key_flags |= STA_KEY_MULTICAST_MSK;
-
-	keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
-	keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
-
-	spin_lock_irqsave(&priv->sta_lock, flags);
-
-	priv->stations[sta_id].keyinfo.cipher = keyconf->cipher;
-	priv->stations[sta_id].keyinfo.keylen = 16;
-
-	if ((priv->stations[sta_id].sta.key.key_flags & STA_KEY_FLG_ENCRYPT_MSK)
-			== STA_KEY_FLG_NO_ENC)
-		priv->stations[sta_id].sta.key.key_offset =
-				 iwl_get_free_ucode_key_index(priv);
-	/* else, we are overriding an existing key => no need to allocated room
-	 * in uCode. */
-
-	WARN(priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET,
-		"no space for a new key");
-
-	priv->stations[sta_id].sta.key.key_flags = key_flags;
-
-
-	/* This copy is acutally not needed: we get the key with each TX */
-	memcpy(priv->stations[sta_id].keyinfo.key, keyconf->key, 16);
-
-	memcpy(priv->stations[sta_id].sta.key.key, keyconf->key, 16);
-
-	spin_unlock_irqrestore(&priv->sta_lock, flags);
-
-	return ret;
-}
-
-void iwl_update_tkip_key(struct iwl_priv *priv,
-			 struct iwl_rxon_context *ctx,
-			 struct ieee80211_key_conf *keyconf,
-			 struct ieee80211_sta *sta, u32 iv32, u16 *phase1key)
+void iwl_dealloc_bcast_stations(struct iwl_priv *priv)
 {
-	u8 sta_id;
 	unsigned long flags;
 	int i;
 
-	if (iwl_scan_cancel(priv)) {
-		/* cancel scan failed, just live w/ bad key and rely
-		   briefly on SW decryption */
-		return;
-	}
-
-	sta_id = iwl_sta_id_or_broadcast(priv, ctx, sta);
-	if (sta_id == IWL_INVALID_STATION)
-		return;
-
-	spin_lock_irqsave(&priv->sta_lock, flags);
-
-	priv->stations[sta_id].sta.key.tkip_rx_tsc_byte2 = (u8) iv32;
-
-	for (i = 0; i < 5; i++)
-		priv->stations[sta_id].sta.key.tkip_rx_ttak[i] =
-			cpu_to_le16(phase1key[i]);
-
-	priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
-	priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
-
-	iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
-
-	spin_unlock_irqrestore(&priv->sta_lock, flags);
-
-}
-EXPORT_SYMBOL(iwl_update_tkip_key);
-
-int iwl_remove_dynamic_key(struct iwl_priv *priv,
-			   struct iwl_rxon_context *ctx,
-			   struct ieee80211_key_conf *keyconf,
-			   u8 sta_id)
-{
-	unsigned long flags;
-	u16 key_flags;
-	u8 keyidx;
-	struct iwl_addsta_cmd sta_cmd;
-
-	lockdep_assert_held(&priv->mutex);
-
-	ctx->key_mapping_keys--;
-
 	spin_lock_irqsave(&priv->sta_lock, flags);
-	key_flags = le16_to_cpu(priv->stations[sta_id].sta.key.key_flags);
-	keyidx = (key_flags >> STA_KEY_FLG_KEYID_POS) & 0x3;
-
-	IWL_DEBUG_WEP(priv, "Remove dynamic key: idx=%d sta=%d\n",
-		      keyconf->keyidx, sta_id);
-
-	if (keyconf->keyidx != keyidx) {
-		/* We need to remove a key with index different that the one
-		 * in the uCode. This means that the key we need to remove has
-		 * been replaced by another one with different index.
-		 * Don't do anything and return ok
-		 */
-		spin_unlock_irqrestore(&priv->sta_lock, flags);
-		return 0;
-	}
-
-	if (priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET) {
-		IWL_WARN(priv, "Removing wrong key %d 0x%x\n",
-			    keyconf->keyidx, key_flags);
-		spin_unlock_irqrestore(&priv->sta_lock, flags);
-		return 0;
-	}
+	for (i = 0; i < priv->hw_params.max_stations; i++) {
+		if (!(priv->stations[i].used & IWL_STA_BCAST))
+			continue;
 
-	if (!test_and_clear_bit(priv->stations[sta_id].sta.key.key_offset,
-		&priv->ucode_key_table))
-		IWL_ERR(priv, "index %d not used in uCode key table.\n",
-			priv->stations[sta_id].sta.key.key_offset);
-	memset(&priv->stations[sta_id].keyinfo, 0,
-					sizeof(struct iwl_hw_key));
-	memset(&priv->stations[sta_id].sta.key, 0,
-					sizeof(struct iwl4965_keyinfo));
-	priv->stations[sta_id].sta.key.key_flags =
-			STA_KEY_FLG_NO_ENC | STA_KEY_FLG_INVALID;
-	priv->stations[sta_id].sta.key.key_offset = WEP_INVALID_OFFSET;
-	priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
-	priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
-
-	if (iwl_is_rfkill(priv)) {
-		IWL_DEBUG_WEP(priv, "Not sending REPLY_ADD_STA command because RFKILL enabled.\n");
-		spin_unlock_irqrestore(&priv->sta_lock, flags);
-		return 0;
+		priv->stations[i].used &= ~IWL_STA_UCODE_ACTIVE;
+		priv->num_stations--;
+		BUG_ON(priv->num_stations < 0);
+		kfree(priv->stations[i].lq);
+		priv->stations[i].lq = NULL;
 	}
-	memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd));
 	spin_unlock_irqrestore(&priv->sta_lock, flags);
-
-	return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
-}
-EXPORT_SYMBOL(iwl_remove_dynamic_key);
-
-int iwl_set_dynamic_key(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
-			struct ieee80211_key_conf *keyconf, u8 sta_id)
-{
-	int ret;
-
-	lockdep_assert_held(&priv->mutex);
-
-	ctx->key_mapping_keys++;
-	keyconf->hw_key_idx = HW_KEY_DYNAMIC;
-
-	switch (keyconf->cipher) {
-	case WLAN_CIPHER_SUITE_CCMP:
-		ret = iwl_set_ccmp_dynamic_key_info(priv, ctx, keyconf, sta_id);
-		break;
-	case WLAN_CIPHER_SUITE_TKIP:
-		ret = iwl_set_tkip_dynamic_key_info(priv, ctx, keyconf, sta_id);
-		break;
-	case WLAN_CIPHER_SUITE_WEP40:
-	case WLAN_CIPHER_SUITE_WEP104:
-		ret = iwl_set_wep_dynamic_key_info(priv, ctx, keyconf, sta_id);
-		break;
-	default:
-		IWL_ERR(priv,
-			"Unknown alg: %s cipher = %x\n", __func__,
-			keyconf->cipher);
-		ret = -EINVAL;
-	}
-
-	IWL_DEBUG_WEP(priv, "Set dynamic key: cipher=%x len=%d idx=%d sta=%d ret=%d\n",
-		      keyconf->cipher, keyconf->keylen, keyconf->keyidx,
-		      sta_id, ret);
-
-	return ret;
 }
-EXPORT_SYMBOL(iwl_set_dynamic_key);
+EXPORT_SYMBOL_GPL(iwl_dealloc_bcast_stations);
 
 #ifdef CONFIG_IWLWIFI_DEBUG
 static void iwl_dump_lq_cmd(struct iwl_priv *priv,
@@ -1240,223 +758,6 @@ int iwl_send_lq_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
 }
 EXPORT_SYMBOL(iwl_send_lq_cmd);
 
-/**
- * iwl_alloc_bcast_station - add broadcast station into driver's station table.
- *
- * This adds the broadcast station into the driver's station table
- * and marks it driver active, so that it will be restored to the
- * device at the next best time.
- */
-int iwl_alloc_bcast_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
-			    bool init_lq)
-{
-	struct iwl_link_quality_cmd *link_cmd;
-	unsigned long flags;
-	u8 sta_id;
-
-	spin_lock_irqsave(&priv->sta_lock, flags);
-	sta_id = iwl_prep_station(priv, ctx, iwl_bcast_addr, false, NULL);
-	if (sta_id == IWL_INVALID_STATION) {
-		IWL_ERR(priv, "Unable to prepare broadcast station\n");
-		spin_unlock_irqrestore(&priv->sta_lock, flags);
-
-		return -EINVAL;
-	}
-
-	priv->stations[sta_id].used |= IWL_STA_DRIVER_ACTIVE;
-	priv->stations[sta_id].used |= IWL_STA_BCAST;
-	spin_unlock_irqrestore(&priv->sta_lock, flags);
-
-	if (init_lq) {
-		link_cmd = iwl_sta_alloc_lq(priv, sta_id);
-		if (!link_cmd) {
-			IWL_ERR(priv,
-				"Unable to initialize rate scaling for bcast station.\n");
-			return -ENOMEM;
-		}
-
-		spin_lock_irqsave(&priv->sta_lock, flags);
-		priv->stations[sta_id].lq = link_cmd;
-		spin_unlock_irqrestore(&priv->sta_lock, flags);
-	}
-
-	return 0;
-}
-EXPORT_SYMBOL_GPL(iwl_alloc_bcast_station);
-
-/**
- * iwl_update_bcast_station - update broadcast station's LQ command
- *
- * Only used by iwlagn. Placed here to have all bcast station management
- * code together.
- */
-static int iwl_update_bcast_station(struct iwl_priv *priv,
-				    struct iwl_rxon_context *ctx)
-{
-	unsigned long flags;
-	struct iwl_link_quality_cmd *link_cmd;
-	u8 sta_id = ctx->bcast_sta_id;
-
-	link_cmd = iwl_sta_alloc_lq(priv, sta_id);
-	if (!link_cmd) {
-		IWL_ERR(priv, "Unable to initialize rate scaling for bcast station.\n");
-		return -ENOMEM;
-	}
-
-	spin_lock_irqsave(&priv->sta_lock, flags);
-	if (priv->stations[sta_id].lq)
-		kfree(priv->stations[sta_id].lq);
-	else
-		IWL_DEBUG_INFO(priv, "Bcast station rate scaling has not been initialized yet.\n");
-	priv->stations[sta_id].lq = link_cmd;
-	spin_unlock_irqrestore(&priv->sta_lock, flags);
-
-	return 0;
-}
-
-int iwl_update_bcast_stations(struct iwl_priv *priv)
-{
-	struct iwl_rxon_context *ctx;
-	int ret = 0;
-
-	for_each_context(priv, ctx) {
-		ret = iwl_update_bcast_station(priv, ctx);
-		if (ret)
-			break;
-	}
-
-	return ret;
-}
-EXPORT_SYMBOL_GPL(iwl_update_bcast_stations);
-
-void iwl_dealloc_bcast_stations(struct iwl_priv *priv)
-{
-	unsigned long flags;
-	int i;
-
-	spin_lock_irqsave(&priv->sta_lock, flags);
-	for (i = 0; i < priv->hw_params.max_stations; i++) {
-		if (!(priv->stations[i].used & IWL_STA_BCAST))
-			continue;
-
-		priv->stations[i].used &= ~IWL_STA_UCODE_ACTIVE;
-		priv->num_stations--;
-		BUG_ON(priv->num_stations < 0);
-		kfree(priv->stations[i].lq);
-		priv->stations[i].lq = NULL;
-	}
-	spin_unlock_irqrestore(&priv->sta_lock, flags);
-}
-EXPORT_SYMBOL_GPL(iwl_dealloc_bcast_stations);
-
-/**
- * iwl_sta_tx_modify_enable_tid - Enable Tx for this TID in station table
- */
-int iwl_sta_tx_modify_enable_tid(struct iwl_priv *priv, int sta_id, int tid)
-{
-	unsigned long flags;
-	struct iwl_addsta_cmd sta_cmd;
-
-	lockdep_assert_held(&priv->mutex);
-
-	/* Remove "disable" flag, to enable Tx for this TID */
-	spin_lock_irqsave(&priv->sta_lock, flags);
-	priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_TID_DISABLE_TX;
-	priv->stations[sta_id].sta.tid_disable_tx &= cpu_to_le16(~(1 << tid));
-	priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
-	memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd));
-	spin_unlock_irqrestore(&priv->sta_lock, flags);
-
-	return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
-}
-EXPORT_SYMBOL(iwl_sta_tx_modify_enable_tid);
-
-int iwl_sta_rx_agg_start(struct iwl_priv *priv, struct ieee80211_sta *sta,
-			 int tid, u16 ssn)
-{
-	unsigned long flags;
-	int sta_id;
-	struct iwl_addsta_cmd sta_cmd;
-
-	lockdep_assert_held(&priv->mutex);
-
-	sta_id = iwl_sta_id(sta);
-	if (sta_id == IWL_INVALID_STATION)
-		return -ENXIO;
-
-	spin_lock_irqsave(&priv->sta_lock, flags);
-	priv->stations[sta_id].sta.station_flags_msk = 0;
-	priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_ADDBA_TID_MSK;
-	priv->stations[sta_id].sta.add_immediate_ba_tid = (u8)tid;
-	priv->stations[sta_id].sta.add_immediate_ba_ssn = cpu_to_le16(ssn);
-	priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
-	memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd));
-	spin_unlock_irqrestore(&priv->sta_lock, flags);
-
-	return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
-}
-EXPORT_SYMBOL(iwl_sta_rx_agg_start);
-
-int iwl_sta_rx_agg_stop(struct iwl_priv *priv, struct ieee80211_sta *sta,
-			int tid)
-{
-	unsigned long flags;
-	int sta_id;
-	struct iwl_addsta_cmd sta_cmd;
-
-	lockdep_assert_held(&priv->mutex);
-
-	sta_id = iwl_sta_id(sta);
-	if (sta_id == IWL_INVALID_STATION) {
-		IWL_ERR(priv, "Invalid station for AGG tid %d\n", tid);
-		return -ENXIO;
-	}
-
-	spin_lock_irqsave(&priv->sta_lock, flags);
-	priv->stations[sta_id].sta.station_flags_msk = 0;
-	priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_DELBA_TID_MSK;
-	priv->stations[sta_id].sta.remove_immediate_ba_tid = (u8)tid;
-	priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
-	memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd));
-	spin_unlock_irqrestore(&priv->sta_lock, flags);
-
-	return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
-}
-EXPORT_SYMBOL(iwl_sta_rx_agg_stop);
-
-void iwl_sta_modify_ps_wake(struct iwl_priv *priv, int sta_id)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&priv->sta_lock, flags);
-	priv->stations[sta_id].sta.station_flags &= ~STA_FLG_PWR_SAVE_MSK;
-	priv->stations[sta_id].sta.station_flags_msk = STA_FLG_PWR_SAVE_MSK;
-	priv->stations[sta_id].sta.sta.modify_mask = 0;
-	priv->stations[sta_id].sta.sleep_tx_count = 0;
-	priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
-	iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
-	spin_unlock_irqrestore(&priv->sta_lock, flags);
-
-}
-EXPORT_SYMBOL(iwl_sta_modify_ps_wake);
-
-void iwl_sta_modify_sleep_tx_count(struct iwl_priv *priv, int sta_id, int cnt)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&priv->sta_lock, flags);
-	priv->stations[sta_id].sta.station_flags |= STA_FLG_PWR_SAVE_MSK;
-	priv->stations[sta_id].sta.station_flags_msk = STA_FLG_PWR_SAVE_MSK;
-	priv->stations[sta_id].sta.sta.modify_mask =
-					STA_MODIFY_SLEEP_TX_COUNT_MSK;
-	priv->stations[sta_id].sta.sleep_tx_count = cpu_to_le16(cnt);
-	priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
-	iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
-	spin_unlock_irqrestore(&priv->sta_lock, flags);
-
-}
-EXPORT_SYMBOL(iwl_sta_modify_sleep_tx_count);
-
 int iwl_mac_sta_remove(struct ieee80211_hw *hw,
 		       struct ieee80211_vif *vif,
 		       struct ieee80211_sta *sta)
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.h b/drivers/net/wireless/iwlwifi/iwl-sta.h
index 56bad3f60d81..06475872eee4 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.h
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.h
@@ -43,35 +43,13 @@
 #define IWL_STA_BCAST BIT(4) /* this station is the special bcast station */
 
 
-int iwl_remove_default_wep_key(struct iwl_priv *priv,
-			       struct iwl_rxon_context *ctx,
-			       struct ieee80211_key_conf *key);
-int iwl_set_default_wep_key(struct iwl_priv *priv,
-			    struct iwl_rxon_context *ctx,
-			    struct ieee80211_key_conf *key);
-int iwl_restore_default_wep_keys(struct iwl_priv *priv,
-				 struct iwl_rxon_context *ctx);
-int iwl_set_dynamic_key(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
-			struct ieee80211_key_conf *key, u8 sta_id);
-int iwl_remove_dynamic_key(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
-			   struct ieee80211_key_conf *key, u8 sta_id);
-void iwl_update_tkip_key(struct iwl_priv *priv,
-			 struct iwl_rxon_context *ctx,
-			 struct ieee80211_key_conf *keyconf,
-			 struct ieee80211_sta *sta, u32 iv32, u16 *phase1key);
-
 void iwl_restore_stations(struct iwl_priv *priv, struct iwl_rxon_context *ctx);
 void iwl_clear_ucode_stations(struct iwl_priv *priv,
 			      struct iwl_rxon_context *ctx);
-int iwl_alloc_bcast_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
-			    bool init_lq);
 void iwl_dealloc_bcast_stations(struct iwl_priv *priv);
-int iwl_update_bcast_stations(struct iwl_priv *priv);
 int iwl_get_free_ucode_key_index(struct iwl_priv *priv);
 int iwl_send_add_sta(struct iwl_priv *priv,
 		     struct iwl_addsta_cmd *sta, u8 flags);
-int iwl_add_bssid_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
-			  const u8 *addr, bool init_rs, u8 *sta_id_r);
 int iwl_add_station_common(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
 			   const u8 *addr, bool is_ap,
 			   struct ieee80211_sta *sta, u8 *sta_id_r);
@@ -79,13 +57,12 @@ int iwl_remove_station(struct iwl_priv *priv, const u8 sta_id,
 		       const u8 *addr);
 int iwl_mac_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 		       struct ieee80211_sta *sta);
-int iwl_sta_tx_modify_enable_tid(struct iwl_priv *priv, int sta_id, int tid);
-int iwl_sta_rx_agg_start(struct iwl_priv *priv, struct ieee80211_sta *sta,
-			 int tid, u16 ssn);
-int iwl_sta_rx_agg_stop(struct iwl_priv *priv, struct ieee80211_sta *sta,
-			int tid);
-void iwl_sta_modify_ps_wake(struct iwl_priv *priv, int sta_id);
-void iwl_sta_modify_sleep_tx_count(struct iwl_priv *priv, int sta_id, int cnt);
+
+u8 iwl_prep_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
+		    const u8 *addr, bool is_ap, struct ieee80211_sta *sta);
+
+int iwl_send_lq_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
+		    struct iwl_link_quality_cmd *lq, u8 flags, bool init);
 
 /**
  * iwl_clear_driver_stations - clear knowledge of all stations from driver
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c
index 3290b1552f5a..7261ee49f282 100644
--- a/drivers/net/wireless/iwlwifi/iwl-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-tx.c
@@ -636,41 +636,3 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
 	meta->flags = 0;
 }
 EXPORT_SYMBOL(iwl_tx_cmd_complete);
-
-#ifdef CONFIG_IWLWIFI_DEBUG
-#define TX_STATUS_FAIL(x) case TX_STATUS_FAIL_ ## x: return #x
-#define TX_STATUS_POSTPONE(x) case TX_STATUS_POSTPONE_ ## x: return #x
-
-const char *iwl_get_tx_fail_reason(u32 status)
-{
-	switch (status & TX_STATUS_MSK) {
-	case TX_STATUS_SUCCESS:
-		return "SUCCESS";
-		TX_STATUS_POSTPONE(DELAY);
-		TX_STATUS_POSTPONE(FEW_BYTES);
-		TX_STATUS_POSTPONE(BT_PRIO);
-		TX_STATUS_POSTPONE(QUIET_PERIOD);
-		TX_STATUS_POSTPONE(CALC_TTAK);
-		TX_STATUS_FAIL(INTERNAL_CROSSED_RETRY);
-		TX_STATUS_FAIL(SHORT_LIMIT);
-		TX_STATUS_FAIL(LONG_LIMIT);
-		TX_STATUS_FAIL(FIFO_UNDERRUN);
-		TX_STATUS_FAIL(DRAIN_FLOW);
-		TX_STATUS_FAIL(RFKILL_FLUSH);
-		TX_STATUS_FAIL(LIFE_EXPIRE);
-		TX_STATUS_FAIL(DEST_PS);
-		TX_STATUS_FAIL(HOST_ABORTED);
-		TX_STATUS_FAIL(BT_RETRY);
-		TX_STATUS_FAIL(STA_INVALID);
-		TX_STATUS_FAIL(FRAG_DROPPED);
-		TX_STATUS_FAIL(TID_DISABLE);
-		TX_STATUS_FAIL(FIFO_FLUSHED);
-		TX_STATUS_FAIL(INSUFFICIENT_CF_POLL);
-		TX_STATUS_FAIL(PASSIVE_NO_RX);
-		TX_STATUS_FAIL(NO_BEACON_ON_RADAR);
-	}
-
-	return "UNKNOWN";
-}
-EXPORT_SYMBOL(iwl_get_tx_fail_reason);
-#endif /* CONFIG_IWLWIFI_DEBUG */
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 43db5f38e3e6..8f8c4b73f8b9 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -317,15 +317,15 @@ unsigned int iwl3945_fill_beacon_frame(struct iwl_priv *priv,
 				int left)
 {
 
-	if (!iwl_is_associated(priv, IWL_RXON_CTX_BSS) || !priv->ibss_beacon)
+	if (!iwl_is_associated(priv, IWL_RXON_CTX_BSS) || !priv->beacon_skb)
 		return 0;
 
-	if (priv->ibss_beacon->len > left)
+	if (priv->beacon_skb->len > left)
 		return 0;
 
-	memcpy(hdr, priv->ibss_beacon->data, priv->ibss_beacon->len);
+	memcpy(hdr, priv->beacon_skb->data, priv->beacon_skb->len);
 
-	return priv->ibss_beacon->len;
+	return priv->beacon_skb->len;
 }
 
 static int iwl3945_send_beacon_cmd(struct iwl_priv *priv)
@@ -813,10 +813,10 @@ static void iwl3945_bg_beacon_update(struct work_struct *work)
 
 	mutex_lock(&priv->mutex);
 	/* new beacon skb is allocated every time; dispose previous.*/
-	if (priv->ibss_beacon)
-		dev_kfree_skb(priv->ibss_beacon);
+	if (priv->beacon_skb)
+		dev_kfree_skb(priv->beacon_skb);
 
-	priv->ibss_beacon = beacon;
+	priv->beacon_skb = beacon;
 	mutex_unlock(&priv->mutex);
 
 	iwl3945_send_beacon_cmd(priv);
@@ -2547,7 +2547,7 @@ static void iwl3945_alive_start(struct iwl_priv *priv)
 	priv->cfg->ops->hcmd->send_bt_config(priv);
 
 	/* Configure the adapter for unassociated operation */
-	iwlcore_commit_rxon(priv, ctx);
+	iwl3945_commit_rxon(priv, ctx);
 
 	iwl3945_reg_txpower_periodic(priv);
 
@@ -2637,14 +2637,14 @@ static void __iwl3945_down(struct iwl_priv *priv)
 	udelay(5);
 
 	/* Stop the device, and put it in low power state */
-	priv->cfg->ops->lib->apm_ops.stop(priv);
+	iwl_apm_stop(priv);
 
  exit:
 	memset(&priv->card_alive, 0, sizeof(struct iwl_alive_resp));
 
-	if (priv->ibss_beacon)
-		dev_kfree_skb(priv->ibss_beacon);
-	priv->ibss_beacon = NULL;
+	if (priv->beacon_skb)
+		dev_kfree_skb(priv->beacon_skb);
+	priv->beacon_skb = NULL;
 
 	/* clear out any free frames */
 	iwl3945_clear_free_frames(priv);
@@ -2661,12 +2661,33 @@ static void iwl3945_down(struct iwl_priv *priv)
 
 #define MAX_HW_RESTARTS 5
 
+static int iwl3945_alloc_bcast_station(struct iwl_priv *priv)
+{
+	struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
+	unsigned long flags;
+	u8 sta_id;
+
+	spin_lock_irqsave(&priv->sta_lock, flags);
+	sta_id = iwl_prep_station(priv, ctx, iwl_bcast_addr, false, NULL);
+	if (sta_id == IWL_INVALID_STATION) {
+		IWL_ERR(priv, "Unable to prepare broadcast station\n");
+		spin_unlock_irqrestore(&priv->sta_lock, flags);
+
+		return -EINVAL;
+	}
+
+	priv->stations[sta_id].used |= IWL_STA_DRIVER_ACTIVE;
+	priv->stations[sta_id].used |= IWL_STA_BCAST;
+	spin_unlock_irqrestore(&priv->sta_lock, flags);
+
+	return 0;
+}
+
 static int __iwl3945_up(struct iwl_priv *priv)
 {
 	int rc, i;
 
-	rc = iwl_alloc_bcast_station(priv, &priv->contexts[IWL_RXON_CTX_BSS],
-				     false);
+	rc = iwl3945_alloc_bcast_station(priv);
 	if (rc)
 		return rc;
 
@@ -2917,18 +2938,10 @@ int iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
 	case IEEE80211_BAND_2GHZ:
 		scan->flags = RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK;
 		scan->tx_cmd.rate = IWL_RATE_1M_PLCP;
-		scan->good_CRC_th = 0;
 		band = IEEE80211_BAND_2GHZ;
 		break;
 	case IEEE80211_BAND_5GHZ:
 		scan->tx_cmd.rate = IWL_RATE_6M_PLCP;
-		/*
-		 * If active scaning is requested but a certain channel
-		 * is marked passive, we can do active scanning if we
-		 * detect transmissions.
-		 */
-		scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH_DEFAULT :
-						IWL_GOOD_CRC_TH_DISABLED;
 		band = IEEE80211_BAND_5GHZ;
 		break;
 	default:
@@ -2936,6 +2949,14 @@ int iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
 		return -EIO;
 	}
 
+	/*
+	 * If active scaning is requested but a certain channel
+	 * is marked passive, we can do active scanning if we
+	 * detect transmissions.
+	 */
+	scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH_DEFAULT :
+					IWL_GOOD_CRC_TH_DISABLED;
+
 	if (!priv->is_internal_short_scan) {
 		scan->tx_cmd.len = cpu_to_le16(
 			iwl_fill_probe_req(priv,
@@ -2983,6 +3004,18 @@ int iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
 	return ret;
 }
 
+void iwl3945_post_scan(struct iwl_priv *priv)
+{
+	struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
+
+	/*
+	 * Since setting the RXON may have been deferred while
+	 * performing the scan, fire one off if needed
+	 */
+	if (memcmp(&ctx->staging, &ctx->active, sizeof(ctx->staging)))
+		iwl3945_commit_rxon(priv, ctx);
+}
+
 static void iwl3945_bg_restart(struct work_struct *data)
 {
 	struct iwl_priv *priv = container_of(data, struct iwl_priv, restart);
@@ -3049,7 +3082,7 @@ void iwl3945_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif)
 	conf = ieee80211_get_hw_conf(priv->hw);
 
 	ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
-	iwlcore_commit_rxon(priv, ctx);
+	iwl3945_commit_rxon(priv, ctx);
 
 	rc = iwl_send_rxon_timing(priv, ctx);
 	if (rc)
@@ -3075,7 +3108,7 @@ void iwl3945_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif)
 			ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
 	}
 
-	iwlcore_commit_rxon(priv, ctx);
+	iwl3945_commit_rxon(priv, ctx);
 
 	switch (vif->type) {
 	case NL80211_IFTYPE_STATION:
@@ -3214,7 +3247,7 @@ void iwl3945_config_ap(struct iwl_priv *priv, struct ieee80211_vif *vif)
 
 		/* RXON - unassoc (to set timing command) */
 		ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
-		iwlcore_commit_rxon(priv, ctx);
+		iwl3945_commit_rxon(priv, ctx);
 
 		/* RXON Timing */
 		rc = iwl_send_rxon_timing(priv, ctx);
@@ -3241,7 +3274,7 @@ void iwl3945_config_ap(struct iwl_priv *priv, struct ieee80211_vif *vif)
 		}
 		/* restore RXON assoc */
 		ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
-		iwlcore_commit_rxon(priv, ctx);
+		iwl3945_commit_rxon(priv, ctx);
 	}
 	iwl3945_send_beacon_cmd(priv);
 
@@ -3507,7 +3540,7 @@ static ssize_t store_flags(struct device *d,
 			IWL_DEBUG_INFO(priv, "Committing rxon.flags = 0x%04X\n",
 				       flags);
 			ctx->staging.flags = cpu_to_le32(flags);
-			iwlcore_commit_rxon(priv, ctx);
+			iwl3945_commit_rxon(priv, ctx);
 		}
 	}
 	mutex_unlock(&priv->mutex);
@@ -3545,7 +3578,7 @@ static ssize_t store_filter_flags(struct device *d,
 				       "0x%04X\n", filter_flags);
 			ctx->staging.filter_flags =
 				cpu_to_le32(filter_flags);
-			iwlcore_commit_rxon(priv, ctx);
+			iwl3945_commit_rxon(priv, ctx);
 		}
 	}
 	mutex_unlock(&priv->mutex);
@@ -3815,7 +3848,7 @@ static int iwl3945_init_drv(struct iwl_priv *priv)
 	struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom;
 
 	priv->retry_rate = 1;
-	priv->ibss_beacon = NULL;
+	priv->beacon_skb = NULL;
 
 	spin_lock_init(&priv->sta_lock);
 	spin_lock_init(&priv->hcmd_lock);
@@ -4179,7 +4212,7 @@ static void __devexit iwl3945_pci_remove(struct pci_dev *pdev)
 	 * paths to avoid running iwl_down() at all before leaving driver.
 	 * This (inexpensive) call *makes sure* device is reset.
 	 */
-	priv->cfg->ops->lib->apm_ops.stop(priv);
+	iwl_apm_stop(priv);
 
 	/* make sure we flush any pending irq or
 	 * tasklet for the driver
@@ -4223,8 +4256,8 @@ static void __devexit iwl3945_pci_remove(struct pci_dev *pdev)
 	iwl_free_channel_map(priv);
 	iwlcore_free_geos(priv);
 	kfree(priv->scan_cmd);
-	if (priv->ibss_beacon)
-		dev_kfree_skb(priv->ibss_beacon);
+	if (priv->beacon_skb)
+		dev_kfree_skb(priv->beacon_skb);
 
 	ieee80211_free_hw(priv->hw);
 }
diff --git a/drivers/net/wireless/libertas/if_usb.c b/drivers/net/wireless/libertas/if_usb.c
index e906616232a2..efaf85032208 100644
--- a/drivers/net/wireless/libertas/if_usb.c
+++ b/drivers/net/wireless/libertas/if_usb.c
@@ -487,11 +487,12 @@ static int if_usb_reset_device(struct if_usb_card *cardp)
  */
 static int usb_tx_block(struct if_usb_card *cardp, uint8_t *payload, uint16_t nb)
 {
-	int ret = -1;
+	int ret;
 
 	/* check if device is removed */
 	if (cardp->surprise_removed) {
 		lbs_deb_usbd(&cardp->udev->dev, "Device removed\n");
+		ret = -ENODEV;
 		goto tx_ret;
 	}
 
@@ -504,7 +505,6 @@ static int usb_tx_block(struct if_usb_card *cardp, uint8_t *payload, uint16_t nb
 
 	if ((ret = usb_submit_urb(cardp->tx_urb, GFP_ATOMIC))) {
 		lbs_deb_usbd(&cardp->udev->dev, "usb_submit_urb failed: %d\n", ret);
-		ret = -1;
 	} else {
 		lbs_deb_usb2(&cardp->udev->dev, "usb_submit_urb success\n");
 		ret = 0;
diff --git a/drivers/net/wireless/p54/eeprom.c b/drivers/net/wireless/p54/eeprom.c
index 8c05266d37f4..35b09aa0529b 100644
--- a/drivers/net/wireless/p54/eeprom.c
+++ b/drivers/net/wireless/p54/eeprom.c
@@ -261,8 +261,10 @@ static int p54_generate_channel_lists(struct ieee80211_hw *dev)
 	list->max_entries = max_channel_num;
 	list->channels = kzalloc(sizeof(struct p54_channel_entry) *
 				 max_channel_num, GFP_KERNEL);
-	if (!list->channels)
+	if (!list->channels) {
+		ret = -ENOMEM;
 		goto free;
+	}
 
 	for (i = 0; i < max_channel_num; i++) {
 		if (i < priv->iq_autocal_len) {
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c
index d49e830fa1da..4f420a9ec5dc 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.c
+++ b/drivers/net/wireless/rt2x00/rt2400pci.c
@@ -1104,7 +1104,7 @@ static void rt2400pci_write_beacon(struct queue_entry *entry,
 	rt2x00_set_field32(&reg, CSR14_BEACON_GEN, 0);
 	rt2x00pci_register_write(rt2x00dev, CSR14, reg);
 
-	rt2x00queue_map_txskb(rt2x00dev, entry->skb);
+	rt2x00queue_map_txskb(entry);
 
 	/*
 	 * Write the TX descriptor for the beacon.
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c
index 2214c3231727..97feb7aef809 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.c
+++ b/drivers/net/wireless/rt2x00/rt2500pci.c
@@ -1258,7 +1258,7 @@ static void rt2500pci_write_beacon(struct queue_entry *entry,
 	rt2x00_set_field32(&reg, CSR14_BEACON_GEN, 0);
 	rt2x00pci_register_write(rt2x00dev, CSR14, reg);
 
-	rt2x00queue_map_txskb(rt2x00dev, entry->skb);
+	rt2x00queue_map_txskb(entry);
 
 	/*
 	 * Write the TX descriptor for the beacon.
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index 10aefc4fb0cc..5f00e00789d8 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -499,7 +499,7 @@ void rt2800_write_tx_data(struct queue_entry *entry,
 }
 EXPORT_SYMBOL_GPL(rt2800_write_tx_data);
 
-static int rt2800_agc_to_rssi(struct rt2x00_dev *rt2x00dev, int rxwi_w2)
+static int rt2800_agc_to_rssi(struct rt2x00_dev *rt2x00dev, u32 rxwi_w2)
 {
 	int rssi0 = rt2x00_get_field32(rxwi_w2, RXWI_W2_RSSI0);
 	int rssi1 = rt2x00_get_field32(rxwi_w2, RXWI_W2_RSSI1);
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c
index 85a134cd62bf..b26739535986 100644
--- a/drivers/net/wireless/rt2x00/rt2800pci.c
+++ b/drivers/net/wireless/rt2x00/rt2800pci.c
@@ -573,7 +573,7 @@ static void rt2800pci_kick_tx_queue(struct data_queue *queue)
 {
 	struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
 	struct queue_entry *entry = rt2x00queue_get_entry(queue, Q_INDEX);
-	unsigned int qidx = 0;
+	unsigned int qidx;
 
 	if (queue->qid == QID_MGMT)
 		qidx = 5;
@@ -676,7 +676,7 @@ static void rt2800pci_txdone(struct rt2x00_dev *rt2x00dev)
 			break;
 		}
 
-		qid = rt2x00_get_field32(status, TX_STA_FIFO_PID_TYPE) - 1;
+		qid = rt2x00_get_field32(status, TX_STA_FIFO_PID_QUEUE);
 		if (qid >= QID_RX) {
 			/*
 			 * Unknown queue, this shouldn't happen. Just drop
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index 75ac6624bf9e..94fe589acfaa 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -338,6 +338,11 @@ struct link {
 
 	/*
 	 * Work structure for scheduling periodic watchdog monitoring.
+	 * This work must be scheduled on the kernel workqueue, while
+	 * all other work structures must be queued on the mac80211
+	 * workqueue. This guarantees that the watchdog can schedule
+	 * other work structures and wait for their completion in order
+	 * to bring the device/driver back into the desired state.
 	 */
 	struct delayed_work watchdog_work;
 };
@@ -1036,17 +1041,15 @@ static inline bool rt2x00_is_soc(struct rt2x00_dev *rt2x00dev)
 
 /**
  * rt2x00queue_map_txskb - Map a skb into DMA for TX purposes.
- * @rt2x00dev: Pointer to &struct rt2x00_dev.
- * @skb: The skb to map.
+ * @entry: Pointer to &struct queue_entry
  */
-void rt2x00queue_map_txskb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb);
+void rt2x00queue_map_txskb(struct queue_entry *entry);
 
 /**
  * rt2x00queue_unmap_skb - Unmap a skb from DMA.
- * @rt2x00dev: Pointer to &struct rt2x00_dev.
- * @skb: The skb to unmap.
+ * @entry: Pointer to &struct queue_entry
  */
-void rt2x00queue_unmap_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb);
+void rt2x00queue_unmap_skb(struct queue_entry *entry);
 
 /**
  * rt2x00queue_get_queue - Convert queue index to queue pointer
@@ -1093,8 +1096,7 @@ void rt2x00lib_dmadone(struct queue_entry *entry);
 void rt2x00lib_txdone(struct queue_entry *entry,
 		      struct txdone_entry_desc *txdesc);
 void rt2x00lib_txdone_noinfo(struct queue_entry *entry, u32 status);
-void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev,
-		      struct queue_entry *entry);
+void rt2x00lib_rxdone(struct queue_entry *entry);
 
 /*
  * mac80211 handlers.
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index 6f442b02b83e..5ba79b935f09 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -253,6 +253,7 @@ EXPORT_SYMBOL_GPL(rt2x00lib_pretbtt);
 
 void rt2x00lib_dmadone(struct queue_entry *entry)
 {
+	clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags);
 	rt2x00queue_index_inc(entry->queue, Q_INDEX_DMA_DONE);
 }
 EXPORT_SYMBOL_GPL(rt2x00lib_dmadone);
@@ -273,7 +274,7 @@ void rt2x00lib_txdone(struct queue_entry *entry,
 	/*
 	 * Unmap the skb.
 	 */
-	rt2x00queue_unmap_skb(rt2x00dev, entry->skb);
+	rt2x00queue_unmap_skb(entry);
 
 	/*
 	 * Remove the extra tx headroom from the skb.
@@ -432,42 +433,50 @@ static int rt2x00lib_rxdone_read_signal(struct rt2x00_dev *rt2x00dev,
 	struct ieee80211_supported_band *sband;
 	const struct rt2x00_rate *rate;
 	unsigned int i;
-	int signal;
-	int type;
+	int signal = rxdesc->signal;
+	int type = (rxdesc->dev_flags & RXDONE_SIGNAL_MASK);
 
-	/*
-	 * For non-HT rates the MCS value needs to contain the
-	 * actually used rate modulation (CCK or OFDM).
-	 */
-	if (rxdesc->dev_flags & RXDONE_SIGNAL_MCS)
-		signal = RATE_MCS(rxdesc->rate_mode, rxdesc->signal);
-	else
-		signal = rxdesc->signal;
-
-	type = (rxdesc->dev_flags & RXDONE_SIGNAL_MASK);
-
-	sband = &rt2x00dev->bands[rt2x00dev->curr_band];
-	for (i = 0; i < sband->n_bitrates; i++) {
-		rate = rt2x00_get_rate(sband->bitrates[i].hw_value);
-
-		if (((type == RXDONE_SIGNAL_PLCP) &&
-		     (rate->plcp == signal)) ||
-		    ((type == RXDONE_SIGNAL_BITRATE) &&
-		      (rate->bitrate == signal)) ||
-		    ((type == RXDONE_SIGNAL_MCS) &&
-		      (rate->mcs == signal))) {
-			return i;
+	switch (rxdesc->rate_mode) {
+	case RATE_MODE_CCK:
+	case RATE_MODE_OFDM:
+		/*
+		 * For non-HT rates the MCS value needs to contain the
+		 * actually used rate modulation (CCK or OFDM).
+		 */
+		if (rxdesc->dev_flags & RXDONE_SIGNAL_MCS)
+			signal = RATE_MCS(rxdesc->rate_mode, signal);
+
+		sband = &rt2x00dev->bands[rt2x00dev->curr_band];
+		for (i = 0; i < sband->n_bitrates; i++) {
+			rate = rt2x00_get_rate(sband->bitrates[i].hw_value);
+			if (((type == RXDONE_SIGNAL_PLCP) &&
+			     (rate->plcp == signal)) ||
+			    ((type == RXDONE_SIGNAL_BITRATE) &&
+			      (rate->bitrate == signal)) ||
+			    ((type == RXDONE_SIGNAL_MCS) &&
+			      (rate->mcs == signal))) {
+				return i;
+			}
 		}
+		break;
+	case RATE_MODE_HT_MIX:
+	case RATE_MODE_HT_GREENFIELD:
+		if (signal >= 0 && signal <= 76)
+			return signal;
+		break;
+	default:
+		break;
 	}
 
 	WARNING(rt2x00dev, "Frame received with unrecognized signal, "
-		"signal=0x%.4x, type=%d.\n", signal, type);
+		"mode=0x%.4x, signal=0x%.4x, type=%d.\n",
+		rxdesc->rate_mode, signal, type);
 	return 0;
 }
 
-void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev,
-		      struct queue_entry *entry)
+void rt2x00lib_rxdone(struct queue_entry *entry)
 {
+	struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
 	struct rxdone_entry_desc rxdesc;
 	struct sk_buff *skb;
 	struct ieee80211_rx_status *rx_status;
@@ -481,14 +490,14 @@ void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev,
 	 * Allocate a new sk_buffer. If no new buffer available, drop the
 	 * received frame and reuse the existing buffer.
 	 */
-	skb = rt2x00queue_alloc_rxskb(rt2x00dev, entry);
+	skb = rt2x00queue_alloc_rxskb(entry);
 	if (!skb)
-		return;
+		goto submit_entry;
 
 	/*
 	 * Unmap the skb.
 	 */
-	rt2x00queue_unmap_skb(rt2x00dev, entry->skb);
+	rt2x00queue_unmap_skb(entry);
 
 	/*
 	 * Extract the RXD details.
@@ -523,18 +532,12 @@ void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev,
 	skb_trim(entry->skb, rxdesc.size);
 
 	/*
-	 * Check if the frame was received using HT. In that case,
-	 * the rate is the MCS index and should be passed to mac80211
-	 * directly. Otherwise we need to translate the signal to
-	 * the correct bitrate index.
+	 * Translate the signal to the correct bitrate index.
 	 */
-	if (rxdesc.rate_mode == RATE_MODE_CCK ||
-	    rxdesc.rate_mode == RATE_MODE_OFDM) {
-		rate_idx = rt2x00lib_rxdone_read_signal(rt2x00dev, &rxdesc);
-	} else {
+	rate_idx = rt2x00lib_rxdone_read_signal(rt2x00dev, &rxdesc);
+	if (rxdesc.rate_mode == RATE_MODE_HT_MIX ||
+	    rxdesc.rate_mode == RATE_MODE_HT_GREENFIELD)
 		rxdesc.flags |= RX_FLAG_HT;
-		rate_idx = rxdesc.signal;
-	}
 
 	/*
 	 * Update extra components
diff --git a/drivers/net/wireless/rt2x00/rt2x00lib.h b/drivers/net/wireless/rt2x00/rt2x00lib.h
index 70c85ac2e53e..619da23b7b56 100644
--- a/drivers/net/wireless/rt2x00/rt2x00lib.h
+++ b/drivers/net/wireless/rt2x00/rt2x00lib.h
@@ -100,18 +100,15 @@ void rt2x00lib_config(struct rt2x00_dev *rt2x00dev,
 
 /**
  * rt2x00queue_alloc_rxskb - allocate a skb for RX purposes.
- * @rt2x00dev: Pointer to &struct rt2x00_dev.
- * @queue: The queue for which the skb will be applicable.
+ * @entry: The entry for which the skb will be applicable.
  */
-struct sk_buff *rt2x00queue_alloc_rxskb(struct rt2x00_dev *rt2x00dev,
-					struct queue_entry *entry);
+struct sk_buff *rt2x00queue_alloc_rxskb(struct queue_entry *entry);
 
 /**
  * rt2x00queue_free_skb - free a skb
- * @rt2x00dev: Pointer to &struct rt2x00_dev.
- * @skb: The skb to free.
+ * @entry: The entry for which the skb will be applicable.
  */
-void rt2x00queue_free_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb);
+void rt2x00queue_free_skb(struct queue_entry *entry);
 
 /**
  * rt2x00queue_align_frame - Align 802.11 frame to 4-byte boundary
diff --git a/drivers/net/wireless/rt2x00/rt2x00link.c b/drivers/net/wireless/rt2x00/rt2x00link.c
index 4d534e9dc628..b971d8798ebf 100644
--- a/drivers/net/wireless/rt2x00/rt2x00link.c
+++ b/drivers/net/wireless/rt2x00/rt2x00link.c
@@ -236,6 +236,12 @@ void rt2x00link_update_stats(struct rt2x00_dev *rt2x00dev,
 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
 
 	/*
+	 * No need to update the stats for !=STA interfaces
+	 */
+	if (!rt2x00dev->intf_sta_count)
+		return;
+
+	/*
 	 * Frame was received successfully since non-succesfull
 	 * frames would have been dropped by the hardware.
 	 */
@@ -411,8 +417,7 @@ void rt2x00link_start_watchdog(struct rt2x00_dev *rt2x00dev)
 	    !test_bit(DRIVER_SUPPORT_WATCHDOG, &rt2x00dev->flags))
 		return;
 
-	ieee80211_queue_delayed_work(rt2x00dev->hw,
-				     &link->watchdog_work, WATCHDOG_INTERVAL);
+	schedule_delayed_work(&link->watchdog_work, WATCHDOG_INTERVAL);
 }
 
 void rt2x00link_stop_watchdog(struct rt2x00_dev *rt2x00dev)
@@ -436,8 +441,7 @@ static void rt2x00link_watchdog(struct work_struct *work)
 	rt2x00dev->ops->lib->watchdog(rt2x00dev);
 
 	if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
-		ieee80211_queue_delayed_work(rt2x00dev->hw,
-					     &link->watchdog_work, WATCHDOG_INTERVAL);
+		schedule_delayed_work(&link->watchdog_work, WATCHDOG_INTERVAL);
 }
 
 void rt2x00link_register(struct rt2x00_dev *rt2x00dev)
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c
index 63c2cc408e15..2449d785cf8d 100644
--- a/drivers/net/wireless/rt2x00/rt2x00pci.c
+++ b/drivers/net/wireless/rt2x00/rt2x00pci.c
@@ -84,7 +84,7 @@ void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev)
 		/*
 		 * Send the frame to rt2x00lib for further processing.
 		 */
-		rt2x00lib_rxdone(rt2x00dev, entry);
+		rt2x00lib_rxdone(entry);
 	}
 }
 EXPORT_SYMBOL_GPL(rt2x00pci_rxdone);
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c
index eede99939db9..e360d287defb 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.c
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.c
@@ -33,9 +33,9 @@
 #include "rt2x00.h"
 #include "rt2x00lib.h"
 
-struct sk_buff *rt2x00queue_alloc_rxskb(struct rt2x00_dev *rt2x00dev,
-					struct queue_entry *entry)
+struct sk_buff *rt2x00queue_alloc_rxskb(struct queue_entry *entry)
 {
+	struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
 	struct sk_buff *skb;
 	struct skb_frame_desc *skbdesc;
 	unsigned int frame_size;
@@ -97,41 +97,42 @@ struct sk_buff *rt2x00queue_alloc_rxskb(struct rt2x00_dev *rt2x00dev,
 	return skb;
 }
 
-void rt2x00queue_map_txskb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb)
+void rt2x00queue_map_txskb(struct queue_entry *entry)
 {
-	struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
+	struct device *dev = entry->queue->rt2x00dev->dev;
+	struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
 
 	skbdesc->skb_dma =
-	    dma_map_single(rt2x00dev->dev, skb->data, skb->len, DMA_TO_DEVICE);
+	    dma_map_single(dev, entry->skb->data, entry->skb->len, DMA_TO_DEVICE);
 	skbdesc->flags |= SKBDESC_DMA_MAPPED_TX;
 }
 EXPORT_SYMBOL_GPL(rt2x00queue_map_txskb);
 
-void rt2x00queue_unmap_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb)
+void rt2x00queue_unmap_skb(struct queue_entry *entry)
 {
-	struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
+	struct device *dev = entry->queue->rt2x00dev->dev;
+	struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
 
 	if (skbdesc->flags & SKBDESC_DMA_MAPPED_RX) {
-		dma_unmap_single(rt2x00dev->dev, skbdesc->skb_dma, skb->len,
+		dma_unmap_single(dev, skbdesc->skb_dma, entry->skb->len,
 				 DMA_FROM_DEVICE);
 		skbdesc->flags &= ~SKBDESC_DMA_MAPPED_RX;
-	}
-
-	if (skbdesc->flags & SKBDESC_DMA_MAPPED_TX) {
-		dma_unmap_single(rt2x00dev->dev, skbdesc->skb_dma, skb->len,
+	} else if (skbdesc->flags & SKBDESC_DMA_MAPPED_TX) {
+		dma_unmap_single(dev, skbdesc->skb_dma, entry->skb->len,
 				 DMA_TO_DEVICE);
 		skbdesc->flags &= ~SKBDESC_DMA_MAPPED_TX;
 	}
 }
 EXPORT_SYMBOL_GPL(rt2x00queue_unmap_skb);
 
-void rt2x00queue_free_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb)
+void rt2x00queue_free_skb(struct queue_entry *entry)
 {
-	if (!skb)
+	if (!entry->skb)
 		return;
 
-	rt2x00queue_unmap_skb(rt2x00dev, skb);
-	dev_kfree_skb_any(skb);
+	rt2x00queue_unmap_skb(entry);
+	dev_kfree_skb_any(entry->skb);
+	entry->skb = NULL;
 }
 
 void rt2x00queue_align_frame(struct sk_buff *skb)
@@ -440,7 +441,7 @@ static int rt2x00queue_write_tx_data(struct queue_entry *entry,
 	 * Map the skb to DMA.
 	 */
 	if (test_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags))
-		rt2x00queue_map_txskb(rt2x00dev, entry->skb);
+		rt2x00queue_map_txskb(entry);
 
 	return 0;
 }
@@ -491,7 +492,8 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb,
 	if (unlikely(rt2x00queue_full(queue)))
 		return -ENOBUFS;
 
-	if (test_and_set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) {
+	if (unlikely(test_and_set_bit(ENTRY_OWNER_DEVICE_DATA,
+				      &entry->flags))) {
 		ERROR(queue->rt2x00dev,
 		      "Arrived at non-free entry in the non-full queue %d.\n"
 		      "Please file bug report to %s.\n",
@@ -586,8 +588,7 @@ int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev,
 	/*
 	 * Clean up the beacon skb.
 	 */
-	rt2x00queue_free_skb(rt2x00dev, intf->beacon->skb);
-	intf->beacon->skb = NULL;
+	rt2x00queue_free_skb(intf->beacon);
 
 	if (!enable_beacon) {
 		rt2x00dev->ops->lib->kill_tx_queue(intf->beacon->queue);
@@ -828,8 +829,7 @@ static int rt2x00queue_alloc_entries(struct data_queue *queue,
 	return 0;
 }
 
-static void rt2x00queue_free_skbs(struct rt2x00_dev *rt2x00dev,
-				  struct data_queue *queue)
+static void rt2x00queue_free_skbs(struct data_queue *queue)
 {
 	unsigned int i;
 
@@ -837,19 +837,17 @@ static void rt2x00queue_free_skbs(struct rt2x00_dev *rt2x00dev,
 		return;
 
 	for (i = 0; i < queue->limit; i++) {
-		if (queue->entries[i].skb)
-			rt2x00queue_free_skb(rt2x00dev, queue->entries[i].skb);
+		rt2x00queue_free_skb(&queue->entries[i]);
 	}
 }
 
-static int rt2x00queue_alloc_rxskbs(struct rt2x00_dev *rt2x00dev,
-				    struct data_queue *queue)
+static int rt2x00queue_alloc_rxskbs(struct data_queue *queue)
 {
 	unsigned int i;
 	struct sk_buff *skb;
 
 	for (i = 0; i < queue->limit; i++) {
-		skb = rt2x00queue_alloc_rxskb(rt2x00dev, &queue->entries[i]);
+		skb = rt2x00queue_alloc_rxskb(&queue->entries[i]);
 		if (!skb)
 			return -ENOMEM;
 		queue->entries[i].skb = skb;
@@ -884,7 +882,7 @@ int rt2x00queue_initialize(struct rt2x00_dev *rt2x00dev)
 			goto exit;
 	}
 
-	status = rt2x00queue_alloc_rxskbs(rt2x00dev, rt2x00dev->rx);
+	status = rt2x00queue_alloc_rxskbs(rt2x00dev->rx);
 	if (status)
 		goto exit;
 
@@ -902,7 +900,7 @@ void rt2x00queue_uninitialize(struct rt2x00_dev *rt2x00dev)
 {
 	struct data_queue *queue;
 
-	rt2x00queue_free_skbs(rt2x00dev, rt2x00dev->rx);
+	rt2x00queue_free_skbs(rt2x00dev->rx);
 
 	queue_for_each(rt2x00dev, queue) {
 		kfree(queue->entries);
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c
index 4c5ae3d45625..b3317df7a7d4 100644
--- a/drivers/net/wireless/rt2x00/rt2x00usb.c
+++ b/drivers/net/wireless/rt2x00/rt2x00usb.c
@@ -208,7 +208,7 @@ static void rt2x00usb_interrupt_txdone(struct urb *urb)
 	struct queue_entry *entry = (struct queue_entry *)urb->context;
 	struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
 
-	if (!__test_and_clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags))
+	if (!test_and_clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags))
 		return;
 
 	/*
@@ -220,7 +220,7 @@ static void rt2x00usb_interrupt_txdone(struct urb *urb)
 	 * Check if the frame was correctly uploaded
 	 */
 	if (urb->status)
-		__set_bit(ENTRY_DATA_IO_FAILED, &entry->flags);
+		set_bit(ENTRY_DATA_IO_FAILED, &entry->flags);
 
 	/*
 	 * Schedule the delayed work for reading the TX status
@@ -253,7 +253,10 @@ static void rt2x00usb_kick_tx_entry(struct queue_entry *entry)
 			  entry->skb->data, length,
 			  rt2x00usb_interrupt_txdone, entry);
 
-	usb_submit_urb(entry_priv->urb, GFP_ATOMIC);
+	if (usb_submit_urb(entry_priv->urb, GFP_ATOMIC)) {
+		set_bit(ENTRY_DATA_IO_FAILED, &entry->flags);
+		rt2x00lib_dmadone(entry);
+	}
 }
 
 void rt2x00usb_kick_tx_queue(struct data_queue *queue)
@@ -280,14 +283,6 @@ static void rt2x00usb_kill_tx_entry(struct queue_entry *entry)
 	if ((entry->queue->qid == QID_BEACON) &&
 	    (test_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags)))
 		usb_kill_urb(bcn_priv->guardian_urb);
-
-	/*
-	 * We need a short delay here to wait for
-	 * the URB to be canceled
-	 */
-	do {
-		udelay(100);
-	} while (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags));
 }
 
 void rt2x00usb_kill_tx_queue(struct data_queue *queue)
@@ -363,10 +358,12 @@ void rt2x00usb_watchdog(struct rt2x00_dev *rt2x00dev)
 	struct data_queue *queue;
 
 	tx_queue_for_each(rt2x00dev, queue) {
-		if (rt2x00queue_dma_timeout(queue))
-			rt2x00usb_watchdog_tx_dma(queue);
-		if (rt2x00queue_timeout(queue))
-			rt2x00usb_watchdog_tx_status(queue);
+		if (!rt2x00queue_empty(queue)) {
+			if (rt2x00queue_dma_timeout(queue))
+				rt2x00usb_watchdog_tx_dma(queue);
+			if (rt2x00queue_timeout(queue))
+				rt2x00usb_watchdog_tx_status(queue);
+		}
 	}
 }
 EXPORT_SYMBOL_GPL(rt2x00usb_watchdog);
@@ -398,7 +395,7 @@ static void rt2x00usb_work_rxdone(struct work_struct *work)
 		/*
 		 * Send the frame to rt2x00lib for further processing.
 		 */
-		rt2x00lib_rxdone(rt2x00dev, entry);
+		rt2x00lib_rxdone(entry);
 	}
 }
 
@@ -407,7 +404,7 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb)
 	struct queue_entry *entry = (struct queue_entry *)urb->context;
 	struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
 
-	if (!__test_and_clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags))
+	if (!test_and_clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags))
 		return;
 
 	/*
@@ -421,7 +418,7 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb)
 	 * a problem.
 	 */
 	if (urb->actual_length < entry->queue->desc_size || urb->status)
-		__set_bit(ENTRY_DATA_IO_FAILED, &entry->flags);
+		set_bit(ENTRY_DATA_IO_FAILED, &entry->flags);
 
 	/*
 	 * Schedule the delayed work for reading the RX status
@@ -467,7 +464,10 @@ void rt2x00usb_clear_entry(struct queue_entry *entry)
 				rt2x00usb_interrupt_rxdone, entry);
 
 		set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags);
-		usb_submit_urb(entry_priv->urb, GFP_ATOMIC);
+		if (usb_submit_urb(entry_priv->urb, GFP_ATOMIC)) {
+			set_bit(ENTRY_DATA_IO_FAILED, &entry->flags);
+			rt2x00lib_dmadone(entry);
+		}
 	}
 }
 EXPORT_SYMBOL_GPL(rt2x00usb_clear_entry);
@@ -542,9 +542,9 @@ static int rt2x00usb_find_endpoints(struct rt2x00_dev *rt2x00dev)
 	return 0;
 }
 
-static int rt2x00usb_alloc_urb(struct rt2x00_dev *rt2x00dev,
-			       struct data_queue *queue)
+static int rt2x00usb_alloc_entries(struct data_queue *queue)
 {
+	struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
 	struct queue_entry_priv_usb *entry_priv;
 	struct queue_entry_priv_usb_bcn *bcn_priv;
 	unsigned int i;
@@ -561,7 +561,7 @@ static int rt2x00usb_alloc_urb(struct rt2x00_dev *rt2x00dev,
 	 * no guardian byte was required for the beacon,
 	 * then we are done.
 	 */
-	if (rt2x00dev->bcn != queue ||
+	if (queue->qid != QID_BEACON ||
 	    !test_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags))
 		return 0;
 
@@ -575,9 +575,9 @@ static int rt2x00usb_alloc_urb(struct rt2x00_dev *rt2x00dev,
 	return 0;
 }
 
-static void rt2x00usb_free_urb(struct rt2x00_dev *rt2x00dev,
-			       struct data_queue *queue)
+static void rt2x00usb_free_entries(struct data_queue *queue)
 {
+	struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
 	struct queue_entry_priv_usb *entry_priv;
 	struct queue_entry_priv_usb_bcn *bcn_priv;
 	unsigned int i;
@@ -596,7 +596,7 @@ static void rt2x00usb_free_urb(struct rt2x00_dev *rt2x00dev,
 	 * no guardian byte was required for the beacon,
 	 * then we are done.
 	 */
-	if (rt2x00dev->bcn != queue ||
+	if (queue->qid != QID_BEACON ||
 	    !test_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags))
 		return;
 
@@ -623,7 +623,7 @@ int rt2x00usb_initialize(struct rt2x00_dev *rt2x00dev)
 	 * Allocate DMA
 	 */
 	queue_for_each(rt2x00dev, queue) {
-		status = rt2x00usb_alloc_urb(rt2x00dev, queue);
+		status = rt2x00usb_alloc_entries(queue);
 		if (status)
 			goto exit;
 	}
@@ -642,7 +642,7 @@ void rt2x00usb_uninitialize(struct rt2x00_dev *rt2x00dev)
 	struct data_queue *queue;
 
 	queue_for_each(rt2x00dev, queue)
-		rt2x00usb_free_urb(rt2x00dev, queue);
+		rt2x00usb_free_entries(queue);
 }
 EXPORT_SYMBOL_GPL(rt2x00usb_uninitialize);
 
diff --git a/drivers/net/wireless/wl1251/Kconfig b/drivers/net/wireless/wl1251/Kconfig
new file mode 100644
index 000000000000..1fb65849414f
--- /dev/null
+++ b/drivers/net/wireless/wl1251/Kconfig
@@ -0,0 +1,33 @@
+menuconfig WL1251
+	tristate "TI wl1251 driver support"
+	depends on MAC80211 && EXPERIMENTAL && GENERIC_HARDIRQS
+	select FW_LOADER
+	select CRC7
+	---help---
+	  This will enable TI wl1251 driver support. The drivers make
+	  use of the mac80211 stack.
+
+	  If you choose to build a module, it'll be called wl1251. Say
+	  N if unsure.
+
+config WL1251_SPI
+	tristate "TI wl1251 SPI support"
+	depends on WL1251 && SPI_MASTER
+	---help---
+	  This module adds support for the SPI interface of adapters using
+	  TI wl1251 chipset.  Select this if your platform is using
+	  the SPI bus.
+
+	  If you choose to build a module, it'll be called wl1251_spi.
+	  Say N if unsure.
+
+config WL1251_SDIO
+	tristate "TI wl1251 SDIO support"
+	depends on WL1251 && MMC
+	---help---
+	  This module adds support for the SDIO interface of adapters using
+	  TI wl1251 chipset.  Select this if your platform is using
+	  the SDIO bus.
+
+	  If you choose to build a module, it'll be called
+	  wl1251_sdio. Say N if unsure.
diff --git a/drivers/net/wireless/wl1251/Makefile b/drivers/net/wireless/wl1251/Makefile
new file mode 100644
index 000000000000..4fe246824db3
--- /dev/null
+++ b/drivers/net/wireless/wl1251/Makefile
@@ -0,0 +1,6 @@
+wl1251-objs		= main.o event.o tx.o rx.o ps.o cmd.o \
+			  acx.o boot.o init.o debugfs.o io.o
+
+obj-$(CONFIG_WL1251)	+= wl1251.o
+obj-$(CONFIG_WL1251_SPI)	+= spi.o
+obj-$(CONFIG_WL1251_SDIO)	+= sdio.o
diff --git a/drivers/net/wireless/wl12xx/wl1251_acx.c b/drivers/net/wireless/wl1251/acx.c
index 2f8a2ba744dc..64a0214cfb29 100644
--- a/drivers/net/wireless/wl12xx/wl1251_acx.c
+++ b/drivers/net/wireless/wl1251/acx.c
@@ -1,13 +1,13 @@
-#include "wl1251_acx.h"
+#include "acx.h"
 
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/crc7.h>
 
 #include "wl1251.h"
-#include "wl1251_reg.h"
-#include "wl1251_cmd.h"
-#include "wl1251_ps.h"
+#include "reg.h"
+#include "cmd.h"
+#include "ps.h"
 
 int wl1251_acx_frame_rates(struct wl1251 *wl, u8 ctrl_rate, u8 ctrl_mod,
 			   u8 mgt_rate, u8 mgt_mod)
diff --git a/drivers/net/wireless/wl12xx/wl1251_acx.h b/drivers/net/wireless/wl1251/acx.h
index c7cc5c1e8a75..e54b21a4f8b1 100644
--- a/drivers/net/wireless/wl12xx/wl1251_acx.h
+++ b/drivers/net/wireless/wl1251/acx.h
@@ -24,7 +24,7 @@
 #define __WL1251_ACX_H__
 
 #include "wl1251.h"
-#include "wl1251_cmd.h"
+#include "cmd.h"
 
 /* Target's information element */
 struct acx_header {
diff --git a/drivers/net/wireless/wl12xx/wl1251_boot.c b/drivers/net/wireless/wl1251/boot.c
index 468b47b0328a..61572dfa1f60 100644
--- a/drivers/net/wireless/wl12xx/wl1251_boot.c
+++ b/drivers/net/wireless/wl1251/boot.c
@@ -22,12 +22,12 @@
 #include <linux/gpio.h>
 #include <linux/slab.h>
 
-#include "wl1251_reg.h"
-#include "wl1251_boot.h"
-#include "wl1251_io.h"
-#include "wl1251_spi.h"
-#include "wl1251_event.h"
-#include "wl1251_acx.h"
+#include "reg.h"
+#include "boot.h"
+#include "io.h"
+#include "spi.h"
+#include "event.h"
+#include "acx.h"
 
 void wl1251_boot_target_enable_interrupts(struct wl1251 *wl)
 {
diff --git a/drivers/net/wireless/wl12xx/wl1251_boot.h b/drivers/net/wireless/wl1251/boot.h
index 7661bc5e4662..7661bc5e4662 100644
--- a/drivers/net/wireless/wl12xx/wl1251_boot.h
+++ b/drivers/net/wireless/wl1251/boot.h
diff --git a/drivers/net/wireless/wl12xx/wl1251_cmd.c b/drivers/net/wireless/wl1251/cmd.c
index 15fb68c6b542..0ade4bd617c0 100644
--- a/drivers/net/wireless/wl12xx/wl1251_cmd.c
+++ b/drivers/net/wireless/wl1251/cmd.c
@@ -1,14 +1,14 @@
-#include "wl1251_cmd.h"
+#include "cmd.h"
 
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/crc7.h>
 
 #include "wl1251.h"
-#include "wl1251_reg.h"
-#include "wl1251_io.h"
-#include "wl1251_ps.h"
-#include "wl1251_acx.h"
+#include "reg.h"
+#include "io.h"
+#include "ps.h"
+#include "acx.h"
 
 /**
  * send command to firmware
diff --git a/drivers/net/wireless/wl12xx/wl1251_cmd.h b/drivers/net/wireless/wl1251/cmd.h
index e5c74c631374..e5c74c631374 100644
--- a/drivers/net/wireless/wl12xx/wl1251_cmd.h
+++ b/drivers/net/wireless/wl1251/cmd.h
diff --git a/drivers/net/wireless/wl12xx/wl1251_debugfs.c b/drivers/net/wireless/wl1251/debugfs.c
index 6ffe4cd58561..6e5caaa9f613 100644
--- a/drivers/net/wireless/wl12xx/wl1251_debugfs.c
+++ b/drivers/net/wireless/wl1251/debugfs.c
@@ -19,14 +19,14 @@
  *
  */
 
-#include "wl1251_debugfs.h"
+#include "debugfs.h"
 
 #include <linux/skbuff.h>
 #include <linux/slab.h>
 
 #include "wl1251.h"
-#include "wl1251_acx.h"
-#include "wl1251_ps.h"
+#include "acx.h"
+#include "ps.h"
 
 /* ms */
 #define WL1251_DEBUGFS_STATS_LIFETIME 1000
diff --git a/drivers/net/wireless/wl12xx/wl1251_debugfs.h b/drivers/net/wireless/wl1251/debugfs.h
index b3417c02a218..b3417c02a218 100644
--- a/drivers/net/wireless/wl12xx/wl1251_debugfs.h
+++ b/drivers/net/wireless/wl1251/debugfs.h
diff --git a/drivers/net/wireless/wl12xx/wl1251_event.c b/drivers/net/wireless/wl1251/event.c
index 54223556b308..712372e50a87 100644
--- a/drivers/net/wireless/wl12xx/wl1251_event.c
+++ b/drivers/net/wireless/wl1251/event.c
@@ -21,10 +21,10 @@
  */
 
 #include "wl1251.h"
-#include "wl1251_reg.h"
-#include "wl1251_io.h"
-#include "wl1251_event.h"
-#include "wl1251_ps.h"
+#include "reg.h"
+#include "io.h"
+#include "event.h"
+#include "ps.h"
 
 static int wl1251_event_scan_complete(struct wl1251 *wl,
 				      struct event_mailbox *mbox)
diff --git a/drivers/net/wireless/wl12xx/wl1251_event.h b/drivers/net/wireless/wl1251/event.h
index 30eb5d150bf7..30eb5d150bf7 100644
--- a/drivers/net/wireless/wl12xx/wl1251_event.h
+++ b/drivers/net/wireless/wl1251/event.h
diff --git a/drivers/net/wireless/wl12xx/wl1251_init.c b/drivers/net/wireless/wl1251/init.c
index c5daec05d9ee..89b43d35473c 100644
--- a/drivers/net/wireless/wl12xx/wl1251_init.c
+++ b/drivers/net/wireless/wl1251/init.c
@@ -23,11 +23,11 @@
 #include <linux/module.h>
 #include <linux/slab.h>
 
-#include "wl1251_init.h"
+#include "init.h"
 #include "wl12xx_80211.h"
-#include "wl1251_acx.h"
-#include "wl1251_cmd.h"
-#include "wl1251_reg.h"
+#include "acx.h"
+#include "cmd.h"
+#include "reg.h"
 
 int wl1251_hw_init_hwenc_config(struct wl1251 *wl)
 {
diff --git a/drivers/net/wireless/wl12xx/wl1251_init.h b/drivers/net/wireless/wl1251/init.h
index 543f17582ead..543f17582ead 100644
--- a/drivers/net/wireless/wl12xx/wl1251_init.h
+++ b/drivers/net/wireless/wl1251/init.h
diff --git a/drivers/net/wireless/wl12xx/wl1251_io.c b/drivers/net/wireless/wl1251/io.c
index ad6ca68b303f..cdcadbf6ac2c 100644
--- a/drivers/net/wireless/wl12xx/wl1251_io.c
+++ b/drivers/net/wireless/wl1251/io.c
@@ -20,8 +20,8 @@
  */
 
 #include "wl1251.h"
-#include "wl1251_reg.h"
-#include "wl1251_io.h"
+#include "reg.h"
+#include "io.h"
 
 /* FIXME: this is static data nowadays and the table can be removed */
 static enum wl12xx_acx_int_reg wl1251_io_reg_table[ACX_REG_TABLE_LEN] = {
diff --git a/drivers/net/wireless/wl12xx/wl1251_io.h b/drivers/net/wireless/wl1251/io.h
index c545e9d5f512..c545e9d5f512 100644
--- a/drivers/net/wireless/wl12xx/wl1251_io.h
+++ b/drivers/net/wireless/wl1251/io.h
diff --git a/drivers/net/wireless/wl12xx/wl1251_main.c b/drivers/net/wireless/wl1251/main.c
index faf221ca3f41..7a8762553cdc 100644
--- a/drivers/net/wireless/wl12xx/wl1251_main.c
+++ b/drivers/net/wireless/wl1251/main.c
@@ -31,16 +31,16 @@
 
 #include "wl1251.h"
 #include "wl12xx_80211.h"
-#include "wl1251_reg.h"
-#include "wl1251_io.h"
-#include "wl1251_cmd.h"
-#include "wl1251_event.h"
-#include "wl1251_tx.h"
-#include "wl1251_rx.h"
-#include "wl1251_ps.h"
-#include "wl1251_init.h"
-#include "wl1251_debugfs.h"
-#include "wl1251_boot.h"
+#include "reg.h"
+#include "io.h"
+#include "cmd.h"
+#include "event.h"
+#include "tx.h"
+#include "rx.h"
+#include "ps.h"
+#include "init.h"
+#include "debugfs.h"
+#include "boot.h"
 
 void wl1251_enable_interrupts(struct wl1251 *wl)
 {
diff --git a/drivers/net/wireless/wl12xx/wl1251_ps.c b/drivers/net/wireless/wl1251/ps.c
index 0b997bdfec09..5ed47c8373d2 100644
--- a/drivers/net/wireless/wl12xx/wl1251_ps.c
+++ b/drivers/net/wireless/wl1251/ps.c
@@ -19,10 +19,10 @@
  *
  */
 
-#include "wl1251_reg.h"
-#include "wl1251_ps.h"
-#include "wl1251_cmd.h"
-#include "wl1251_io.h"
+#include "reg.h"
+#include "ps.h"
+#include "cmd.h"
+#include "io.h"
 
 /* in ms */
 #define WL1251_WAKEUP_TIMEOUT 100
diff --git a/drivers/net/wireless/wl12xx/wl1251_ps.h b/drivers/net/wireless/wl1251/ps.h
index e5db81fc1dfc..55c3dda75e69 100644
--- a/drivers/net/wireless/wl12xx/wl1251_ps.h
+++ b/drivers/net/wireless/wl1251/ps.h
@@ -24,7 +24,7 @@
 #define __WL1251_PS_H__
 
 #include "wl1251.h"
-#include "wl1251_acx.h"
+#include "acx.h"
 
 int wl1251_ps_set_mode(struct wl1251 *wl, enum wl1251_cmd_ps_mode mode);
 void wl1251_ps_elp_sleep(struct wl1251 *wl);
diff --git a/drivers/net/wireless/wl12xx/wl1251_reg.h b/drivers/net/wireless/wl1251/reg.h
index a5809019c5c1..a5809019c5c1 100644
--- a/drivers/net/wireless/wl12xx/wl1251_reg.h
+++ b/drivers/net/wireless/wl1251/reg.h
diff --git a/drivers/net/wireless/wl12xx/wl1251_rx.c b/drivers/net/wireless/wl1251/rx.c
index 25764592a596..efa53607d5c9 100644
--- a/drivers/net/wireless/wl12xx/wl1251_rx.c
+++ b/drivers/net/wireless/wl1251/rx.c
@@ -25,11 +25,11 @@
 #include <net/mac80211.h>
 
 #include "wl1251.h"
-#include "wl1251_reg.h"
-#include "wl1251_io.h"
-#include "wl1251_rx.h"
-#include "wl1251_cmd.h"
-#include "wl1251_acx.h"
+#include "reg.h"
+#include "io.h"
+#include "rx.h"
+#include "cmd.h"
+#include "acx.h"
 
 static void wl1251_rx_header(struct wl1251 *wl,
 			     struct wl1251_rx_descriptor *desc)
diff --git a/drivers/net/wireless/wl12xx/wl1251_rx.h b/drivers/net/wireless/wl1251/rx.h
index 4448f635a4d8..4448f635a4d8 100644
--- a/drivers/net/wireless/wl12xx/wl1251_rx.h
+++ b/drivers/net/wireless/wl1251/rx.h
diff --git a/drivers/net/wireless/wl12xx/wl1251_sdio.c b/drivers/net/wireless/wl1251/sdio.c
index 74ba9ced5393..74ba9ced5393 100644
--- a/drivers/net/wireless/wl12xx/wl1251_sdio.c
+++ b/drivers/net/wireless/wl1251/sdio.c
diff --git a/drivers/net/wireless/wl12xx/wl1251_spi.c b/drivers/net/wireless/wl1251/spi.c
index 320de79667a6..88fa8e69d0d1 100644
--- a/drivers/net/wireless/wl12xx/wl1251_spi.c
+++ b/drivers/net/wireless/wl1251/spi.c
@@ -27,8 +27,8 @@
 #include <linux/wl12xx.h>
 
 #include "wl1251.h"
-#include "wl1251_reg.h"
-#include "wl1251_spi.h"
+#include "reg.h"
+#include "spi.h"
 
 static irqreturn_t wl1251_irq(int irq, void *cookie)
 {
diff --git a/drivers/net/wireless/wl12xx/wl1251_spi.h b/drivers/net/wireless/wl1251/spi.h
index 7dcf3cf7ae40..16d506955cc0 100644
--- a/drivers/net/wireless/wl12xx/wl1251_spi.h
+++ b/drivers/net/wireless/wl1251/spi.h
@@ -23,9 +23,9 @@
 #ifndef __WL1251_SPI_H__
 #define __WL1251_SPI_H__
 
-#include "wl1251_cmd.h"
-#include "wl1251_acx.h"
-#include "wl1251_reg.h"
+#include "cmd.h"
+#include "acx.h"
+#include "reg.h"
 
 #define WSPI_CMD_READ                 0x40000000
 #define WSPI_CMD_WRITE                0x00000000
diff --git a/drivers/net/wireless/wl12xx/wl1251_tx.c b/drivers/net/wireless/wl1251/tx.c
index 388492a7f41f..554b4f9a3d3e 100644
--- a/drivers/net/wireless/wl12xx/wl1251_tx.c
+++ b/drivers/net/wireless/wl1251/tx.c
@@ -24,10 +24,10 @@
 #include <linux/module.h>
 
 #include "wl1251.h"
-#include "wl1251_reg.h"
-#include "wl1251_tx.h"
-#include "wl1251_ps.h"
-#include "wl1251_io.h"
+#include "reg.h"
+#include "tx.h"
+#include "ps.h"
+#include "io.h"
 
 static bool wl1251_tx_double_buffer_busy(struct wl1251 *wl, u32 data_out_count)
 {
diff --git a/drivers/net/wireless/wl12xx/wl1251_tx.h b/drivers/net/wireless/wl1251/tx.h
index 96011e78cd5a..81338d39b43e 100644
--- a/drivers/net/wireless/wl12xx/wl1251_tx.h
+++ b/drivers/net/wireless/wl1251/tx.h
@@ -24,7 +24,7 @@
 #define __WL1251_TX_H__
 
 #include <linux/bitops.h>
-#include "wl1251_acx.h"
+#include "acx.h"
 
 /*
  *
diff --git a/drivers/net/wireless/wl12xx/wl1251.h b/drivers/net/wireless/wl1251/wl1251.h
index e113d4c1fb35..e113d4c1fb35 100644
--- a/drivers/net/wireless/wl12xx/wl1251.h
+++ b/drivers/net/wireless/wl1251/wl1251.h
diff --git a/drivers/net/wireless/wl1251/wl12xx_80211.h b/drivers/net/wireless/wl1251/wl12xx_80211.h
new file mode 100644
index 000000000000..184628027213
--- /dev/null
+++ b/drivers/net/wireless/wl1251/wl12xx_80211.h
@@ -0,0 +1,156 @@
+#ifndef __WL12XX_80211_H__
+#define __WL12XX_80211_H__
+
+#include <linux/if_ether.h>	/* ETH_ALEN */
+
+/* RATES */
+#define IEEE80211_CCK_RATE_1MB		        0x02
+#define IEEE80211_CCK_RATE_2MB		        0x04
+#define IEEE80211_CCK_RATE_5MB		        0x0B
+#define IEEE80211_CCK_RATE_11MB		        0x16
+#define IEEE80211_OFDM_RATE_6MB		        0x0C
+#define IEEE80211_OFDM_RATE_9MB		        0x12
+#define IEEE80211_OFDM_RATE_12MB		0x18
+#define IEEE80211_OFDM_RATE_18MB		0x24
+#define IEEE80211_OFDM_RATE_24MB		0x30
+#define IEEE80211_OFDM_RATE_36MB		0x48
+#define IEEE80211_OFDM_RATE_48MB		0x60
+#define IEEE80211_OFDM_RATE_54MB		0x6C
+#define IEEE80211_BASIC_RATE_MASK		0x80
+
+#define IEEE80211_CCK_RATE_1MB_MASK		(1<<0)
+#define IEEE80211_CCK_RATE_2MB_MASK		(1<<1)
+#define IEEE80211_CCK_RATE_5MB_MASK		(1<<2)
+#define IEEE80211_CCK_RATE_11MB_MASK		(1<<3)
+#define IEEE80211_OFDM_RATE_6MB_MASK		(1<<4)
+#define IEEE80211_OFDM_RATE_9MB_MASK		(1<<5)
+#define IEEE80211_OFDM_RATE_12MB_MASK		(1<<6)
+#define IEEE80211_OFDM_RATE_18MB_MASK		(1<<7)
+#define IEEE80211_OFDM_RATE_24MB_MASK		(1<<8)
+#define IEEE80211_OFDM_RATE_36MB_MASK		(1<<9)
+#define IEEE80211_OFDM_RATE_48MB_MASK		(1<<10)
+#define IEEE80211_OFDM_RATE_54MB_MASK		(1<<11)
+
+#define IEEE80211_CCK_RATES_MASK	  0x0000000F
+#define IEEE80211_CCK_BASIC_RATES_MASK	 (IEEE80211_CCK_RATE_1MB_MASK | \
+	IEEE80211_CCK_RATE_2MB_MASK)
+#define IEEE80211_CCK_DEFAULT_RATES_MASK (IEEE80211_CCK_BASIC_RATES_MASK | \
+	IEEE80211_CCK_RATE_5MB_MASK | \
+	IEEE80211_CCK_RATE_11MB_MASK)
+
+#define IEEE80211_OFDM_RATES_MASK	  0x00000FF0
+#define IEEE80211_OFDM_BASIC_RATES_MASK	  (IEEE80211_OFDM_RATE_6MB_MASK | \
+	IEEE80211_OFDM_RATE_12MB_MASK | \
+	IEEE80211_OFDM_RATE_24MB_MASK)
+#define IEEE80211_OFDM_DEFAULT_RATES_MASK (IEEE80211_OFDM_BASIC_RATES_MASK | \
+	IEEE80211_OFDM_RATE_9MB_MASK  | \
+	IEEE80211_OFDM_RATE_18MB_MASK | \
+	IEEE80211_OFDM_RATE_36MB_MASK | \
+	IEEE80211_OFDM_RATE_48MB_MASK | \
+	IEEE80211_OFDM_RATE_54MB_MASK)
+#define IEEE80211_DEFAULT_RATES_MASK (IEEE80211_OFDM_DEFAULT_RATES_MASK | \
+				      IEEE80211_CCK_DEFAULT_RATES_MASK)
+
+
+/* This really should be 8, but not for our firmware */
+#define MAX_SUPPORTED_RATES 32
+#define COUNTRY_STRING_LEN 3
+#define MAX_COUNTRY_TRIPLETS 32
+
+/* Headers */
+struct ieee80211_header {
+	__le16 frame_ctl;
+	__le16 duration_id;
+	u8 da[ETH_ALEN];
+	u8 sa[ETH_ALEN];
+	u8 bssid[ETH_ALEN];
+	__le16 seq_ctl;
+	u8 payload[0];
+} __packed;
+
+struct wl12xx_ie_header {
+	u8 id;
+	u8 len;
+} __packed;
+
+/* IEs */
+
+struct wl12xx_ie_ssid {
+	struct wl12xx_ie_header header;
+	char ssid[IW_ESSID_MAX_SIZE];
+} __packed;
+
+struct wl12xx_ie_rates {
+	struct wl12xx_ie_header header;
+	u8 rates[MAX_SUPPORTED_RATES];
+} __packed;
+
+struct wl12xx_ie_ds_params {
+	struct wl12xx_ie_header header;
+	u8 channel;
+} __packed;
+
+struct country_triplet {
+	u8 channel;
+	u8 num_channels;
+	u8 max_tx_power;
+} __packed;
+
+struct wl12xx_ie_country {
+	struct wl12xx_ie_header header;
+	u8 country_string[COUNTRY_STRING_LEN];
+	struct country_triplet triplets[MAX_COUNTRY_TRIPLETS];
+} __packed;
+
+
+/* Templates */
+
+struct wl12xx_beacon_template {
+	struct ieee80211_header header;
+	__le32 time_stamp[2];
+	__le16 beacon_interval;
+	__le16 capability;
+	struct wl12xx_ie_ssid ssid;
+	struct wl12xx_ie_rates rates;
+	struct wl12xx_ie_rates ext_rates;
+	struct wl12xx_ie_ds_params ds_params;
+	struct wl12xx_ie_country country;
+} __packed;
+
+struct wl12xx_null_data_template {
+	struct ieee80211_header header;
+} __packed;
+
+struct wl12xx_ps_poll_template {
+	__le16 fc;
+	__le16 aid;
+	u8 bssid[ETH_ALEN];
+	u8 ta[ETH_ALEN];
+} __packed;
+
+struct wl12xx_qos_null_data_template {
+	struct ieee80211_header header;
+	__le16 qos_ctl;
+} __packed;
+
+struct wl12xx_probe_req_template {
+	struct ieee80211_header header;
+	struct wl12xx_ie_ssid ssid;
+	struct wl12xx_ie_rates rates;
+	struct wl12xx_ie_rates ext_rates;
+} __packed;
+
+
+struct wl12xx_probe_resp_template {
+	struct ieee80211_header header;
+	__le32 time_stamp[2];
+	__le16 beacon_interval;
+	__le16 capability;
+	struct wl12xx_ie_ssid ssid;
+	struct wl12xx_ie_rates rates;
+	struct wl12xx_ie_rates ext_rates;
+	struct wl12xx_ie_ds_params ds_params;
+	struct wl12xx_ie_country country;
+} __packed;
+
+#endif
diff --git a/drivers/net/wireless/wl12xx/Kconfig b/drivers/net/wireless/wl12xx/Kconfig
index 4a8bb25c1739..b447559f1db5 100644
--- a/drivers/net/wireless/wl12xx/Kconfig
+++ b/drivers/net/wireless/wl12xx/Kconfig
@@ -5,40 +5,6 @@ menuconfig WL12XX
 	  This will enable TI wl12xx driver support. The drivers make
 	  use of the mac80211 stack.
 
-config WL1251
-	tristate "TI wl1251 support"
-	depends on WL12XX && GENERIC_HARDIRQS
-	select FW_LOADER
-	select CRC7
-	---help---
-	  This module adds support for wireless adapters based on
-	  TI wl1251 chipset.
-
-	  If you choose to build a module, it'll be called wl1251. Say
-	  N if unsure.
-
-config WL1251_SPI
-	tristate "TI wl1251 SPI support"
-	depends on WL1251 && SPI_MASTER
-	---help---
-	  This module adds support for the SPI interface of adapters using
-	  TI wl1251 chipset.  Select this if your platform is using
-	  the SPI bus.
-
-	  If you choose to build a module, it'll be called wl1251_spi.
-	  Say N if unsure.
-
-config WL1251_SDIO
-	tristate "TI wl1251 SDIO support"
-	depends on WL1251 && MMC
-	---help---
-	  This module adds support for the SDIO interface of adapters using
-	  TI wl1251 chipset.  Select this if your platform is using
-	  the SDIO bus.
-
-	  If you choose to build a module, it'll be called
-	  wl1251_sdio. Say N if unsure.
-
 config WL1271
 	tristate "TI wl1271 support"
 	depends on WL12XX && GENERIC_HARDIRQS
diff --git a/drivers/net/wireless/wl12xx/Makefile b/drivers/net/wireless/wl12xx/Makefile
index 0d334d6f86f4..3a807444b2af 100644
--- a/drivers/net/wireless/wl12xx/Makefile
+++ b/drivers/net/wireless/wl12xx/Makefile
@@ -1,12 +1,3 @@
-wl1251-objs		= wl1251_main.o wl1251_event.o \
-			  wl1251_tx.o wl1251_rx.o wl1251_ps.o wl1251_cmd.o \
-			  wl1251_acx.o wl1251_boot.o wl1251_init.o \
-			  wl1251_debugfs.o wl1251_io.o
-
-obj-$(CONFIG_WL1251)	+= wl1251.o
-obj-$(CONFIG_WL1251_SPI)	+= wl1251_spi.o
-obj-$(CONFIG_WL1251_SDIO)	+= wl1251_sdio.o
-
 wl1271-objs		= wl1271_main.o  wl1271_cmd.o wl1271_io.o \
 			  wl1271_event.o wl1271_tx.o  wl1271_rx.o   \
 			  wl1271_ps.o    wl1271_acx.o wl1271_boot.o \
diff --git a/drivers/net/wireless/wl12xx/wl1271_sdio.c b/drivers/net/wireless/wl12xx/wl1271_sdio.c
index 4c250d7dc3fa..784ef3432641 100644
--- a/drivers/net/wireless/wl12xx/wl1271_sdio.c
+++ b/drivers/net/wireless/wl12xx/wl1271_sdio.c
@@ -30,6 +30,7 @@
 #include <linux/mmc/card.h>
 #include <linux/gpio.h>
 #include <linux/wl12xx.h>
+#include <linux/pm_runtime.h>
 
 #include "wl1271.h"
 #include "wl12xx_80211.h"
@@ -160,12 +161,19 @@ static void wl1271_sdio_raw_write(struct wl1271 *wl, int addr, void *buf,
 static int wl1271_sdio_power_on(struct wl1271 *wl)
 {
 	struct sdio_func *func = wl_to_func(wl);
+	int ret;
+
+	/* Power up the card */
+	ret = pm_runtime_get_sync(&func->dev);
+	if (ret < 0)
+		goto out;
 
 	sdio_claim_host(func);
 	sdio_enable_func(func);
 	sdio_release_host(func);
 
-	return 0;
+out:
+	return ret;
 }
 
 static int wl1271_sdio_power_off(struct wl1271 *wl)
@@ -176,15 +184,12 @@ static int wl1271_sdio_power_off(struct wl1271 *wl)
 	sdio_disable_func(func);
 	sdio_release_host(func);
 
-	return 0;
+	/* Power down the card */
+	return pm_runtime_put_sync(&func->dev);
 }
 
 static int wl1271_sdio_set_power(struct wl1271 *wl, bool enable)
 {
-	/* Let the SDIO stack handle wlan_enable control, so we
-	 * keep host claimed while wlan is in use to keep wl1271
-	 * alive.
-	 */
 	if (enable)
 		return wl1271_sdio_power_on(wl);
 	else
@@ -256,6 +261,9 @@ static int __devinit wl1271_probe(struct sdio_func *func,
 
 	sdio_set_drvdata(func, wl);
 
+	/* Tell PM core that we don't need the card to be powered now */
+	pm_runtime_put_noidle(&func->dev);
+
 	wl1271_notice("initialized");
 
 	return 0;
@@ -274,16 +282,39 @@ static void __devexit wl1271_remove(struct sdio_func *func)
 {
 	struct wl1271 *wl = sdio_get_drvdata(func);
 
+	/* Undo decrement done above in wl1271_probe */
+	pm_runtime_get_noresume(&func->dev);
+
 	wl1271_unregister_hw(wl);
 	free_irq(wl->irq, wl);
 	wl1271_free_hw(wl);
 }
 
+static int wl1271_suspend(struct device *dev)
+{
+	/* Tell MMC/SDIO core it's OK to power down the card
+	 * (if it isn't already), but not to remove it completely */
+	return 0;
+}
+
+static int wl1271_resume(struct device *dev)
+{
+	return 0;
+}
+
+static const struct dev_pm_ops wl1271_sdio_pm_ops = {
+	.suspend	= wl1271_suspend,
+	.resume		= wl1271_resume,
+};
+
 static struct sdio_driver wl1271_sdio_driver = {
 	.name		= "wl1271_sdio",
 	.id_table	= wl1271_devices,
 	.probe		= wl1271_probe,
 	.remove		= __devexit_p(wl1271_remove),
+	.drv = {
+		.pm = &wl1271_sdio_pm_ops,
+	},
 };
 
 static int __init wl1271_init(void)
diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index 97b2eae6a22c..ed5a03cbe184 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -986,6 +986,7 @@ struct ieee80211_ht_info {
 #define WLAN_AUTH_OPEN 0
 #define WLAN_AUTH_SHARED_KEY 1
 #define WLAN_AUTH_FT 2
+#define WLAN_AUTH_SAE 3
 #define WLAN_AUTH_LEAP 128
 
 #define WLAN_AUTH_CHALLENGE_LEN 128
@@ -1072,6 +1073,10 @@ enum ieee80211_statuscode {
 	WLAN_STATUS_NO_DIRECT_LINK = 48,
 	WLAN_STATUS_STA_NOT_PRESENT = 49,
 	WLAN_STATUS_STA_NOT_QSTA = 50,
+	/* 802.11s */
+	WLAN_STATUS_ANTI_CLOG_REQUIRED = 76,
+	WLAN_STATUS_FCG_NOT_SUPP = 78,
+	WLAN_STATUS_STA_NO_TBTT = 78,
 };
 
 
@@ -1112,6 +1117,22 @@ enum ieee80211_reasoncode {
 	WLAN_REASON_QSTA_REQUIRE_SETUP = 38,
 	WLAN_REASON_QSTA_TIMEOUT = 39,
 	WLAN_REASON_QSTA_CIPHER_NOT_SUPP = 45,
+	/* 802.11s */
+	WLAN_REASON_MESH_PEER_CANCELED = 52,
+	WLAN_REASON_MESH_MAX_PEERS = 53,
+	WLAN_REASON_MESH_CONFIG = 54,
+	WLAN_REASON_MESH_CLOSE = 55,
+	WLAN_REASON_MESH_MAX_RETRIES = 56,
+	WLAN_REASON_MESH_CONFIRM_TIMEOUT = 57,
+	WLAN_REASON_MESH_INVALID_GTK = 58,
+	WLAN_REASON_MESH_INCONSISTENT_PARAM = 59,
+	WLAN_REASON_MESH_INVALID_SECURITY = 60,
+	WLAN_REASON_MESH_PATH_ERROR = 61,
+	WLAN_REASON_MESH_PATH_NOFORWARD = 62,
+	WLAN_REASON_MESH_PATH_DEST_UNREACHABLE = 63,
+	WLAN_REASON_MAC_EXISTS_IN_MBSS = 64,
+	WLAN_REASON_MESH_CHAN_REGULATORY = 65,
+	WLAN_REASON_MESH_CHAN = 66,
 };
 
 
@@ -1139,20 +1160,33 @@ enum ieee80211_eid {
 	WLAN_EID_TS_DELAY = 43,
 	WLAN_EID_TCLAS_PROCESSING = 44,
 	WLAN_EID_QOS_CAPA = 46,
-	/* 802.11s
-	 *
-	 * All mesh EID numbers are pending IEEE 802.11 ANA approval.
-	 * The numbers have been incremented from those suggested in
-	 * 802.11s/D2.0 so that MESH_CONFIG does not conflict with
-	 * EXT_SUPP_RATES.
+	/* 802.11s */
+	WLAN_EID_MESH_CONFIG = 113,
+	WLAN_EID_MESH_ID = 114,
+	WLAN_EID_LINK_METRIC_REPORT = 115,
+	WLAN_EID_CONGESTION_NOTIFICATION = 116,
+	/* Note that the Peer Link IE has been replaced with the similar
+	 * Peer Management IE.  We will keep the former definition until mesh
+	 * code is changed to comply with latest 802.11s drafts.
 	 */
-	WLAN_EID_MESH_CONFIG = 51,
-	WLAN_EID_MESH_ID = 52,
-	WLAN_EID_PEER_LINK = 55,
-	WLAN_EID_PREQ = 68,
-	WLAN_EID_PREP = 69,
-	WLAN_EID_PERR = 70,
-	WLAN_EID_RANN = 49,	/* compatible with FreeBSD */
+	WLAN_EID_PEER_LINK = 55,  /* no longer in 802.11s drafts */
+	WLAN_EID_PEER_MGMT = 117,
+	WLAN_EID_CHAN_SWITCH_PARAM = 118,
+	WLAN_EID_MESH_AWAKE_WINDOW = 119,
+	WLAN_EID_BEACON_TIMING = 120,
+	WLAN_EID_MCCAOP_SETUP_REQ = 121,
+	WLAN_EID_MCCAOP_SETUP_RESP = 122,
+	WLAN_EID_MCCAOP_ADVERT = 123,
+	WLAN_EID_MCCAOP_TEARDOWN = 124,
+	WLAN_EID_GANN = 125,
+	WLAN_EID_RANN = 126,
+	WLAN_EID_PREQ = 130,
+	WLAN_EID_PREP = 131,
+	WLAN_EID_PERR = 132,
+	WLAN_EID_PXU = 137,
+	WLAN_EID_PXUC = 138,
+	WLAN_EID_AUTH_MESH_PEER_EXCH = 139,
+	WLAN_EID_MIC = 140,
 
 	WLAN_EID_PWR_CONSTRAINT = 32,
 	WLAN_EID_PWR_CAPABILITY = 33,
@@ -1211,9 +1245,14 @@ enum ieee80211_category {
 	WLAN_CATEGORY_HT = 7,
 	WLAN_CATEGORY_SA_QUERY = 8,
 	WLAN_CATEGORY_PROTECTED_DUAL_OF_ACTION = 9,
+	WLAN_CATEGORY_MESH_ACTION = 13,
+	WLAN_CATEGORY_MULTIHOP_ACTION = 14,
+	WLAN_CATEGORY_SELF_PROTECTED = 15,
 	WLAN_CATEGORY_WMM = 17,
-	WLAN_CATEGORY_MESH_PLINK = 30,		/* Pending ANA approval */
-	WLAN_CATEGORY_MESH_PATH_SEL = 32,	/* Pending ANA approval */
+	/* TODO: remove MESH_PLINK and MESH_PATH_SEL after */
+	/*       mesh is updated to current 802.11s draft  */
+	WLAN_CATEGORY_MESH_PLINK = 30,
+	WLAN_CATEGORY_MESH_PATH_SEL = 32,
 	WLAN_CATEGORY_VENDOR_SPECIFIC_PROTECTED = 126,
 	WLAN_CATEGORY_VENDOR_SPECIFIC = 127,
 };
@@ -1351,6 +1390,8 @@ enum ieee80211_sa_query_action {
 /* AKM suite selectors */
 #define WLAN_AKM_SUITE_8021X		0x000FAC01
 #define WLAN_AKM_SUITE_PSK		0x000FAC02
+#define WLAN_AKM_SUITE_SAE			0x000FAC08
+#define WLAN_AKM_SUITE_FT_OVER_SAE	0x000FAC09
 
 #define WLAN_MAX_KEY_LEN		32
 
diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h
index c08709fe36fc..0edb2566c14c 100644
--- a/include/linux/nl80211.h
+++ b/include/linux/nl80211.h
@@ -1413,6 +1413,16 @@ enum nl80211_reg_rule_flags {
  * @NL80211_SURVEY_INFO_FREQUENCY: center frequency of channel
  * @NL80211_SURVEY_INFO_NOISE: noise level of channel (u8, dBm)
  * @NL80211_SURVEY_INFO_IN_USE: channel is currently being used
+ * @NL80211_SURVEY_INFO_CHANNEL_TIME: amount of time (in ms) that the radio
+ *	spent on this channel
+ * @NL80211_SURVEY_INFO_CHANNEL_TIME_BUSY: amount of the time the primary
+ *	channel was sensed busy (either due to activity or energy detect)
+ * @NL80211_SURVEY_INFO_CHANNEL_TIME_EXT_BUSY: amount of time the extension
+ *	channel was sensed busy
+ * @NL80211_SURVEY_INFO_CHANNEL_TIME_RX: amount of time the radio spent
+ *	receiving data
+ * @NL80211_SURVEY_INFO_CHANNEL_TIME_TX: amount of time the radio spent
+ *	transmitting data
  * @NL80211_SURVEY_INFO_MAX: highest survey info attribute number
  *	currently defined
  * @__NL80211_SURVEY_INFO_AFTER_LAST: internal use
@@ -1422,6 +1432,11 @@ enum nl80211_survey_info {
 	NL80211_SURVEY_INFO_FREQUENCY,
 	NL80211_SURVEY_INFO_NOISE,
 	NL80211_SURVEY_INFO_IN_USE,
+	NL80211_SURVEY_INFO_CHANNEL_TIME,
+	NL80211_SURVEY_INFO_CHANNEL_TIME_BUSY,
+	NL80211_SURVEY_INFO_CHANNEL_TIME_EXT_BUSY,
+	NL80211_SURVEY_INFO_CHANNEL_TIME_RX,
+	NL80211_SURVEY_INFO_CHANNEL_TIME_TX,
 
 	/* keep last */
 	__NL80211_SURVEY_INFO_AFTER_LAST,
diff --git a/include/linux/wireless.h b/include/linux/wireless.h
index e6827eedf18b..4395b28bb86c 100644
--- a/include/linux/wireless.h
+++ b/include/linux/wireless.h
@@ -1157,6 +1157,6 @@ struct __compat_iw_event {
 #define IW_EV_PARAM_PK_LEN	(IW_EV_LCP_PK_LEN + sizeof(struct iw_param))
 #define IW_EV_ADDR_PK_LEN	(IW_EV_LCP_PK_LEN + sizeof(struct sockaddr))
 #define IW_EV_QUAL_PK_LEN	(IW_EV_LCP_PK_LEN + sizeof(struct iw_quality))
-#define IW_EV_POINT_PK_LEN	(IW_EV_LCP_LEN + 4)
+#define IW_EV_POINT_PK_LEN	(IW_EV_LCP_PK_LEN + 4)
 
 #endif	/* _LINUX_WIRELESS_H */
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 0778d04b3bbe..2a7936d7851d 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -294,6 +294,11 @@ struct key_params {
  *
  * @SURVEY_INFO_NOISE_DBM: noise (in dBm) was filled in
  * @SURVEY_INFO_IN_USE: channel is currently being used
+ * @SURVEY_INFO_CHANNEL_TIME: channel active time (in ms) was filled in
+ * @SURVEY_INFO_CHANNEL_TIME_BUSY: channel busy time was filled in
+ * @SURVEY_INFO_CHANNEL_TIME_EXT_BUSY: extension channel busy time was filled in
+ * @SURVEY_INFO_CHANNEL_TIME_RX: channel receive time was filled in
+ * @SURVEY_INFO_CHANNEL_TIME_TX: channel transmit time was filled in
  *
  * Used by the driver to indicate which info in &struct survey_info
  * it has filled in during the get_survey().
@@ -301,6 +306,11 @@ struct key_params {
 enum survey_info_flags {
 	SURVEY_INFO_NOISE_DBM = 1<<0,
 	SURVEY_INFO_IN_USE = 1<<1,
+	SURVEY_INFO_CHANNEL_TIME = 1<<2,
+	SURVEY_INFO_CHANNEL_TIME_BUSY = 1<<3,
+	SURVEY_INFO_CHANNEL_TIME_EXT_BUSY = 1<<4,
+	SURVEY_INFO_CHANNEL_TIME_RX = 1<<5,
+	SURVEY_INFO_CHANNEL_TIME_TX = 1<<6,
 };
 
 /**
@@ -310,6 +320,11 @@ enum survey_info_flags {
  * @filled: bitflag of flags from &enum survey_info_flags
  * @noise: channel noise in dBm. This and all following fields are
  *     optional
+ * @channel_time: amount of time in ms the radio spent on the channel
+ * @channel_time_busy: amount of time the primary channel was sensed busy
+ * @channel_time_ext_busy: amount of time the extension channel was sensed busy
+ * @channel_time_rx: amount of time the radio spent receiving data
+ * @channel_time_tx: amount of time the radio spent transmitting data
  *
  * Used by dump_survey() to report back per-channel survey information.
  *
@@ -318,6 +333,11 @@ enum survey_info_flags {
  */
 struct survey_info {
 	struct ieee80211_channel *channel;
+	u64 channel_time;
+	u64 channel_time_busy;
+	u64 channel_time_ext_busy;
+	u64 channel_time_rx;
+	u64 channel_time_tx;
 	u32 filled;
 	s8 noise;
 };
@@ -403,6 +423,7 @@ struct station_parameters {
  * @STATION_INFO_TX_PACKETS: @tx_packets filled
  * @STATION_INFO_TX_RETRIES: @tx_retries filled
  * @STATION_INFO_TX_FAILED: @tx_failed filled
+ * @STATION_INFO_RX_DROP_MISC: @rx_dropped_misc filled
  */
 enum station_info_flags {
 	STATION_INFO_INACTIVE_TIME	= 1<<0,
@@ -417,6 +438,7 @@ enum station_info_flags {
 	STATION_INFO_TX_PACKETS		= 1<<9,
 	STATION_INFO_TX_RETRIES		= 1<<10,
 	STATION_INFO_TX_FAILED		= 1<<11,
+	STATION_INFO_RX_DROP_MISC	= 1<<12,
 };
 
 /**
@@ -468,6 +490,7 @@ struct rate_info {
  * @tx_packets: packets transmitted to this station
  * @tx_retries: cumulative retry counts
  * @tx_failed: number of failed transmissions (retries exceeded, no ACK)
+ * @rx_dropped_misc:  Dropped for un-specified reason.
  * @generation: generation number for nl80211 dumps.
  *	This number should increase every time the list of stations
  *	changes, i.e. when a station is added or removed, so that
@@ -487,6 +510,7 @@ struct station_info {
 	u32 tx_packets;
 	u32 tx_retries;
 	u32 tx_failed;
+	u32 rx_dropped_misc;
 
 	int generation;
 };
@@ -1123,6 +1147,9 @@ struct cfg80211_pmksa {
  *	allows the driver to adjust the dynamic ps timeout value.
  * @set_cqm_rssi_config: Configure connection quality monitor RSSI threshold.
  *
+ * @mgmt_frame_register: Notify driver that a management frame type was
+ *	registered. Note that this callback may not sleep, and cannot run
+ *	concurrently with itself.
  */
 struct cfg80211_ops {
 	int	(*suspend)(struct wiphy *wiphy);
@@ -1273,6 +1300,10 @@ struct cfg80211_ops {
 	int	(*set_cqm_rssi_config)(struct wiphy *wiphy,
 				       struct net_device *dev,
 				       s32 rssi_thold, u32 rssi_hyst);
+
+	void	(*mgmt_frame_register)(struct wiphy *wiphy,
+				       struct net_device *dev,
+				       u16 frame_type, bool reg);
 };
 
 /*
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 33aa2e39147b..9fdf982d1286 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -1478,12 +1478,14 @@ ieee80211_get_alt_retry_rate(const struct ieee80211_hw *hw,
  *	honour this flag if possible.
  *
  * @FIF_CONTROL: pass control frames (except for PS Poll), if PROMISC_IN_BSS
- *  is not set then only those addressed to this station.
+ * 	is not set then only those addressed to this station.
  *
  * @FIF_OTHER_BSS: pass frames destined to other BSSes
  *
- * @FIF_PSPOLL: pass PS Poll frames, if PROMISC_IN_BSS  is not set then only
- *  those addressed to this station.
+ * @FIF_PSPOLL: pass PS Poll frames, if PROMISC_IN_BSS is not set then only
+ * 	those addressed to this station.
+ *
+ * @FIF_PROBE_REQ: pass probe request frames
  */
 enum ieee80211_filter_flags {
 	FIF_PROMISC_IN_BSS	= 1<<0,
@@ -1494,6 +1496,7 @@ enum ieee80211_filter_flags {
 	FIF_CONTROL		= 1<<5,
 	FIF_OTHER_BSS		= 1<<6,
 	FIF_PSPOLL		= 1<<7,
+	FIF_PROBE_REQ		= 1<<8,
 };
 
 /**
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index ecf9b7166ed1..18bd0e550600 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -329,7 +329,8 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
 			STATION_INFO_TX_PACKETS |
 			STATION_INFO_TX_RETRIES |
 			STATION_INFO_TX_FAILED |
-			STATION_INFO_TX_BITRATE;
+			STATION_INFO_TX_BITRATE |
+			STATION_INFO_RX_DROP_MISC;
 
 	sinfo->inactive_time = jiffies_to_msecs(jiffies - sta->last_rx);
 	sinfo->rx_bytes = sta->rx_bytes;
@@ -338,6 +339,7 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
 	sinfo->tx_packets = sta->tx_packets;
 	sinfo->tx_retries = sta->tx_retry_count;
 	sinfo->tx_failed = sta->tx_retry_failed;
+	sinfo->rx_dropped_misc = sta->rx_dropped;
 
 	if ((sta->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) ||
 	    (sta->local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC)) {
@@ -1602,6 +1604,23 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev,
 	return 0;
 }
 
+static void ieee80211_mgmt_frame_register(struct wiphy *wiphy,
+					  struct net_device *dev,
+					  u16 frame_type, bool reg)
+{
+	struct ieee80211_local *local = wiphy_priv(wiphy);
+
+	if (frame_type != (IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_REQ))
+		return;
+
+	if (reg)
+		local->probe_req_reg++;
+	else
+		local->probe_req_reg--;
+
+	ieee80211_queue_work(&local->hw, &local->reconfig_filter);
+}
+
 struct cfg80211_ops mac80211_config_ops = {
 	.add_virtual_intf = ieee80211_add_iface,
 	.del_virtual_intf = ieee80211_del_iface,
@@ -1653,4 +1672,5 @@ struct cfg80211_ops mac80211_config_ops = {
 	.cancel_remain_on_channel = ieee80211_cancel_remain_on_channel,
 	.mgmt_tx = ieee80211_mgmt_tx,
 	.set_cqm_rssi_config = ieee80211_set_cqm_rssi_config,
+	.mgmt_frame_register = ieee80211_mgmt_frame_register,
 };
diff --git a/net/mac80211/ht.c b/net/mac80211/ht.c
index 4214bb6e12fc..75d679d75e63 100644
--- a/net/mac80211/ht.c
+++ b/net/mac80211/ht.c
@@ -291,6 +291,8 @@ void ieee80211_request_smps(struct ieee80211_vif *vif,
 	if (WARN_ON(smps_mode == IEEE80211_SMPS_OFF))
 		smps_mode = IEEE80211_SMPS_AUTOMATIC;
 
+	sdata->u.mgd.driver_smps_mode = smps_mode;
+
 	ieee80211_queue_work(&sdata->local->hw,
 			     &sdata->u.mgd.request_smps_work);
 }
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index f0610fa4fbe0..b80c38689927 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -707,7 +707,9 @@ struct ieee80211_local {
 	int open_count;
 	int monitors, cooked_mntrs;
 	/* number of interfaces with corresponding FIF_ flags */
-	int fif_fcsfail, fif_plcpfail, fif_control, fif_other_bss, fif_pspoll;
+	int fif_fcsfail, fif_plcpfail, fif_control, fif_other_bss, fif_pspoll,
+	    fif_probe_req;
+	int probe_req_reg;
 	unsigned int filter_flags; /* FIF_* */
 
 	bool wiphy_ciphers_allocated;
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index e99d1b60557c..f9163b12c7f1 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -280,8 +280,11 @@ static int ieee80211_do_open(struct net_device *dev, bool coming_up)
 			ieee80211_start_mesh(sdata);
 		} else if (sdata->vif.type == NL80211_IFTYPE_AP) {
 			local->fif_pspoll++;
+			local->fif_probe_req++;
 
 			ieee80211_configure_filter(local);
+		} else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
+			local->fif_probe_req++;
 		}
 
 		changed |= ieee80211_reset_erp_info(sdata);
@@ -428,8 +431,12 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
 	if (sdata->flags & IEEE80211_SDATA_PROMISC)
 		atomic_dec(&local->iff_promiscs);
 
-	if (sdata->vif.type == NL80211_IFTYPE_AP)
+	if (sdata->vif.type == NL80211_IFTYPE_AP) {
 		local->fif_pspoll--;
+		local->fif_probe_req--;
+	} else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
+		local->fif_probe_req--;
+	}
 
 	netif_addr_lock_bh(sdata->dev);
 	spin_lock_bh(&local->filter_lock);
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index eb0f59977676..22bc42b18991 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -54,6 +54,9 @@ void ieee80211_configure_filter(struct ieee80211_local *local)
 	if (local->monitors || local->scanning)
 		new_flags |= FIF_BCN_PRBRESP_PROMISC;
 
+	if (local->fif_probe_req || local->probe_req_reg)
+		new_flags |= FIF_PROBE_REQ;
+
 	if (local->fif_fcsfail)
 		new_flags |= FIF_FCSFAIL;
 
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index ea13a80a476c..1c91f0f3c307 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -412,7 +412,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
 	enum plink_event event;
 	enum plink_frame_type ftype;
 	size_t baselen;
-	bool deactivated;
+	bool deactivated, matches_local = true;
 	u8 ie_len;
 	u8 *baseaddr;
 	__le16 plid, llid, reason;
@@ -487,6 +487,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
 	/* Now we will figure out the appropriate event... */
 	event = PLINK_UNDEFINED;
 	if (ftype != PLINK_CLOSE && (!mesh_matches_local(&elems, sdata))) {
+		matches_local = false;
 		switch (ftype) {
 		case PLINK_OPEN:
 			event = OPN_RJCT;
@@ -498,7 +499,15 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
 			/* avoid warning */
 			break;
 		}
-		spin_lock_bh(&sta->lock);
+	}
+
+	if (!sta && !matches_local) {
+		rcu_read_unlock();
+		reason = cpu_to_le16(MESH_CAPABILITY_POLICY_VIOLATION);
+		llid = 0;
+		mesh_plink_frame_tx(sdata, PLINK_CLOSE, mgmt->sa, llid,
+				    plid, reason);
+		return;
 	} else if (!sta) {
 		/* ftype == PLINK_OPEN */
 		u32 rates;
@@ -522,7 +531,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
 		}
 		event = OPN_ACPT;
 		spin_lock_bh(&sta->lock);
-	} else {
+	} else if (matches_local) {
 		spin_lock_bh(&sta->lock);
 		switch (ftype) {
 		case PLINK_OPEN:
@@ -564,6 +573,8 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
 			rcu_read_unlock();
 			return;
 		}
+	} else {
+		spin_lock_bh(&sta->lock);
 	}
 
 	mpl_dbg("Mesh plink (peer, state, llid, plid, event): %pM %s %d %d %d\n",
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 5695c94c49aa..a3a9421555af 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -1864,10 +1864,12 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata)
 
 		else if (ifmgd->probe_send_count < IEEE80211_MAX_PROBE_TRIES) {
 #ifdef CONFIG_MAC80211_VERBOSE_DEBUG
-			printk(KERN_DEBUG "No probe response from AP %pM"
-				" after %dms, try %d\n", bssid,
-				(1000 * IEEE80211_PROBE_WAIT)/HZ,
-				ifmgd->probe_send_count);
+			wiphy_debug(local->hw.wiphy,
+				    "%s: No probe response from AP %pM"
+				    " after %dms, try %d\n",
+				    sdata->name,
+				    bssid, (1000 * IEEE80211_PROBE_WAIT)/HZ,
+				    ifmgd->probe_send_count);
 #endif
 			ieee80211_mgd_probe_ap_send(sdata);
 		} else {
@@ -1877,9 +1879,11 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata)
 			 */
 			ifmgd->flags &= ~(IEEE80211_STA_CONNECTION_POLL |
 					  IEEE80211_STA_BEACON_POLL);
-			printk(KERN_DEBUG "No probe response from AP %pM"
-				" after %dms, disconnecting.\n",
-				bssid, (1000 * IEEE80211_PROBE_WAIT)/HZ);
+			wiphy_debug(local->hw.wiphy,
+				    "%s: No probe response from AP %pM"
+				    " after %dms, disconnecting.\n",
+				    sdata->name,
+				    bssid, (1000 * IEEE80211_PROBE_WAIT)/HZ);
 			ieee80211_set_disassoc(sdata, true, true);
 			mutex_unlock(&ifmgd->mtx);
 			mutex_lock(&local->mtx);
diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c
index c5b465904e3b..2a18d6602d4a 100644
--- a/net/mac80211/rc80211_minstrel_ht.c
+++ b/net/mac80211/rc80211_minstrel_ht.c
@@ -397,8 +397,9 @@ minstrel_ht_tx_status(void *priv, struct ieee80211_supported_band *sband,
 	    !(info->flags & IEEE80211_TX_STAT_AMPDU))
 		return;
 
-	if (!info->status.ampdu_len) {
-		info->status.ampdu_ack_len = 1;
+	if (!(info->flags & IEEE80211_TX_STAT_AMPDU)) {
+		info->status.ampdu_ack_len =
+			(info->flags & IEEE80211_TX_STAT_ACK ? 1 : 0);
 		info->status.ampdu_len = 1;
 	}
 
@@ -426,7 +427,7 @@ minstrel_ht_tx_status(void *priv, struct ieee80211_supported_band *sband,
 		group = minstrel_ht_get_group_idx(&ar[i]);
 		rate = &mi->groups[group].rates[ar[i].idx % 8];
 
-		if (last && (info->flags & IEEE80211_TX_STAT_ACK))
+		if (last)
 			rate->success += info->status.ampdu_ack_len;
 
 		rate->attempts += ar[i].count * info->status.ampdu_len;
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index b67221def584..902b03ee8f60 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -622,6 +622,26 @@ static void ieee80211_sta_reorder_release(struct ieee80211_hw *hw,
 							tid_agg_rx->buf_size;
 	}
 
+	/*
+	 * Disable the reorder release timer for now.
+	 *
+	 * The current implementation lacks a proper locking scheme
+	 * which would protect vital statistic and debug counters
+	 * from being updated by two different but concurrent BHs.
+	 *
+	 * More information about the topic is available from:
+	 * - thread: http://marc.info/?t=128635927000001
+	 *
+	 * What was wrong:
+	 * =>  http://marc.info/?l=linux-wireless&m=128636170811964
+	 * "Basically the thing is that until your patch, the data
+	 *  in the struct didn't actually need locking because it
+	 *  was accessed by the RX path only which is not concurrent."
+	 *
+	 * List of what needs to be fixed:
+	 * => http://marc.info/?l=linux-wireless&m=128656352920957
+	 *
+
 	if (tid_agg_rx->stored_mpdu_num) {
 		j = index = seq_sub(tid_agg_rx->head_seq_num,
 				    tid_agg_rx->ssn) % tid_agg_rx->buf_size;
@@ -640,6 +660,10 @@ static void ieee80211_sta_reorder_release(struct ieee80211_hw *hw,
 	} else {
 		del_timer(&tid_agg_rx->reorder_timer);
 	}
+	*/
+
+set_release_timer:
+	return;
 }
 
 /*
diff --git a/net/mac80211/wep.c b/net/mac80211/wep.c
index f27484c22b9f..2ff6d1e3ed21 100644
--- a/net/mac80211/wep.c
+++ b/net/mac80211/wep.c
@@ -222,7 +222,7 @@ static int ieee80211_wep_decrypt(struct ieee80211_local *local,
 				 struct ieee80211_key *key)
 {
 	u32 klen;
-	u8 *rc4key;
+	u8 rc4key[3 + WLAN_KEY_LEN_WEP104];
 	u8 keyidx;
 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
 	unsigned int hdrlen;
@@ -245,10 +245,6 @@ static int ieee80211_wep_decrypt(struct ieee80211_local *local,
 
 	klen = 3 + key->conf.keylen;
 
-	rc4key = kmalloc(klen, GFP_ATOMIC);
-	if (!rc4key)
-		return -1;
-
 	/* Prepend 24-bit IV to RC4 key */
 	memcpy(rc4key, skb->data + hdrlen, 3);
 
@@ -260,8 +256,6 @@ static int ieee80211_wep_decrypt(struct ieee80211_local *local,
 				       len))
 		ret = -1;
 
-	kfree(rc4key);
-
 	/* Trim ICV */
 	skb_trim(skb, skb->len - WEP_ICV_LEN);
 
diff --git a/net/wireless/core.c b/net/wireless/core.c
index 1684ad91763c..9c21ebf9780e 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -178,10 +178,26 @@ int cfg80211_dev_rename(struct cfg80211_registered_device *rdev,
 			char *newname)
 {
 	struct cfg80211_registered_device *rdev2;
-	int result;
+	int wiphy_idx, taken = -1, result, digits;
 
 	assert_cfg80211_lock();
 
+	/* prohibit calling the thing phy%d when %d is not its number */
+	sscanf(newname, PHY_NAME "%d%n", &wiphy_idx, &taken);
+	if (taken == strlen(newname) && wiphy_idx != rdev->wiphy_idx) {
+		/* count number of places needed to print wiphy_idx */
+		digits = 1;
+		while (wiphy_idx /= 10)
+			digits++;
+		/*
+		 * deny the name if it is phy<idx> where <idx> is printed
+		 * without leading zeroes. taken == strlen(newname) here
+		 */
+		if (taken == strlen(PHY_NAME) + digits)
+			return -EINVAL;
+	}
+
+
 	/* Ignore nop renames */
 	if (strcmp(newname, dev_name(&rdev->wiphy.dev)) == 0)
 		return 0;
@@ -189,7 +205,7 @@ int cfg80211_dev_rename(struct cfg80211_registered_device *rdev,
 	/* Ensure another device does not already have this name. */
 	list_for_each_entry(rdev2, &cfg80211_rdev_list, list)
 		if (strcmp(newname, dev_name(&rdev2->wiphy.dev)) == 0)
-			return -EEXIST;
+			return -EINVAL;
 
 	result = device_rename(&rdev->wiphy.dev, newname);
 	if (result)
@@ -304,11 +320,9 @@ static void cfg80211_event_work(struct work_struct *work)
 struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv)
 {
 	static int wiphy_counter;
-	int i;
-	struct cfg80211_registered_device *rdev, *rdev2;
+
+	struct cfg80211_registered_device *rdev;
 	int alloc_size;
-	char nname[IFNAMSIZ + 1];
-	bool found = false;
 
 	WARN_ON(ops->add_key && (!ops->del_key || !ops->set_default_key));
 	WARN_ON(ops->auth && (!ops->assoc || !ops->deauth || !ops->disassoc));
@@ -332,37 +346,17 @@ struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv)
 
 	if (unlikely(!wiphy_idx_valid(rdev->wiphy_idx))) {
 		wiphy_counter--;
-		goto too_many_devs;
-	}
-
-	/* 64k wiphy devices is enough for anyone! */
-	for (i = 0; i < 0xFFFF; i++) {
-		found = false;
-		snprintf(nname, sizeof(nname)-1, PHY_NAME "%d", i);
-		nname[sizeof(nname)-1] = 0;
-		list_for_each_entry(rdev2, &cfg80211_rdev_list, list)
-			if (strcmp(nname, dev_name(&rdev2->wiphy.dev)) == 0) {
-				found = true;
-				break;
-			}
-
-		if (!found)
-			break;
-	}
-
-	if (unlikely(found)) {
-too_many_devs:
 		mutex_unlock(&cfg80211_mutex);
-		/* ugh, too many devices already! */
+		/* ugh, wrapped! */
 		kfree(rdev);
 		return NULL;
 	}
 
-	/* give it a proper name */
-	dev_set_name(&rdev->wiphy.dev, "%s", nname);
-
 	mutex_unlock(&cfg80211_mutex);
 
+	/* give it a proper name */
+	dev_set_name(&rdev->wiphy.dev, PHY_NAME "%d", rdev->wiphy_idx);
+
 	mutex_init(&rdev->mtx);
 	mutex_init(&rdev->devlist_mtx);
 	INIT_LIST_HEAD(&rdev->netdev_list);
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
index caf11a427507..26838d903b9a 100644
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
@@ -764,6 +764,8 @@ int cfg80211_mlme_register_mgmt(struct wireless_dev *wdev, u32 snd_pid,
 				u16 frame_type, const u8 *match_data,
 				int match_len)
 {
+	struct wiphy *wiphy = wdev->wiphy;
+	struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
 	struct cfg80211_mgmt_registration *reg, *nreg;
 	int err = 0;
 	u16 mgmt_type;
@@ -810,22 +812,37 @@ int cfg80211_mlme_register_mgmt(struct wireless_dev *wdev, u32 snd_pid,
 	nreg->frame_type = cpu_to_le16(frame_type);
 	list_add(&nreg->list, &wdev->mgmt_registrations);
 
+	if (rdev->ops->mgmt_frame_register)
+		rdev->ops->mgmt_frame_register(wiphy, wdev->netdev,
+					       frame_type, true);
+
  out:
 	spin_unlock_bh(&wdev->mgmt_registrations_lock);
+
 	return err;
 }
 
 void cfg80211_mlme_unregister_socket(struct wireless_dev *wdev, u32 nlpid)
 {
+	struct wiphy *wiphy = wdev->wiphy;
+	struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
 	struct cfg80211_mgmt_registration *reg, *tmp;
 
 	spin_lock_bh(&wdev->mgmt_registrations_lock);
 
 	list_for_each_entry_safe(reg, tmp, &wdev->mgmt_registrations, list) {
-		if (reg->nlpid == nlpid) {
-			list_del(&reg->list);
-			kfree(reg);
+		if (reg->nlpid != nlpid)
+			continue;
+
+		if (rdev->ops->mgmt_frame_register) {
+			u16 frame_type = le16_to_cpu(reg->frame_type);
+
+			rdev->ops->mgmt_frame_register(wiphy, wdev->netdev,
+						       frame_type, false);
 		}
+
+		list_del(&reg->list);
+		kfree(reg);
 	}
 
 	spin_unlock_bh(&wdev->mgmt_registrations_lock);
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 882dc921103b..c506241f8637 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -3153,6 +3153,21 @@ static int nl80211_send_survey(struct sk_buff *msg, u32 pid, u32 seq,
 			    survey->noise);
 	if (survey->filled & SURVEY_INFO_IN_USE)
 		NLA_PUT_FLAG(msg, NL80211_SURVEY_INFO_IN_USE);
+	if (survey->filled & SURVEY_INFO_CHANNEL_TIME)
+		NLA_PUT_U64(msg, NL80211_SURVEY_INFO_CHANNEL_TIME,
+			    survey->channel_time);
+	if (survey->filled & SURVEY_INFO_CHANNEL_TIME_BUSY)
+		NLA_PUT_U64(msg, NL80211_SURVEY_INFO_CHANNEL_TIME_BUSY,
+			    survey->channel_time_busy);
+	if (survey->filled & SURVEY_INFO_CHANNEL_TIME_EXT_BUSY)
+		NLA_PUT_U64(msg, NL80211_SURVEY_INFO_CHANNEL_TIME_EXT_BUSY,
+			    survey->channel_time_ext_busy);
+	if (survey->filled & SURVEY_INFO_CHANNEL_TIME_RX)
+		NLA_PUT_U64(msg, NL80211_SURVEY_INFO_CHANNEL_TIME_RX,
+			    survey->channel_time_rx);
+	if (survey->filled & SURVEY_INFO_CHANNEL_TIME_TX)
+		NLA_PUT_U64(msg, NL80211_SURVEY_INFO_CHANNEL_TIME_TX,
+			    survey->channel_time_tx);
 
 	nla_nest_end(msg, infoattr);
 
diff --git a/net/wireless/radiotap.c b/net/wireless/radiotap.c
index c774bc0f155e..dbe35e138e94 100644
--- a/net/wireless/radiotap.c
+++ b/net/wireless/radiotap.c
@@ -201,7 +201,7 @@ int ieee80211_radiotap_iterator_next(
 {
 	while (1) {
 		int hit = 0;
-		int pad, align, size, subns, vnslen;
+		int pad, align, size, subns;
 		uint32_t oui;
 
 		/* if no more EXT bits, that's it */
@@ -261,6 +261,27 @@ int ieee80211_radiotap_iterator_next(
 		if (pad)
 			iterator->_arg += align - pad;
 
+		if (iterator->_arg_index % 32 == IEEE80211_RADIOTAP_VENDOR_NAMESPACE) {
+			int vnslen;
+
+			if ((unsigned long)iterator->_arg + size -
+			    (unsigned long)iterator->_rtheader >
+			    (unsigned long)iterator->_max_length)
+				return -EINVAL;
+
+			oui = (*iterator->_arg << 16) |
+				(*(iterator->_arg + 1) << 8) |
+				*(iterator->_arg + 2);
+			subns = *(iterator->_arg + 3);
+
+			find_ns(iterator, oui, subns);
+
+			vnslen = get_unaligned_le16(iterator->_arg + 4);
+			iterator->_next_ns_data = iterator->_arg + size + vnslen;
+			if (!iterator->current_namespace)
+				size += vnslen;
+		}
+
 		/*
 		 * this is what we will return to user, but we need to
 		 * move on first so next call has something fresh to test
@@ -287,40 +308,25 @@ int ieee80211_radiotap_iterator_next(
 		/* these special ones are valid in each bitmap word */
 		switch (iterator->_arg_index % 32) {
 		case IEEE80211_RADIOTAP_VENDOR_NAMESPACE:
-			iterator->_bitmap_shifter >>= 1;
-			iterator->_arg_index++;
-
 			iterator->_reset_on_ext = 1;
 
-			vnslen = get_unaligned_le16(iterator->this_arg + 4);
-			iterator->_next_ns_data = iterator->_arg + vnslen;
-			oui = (*iterator->this_arg << 16) |
-				(*(iterator->this_arg + 1) << 8) |
-				*(iterator->this_arg + 2);
-			subns = *(iterator->this_arg + 3);
-
-			find_ns(iterator, oui, subns);
-
 			iterator->is_radiotap_ns = 0;
-			/* allow parsers to show this information */
+			/*
+			 * If parser didn't register this vendor
+			 * namespace with us, allow it to show it
+			 * as 'raw. Do do that, set argument index
+			 * to vendor namespace.
+			 */
 			iterator->this_arg_index =
 				IEEE80211_RADIOTAP_VENDOR_NAMESPACE;
-			iterator->this_arg_size += vnslen;
-			if ((unsigned long)iterator->this_arg +
-			    iterator->this_arg_size -
-			    (unsigned long)iterator->_rtheader >
-			    (unsigned long)(unsigned long)iterator->_max_length)
-				return -EINVAL;
-			hit = 1;
-			break;
+			if (!iterator->current_namespace)
+				hit = 1;
+			goto next_entry;
 		case IEEE80211_RADIOTAP_RADIOTAP_NAMESPACE:
-			iterator->_bitmap_shifter >>= 1;
-			iterator->_arg_index++;
-
 			iterator->_reset_on_ext = 1;
 			iterator->current_namespace = &radiotap_ns;
 			iterator->is_radiotap_ns = 1;
-			break;
+			goto next_entry;
 		case IEEE80211_RADIOTAP_EXT:
 			/*
 			 * bit 31 was set, there is more
diff --git a/net/wireless/sysfs.c b/net/wireless/sysfs.c
index 74a9e3cce452..4294fa22bb2d 100644
--- a/net/wireless/sysfs.c
+++ b/net/wireless/sysfs.c
@@ -35,6 +35,14 @@ SHOW_FMT(index, "%d", wiphy_idx);
 SHOW_FMT(macaddress, "%pM", wiphy.perm_addr);
 SHOW_FMT(address_mask, "%pM", wiphy.addr_mask);
 
+static ssize_t name_show(struct device *dev,
+			 struct device_attribute *attr,
+			 char *buf) {
+	struct wiphy *wiphy = &dev_to_rdev(dev)->wiphy;
+	return sprintf(buf, "%s\n", dev_name(&wiphy->dev));
+}
+
+
 static ssize_t addresses_show(struct device *dev,
 			      struct device_attribute *attr,
 			      char *buf)
@@ -57,6 +65,7 @@ static struct device_attribute ieee80211_dev_attrs[] = {
 	__ATTR_RO(macaddress),
 	__ATTR_RO(address_mask),
 	__ATTR_RO(addresses),
+	__ATTR_RO(name),
 	{}
 };
 
diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c
index 6002265289c6..12222ee6ebf2 100644
--- a/net/wireless/wext-compat.c
+++ b/net/wireless/wext-compat.c
@@ -1366,6 +1366,10 @@ struct iw_statistics *cfg80211_wireless_stats(struct net_device *dev)
 	}
 
 	wstats.qual.updated |= IW_QUAL_NOISE_INVALID;
+	if (sinfo.filled & STATION_INFO_RX_DROP_MISC)
+		wstats.discard.misc = sinfo.rx_dropped_misc;
+	if (sinfo.filled & STATION_INFO_TX_FAILED)
+		wstats.discard.retries = sinfo.tx_failed;
 
 	return &wstats;
 }