Jelajahi Sumber

mac80211: update to wireless-testing 2014-09-26

Signed-off-by: Felix Fietkau <[email protected]>

SVN-Revision: 42683
Felix Fietkau 11 tahun lalu
induk
melakukan
8be721208d
89 mengubah file dengan 653 tambahan dan 9209 penghapusan
  1. 2 2
      package/kernel/mac80211/Makefile
  2. 1 1
      package/kernel/mac80211/patches/000-fix_kconfig.patch
  3. 0 44
      package/kernel/mac80211/patches/005-make-genregdb.awk-skip-antenna-gain.patch
  4. 0 11
      package/kernel/mac80211/patches/007-select_queue.patch
  5. 2 2
      package/kernel/mac80211/patches/008-fix_netdev_unregister.patch
  6. 2 2
      package/kernel/mac80211/patches/050-lib80211_option.patch
  7. 4 4
      package/kernel/mac80211/patches/060-no_local_ssb_bcma.patch
  8. 0 10
      package/kernel/mac80211/patches/070-add-missing-header.patch
  9. 5 5
      package/kernel/mac80211/patches/100-revert_aes_ccm_port.patch
  10. 5 5
      package/kernel/mac80211/patches/150-disable_addr_notifier.patch
  11. 0 27
      package/kernel/mac80211/patches/160-backports-only-add-net_get_random_once-when-not-avai.patch
  12. 0 11
      package/kernel/mac80211/patches/200-ath5k_pci_dependency.patch
  13. 351 3260
      package/kernel/mac80211/patches/300-pending_work.patch
  14. 1 1
      package/kernel/mac80211/patches/310-ap_scan.patch
  15. 1 1
      package/kernel/mac80211/patches/400-ath_move_debug_code.patch
  16. 1 1
      package/kernel/mac80211/patches/403-ath_regd_optional.patch
  17. 2 2
      package/kernel/mac80211/patches/405-regd_no_assoc_hints.patch
  18. 2 2
      package/kernel/mac80211/patches/410-ath9k_allow_adhoc_and_ap.patch
  19. 3 3
      package/kernel/mac80211/patches/411-ath5k_allow_adhoc_and_ap.patch
  20. 1 1
      package/kernel/mac80211/patches/432-ath5k_add_pciids.patch
  21. 3 3
      package/kernel/mac80211/patches/440-ath5k_channel_bw_debugfs.patch
  22. 2 2
      package/kernel/mac80211/patches/500-ath9k_eeprom_debugfs.patch
  23. 2 2
      package/kernel/mac80211/patches/501-ath9k-eeprom_endianess.patch
  24. 1 1
      package/kernel/mac80211/patches/502-ath9k_ahb_init.patch
  25. 1 1
      package/kernel/mac80211/patches/511-ath9k_reduce_rxbuf.patch
  26. 3 3
      package/kernel/mac80211/patches/512-ath9k_channelbw_debugfs.patch
  27. 2 2
      package/kernel/mac80211/patches/513-ath9k_add_pci_ids.patch
  28. 3 3
      package/kernel/mac80211/patches/520-mac80211_cur_txpower.patch
  29. 5 5
      package/kernel/mac80211/patches/521-ath9k_cur_txpower.patch
  30. 21 21
      package/kernel/mac80211/patches/522-mac80211_configure_antenna_gain.patch
  31. 0 34
      package/kernel/mac80211/patches/523-ath9k_use_configured_antenna_gain.patch
  32. 10 10
      package/kernel/mac80211/patches/530-ath9k_extra_leds.patch
  33. 9 9
      package/kernel/mac80211/patches/542-ath9k_debugfs_diag.patch
  34. 4 4
      package/kernel/mac80211/patches/543-ath9k-allow-to-disable-bands-via-platform-data.patch
  35. 9 9
      package/kernel/mac80211/patches/550-ath9k_entropy_from_adc.patch
  36. 6 6
      package/kernel/mac80211/patches/551-ath9k-ar933x-usb-hang-workaround.patch
  37. 18 18
      package/kernel/mac80211/patches/560-ath9k_pcoem_optional.patch
  38. 1 1
      package/kernel/mac80211/patches/561-ath9k_remove_gain_tables.patch
  39. 2 2
      package/kernel/mac80211/patches/562-ath9k_ani_ws_detect.patch
  40. 1 1
      package/kernel/mac80211/patches/563-ath9k_rxorn_intr_fix.patch
  41. 1 1
      package/kernel/mac80211/patches/564-ath9k_cleanup_reset_debug.patch
  42. 2 2
      package/kernel/mac80211/patches/565-ath9k_restart_after_nfcal_failure.patch
  43. 1 1
      package/kernel/mac80211/patches/567-ath9k_fix_init_nfcal.patch
  44. 1 1
      package/kernel/mac80211/patches/600-0001-rt2x00-rt2800lib-move-rt2800_drv_data-declaration-in.patch
  45. 2 2
      package/kernel/mac80211/patches/600-0002-rt2x00-rt2800lib-introduce-RT2800_HAS_HIGH_SHARED_ME.patch
  46. 11 11
      package/kernel/mac80211/patches/600-0003-rt2x00-rt2800-serialize-shared-memory-access.patch
  47. 2 2
      package/kernel/mac80211/patches/600-0004-rt2x00-rt2800lib-fix-beacon-generation-on-RT3593.patch
  48. 3 3
      package/kernel/mac80211/patches/600-0005-rt2x00-rt2800lib-add-hw_beacon_count-field-to-struct.patch
  49. 2 2
      package/kernel/mac80211/patches/600-0006-rt2x00-rt2800lib-init-additional-beacon-offset-regis.patch
  50. 1 1
      package/kernel/mac80211/patches/600-0007-rt2x00-rt2800lib-fix-max-supported-beacon-count-for-.patch
  51. 1 1
      package/kernel/mac80211/patches/600-0009-rt2x00-rt2800lib-enable-support-for-RT3883.patch
  52. 4 4
      package/kernel/mac80211/patches/600-0010-rt2x00-rt2800lib-add-rf_vals-for-RF3853.patch
  53. 4 4
      package/kernel/mac80211/patches/600-0011-rt2x00-rt2800lib-enable-VCO-calibration-for-RF3853.patch
  54. 1 1
      package/kernel/mac80211/patches/600-0012-rt2x00-rt2800lib-add-channel-configuration-function-.patch
  55. 2 2
      package/kernel/mac80211/patches/600-0013-rt2x00-rt2800lib-enable-RF3853-support.patch
  56. 4 4
      package/kernel/mac80211/patches/600-0014-rt2x00-rt2800lib-add-MAC-register-initialization-for.patch
  57. 2 2
      package/kernel/mac80211/patches/600-0016-rt2x00-rt2800lib-add-BBP-register-initialization-for.patch
  58. 3 3
      package/kernel/mac80211/patches/600-0017-rt2x00-rt2800lib-add-RFCSR-initialization-for-RT3883.patch
  59. 1 1
      package/kernel/mac80211/patches/600-0019-rt2x00-rt2800lib-force-rf-type-to-RF3853-on-RT3883.patch
  60. 4 4
      package/kernel/mac80211/patches/600-0020-rt2x00-rt2800lib-add-channel-configuration-code-for-.patch
  61. 1 1
      package/kernel/mac80211/patches/600-0022-rt2x00-rt2800lib-use-correct-txpower-calculation-fun.patch
  62. 2 2
      package/kernel/mac80211/patches/600-0023-rt2x00-rt2800lib-hardcode-txmixer-gain-values-to-zer.patch
  63. 1 1
      package/kernel/mac80211/patches/600-0026-rt2x00-rt2800lib-use-correct-beacon-count-for-RT3883.patch
  64. 3 3
      package/kernel/mac80211/patches/600-0029-rt2x00-rt2800lib-fix-VGC-setup-for-RT3883.patch
  65. 3 3
      package/kernel/mac80211/patches/600-0030-rt2x00-rt2800lib-fix-EEPROM-LNA-validation-for-RT388.patch
  66. 1 1
      package/kernel/mac80211/patches/600-0031-rt2x00-rt2800lib-fix-txpower-compensation-for-RT3883.patch
  67. 1 1
      package/kernel/mac80211/patches/600-0032-rt2x00-rt2800lib-enable-RT2800_HAS_HIGH_SHARED_MEM-f.patch
  68. 1 1
      package/kernel/mac80211/patches/600-0034-rt2x00-rt2800mmio-add-a-workaround-for-spurious-TX_F.patch
  69. 8 8
      package/kernel/mac80211/patches/603-rt2x00-introduce-rt2x00eeprom.patch
  70. 1 1
      package/kernel/mac80211/patches/608-add_platform_data_mac_addr.patch
  71. 13 13
      package/kernel/mac80211/patches/610-rt2x00-fix-rt3352-ext-pa.patch
  72. 4 4
      package/kernel/mac80211/patches/611-rt2x00-rf_vals-rt3352-xtal20.patch
  73. 1 1
      package/kernel/mac80211/patches/615-rt2x00-fix_20mhz_clk.patch
  74. 24 24
      package/kernel/mac80211/patches/616-rt2x00-support-rt5350.patch
  75. 1 1
      package/kernel/mac80211/patches/619-rt2x00-change-led-polarity-from-OF.patch
  76. 1 1
      package/kernel/mac80211/patches/620-rt2x00-add-AP+STA-support.patch
  77. 1 1
      package/kernel/mac80211/patches/620-rt2x00-rt3352-rf-id.patch
  78. 6 10
      package/kernel/mac80211/patches/621-rt2x00-ht20_40_fix.patch
  79. 2 2
      package/kernel/mac80211/patches/700-mwl8k-missing-pci-id-for-WNR854T.patch
  80. 0 5202
      package/kernel/mac80211/patches/800-b43-backports-form-wireless-testing-master-master-20.patch
  81. 0 12
      package/kernel/mac80211/patches/801-fix-5ghz.patch
  82. 2 2
      package/kernel/mac80211/patches/805-b43-gpio-mask-module-option.patch
  83. 2 2
      package/kernel/mac80211/patches/810-b43_no_pio.patch
  84. 9 9
      package/kernel/mac80211/patches/820-b43-add-antenna-control.patch
  85. 0 256
      package/kernel/mac80211/patches/830-b43-workaround-pcie-bcm4716.patch
  86. 1 1
      package/kernel/mac80211/patches/845-b43-only-use-gpio-0-1-for-led.patch
  87. 0 36
      package/kernel/mac80211/patches/901-wlcore-don-t-switch-channels-on-disconnected-STA-vif.patch
  88. 22 22
      package/kernel/mac80211/patches/910-01-add-support-for-mt7620.patch
  89. 4 4
      package/kernel/mac80211/patches/920-ath10k_allow_fallback_to_board_bin_on_empty_otp_stream.patch

+ 2 - 2
package/kernel/mac80211/Makefile

@@ -10,11 +10,11 @@ include $(INCLUDE_DIR)/kernel.mk
 
 PKG_NAME:=mac80211
 
-PKG_VERSION:=2014-05-22
+PKG_VERSION:=2014-09-26
 PKG_RELEASE:=1
 PKG_SOURCE_URL:=http://mirror2.openwrt.org/sources
 PKG_BACKPORT_VERSION:=
-PKG_MD5SUM:=367937d4f8c05cb36ca989ee26abc3df
+PKG_MD5SUM:=b66f5fbd10e335fc660182ce6114d41f
 
 PKG_SOURCE:=compat-wireless-$(PKG_VERSION)$(PKG_BACKPORT_VERSION).tar.bz2
 PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/compat-wireless-$(PKG_VERSION)

+ 1 - 1
package/kernel/mac80211/patches/000-fix_kconfig.patch

@@ -7,7 +7,7 @@
  LXDIALOG := lxdialog/checklist.o lxdialog/inputbox.o lxdialog/menubox.o lxdialog/textbox.o lxdialog/util.o lxdialog/yesno.o
  
  conf: conf.o zconf.tab.o
--mconf: LDFLAGS = -Wl,--no-as-needed $(shell ./lxdialog/check-lxdialog.sh -ldflags $(CC))
+-mconf: LDFLAGS = -Wl,--add-needed $(shell ./lxdialog/check-lxdialog.sh -ldflags $(CC))
 -mconf: CFLAGS += -DCURSES_LOC="<ncurses.h>" -DLOCALE
 +mconf: LDFLAGS = $(shell ./lxdialog/check-lxdialog.sh -ldflags $(CC))
 +mconf: CFLAGS += -DCURSES_LOC="<ncurses.h>"

+ 0 - 44
package/kernel/mac80211/patches/005-make-genregdb.awk-skip-antenna-gain.patch

@@ -1,44 +0,0 @@
-From: Luis R. Rodriguez <[email protected]>
-Date: Wed, 23 Oct 2013 14:55:36 -0400
-Subject: [RFC] cfg80211: make genregdb.awk skip antenna gain
-
-Now that wireless-regdb doesn't include
-antenna gain lets skip parsing it completely
-for when CONFIG_CFG80211_INTERNAL_REGDB is
-enabled.
-
-Signed-off-by: Luis R. Rodriguez <[email protected]>
----
- net/wireless/genregdb.awk | 11 ++++-------
- 1 file changed, 4 insertions(+), 7 deletions(-)
- mode change 100644 => 100755 net/wireless/genregdb.awk
-
---- a/net/wireless/genregdb.awk
-+++ b/net/wireless/genregdb.awk
-@@ -56,14 +56,11 @@ function parse_reg_rule()
- 	end = $3
- 	bw = $5
- 	sub(/\),/, "", bw)
--	gain = $6
--	sub(/\(/, "", gain)
--	sub(/,/, "", gain)
--	power = $7
--	sub(/\)/, "", power)
-+	power = $6
-+	sub(/\(/, "", power)
- 	sub(/,/, "", power)
- 	# power might be in mW...
--	units = $8
-+	units = $7
- 	sub(/\)/, "", units)
- 	sub(/,/, "", units)
- 	dfs_cac = $9
-@@ -86,7 +83,7 @@ function parse_reg_rule()
- 	sub(/\(/, "", dfs_cac)
- 	sub(/\)/, "", dfs_cac)
- 	flagstr = ""
--	for (i=8; i<=NF; i++)
-+	for (i=7; i<=NF; i++)
- 		flagstr = flagstr $i
- 	split(flagstr, flagarray, ",")
- 	flags = ""

+ 0 - 11
package/kernel/mac80211/patches/007-select_queue.patch

@@ -1,11 +0,0 @@
---- a/drivers/net/wireless/mwifiex/main.c
-+++ b/drivers/net/wireless/mwifiex/main.c
-@@ -745,7 +745,7 @@ static struct net_device_stats *mwifiex_
- 	return &priv->stats;
- }
- 
--#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0)
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)
- static u16
- mwifiex_netdev_select_wmm_queue(struct net_device *dev, struct sk_buff *skb,
- 				void *accel_priv, select_queue_fallback_t fallback)

+ 2 - 2
package/kernel/mac80211/patches/008-fix_netdev_unregister.patch

@@ -1,13 +1,13 @@
 --- a/net/mac80211/iface.c
 +++ b/net/mac80211/iface.c
-@@ -1796,7 +1796,11 @@ void ieee80211_remove_interfaces(struct 
+@@ -1825,6 +1825,11 @@ void ieee80211_remove_interfaces(struct 
  	}
  	mutex_unlock(&local->iflist_mtx);
  	unregister_netdevice_many(&unreg_list);
 +#if (!(LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,45) && \
 +       LINUX_VERSION_CODE < KERNEL_VERSION(3,11,0)) && \
 +     (LINUX_VERSION_CODE < KERNEL_VERSION(3,16,0)))
- 	list_del(&unreg_list);
++	list_del(&unreg_list);
 +#endif
  
  	list_for_each_entry_safe(sdata, tmp, &wdev_list, list) {

+ 2 - 2
package/kernel/mac80211/patches/050-lib80211_option.patch

@@ -1,6 +1,6 @@
 --- a/net/wireless/Kconfig
 +++ b/net/wireless/Kconfig
-@@ -160,7 +160,7 @@ config CFG80211_WEXT
+@@ -166,7 +166,7 @@ config CFG80211_WEXT
  	  extensions with cfg80211-based drivers.
  
  config LIB80211
@@ -9,7 +9,7 @@
  	depends on m
  	default n
  	help
-@@ -170,15 +170,15 @@ config LIB80211
+@@ -176,15 +176,15 @@ config LIB80211
  	  Drivers should select this themselves if needed.
  
  config LIB80211_CRYPT_WEP

+ 4 - 4
package/kernel/mac80211/patches/060-no_local_ssb_bcma.patch

@@ -1,6 +1,6 @@
 --- a/.local-symbols
 +++ b/.local-symbols
-@@ -403,42 +403,6 @@ USB_CDC_PHONET=
+@@ -414,42 +414,6 @@ USB_CDC_PHONET=
  USB_IPHETH=
  USB_SIERRA_NET=
  USB_VL600=
@@ -54,7 +54,7 @@
 -
  source net/nfc/Kconfig
  
- source drivers/regulator/Kconfig
+ source drivers/media/Kconfig
 --- a/Makefile.kernel
 +++ b/Makefile.kernel
 @@ -25,8 +25,6 @@ obj-$(CPTCFG_MAC80211) += net/mac80211/
@@ -68,7 +68,7 @@
  obj-$(CPTCFG_NFC) += net/nfc/
 --- a/drivers/net/wireless/b43/main.c
 +++ b/drivers/net/wireless/b43/main.c
-@@ -2733,7 +2733,7 @@ static struct ssb_device *b43_ssb_gpio_d
+@@ -2828,7 +2828,7 @@ static struct ssb_device *b43_ssb_gpio_d
  {
  	struct ssb_bus *bus = dev->dev->sdev->bus;
  
@@ -77,7 +77,7 @@
  	return (bus->chipco.dev ? bus->chipco.dev : bus->pcicore.dev);
  #else
  	return bus->chipco.dev;
-@@ -4698,7 +4698,7 @@ static int b43_wireless_core_init(struct
+@@ -4858,7 +4858,7 @@ static int b43_wireless_core_init(struct
  	}
  	if (sprom->boardflags_lo & B43_BFL_XTAL_NOSLOW)
  		hf |= B43_HF_DSCRQ; /* Disable slowclock requests from ucode. */

+ 0 - 10
package/kernel/mac80211/patches/070-add-missing-header.patch

@@ -1,10 +0,0 @@
---- a/compat/backport-3.15.c
-+++ b/compat/backport-3.15.c
-@@ -12,6 +12,7 @@
- #include <linux/kernel.h>
- #include <linux/device.h>
- #include <linux/of.h>
-+#include <linux/string.h>
- #include <net/net_namespace.h>
- 
- #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0))

+ 5 - 5
package/kernel/mac80211/patches/100-revert_aes_ccm_port.patch

@@ -246,7 +246,7 @@
  		struct {
 --- a/net/mac80211/wpa.c
 +++ b/net/mac80211/wpa.c
-@@ -301,15 +301,22 @@ ieee80211_crypto_tkip_decrypt(struct iee
+@@ -304,15 +304,22 @@ ieee80211_crypto_tkip_decrypt(struct iee
  }
  
  
@@ -271,7 +271,7 @@
  	/*
  	 * Mask FC: zero subtype b4 b5 b6 (if not mgmt)
  	 * Retry, PwrMgt, MoreData; set Protected
-@@ -331,21 +338,20 @@ static void ccmp_special_blocks(struct s
+@@ -334,21 +341,20 @@ static void ccmp_special_blocks(struct s
  	else
  		qos_tid = 0;
  
@@ -300,7 +300,7 @@
  
  	/* AAD (extra authenticate-only data) / masked 802.11 header
  	 * FC | A1 | A2 | A3 | SC | [A4] | [QC] */
-@@ -401,8 +407,7 @@ static int ccmp_encrypt_skb(struct ieee8
+@@ -404,8 +410,7 @@ static int ccmp_encrypt_skb(struct ieee8
  	u8 *pos;
  	u8 pn[6];
  	u64 pn64;
@@ -310,7 +310,7 @@
  
  	if (info->control.hw_key &&
  	    !(info->control.hw_key->flags & IEEE80211_KEY_FLAG_GENERATE_IV) &&
-@@ -458,9 +463,9 @@ static int ccmp_encrypt_skb(struct ieee8
+@@ -461,9 +466,9 @@ static int ccmp_encrypt_skb(struct ieee8
  		return 0;
  
  	pos += IEEE80211_CCMP_HDR_LEN;
@@ -323,7 +323,7 @@
  
  	return 0;
  }
-@@ -523,16 +528,16 @@ ieee80211_crypto_ccmp_decrypt(struct iee
+@@ -526,16 +531,16 @@ ieee80211_crypto_ccmp_decrypt(struct iee
  	}
  
  	if (!(status->flag & RX_FLAG_DECRYPTED)) {

+ 5 - 5
package/kernel/mac80211/patches/150-disable_addr_notifier.patch

@@ -1,6 +1,6 @@
 --- a/net/mac80211/main.c
 +++ b/net/mac80211/main.c
-@@ -285,7 +285,7 @@ void ieee80211_restart_hw(struct ieee802
+@@ -287,7 +287,7 @@ void ieee80211_restart_hw(struct ieee802
  }
  EXPORT_SYMBOL(ieee80211_restart_hw);
  
@@ -9,7 +9,7 @@
  static int ieee80211_ifa_changed(struct notifier_block *nb,
  				 unsigned long data, void *arg)
  {
-@@ -344,7 +344,7 @@ static int ieee80211_ifa_changed(struct 
+@@ -346,7 +346,7 @@ static int ieee80211_ifa_changed(struct 
  }
  #endif
  
@@ -18,7 +18,7 @@
  static int ieee80211_ifa6_changed(struct notifier_block *nb,
  				  unsigned long data, void *arg)
  {
-@@ -1036,14 +1036,14 @@ int ieee80211_register_hw(struct ieee802
+@@ -1038,14 +1038,14 @@ int ieee80211_register_hw(struct ieee802
  		goto fail_pm_qos;
  	}
  
@@ -35,7 +35,7 @@
  	local->ifa6_notifier.notifier_call = ieee80211_ifa6_changed;
  	result = register_inet6addr_notifier(&local->ifa6_notifier);
  	if (result)
-@@ -1052,13 +1052,13 @@ int ieee80211_register_hw(struct ieee802
+@@ -1054,13 +1054,13 @@ int ieee80211_register_hw(struct ieee802
  
  	return 0;
  
@@ -52,7 +52,7 @@
   fail_ifa:
  	pm_qos_remove_notifier(PM_QOS_NETWORK_LATENCY,
  			       &local->network_latency_notifier);
-@@ -1103,10 +1103,10 @@ void ieee80211_unregister_hw(struct ieee
+@@ -1105,10 +1105,10 @@ void ieee80211_unregister_hw(struct ieee
  
  	pm_qos_remove_notifier(PM_QOS_NETWORK_LATENCY,
  			       &local->network_latency_notifier);

+ 0 - 27
package/kernel/mac80211/patches/160-backports-only-add-net_get_random_once-when-not-avai.patch

@@ -1,27 +0,0 @@
-From 6e5603fa9e5b0d3c602eb1672473e81a1692f61e Mon Sep 17 00:00:00 2001
-From: Hauke Mehrtens <[email protected]>
-Date: Sat, 31 May 2014 15:52:42 +0200
-Subject: [PATCH] backports: only add net_get_random_once() when not available
-
-Upstream commit: d787b3dd3b4fcb5f40eb6532163dc3abdca4fd45
-
-net_get_random_once() was added unconditionally also when the kernel we
-are compiling against already provided this function, this patch checks
-that first.
-
-Signed-off-by: Hauke Mehrtens <[email protected]>
----
- backport/backport-include/linux/net.h | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/backport-include/linux/net.h
-+++ b/backport-include/linux/net.h
-@@ -64,7 +64,7 @@ do {								\
-  * may affect tracing. My recommendation is that if you have a need for
-  * static keys you just require at least 3.5 to remain sane.
-  */
--#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0) && !defined(net_get_random_once)
- #define __BACKPORT_NET_GET_RANDOM_ONCE 1
- #endif
- #endif /* ___NET_RANDOM_STATIC_KEY_INIT */

+ 0 - 11
package/kernel/mac80211/patches/200-ath5k_pci_dependency.patch

@@ -1,11 +0,0 @@
---- a/drivers/net/wireless/ath/ath5k/Kconfig
-+++ b/drivers/net/wireless/ath/ath5k/Kconfig
-@@ -55,7 +55,7 @@ config ATH5K_TRACER
- 
- config ATH5K_AHB
- 	bool "Atheros 5xxx AHB bus support"
--	depends on (ATHEROS_AR231X && !PCI)
-+	depends on ATHEROS_AR231X
- 	---help---
- 	  This adds support for WiSoC type chipsets of the 5xxx Atheros
- 	  family.

+ 351 - 3260
package/kernel/mac80211/patches/300-pending_work.patch

@@ -1,3322 +1,413 @@
-commit fb77a822cc68745186b38db7d105ad97e0622152
-Author: Johannes Stezenbach <[email protected]>
-Date:   Fri Sep 12 22:36:51 2014 +0200
-
-    ath9k_htc: fix random decryption failure
-    
-    In v3.15 the driver stopped to accept network packets after successful
-    authentification, which could be worked around by passing the
-    nohwcrypt=1 module parameter.  This was not reproducible by
-    everyone, and showed random behaviour in some tests.
-    It was caused by an uninitialized variable introduced
-    in 4ed1a8d4a257 ("ath9k_htc: use ath9k_cmn_rx_accept") and
-    used in 341b29b9cd2f ("ath9k_htc: use ath9k_cmn_rx_skb_postprocess").
-    
-    Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=78581
-    Fixes: 341b29b9cd2f ("ath9k_htc: use ath9k_cmn_rx_skb_postprocess")
-    Signed-off-by: Johannes Stezenbach <[email protected]>
-
-commit 11f17631d9bf2a9e910dac7d09ba4581f5693831
-Author: Felix Fietkau <[email protected]>
-Date:   Tue Sep 9 09:48:30 2014 +0200
-
-    ath9k_hw: fix PLL clock initialization for newer SoC
-    
-    On AR934x and newer SoC devices, the layout of the AR_RTC_PLL_CONTROL
-    register changed. This currently breaks at least 5/10 MHz operation.
-    AR933x uses the old layout.
-    
-    It might also have been causing other stability issues because of the
-    different location of the PLL_BYPASS bit which needs to be set during
-    PLL clock initialization.
-    
-    This patch also removes more instances of hardcoded register values in
-    favor of properly computed ones with the PLL_BYPASS bit added.
-    
-    Reported-by: Lorenzo Bianconi <[email protected]>
-    Signed-off-by: Felix Fietkau <[email protected]>
-
-commit 0fecedddd4a0945873db1bd230ec6a168b3cc4fe
-Author: Felix Fietkau <[email protected]>
-Date:   Mon Sep 8 18:35:08 2014 +0200
-
-    ath9k_hw: reduce ANI spur immunity setting on HT40 extension channel
-    
-    The cycpwr_thr1 value needs to be lower on the extension channel than on
-    the control channel, similar to how the register settings are programmed
-    in the initvals.
-    
-    Also drop the unnecessary check for HT40 - this register can always be
-    written. This patch has been reported to improve HT40 stability and
-    throughput in some environments.
-    
-    Signed-off-by: Felix Fietkau <[email protected]>
-
-commit 30d7434ccb853b96de698a040888fa4dacd0cc19
-Author: Felix Fietkau <[email protected]>
-Date:   Mon Sep 8 18:31:26 2014 +0200
-
-    Revert "ath9k_hw: reduce ANI firstep range for older chips"
-    
-    This reverts commit 09efc56345be4146ab9fc87a55c837ed5d6ea1ab
-    
-    I've received reports that this change is decreasing throughput in some
-    rare conditions on an AR9280 based device
-    
-    Cc: [email protected]
-    Signed-off-by: Felix Fietkau <[email protected]>
-
-commit 15ed54948f508ad1baad79c30050e2d29a21696d
-Author: Felix Fietkau <[email protected]>
-Date:   Fri Jul 25 16:18:03 2014 +0200
-
-    mac80211: fix smps mode check for AP_VLAN
-    
-    In ieee80211_sta_ps_deliver_wakeup, sdata->smps_mode is checked. This is
-    initialized only for the base AP interface, not the individual VLANs.
-    
-    Signed-off-by: Felix Fietkau <[email protected]>
-
-commit bc74ad816bba291359ae46301173ea744bdda9d2
-Author: Felix Fietkau <[email protected]>
-Date:   Fri Jul 25 16:15:44 2014 +0200
-
-    mac80211: ignore AP_VLAN in ieee80211_recalc_chanctx_chantype
-    
-    When bringing down the AP, a WARN_ON is hit because the bss config chandef
-    is empty here.
-    Since AP_VLAN channel settings do not matter for anything chanctx related
-    (always inherits the settings from the AP interface), let's just ignore
-    it here.
-    
-    Signed-off-by: Felix Fietkau <[email protected]>
-
-commit ff354dbdd743e5fe186df8cd17982db19f78231a
-Author: Felix Fietkau <[email protected]>
-Date:   Wed Jul 23 15:33:26 2014 +0200
-
-    ath9k: fix aggregation session lockup
-    
-    If an aggregation session fails, frames still end up in the driver queue
-    with IEEE80211_TX_CTL_AMPDU set.
-    This causes tx for the affected station/tid to stall, since
-    ath_tx_get_tid_subframe returning packets to send.
-    
-    Fix this by clearing IEEE80211_TX_CTL_AMPDU as long as no aggregation
-    session is running.
-    
-    Cc: [email protected]
-    Reported-by: Antonio Quartulli <[email protected]>
-    Signed-off-by: Felix Fietkau <[email protected]>
-
-commit 38695a6e5a940e6a524523b88a33916b016fb2a1
-Author: Felix Fietkau <[email protected]>
-Date:   Fri Jul 11 12:06:18 2014 +0200
-
-    mac80211: fix crash on getting sta info with uninitialized rate control
-    
-    If the expected throughput is queried before rate control has been
-    initialized, the minstrel op for it will crash while trying to access
-    the rate table.
-    Check for WLAN_STA_RATE_CONTROL before attempting to use the rate
-    control op.
-    
-    Reported-by: Jean-Pierre Tosoni <[email protected]>
-    Signed-off-by: Felix Fietkau <[email protected]>
-
-commit c0ee7fa4c0da824ccccc172bf175fb1f86540921
-Author: Felix Fietkau <[email protected]>
-Date:   Wed Jul 16 18:00:31 2014 +0200
-
-    ath9k: fix pending tx frames accounting
-    
-    Packets originally buffered for the regular hardware tx queues can end
-    up being transmitted through the U-APSD queue (via PS-Poll or U-APSD).
-    When packets are dropped due to retransmit failures, the pending frames
-    counter is not always updated properly.
-    Fix this by keeping track of the queue that a frame was accounted for in
-    the ath_frame_info struct, and using that on completion to decide
-    whether the counter should be updated.
-    This fixes some spurious transmit queue hangs.
-    
-    Cc: [email protected]
-    Signed-off-by: Felix Fietkau <[email protected]>
-
-commit edcdf0989410a05a6a4b8438df4010447eaa7d9a
-Author: Felix Fietkau <[email protected]>
-Date:   Sun Jun 22 13:36:20 2014 +0200
-
-    Revert "cfg80211: Use 5MHz bandwidth by default when checking usable channels"
-    
-    It enables channels that are not supposed to be enabled according to the
-    regulatory rules.
-    
-    This reverts commit 8eca1fb692cc9557f386eddce75c300a3855d11a.
-
-commit 6e7341074823d2a45b81f2742cbf75f1da790031
-Author: Rafał Miłecki <[email protected]>
-Date:   Sat May 31 19:40:45 2014 +0200
-
-    b43: disable 5 GHz on G-PHY
-    
-    This fixes regression introduced by adding some G-PHY devices to the
-    list of dual band devices. There is simply no support for 5 GHz on
-    G-PHY devices in b43. It results in:
-    WARNING: CPU: 0 PID: 79 at drivers/net/wireless/b43/phy_g.c:75 b43_gphy_channel_switch+0x125/0x130 [b43]()
-    b43-phy1 ERROR: PHY init: Channel switch to default failed
-    
-    Regression was introduced by the following commit:
-    
-    commit 773cfc508f4d64c14547ff8751b5cbd473124364
-    Author: Rafał Miłecki <[email protected]>
-    Date:   Mon May 19 23:18:55 2014 +0200
-    
-        b43: add more devices to the bands database
-    
-    Signed-off-by: Rafał Miłecki <[email protected]>
-    Signed-off-by: John W. Linville <[email protected]>
-
-commit 1186edbef91f15722e5bdf56326ce0abc2935ce7
-Author: Stanislaw Gruszka <[email protected]>
-Date:   Tue Jun 10 12:51:06 2014 +0200
-
-    rt2x00: disable TKIP on USB
-    
-    On USB we can not get atomically TKIP key. We have to disable support
-    for TKIP acceleration on USB hardware to avoid bug as showed bellow.
-    
-    [  860.827243] BUG: scheduling while atomic: hostapd/3397/0x00000002
-    <snip>
-    [  860.827280] Call Trace:
-    [  860.827282]  [<ffffffff81682ea6>] dump_stack+0x4d/0x66
-    [  860.827284]  [<ffffffff8167eb9b>] __schedule_bug+0x47/0x55
-    [  860.827285]  [<ffffffff81685bb3>] __schedule+0x733/0x7b0
-    [  860.827287]  [<ffffffff81685c59>] schedule+0x29/0x70
-    [  860.827289]  [<ffffffff81684f8a>] schedule_timeout+0x15a/0x2b0
-    [  860.827291]  [<ffffffff8105ac50>] ? ftrace_raw_event_tick_stop+0xc0/0xc0
-    [  860.827294]  [<ffffffff810c13c2>] ? __module_text_address+0x12/0x70
-    [  860.827296]  [<ffffffff81686823>] wait_for_completion_timeout+0xb3/0x140
-    [  860.827298]  [<ffffffff81080fc0>] ? wake_up_state+0x20/0x20
-    [  860.827301]  [<ffffffff814d5b3d>] usb_start_wait_urb+0x7d/0x150
-    [  860.827303]  [<ffffffff814d5cd5>] usb_control_msg+0xc5/0x110
-    [  860.827305]  [<ffffffffa02fb0c6>] rt2x00usb_vendor_request+0xc6/0x160  [rt2x00usb]
-    [  860.827307]  [<ffffffffa02fb215>] rt2x00usb_vendor_req_buff_lock+0x75/0x150 [rt2x00usb]
-    [  860.827309]  [<ffffffffa02fb393>] rt2x00usb_vendor_request_buff+0xa3/0xe0 [rt2x00usb]
-    [  860.827311]  [<ffffffffa023d1a3>] rt2x00usb_register_multiread+0x33/0x40 [rt2800usb]
-    [  860.827314]  [<ffffffffa05805f9>] rt2800_get_tkip_seq+0x39/0x50  [rt2800lib]
-    [  860.827321]  [<ffffffffa0480f88>] ieee80211_get_key+0x218/0x2a0  [mac80211]
-    [  860.827322]  [<ffffffff815cc68c>] ? __nlmsg_put+0x6c/0x80
-    [  860.827329]  [<ffffffffa051b02e>] nl80211_get_key+0x22e/0x360 [cfg80211]
-    
-    Cc: [email protected]
-    Reported-and-tested-by: Peter Wu <[email protected]>
-    Reported-and-tested-by: Pontus Fuchs <[email protected]>
-    Signed-off-by: Stanislaw Gruszka <[email protected]>
-    Signed-off-by: John W. Linville <[email protected]>
-
-commit 5f313a15da92dda80ac4c9a137bc42d7d0b49adf
-Author: Rafał Miłecki <[email protected]>
-Date:   Thu Jun 12 09:28:38 2014 +0200
-
-    b43: fix frequency reported on G-PHY with /new/ firmware
-
-commit d3a58df87a2e4c2301ac843604202d290a48440b
-Author: Avraham Stern <[email protected]>
-Date:   Thu May 22 12:17:47 2014 +0300
-
-    mac80211: set new interfaces as idle upon init
-    
-    Mark new interfaces as idle to allow operations that require that
-    interfaces are idle to take place. Interface types that are always
-    not idle (like AP interfaces) will be set as not idle when they are
-    assigned a channel context.
-    
-    Signed-off-by: Avraham Stern <[email protected]>
-    Signed-off-by: Emmanuel Grumbach<[email protected]>
-    Signed-off-by: Johannes Berg <[email protected]>
-
-commit 923eaf367206e01f22c97aee22300e332d071916
-Author: Arik Nemtsov <[email protected]>
-Date:   Mon May 26 14:40:51 2014 +0300
-
-    mac80211: don't check netdev state for debugfs read/write
-    
-    Doing so will lead to an oops for a p2p-dev interface, since it has
-    no netdev.
-    
-    Cc: [email protected]
-    Signed-off-by: Arik Nemtsov <[email protected]>
-    Signed-off-by: Emmanuel Grumbach <[email protected]>
-    Signed-off-by: Johannes Berg <[email protected]>
-
-commit a9fb54169b197f31aff24c8d6270dd1e56cde395
-Author: [email protected] <[email protected]>
-Date:   Mon May 26 18:01:44 2014 +0530
-
-    regdb: Generalize the mW to dBm power conversion
-    
-    Generalize the power conversion from mW to dBm
-    using log. This should fix the below compilation
-    error for country NO which adds a new power value
-    2000mW which is not handled earlier.
-    
-     CC [M]  net/wireless/wext-sme.o
-     CC [M]  net/wireless/regdb.o
-    net/wireless/regdb.c:1130:1: error: Unknown undeclared here (not in
-    a function)
-    net/wireless/regdb.c:1130:9: error: expected } before power
-    make[2]: *** [net/wireless/regdb.o] Error 1
-    make[1]: *** [net/wireless] Error 2
-    make: *** [net] Error 2
-    
-    Reported-By:  John Walker <[email protected]>
-    Signed-off-by: Chaitanya T K <[email protected]>
-    Acked-by: John W. Linville <[email protected]>
-    [remove unneeded parentheses, fix rounding by using %.0f]
-    Signed-off-by: Johannes Berg <[email protected]>
-
-commit c7d37a66e345df2fdf1aa7b2c9a6d3d53846ca5b
-Author: Krzysztof Hałasa <[email protected]>
-Date:   Mon May 26 14:14:46 2014 +0200
-
-    mac80211: fix IBSS join by initializing last_scan_completed
-    
-    Without this fix, freshly rebooted Linux creates a new IBSS
-    instead of joining an existing one. Only when jiffies counter
-    overflows after 5 minutes the IBSS can be successfully joined.
-    
-    Signed-off-by: Krzysztof Hałasa <[email protected]>
-    [edit commit message slightly]
-    Cc: [email protected]
-    Signed-off-by: Johannes Berg <[email protected]>
-
-commit 34171dc0d623be2c1032416bf7d3819f388ed70d
-Author: Emmanuel Grumbach <[email protected]>
-Date:   Sun May 25 15:35:41 2014 +0300
-
-    mac80211: fix virtual monitor interface addition
-    
-    Since the commit below, cfg80211_chandef_dfs_required()
-    will warn if it gets a an NL80211_IFTYPE_UNSPECIFIED iftype
-    as explicitely written in the commit log.
-    When an virtual monitor interface is added, its type is set
-    in ieee80211_sub_if_data.vif.type, but not in
-    ieee80211_sub_if_data.wdev.iftype which is passed to
-    cfg80211_chandef_dfs_required() hence resulting in the
-    following warning:
-    
-    WARNING: CPU: 1 PID: 21265 at net/wireless/chan.c:376 cfg80211_chandef_dfs_required+0xbc/0x130 [cfg80211]()
-    Modules linked in: [...]
-    CPU: 1 PID: 21265 Comm: ifconfig Tainted: G        W  O 3.13.11+ #12
-    Hardware name: Dell Inc. Latitude E6410/0667CC, BIOS A01 03/05/2010
-     0000000000000009 ffff88008f5fdb08 ffffffff817d4219 ffff88008f5fdb50
-     ffff88008f5fdb40 ffffffff8106f57d 0000000000000000 0000000000000000
-     ffff880081062fb8 ffff8800810604e0 0000000000000001 ffff88008f5fdba0
-    Call Trace:
-     [<ffffffff817d4219>] dump_stack+0x4d/0x66
-     [<ffffffff8106f57d>] warn_slowpath_common+0x7d/0xa0
-     [<ffffffff8106f5ec>] warn_slowpath_fmt+0x4c/0x50
-     [<ffffffffa04ea4ec>] cfg80211_chandef_dfs_required+0xbc/0x130 [cfg80211]
-     [<ffffffffa06b1024>] ieee80211_vif_use_channel+0x94/0x500 [mac80211]
-     [<ffffffffa0684e6b>] ieee80211_add_virtual_monitor+0x1ab/0x5c0 [mac80211]
-     [<ffffffffa0686ae5>] ieee80211_do_open+0xe75/0x1580 [mac80211]
-     [<ffffffffa0687259>] ieee80211_open+0x69/0x70 [mac80211]
-    [snip]
-    
-    Fixes: 00ec75fc5a64 ("cfg80211: pass the actual iftype when calling cfg80211_chandef_dfs_required()")
-    Signed-off-by: Emmanuel Grumbach <[email protected]>
-    Acked-by: Luciano Coelho <[email protected]>
-    Signed-off-by: Johannes Berg <[email protected]>
-
-commit d93cc72b37b4e2c314e1c499e80e8801907c2fea
-Author: Michal Kazior <[email protected]>
-Date:   Thu Jun 5 14:21:37 2014 +0200
-
-    mac80211: use csa counter offsets instead of csa_active
-    
-    vif->csa_active is protected by mutexes only. This
-    means it is unreliable to depend on it on codeflow
-    in non-sleepable beacon and CSA code. There was no
-    guarantee to have vif->csa_active update be
-    visible before beacons are updated on SMP systems.
-    
-    Using csa counter offsets which are embedded in
-    beacon struct (and thus are protected with single
-    RCU assignment) is much safer.
-    
-    Signed-off-by: Michal Kazior <[email protected]>
-    Signed-off-by: Johannes Berg <[email protected]>
-
-commit d2746694fcdef24e0a7a1947d8c70082cde81a26
-Author: Michal Kazior <[email protected]>
-Date:   Thu Jun 5 14:21:36 2014 +0200
-
-    mac80211: move csa counters from sdata to beacon/presp
-    
-    Having csa counters part of beacon and probe_resp
-    structures makes it easier to get rid of possible
-    races between setting a beacon and updating
-    counters on SMP systems by guaranteeing counters
-    are always consistent against given beacon struct.
-    
-    While at it relax WARN_ON into WARN_ON_ONCE to
-    prevent spamming logs and racing.
-    
-    Signed-off-by: Michal Kazior <[email protected]>
-    Signed-off-by: Johannes Berg <[email protected]>
-
-commit 5dcb54f3a1a8cd7e0331e773487574f9743615db
-Author: Janusz Dziedzic <[email protected]>
-Date:   Thu Jun 5 08:12:57 2014 +0200
-
-    mac80211: allow tx via monitor iface when DFS
-    
-    Allow send frames using monitor interface
-    when DFS chandef and we pass CAC (beaconing
-    allowed).
-    
-    This fix problem when old kernel and new backports used,
-    in such case hostapd create/use also monitor interface.
-    Before this patch all frames hostapd send using monitor
-    iface were dropped when AP was configured on DFS channel.
-    
-    Signed-off-by: Janusz Dziedzic <[email protected]>
-    Signed-off-by: Johannes Berg <[email protected]>
-
-commit 6f09a1beb0d2007572248c986780562219bd206f
-Author: Johannes Berg <[email protected]>
-Date:   Wed Jun 4 17:31:56 2014 +0200
-
-    cfg80211: make ethtool the driver's responsibility
-    
-    Currently, cfg80211 tries to implement ethtool, but that doesn't
-    really scale well, with all the different operations. Make the
-    lower-level driver responsible for it, which currently only has
-    an effect on mac80211. It will similarly not scale well at that
-    level though, since mac80211 also has many drivers.
-    
-    To cleanly implement this in mac80211, introduce a new file and
-    move some code to appropriate places.
-    
-    Signed-off-by: Johannes Berg <[email protected]>
-
-commit 6b0c6f133de8f90caeb1c4a902e6140567c5bf96
-Author: Johannes Berg <[email protected]>
-Date:   Wed Jun 4 17:06:23 2014 +0200
-
-    mac80211: remove weak WEP IV accounting
-    
-    Since WEP is practically dead, there seems very little
-    point in keeping WEP weak IV accounting.
-    
-    Signed-off-by: Johannes Berg <[email protected]>
-
-commit aecdc89fb4664c76baa4bbd46008f220532309ff
-Author: Luciano Coelho <[email protected]>
-Date:   Fri May 23 11:04:50 2014 +0300
-
-    ath9k/ath10k: remove unnecessary channel_switch_beacon callbacks
-    
-    The channel_switch_beacon callback is optional, so it doesn't have to
-    be defined if it's not going to do anything useful with it.  Both
-    ath9k and ath10k define the callback and just returns.  This commit
-    removes them.
-    
-    Cc: Michal Kazior <[email protected]>
-    Signed-off-by: Luciano Coelho <[email protected]>
-    Signed-off-by: Kalle Valo <[email protected]>
-
-commit 60ccc107c9b9fb732fdee1f76bb2dad44f0e1798
-Author: Rajkumar Manoharan <[email protected]>
-Date:   Tue May 27 16:58:02 2014 +0530
-
-    ath9k: Fix deadlock while updating p2p beacon timer
-    
-    pm_lock is taken twice while syncing HW TSF of p2p vif.
-    Fix this by taking the lock at caller side.
-    
-    Cc: Felix Fietkau <[email protected]>
-    Signed-off-by: Rajkumar Manoharan <[email protected]>
-    Signed-off-by: John W. Linville <[email protected]>
-
-commit f3831a4e3903dbc1a57d5df56deb6a143fd001bc
-Author: Stanislaw Gruszka <[email protected]>
-Date:   Thu Jun 5 13:52:27 2014 +0200
-
-    rt2x00: do not initialize BCN_OFFSET registers
-    
-    We setup BCN_OFFSET{0,1} registers dynamically, don't have to
-    initialize them.
-    
-    Signed-off-by: Stanislaw Gruszka <[email protected]>
-
-commit e5c58ca7a48d4c82f282749a978052c47fd95998
-Author: Stanislaw Gruszka <[email protected]>
-Date:   Thu Jun 5 13:52:26 2014 +0200
-
-    rt2x00: change order when stop beaconing
-    
-    When no beaconing is needed, first stop beacon queue (disable beaconing
-    globally) to avoid possible sending of not prepared beacon on short
-    period after clearing beacon and before stop of BCN queue.
-    
-    Signed-off-by: Stanislaw Gruszka <[email protected]>
-
-commit 382c1b9e03f52d0cd741ef1d942cad0f649f0744
-Author: Stanislaw Gruszka <[email protected]>
-Date:   Thu Jun 5 13:52:25 2014 +0200
-
-    rt2x00: change default MAC_BSSID_DW1_BSS_BCN_NUM
-    
-    We setup MAC_BSSID_DW1_BSS_BCN_NUM dynamically when numbers of active
-    beacons increase. Change default to 0 to tell hardware that we want to
-    send only one beacon as default.
-    
-    Signed-off-by: Stanislaw Gruszka <[email protected]>
-
-commit 3b400571dd033e46fa7e76c5bb92a3ce8198afa9
-Author: Stanislaw Gruszka <[email protected]>
-Date:   Thu Jun 5 13:52:24 2014 +0200
-
-    rt2x00: change beaconing setup on RT2800
-    
-    As reported by Matthias, on 5572 chip, even if we clear up TXWI
-    of corresponding beacon, hardware still try to send it or do other
-    action that increase power consumption peak up to 1A.
-    
-    To avoid the issue, setup beaconing dynamically by configuring offsets
-    of currently active beacons and MAC_BSSID_DW1_BSS_BCN_NUM variable,
-    which limit number of beacons that hardware will try to send.
-    
-    Reported-by: Matthias Fend <[email protected]>
-    Signed-off-by: Stanislaw Gruszka <[email protected]>
-
-commit 916e591b2cc41f7e572992175ca56d866d7bc958
-Author: Stanislaw Gruszka <[email protected]>
-Date:   Thu Jun 5 13:52:23 2014 +0200
-
-    rt2x00: change beaconing locking
-    
-    This patch is needed for further changes to keep global variables
-    consistent when changing beaconing on diffrent vif's.
-    
-    Signed-off-by: Stanislaw Gruszka <[email protected]>
-
-commit 930b0dffd1731f3f418f9132faea720a23b7af61
-Author: Johannes Berg <[email protected]>
-Date:   Tue Jun 3 11:18:47 2014 +0200
-
-    mac80211: fix station/driver powersave race
-    
-    It is currently possible to have a race due to the station PS
-    unblock work like this:
-     * station goes to sleep with frames buffered in the driver
-     * driver blocks wakeup
-     * station wakes up again
-     * driver flushes/returns frames, and unblocks, which schedules
-       the unblock work
-     * unblock work starts to run, and checks that the station is
-       awake (i.e. that the WLAN_STA_PS_STA flag isn't set)
-     * we process a received frame with PM=1, setting the flag again
-     * ieee80211_sta_ps_deliver_wakeup() runs, delivering all frames
-       to the driver, and then clearing the WLAN_STA_PS_DRIVER and
-       WLAN_STA_PS_STA flags
-    
-    In this scenario, mac80211 will think that the station is awake,
-    while it really is asleep, and any TX'ed frames should be filtered
-    by the device (it will know that the station is sleeping) but then
-    passed to mac80211 again, which will not buffer it either as it
-    thinks the station is awake, and eventually the packets will be
-    dropped.
-    
-    Fix this by moving the clearing of the flags to exactly where we
-    learn about the situation. This creates a problem of reordering,
-    so introduce another flag indicating that delivery is being done,
-    this new flag also queues frames and is cleared only while the
-    spinlock is held (which the queuing code also holds) so that any
-    concurrent delivery/TX is handled correctly.
-    
-    Reported-by: Andrei Otcheretianski <[email protected]>
-    Signed-off-by: Johannes Berg <[email protected]>
-
-commit 6df35206bc6c1c6aad1d8077df5786b4a7f77873
-Author: Felix Fietkau <[email protected]>
-Date:   Fri May 23 19:58:14 2014 +0200
-
-    mac80211: reduce packet loss notifications under load
-    
-    During strong signal fluctuations under high throughput, few consecutive
-    failed A-MPDU transmissions can easily trigger packet loss notification,
-    and thus (in AP mode) client disconnection.
-    
-    Reduce the number of false positives by checking the A-MPDU status flag
-    and treating a failed A-MPDU as a single packet.
-    
-    Signed-off-by: Felix Fietkau <[email protected]>
-
-commit 7b7843a36fbcc568834404c7430ff895d8502131
-Author: Felix Fietkau <[email protected]>
-Date:   Fri May 23 19:26:32 2014 +0200
-
-    mac80211: fix a memory leak on sta rate selection table
-    
-    Cc: [email protected]
-    Reported-by: Christophe Prévotaux <[email protected]>
-    Signed-off-by: Felix Fietkau <[email protected]>
-
-commit 96892d6aa0a153423070addf3070bc79578b3897
-Author: Felix Fietkau <[email protected]>
-Date:   Mon May 19 21:20:49 2014 +0200
-
-    ath9k: avoid passing buffers to the hardware during flush
-    
-    The commit "ath9k: fix possible hang on flush" changed the receive code
-    to always link rx descriptors of processed frames, even when flushing.
-    In some cases, this leads to flushed rx buffers being passed to the
-    hardware while rx is already stopped.
-    
-    Signed-off-by: Felix Fietkau <[email protected]>
-
---- a/drivers/net/wireless/ath/ath9k/recv.c
-+++ b/drivers/net/wireless/ath/ath9k/recv.c
-@@ -34,7 +34,8 @@ static inline bool ath9k_check_auto_slee
-  * buffer (or rx fifo). This can incorrectly acknowledge packets
-  * to a sender if last desc is self-linked.
-  */
--static void ath_rx_buf_link(struct ath_softc *sc, struct ath_rxbuf *bf)
-+static void ath_rx_buf_link(struct ath_softc *sc, struct ath_rxbuf *bf,
-+			    bool flush)
- {
- 	struct ath_hw *ah = sc->sc_ah;
- 	struct ath_common *common = ath9k_hw_common(ah);
-@@ -59,18 +60,19 @@ static void ath_rx_buf_link(struct ath_s
- 			     common->rx_bufsize,
- 			     0);
- 
--	if (sc->rx.rxlink == NULL)
--		ath9k_hw_putrxbuf(ah, bf->bf_daddr);
--	else
-+	if (sc->rx.rxlink)
- 		*sc->rx.rxlink = bf->bf_daddr;
-+	else if (!flush)
-+		ath9k_hw_putrxbuf(ah, bf->bf_daddr);
- 
- 	sc->rx.rxlink = &ds->ds_link;
- }
- 
--static void ath_rx_buf_relink(struct ath_softc *sc, struct ath_rxbuf *bf)
-+static void ath_rx_buf_relink(struct ath_softc *sc, struct ath_rxbuf *bf,
-+			      bool flush)
- {
- 	if (sc->rx.buf_hold)
--		ath_rx_buf_link(sc, sc->rx.buf_hold);
-+		ath_rx_buf_link(sc, sc->rx.buf_hold, flush);
- 
- 	sc->rx.buf_hold = bf;
- }
-@@ -442,7 +444,7 @@ int ath_startrecv(struct ath_softc *sc)
- 	sc->rx.buf_hold = NULL;
- 	sc->rx.rxlink = NULL;
- 	list_for_each_entry_safe(bf, tbf, &sc->rx.rxbuf, list) {
--		ath_rx_buf_link(sc, bf);
-+		ath_rx_buf_link(sc, bf, false);
- 	}
- 
- 	/* We could have deleted elements so the list may be empty now */
-@@ -1118,12 +1120,12 @@ requeue_drop_frag:
- requeue:
- 		list_add_tail(&bf->list, &sc->rx.rxbuf);
- 
--		if (edma) {
--			ath_rx_edma_buf_link(sc, qtype);
--		} else {
--			ath_rx_buf_relink(sc, bf);
-+		if (!edma) {
-+			ath_rx_buf_relink(sc, bf, flush);
- 			if (!flush)
- 				ath9k_hw_rxena(ah);
-+		} else if (!flush) {
-+			ath_rx_edma_buf_link(sc, qtype);
- 		}
- 
- 		if (!budget--)
---- a/net/mac80211/sta_info.c
-+++ b/net/mac80211/sta_info.c
-@@ -100,7 +100,8 @@ static void __cleanup_single_sta(struct 
- 	struct ps_data *ps;
- 
- 	if (test_sta_flag(sta, WLAN_STA_PS_STA) ||
--	    test_sta_flag(sta, WLAN_STA_PS_DRIVER)) {
-+	    test_sta_flag(sta, WLAN_STA_PS_DRIVER) ||
-+	    test_sta_flag(sta, WLAN_STA_PS_DELIVER)) {
- 		if (sta->sdata->vif.type == NL80211_IFTYPE_AP ||
- 		    sta->sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
- 			ps = &sdata->bss->ps;
-@@ -111,6 +112,7 @@ static void __cleanup_single_sta(struct 
- 
- 		clear_sta_flag(sta, WLAN_STA_PS_STA);
- 		clear_sta_flag(sta, WLAN_STA_PS_DRIVER);
-+		clear_sta_flag(sta, WLAN_STA_PS_DELIVER);
- 
- 		atomic_dec(&ps->num_sta_ps);
- 		sta_info_recalc_tim(sta);
-@@ -125,7 +127,7 @@ static void __cleanup_single_sta(struct 
- 	if (ieee80211_vif_is_mesh(&sdata->vif))
- 		mesh_sta_cleanup(sta);
- 
--	cancel_work_sync(&sta->drv_unblock_wk);
-+	cancel_work_sync(&sta->drv_deliver_wk);
- 
- 	/*
- 	 * Destroy aggregation state here. It would be nice to wait for the
-@@ -227,6 +229,7 @@ struct sta_info *sta_info_get_by_idx(str
-  */
- void sta_info_free(struct ieee80211_local *local, struct sta_info *sta)
- {
-+	struct ieee80211_sta_rates *rates;
- 	int i;
- 
- 	if (sta->rate_ctrl)
-@@ -238,6 +241,10 @@ void sta_info_free(struct ieee80211_loca
- 		kfree(sta->tx_lat);
- 	}
- 
-+	rates = rcu_dereference_protected(sta->sta.rates, true);
-+	if (rates)
-+		kfree(rates);
-+
- 	sta_dbg(sta->sdata, "Destroyed STA %pM\n", sta->sta.addr);
- 
- 	kfree(sta);
-@@ -252,33 +259,23 @@ static void sta_info_hash_add(struct iee
- 	rcu_assign_pointer(local->sta_hash[STA_HASH(sta->sta.addr)], sta);
- }
- 
--static void sta_unblock(struct work_struct *wk)
-+static void sta_deliver_ps_frames(struct work_struct *wk)
- {
- 	struct sta_info *sta;
- 
--	sta = container_of(wk, struct sta_info, drv_unblock_wk);
-+	sta = container_of(wk, struct sta_info, drv_deliver_wk);
- 
- 	if (sta->dead)
- 		return;
- 
--	if (!test_sta_flag(sta, WLAN_STA_PS_STA)) {
--		local_bh_disable();
-+	local_bh_disable();
-+	if (!test_sta_flag(sta, WLAN_STA_PS_STA))
- 		ieee80211_sta_ps_deliver_wakeup(sta);
--		local_bh_enable();
--	} else if (test_and_clear_sta_flag(sta, WLAN_STA_PSPOLL)) {
--		clear_sta_flag(sta, WLAN_STA_PS_DRIVER);
--
--		local_bh_disable();
-+	else if (test_and_clear_sta_flag(sta, WLAN_STA_PSPOLL))
- 		ieee80211_sta_ps_deliver_poll_response(sta);
--		local_bh_enable();
--	} else if (test_and_clear_sta_flag(sta, WLAN_STA_UAPSD)) {
--		clear_sta_flag(sta, WLAN_STA_PS_DRIVER);
--
--		local_bh_disable();
-+	else if (test_and_clear_sta_flag(sta, WLAN_STA_UAPSD))
- 		ieee80211_sta_ps_deliver_uapsd(sta);
--		local_bh_enable();
--	} else
--		clear_sta_flag(sta, WLAN_STA_PS_DRIVER);
-+	local_bh_enable();
- }
- 
- static int sta_prepare_rate_control(struct ieee80211_local *local,
-@@ -340,7 +337,7 @@ struct sta_info *sta_info_alloc(struct i
- 
- 	spin_lock_init(&sta->lock);
- 	spin_lock_init(&sta->ps_lock);
--	INIT_WORK(&sta->drv_unblock_wk, sta_unblock);
-+	INIT_WORK(&sta->drv_deliver_wk, sta_deliver_ps_frames);
- 	INIT_WORK(&sta->ampdu_mlme.work, ieee80211_ba_session_work);
- 	mutex_init(&sta->ampdu_mlme.mtx);
- #ifdef CPTCFG_MAC80211_MESH
-@@ -1101,8 +1098,11 @@ void ieee80211_sta_ps_deliver_wakeup(str
- 	unsigned long flags;
- 	struct ps_data *ps;
- 
--	if (sdata->vif.type == NL80211_IFTYPE_AP ||
--	    sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
-+	if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
-+		sdata = container_of(sdata->bss, struct ieee80211_sub_if_data,
-+				     u.ap);
-+
-+	if (sdata->vif.type == NL80211_IFTYPE_AP)
- 		ps = &sdata->bss->ps;
- 	else if (ieee80211_vif_is_mesh(&sdata->vif))
- 		ps = &sdata->u.mesh.ps;
-@@ -1140,8 +1140,15 @@ void ieee80211_sta_ps_deliver_wakeup(str
- 	}
- 
- 	ieee80211_add_pending_skbs(local, &pending);
--	clear_sta_flag(sta, WLAN_STA_PS_DRIVER);
--	clear_sta_flag(sta, WLAN_STA_PS_STA);
-+
-+	/* now we're no longer in the deliver code */
-+	clear_sta_flag(sta, WLAN_STA_PS_DELIVER);
-+
-+	/* The station might have polled and then woken up before we responded,
-+	 * so clear these flags now to avoid them sticking around.
-+	 */
-+	clear_sta_flag(sta, WLAN_STA_PSPOLL);
-+	clear_sta_flag(sta, WLAN_STA_UAPSD);
- 	spin_unlock(&sta->ps_lock);
- 
- 	atomic_dec(&ps->num_sta_ps);
-@@ -1542,10 +1549,26 @@ void ieee80211_sta_block_awake(struct ie
- 
- 	trace_api_sta_block_awake(sta->local, pubsta, block);
- 
--	if (block)
-+	if (block) {
- 		set_sta_flag(sta, WLAN_STA_PS_DRIVER);
--	else if (test_sta_flag(sta, WLAN_STA_PS_DRIVER))
--		ieee80211_queue_work(hw, &sta->drv_unblock_wk);
-+		return;
-+	}
-+
-+	if (!test_sta_flag(sta, WLAN_STA_PS_DRIVER))
-+		return;
-+
-+	if (!test_sta_flag(sta, WLAN_STA_PS_STA)) {
-+		set_sta_flag(sta, WLAN_STA_PS_DELIVER);
-+		clear_sta_flag(sta, WLAN_STA_PS_DRIVER);
-+		ieee80211_queue_work(hw, &sta->drv_deliver_wk);
-+	} else if (test_sta_flag(sta, WLAN_STA_PSPOLL) ||
-+		   test_sta_flag(sta, WLAN_STA_UAPSD)) {
-+		/* must be asleep in this case */
-+		clear_sta_flag(sta, WLAN_STA_PS_DRIVER);
-+		ieee80211_queue_work(hw, &sta->drv_deliver_wk);
-+	} else {
-+		clear_sta_flag(sta, WLAN_STA_PS_DRIVER);
-+	}
- }
- EXPORT_SYMBOL(ieee80211_sta_block_awake);
- 
-@@ -1703,3 +1726,140 @@ u8 sta_info_tx_streams(struct sta_info *
- 	return ((ht_cap->mcs.tx_params & IEEE80211_HT_MCS_TX_MAX_STREAMS_MASK)
- 			>> IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT) + 1;
- }
-+
-+void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
-+{
-+	struct ieee80211_sub_if_data *sdata = sta->sdata;
-+	struct ieee80211_local *local = sdata->local;
-+	struct rate_control_ref *ref = NULL;
-+	struct timespec uptime;
-+	u64 packets = 0;
-+	u32 thr = 0;
-+	int i, ac;
-+
-+	if (test_sta_flag(sta, WLAN_STA_RATE_CONTROL))
-+		ref = local->rate_ctrl;
-+
-+	sinfo->generation = sdata->local->sta_generation;
-+
-+	sinfo->filled = STATION_INFO_INACTIVE_TIME |
-+			STATION_INFO_RX_BYTES64 |
-+			STATION_INFO_TX_BYTES64 |
-+			STATION_INFO_RX_PACKETS |
-+			STATION_INFO_TX_PACKETS |
-+			STATION_INFO_TX_RETRIES |
-+			STATION_INFO_TX_FAILED |
-+			STATION_INFO_TX_BITRATE |
-+			STATION_INFO_RX_BITRATE |
-+			STATION_INFO_RX_DROP_MISC |
-+			STATION_INFO_BSS_PARAM |
-+			STATION_INFO_CONNECTED_TIME |
-+			STATION_INFO_STA_FLAGS |
-+			STATION_INFO_BEACON_LOSS_COUNT;
-+
-+	do_posix_clock_monotonic_gettime(&uptime);
-+	sinfo->connected_time = uptime.tv_sec - sta->last_connected;
-+
-+	sinfo->inactive_time = jiffies_to_msecs(jiffies - sta->last_rx);
-+	sinfo->tx_bytes = 0;
-+	for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
-+		sinfo->tx_bytes += sta->tx_bytes[ac];
-+		packets += sta->tx_packets[ac];
-+	}
-+	sinfo->tx_packets = packets;
-+	sinfo->rx_bytes = sta->rx_bytes;
-+	sinfo->rx_packets = sta->rx_packets;
-+	sinfo->tx_retries = sta->tx_retry_count;
-+	sinfo->tx_failed = sta->tx_retry_failed;
-+	sinfo->rx_dropped_misc = sta->rx_dropped;
-+	sinfo->beacon_loss_count = sta->beacon_loss_count;
-+
-+	if ((sta->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) ||
-+	    (sta->local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC)) {
-+		sinfo->filled |= STATION_INFO_SIGNAL | STATION_INFO_SIGNAL_AVG;
-+		if (!local->ops->get_rssi ||
-+		    drv_get_rssi(local, sdata, &sta->sta, &sinfo->signal))
-+			sinfo->signal = (s8)sta->last_signal;
-+		sinfo->signal_avg = (s8) -ewma_read(&sta->avg_signal);
-+	}
-+	if (sta->chains) {
-+		sinfo->filled |= STATION_INFO_CHAIN_SIGNAL |
-+				 STATION_INFO_CHAIN_SIGNAL_AVG;
-+
-+		sinfo->chains = sta->chains;
-+		for (i = 0; i < ARRAY_SIZE(sinfo->chain_signal); i++) {
-+			sinfo->chain_signal[i] = sta->chain_signal_last[i];
-+			sinfo->chain_signal_avg[i] =
-+				(s8) -ewma_read(&sta->chain_signal_avg[i]);
-+		}
-+	}
-+
-+	sta_set_rate_info_tx(sta, &sta->last_tx_rate, &sinfo->txrate);
-+	sta_set_rate_info_rx(sta, &sinfo->rxrate);
-+
-+	if (ieee80211_vif_is_mesh(&sdata->vif)) {
-+#ifdef CPTCFG_MAC80211_MESH
-+		sinfo->filled |= STATION_INFO_LLID |
-+				 STATION_INFO_PLID |
-+				 STATION_INFO_PLINK_STATE |
-+				 STATION_INFO_LOCAL_PM |
-+				 STATION_INFO_PEER_PM |
-+				 STATION_INFO_NONPEER_PM;
-+
-+		sinfo->llid = sta->llid;
-+		sinfo->plid = sta->plid;
-+		sinfo->plink_state = sta->plink_state;
-+		if (test_sta_flag(sta, WLAN_STA_TOFFSET_KNOWN)) {
-+			sinfo->filled |= STATION_INFO_T_OFFSET;
-+			sinfo->t_offset = sta->t_offset;
-+		}
-+		sinfo->local_pm = sta->local_pm;
-+		sinfo->peer_pm = sta->peer_pm;
-+		sinfo->nonpeer_pm = sta->nonpeer_pm;
-+#endif
-+	}
-+
-+	sinfo->bss_param.flags = 0;
-+	if (sdata->vif.bss_conf.use_cts_prot)
-+		sinfo->bss_param.flags |= BSS_PARAM_FLAGS_CTS_PROT;
-+	if (sdata->vif.bss_conf.use_short_preamble)
-+		sinfo->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_PREAMBLE;
-+	if (sdata->vif.bss_conf.use_short_slot)
-+		sinfo->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_SLOT_TIME;
-+	sinfo->bss_param.dtim_period = sdata->local->hw.conf.ps_dtim_period;
-+	sinfo->bss_param.beacon_interval = sdata->vif.bss_conf.beacon_int;
-+
-+	sinfo->sta_flags.set = 0;
-+	sinfo->sta_flags.mask = BIT(NL80211_STA_FLAG_AUTHORIZED) |
-+				BIT(NL80211_STA_FLAG_SHORT_PREAMBLE) |
-+				BIT(NL80211_STA_FLAG_WME) |
-+				BIT(NL80211_STA_FLAG_MFP) |
-+				BIT(NL80211_STA_FLAG_AUTHENTICATED) |
-+				BIT(NL80211_STA_FLAG_ASSOCIATED) |
-+				BIT(NL80211_STA_FLAG_TDLS_PEER);
-+	if (test_sta_flag(sta, WLAN_STA_AUTHORIZED))
-+		sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_AUTHORIZED);
-+	if (test_sta_flag(sta, WLAN_STA_SHORT_PREAMBLE))
-+		sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_SHORT_PREAMBLE);
-+	if (test_sta_flag(sta, WLAN_STA_WME))
-+		sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_WME);
-+	if (test_sta_flag(sta, WLAN_STA_MFP))
-+		sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_MFP);
-+	if (test_sta_flag(sta, WLAN_STA_AUTH))
-+		sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_AUTHENTICATED);
-+	if (test_sta_flag(sta, WLAN_STA_ASSOC))
-+		sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_ASSOCIATED);
-+	if (test_sta_flag(sta, WLAN_STA_TDLS_PEER))
-+		sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_TDLS_PEER);
-+
-+	/* check if the driver has a SW RC implementation */
-+	if (ref && ref->ops->get_expected_throughput)
-+		thr = ref->ops->get_expected_throughput(sta->rate_ctrl_priv);
-+	else
-+		thr = drv_get_expected_throughput(local, &sta->sta);
-+
-+	if (thr != 0) {
-+		sinfo->filled |= STATION_INFO_EXPECTED_THROUGHPUT;
-+		sinfo->expected_throughput = thr;
-+	}
-+}
---- a/net/mac80211/status.c
-+++ b/net/mac80211/status.c
-@@ -541,6 +541,23 @@ static void ieee80211_tx_latency_end_msr
-  */
- #define STA_LOST_PKT_THRESHOLD	50
- 
-+static void ieee80211_lost_packet(struct sta_info *sta, struct sk_buff *skb)
-+{
-+	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
-+
-+	/* This packet was aggregated but doesn't carry status info */
-+	if ((info->flags & IEEE80211_TX_CTL_AMPDU) &&
-+	    !(info->flags & IEEE80211_TX_STAT_AMPDU))
-+		return;
-+
-+	if (++sta->lost_packets < STA_LOST_PKT_THRESHOLD)
-+		return;
-+
-+	cfg80211_cqm_pktloss_notify(sta->sdata->dev, sta->sta.addr,
-+				    sta->lost_packets, GFP_ATOMIC);
-+	sta->lost_packets = 0;
-+}
-+
- void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
- {
- 	struct sk_buff *skb2;
-@@ -680,12 +697,8 @@ void ieee80211_tx_status(struct ieee8021
- 			if (info->flags & IEEE80211_TX_STAT_ACK) {
- 				if (sta->lost_packets)
- 					sta->lost_packets = 0;
--			} else if (++sta->lost_packets >= STA_LOST_PKT_THRESHOLD) {
--				cfg80211_cqm_pktloss_notify(sta->sdata->dev,
--							    sta->sta.addr,
--							    sta->lost_packets,
--							    GFP_ATOMIC);
--				sta->lost_packets = 0;
-+			} else {
-+				ieee80211_lost_packet(sta, skb);
- 			}
- 		}
- 
---- a/net/mac80211/rx.c
-+++ b/net/mac80211/rx.c
-@@ -1107,6 +1107,8 @@ static void sta_ps_end(struct sta_info *
- 		return;
- 	}
- 
-+	set_sta_flag(sta, WLAN_STA_PS_DELIVER);
-+	clear_sta_flag(sta, WLAN_STA_PS_STA);
- 	ieee80211_sta_ps_deliver_wakeup(sta);
- }
- 
---- a/net/mac80211/sta_info.h
-+++ b/net/mac80211/sta_info.h
-@@ -82,6 +82,7 @@ enum ieee80211_sta_info_flags {
- 	WLAN_STA_TOFFSET_KNOWN,
- 	WLAN_STA_MPSP_OWNER,
- 	WLAN_STA_MPSP_RECIPIENT,
-+	WLAN_STA_PS_DELIVER,
- };
- 
- #define ADDBA_RESP_INTERVAL HZ
-@@ -265,7 +266,7 @@ struct ieee80211_tx_latency_stat {
-  * @last_rx_rate_vht_nss: rx status nss of last data packet
-  * @lock: used for locking all fields that require locking, see comments
-  *	in the header file.
-- * @drv_unblock_wk: used for driver PS unblocking
-+ * @drv_deliver_wk: used for delivering frames after driver PS unblocking
-  * @listen_interval: listen interval of this station, when we're acting as AP
-  * @_flags: STA flags, see &enum ieee80211_sta_info_flags, do not use directly
-  * @ps_lock: used for powersave (when mac80211 is the AP) related locking
-@@ -278,7 +279,6 @@ struct ieee80211_tx_latency_stat {
-  * @driver_buffered_tids: bitmap of TIDs the driver has data buffered on
-  * @rx_packets: Number of MSDUs received from this STA
-  * @rx_bytes: Number of bytes received from this STA
-- * @wep_weak_iv_count: number of weak WEP IVs received from this station
-  * @last_rx: time (in jiffies) when last frame was received from this STA
-  * @last_connected: time (in seconds) when a station got connected
-  * @num_duplicates: number of duplicate frames received from this STA
-@@ -345,7 +345,7 @@ struct sta_info {
- 	void *rate_ctrl_priv;
- 	spinlock_t lock;
- 
--	struct work_struct drv_unblock_wk;
-+	struct work_struct drv_deliver_wk;
- 
- 	u16 listen_interval;
- 
-@@ -367,7 +367,6 @@ struct sta_info {
- 	/* Updated from RX path only, no locking requirements */
- 	unsigned long rx_packets;
- 	u64 rx_bytes;
--	unsigned long wep_weak_iv_count;
- 	unsigned long last_rx;
- 	long last_connected;
- 	unsigned long num_duplicates;
-@@ -628,6 +627,8 @@ void sta_set_rate_info_tx(struct sta_inf
- 			  struct rate_info *rinfo);
- void sta_set_rate_info_rx(struct sta_info *sta,
- 			  struct rate_info *rinfo);
-+void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo);
-+
- void ieee80211_sta_expire(struct ieee80211_sub_if_data *sdata,
- 			  unsigned long exp_time);
- u8 sta_info_tx_streams(struct sta_info *sta);
---- a/net/mac80211/tx.c
-+++ b/net/mac80211/tx.c
-@@ -469,7 +469,8 @@ ieee80211_tx_h_unicast_ps_buf(struct iee
- 		return TX_CONTINUE;
- 
- 	if (unlikely((test_sta_flag(sta, WLAN_STA_PS_STA) ||
--		      test_sta_flag(sta, WLAN_STA_PS_DRIVER)) &&
-+		      test_sta_flag(sta, WLAN_STA_PS_DRIVER) ||
-+		      test_sta_flag(sta, WLAN_STA_PS_DELIVER)) &&
- 		     !(info->flags & IEEE80211_TX_CTL_NO_PS_BUFFER))) {
- 		int ac = skb_get_queue_mapping(tx->skb);
- 
-@@ -486,7 +487,8 @@ ieee80211_tx_h_unicast_ps_buf(struct iee
- 		 * ahead and Tx the packet.
- 		 */
- 		if (!test_sta_flag(sta, WLAN_STA_PS_STA) &&
--		    !test_sta_flag(sta, WLAN_STA_PS_DRIVER)) {
-+		    !test_sta_flag(sta, WLAN_STA_PS_DRIVER) &&
-+		    !test_sta_flag(sta, WLAN_STA_PS_DELIVER)) {
- 			spin_unlock(&sta->ps_lock);
- 			return TX_CONTINUE;
- 		}
-@@ -1618,12 +1620,12 @@ netdev_tx_t ieee80211_monitor_start_xmit
- {
- 	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
- 	struct ieee80211_chanctx_conf *chanctx_conf;
--	struct ieee80211_channel *chan;
- 	struct ieee80211_radiotap_header *prthdr =
- 		(struct ieee80211_radiotap_header *)skb->data;
- 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
- 	struct ieee80211_hdr *hdr;
- 	struct ieee80211_sub_if_data *tmp_sdata, *sdata;
-+	struct cfg80211_chan_def *chandef;
- 	u16 len_rthdr;
- 	int hdrlen;
- 
-@@ -1721,9 +1723,9 @@ netdev_tx_t ieee80211_monitor_start_xmit
- 	}
- 
- 	if (chanctx_conf)
--		chan = chanctx_conf->def.chan;
-+		chandef = &chanctx_conf->def;
- 	else if (!local->use_chanctx)
--		chan = local->_oper_chandef.chan;
-+		chandef = &local->_oper_chandef;
- 	else
- 		goto fail_rcu;
- 
-@@ -1743,10 +1745,11 @@ netdev_tx_t ieee80211_monitor_start_xmit
- 	 * radar detection by itself. We can do that later by adding a
- 	 * monitor flag interfaces used for AP support.
- 	 */
--	if ((chan->flags & (IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_RADAR)))
-+	if (!cfg80211_reg_can_beacon(local->hw.wiphy, chandef,
-+				     sdata->vif.type))
- 		goto fail_rcu;
- 
--	ieee80211_xmit(sdata, skb, chan->band);
-+	ieee80211_xmit(sdata, skb, chandef->chan->band);
- 	rcu_read_unlock();
- 
- 	return NETDEV_TX_OK;
-@@ -2425,7 +2428,7 @@ static void ieee80211_set_csa(struct iee
- 	u8 *beacon_data;
- 	size_t beacon_data_len;
- 	int i;
--	u8 count = sdata->csa_current_counter;
-+	u8 count = beacon->csa_current_counter;
- 
- 	switch (sdata->vif.type) {
- 	case NL80211_IFTYPE_AP:
-@@ -2444,46 +2447,54 @@ static void ieee80211_set_csa(struct iee
- 		return;
- 	}
- 
-+	rcu_read_lock();
- 	for (i = 0; i < IEEE80211_MAX_CSA_COUNTERS_NUM; ++i) {
--		u16 counter_offset_beacon =
--			sdata->csa_counter_offset_beacon[i];
--		u16 counter_offset_presp = sdata->csa_counter_offset_presp[i];
--
--		if (counter_offset_beacon) {
--			if (WARN_ON(counter_offset_beacon >= beacon_data_len))
--				return;
--
--			beacon_data[counter_offset_beacon] = count;
--		}
--
--		if (sdata->vif.type == NL80211_IFTYPE_AP &&
--		    counter_offset_presp) {
--			rcu_read_lock();
--			resp = rcu_dereference(sdata->u.ap.probe_resp);
-+		resp = rcu_dereference(sdata->u.ap.probe_resp);
- 
--			/* If nl80211 accepted the offset, this should
--			 * not happen.
--			 */
--			if (WARN_ON(!resp)) {
-+		if (beacon->csa_counter_offsets[i]) {
-+			if (WARN_ON_ONCE(beacon->csa_counter_offsets[i] >=
-+					 beacon_data_len)) {
- 				rcu_read_unlock();
- 				return;
- 			}
--			resp->data[counter_offset_presp] = count;
--			rcu_read_unlock();
-+
-+			beacon_data[beacon->csa_counter_offsets[i]] = count;
- 		}
-+
-+		if (sdata->vif.type == NL80211_IFTYPE_AP && resp &&
-+		    resp->csa_counter_offsets)
-+			resp->data[resp->csa_counter_offsets[i]] = count;
- 	}
-+	rcu_read_unlock();
- }
- 
- u8 ieee80211_csa_update_counter(struct ieee80211_vif *vif)
- {
- 	struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
-+	struct beacon_data *beacon = NULL;
-+	u8 count = 0;
-+
-+	rcu_read_lock();
-+
-+	if (sdata->vif.type == NL80211_IFTYPE_AP)
-+		beacon = rcu_dereference(sdata->u.ap.beacon);
-+	else if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
-+		beacon = rcu_dereference(sdata->u.ibss.presp);
-+	else if (ieee80211_vif_is_mesh(&sdata->vif))
-+		beacon = rcu_dereference(sdata->u.mesh.beacon);
-+
-+	if (!beacon)
-+		goto unlock;
- 
--	sdata->csa_current_counter--;
-+	beacon->csa_current_counter--;
- 
- 	/* the counter should never reach 0 */
--	WARN_ON(!sdata->csa_current_counter);
-+	WARN_ON_ONCE(!beacon->csa_current_counter);
-+	count = beacon->csa_current_counter;
- 
--	return sdata->csa_current_counter;
-+unlock:
-+	rcu_read_unlock();
-+	return count;
- }
- EXPORT_SYMBOL(ieee80211_csa_update_counter);
- 
-@@ -2493,7 +2504,6 @@ bool ieee80211_csa_is_complete(struct ie
- 	struct beacon_data *beacon = NULL;
- 	u8 *beacon_data;
- 	size_t beacon_data_len;
--	int counter_beacon = sdata->csa_counter_offset_beacon[0];
- 	int ret = false;
- 
- 	if (!ieee80211_sdata_running(sdata))
-@@ -2531,10 +2541,13 @@ bool ieee80211_csa_is_complete(struct ie
- 		goto out;
- 	}
- 
--	if (WARN_ON(counter_beacon > beacon_data_len))
-+	if (!beacon->csa_counter_offsets[0])
-+		goto out;
-+
-+	if (WARN_ON_ONCE(beacon->csa_counter_offsets[0] > beacon_data_len))
- 		goto out;
- 
--	if (beacon_data[counter_beacon] == 1)
-+	if (beacon_data[beacon->csa_counter_offsets[0]] == 1)
- 		ret = true;
-  out:
- 	rcu_read_unlock();
-@@ -2550,6 +2563,7 @@ __ieee80211_beacon_get(struct ieee80211_
- 		       bool is_template)
- {
- 	struct ieee80211_local *local = hw_to_local(hw);
-+	struct beacon_data *beacon = NULL;
- 	struct sk_buff *skb = NULL;
- 	struct ieee80211_tx_info *info;
- 	struct ieee80211_sub_if_data *sdata = NULL;
-@@ -2571,10 +2585,10 @@ __ieee80211_beacon_get(struct ieee80211_
- 
- 	if (sdata->vif.type == NL80211_IFTYPE_AP) {
- 		struct ieee80211_if_ap *ap = &sdata->u.ap;
--		struct beacon_data *beacon = rcu_dereference(ap->beacon);
- 
-+		beacon = rcu_dereference(ap->beacon);
- 		if (beacon) {
--			if (sdata->vif.csa_active) {
-+			if (beacon->csa_counter_offsets[0]) {
- 				if (!is_template)
- 					ieee80211_csa_update_counter(vif);
- 
-@@ -2615,37 +2629,37 @@ __ieee80211_beacon_get(struct ieee80211_
- 	} else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
- 		struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
- 		struct ieee80211_hdr *hdr;
--		struct beacon_data *presp = rcu_dereference(ifibss->presp);
- 
--		if (!presp)
-+		beacon = rcu_dereference(ifibss->presp);
-+		if (!beacon)
- 			goto out;
- 
--		if (sdata->vif.csa_active) {
-+		if (beacon->csa_counter_offsets[0]) {
- 			if (!is_template)
- 				ieee80211_csa_update_counter(vif);
- 
--			ieee80211_set_csa(sdata, presp);
-+			ieee80211_set_csa(sdata, beacon);
- 		}
- 
--		skb = dev_alloc_skb(local->tx_headroom + presp->head_len +
-+		skb = dev_alloc_skb(local->tx_headroom + beacon->head_len +
- 				    local->hw.extra_beacon_tailroom);
- 		if (!skb)
- 			goto out;
- 		skb_reserve(skb, local->tx_headroom);
--		memcpy(skb_put(skb, presp->head_len), presp->head,
--		       presp->head_len);
-+		memcpy(skb_put(skb, beacon->head_len), beacon->head,
-+		       beacon->head_len);
- 
- 		hdr = (struct ieee80211_hdr *) skb->data;
- 		hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
- 						 IEEE80211_STYPE_BEACON);
- 	} else if (ieee80211_vif_is_mesh(&sdata->vif)) {
- 		struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
--		struct beacon_data *bcn = rcu_dereference(ifmsh->beacon);
- 
--		if (!bcn)
-+		beacon = rcu_dereference(ifmsh->beacon);
-+		if (!beacon)
- 			goto out;
- 
--		if (sdata->vif.csa_active) {
-+		if (beacon->csa_counter_offsets[0]) {
- 			if (!is_template)
- 				/* TODO: For mesh csa_counter is in TU, so
- 				 * decrementing it by one isn't correct, but
-@@ -2654,40 +2668,42 @@ __ieee80211_beacon_get(struct ieee80211_
- 				 */
- 				ieee80211_csa_update_counter(vif);
- 
--			ieee80211_set_csa(sdata, bcn);
-+			ieee80211_set_csa(sdata, beacon);
- 		}
- 
- 		if (ifmsh->sync_ops)
--			ifmsh->sync_ops->adjust_tbtt(sdata, bcn);
-+			ifmsh->sync_ops->adjust_tbtt(sdata, beacon);
- 
- 		skb = dev_alloc_skb(local->tx_headroom +
--				    bcn->head_len +
-+				    beacon->head_len +
- 				    256 + /* TIM IE */
--				    bcn->tail_len +
-+				    beacon->tail_len +
- 				    local->hw.extra_beacon_tailroom);
- 		if (!skb)
- 			goto out;
- 		skb_reserve(skb, local->tx_headroom);
--		memcpy(skb_put(skb, bcn->head_len), bcn->head, bcn->head_len);
-+		memcpy(skb_put(skb, beacon->head_len), beacon->head,
-+		       beacon->head_len);
- 		ieee80211_beacon_add_tim(sdata, &ifmsh->ps, skb, is_template);
- 
- 		if (offs) {
--			offs->tim_offset = bcn->head_len;
--			offs->tim_length = skb->len - bcn->head_len;
-+			offs->tim_offset = beacon->head_len;
-+			offs->tim_length = skb->len - beacon->head_len;
- 		}
- 
--		memcpy(skb_put(skb, bcn->tail_len), bcn->tail, bcn->tail_len);
-+		memcpy(skb_put(skb, beacon->tail_len), beacon->tail,
-+		       beacon->tail_len);
- 	} else {
- 		WARN_ON(1);
- 		goto out;
- 	}
- 
- 	/* CSA offsets */
--	if (offs) {
-+	if (offs && beacon) {
- 		int i;
- 
- 		for (i = 0; i < IEEE80211_MAX_CSA_COUNTERS_NUM; i++) {
--			u16 csa_off = sdata->csa_counter_offset_beacon[i];
-+			u16 csa_off = beacon->csa_counter_offsets[i];
- 
- 			if (!csa_off)
- 				continue;
---- a/drivers/net/wireless/rt2x00/rt2800lib.c
-+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
-@@ -947,6 +947,40 @@ static inline u8 rt2800_get_beacon_offse
- 	return BEACON_BASE_TO_OFFSET(rt2800_hw_beacon_base(rt2x00dev, index));
- }
- 
-+static void rt2800_update_beacons_setup(struct rt2x00_dev *rt2x00dev)
-+{
-+	struct data_queue *queue = rt2x00dev->bcn;
-+	struct queue_entry *entry;
-+	int i, bcn_num = 0;
-+	u64 off, reg = 0;
-+	u32 bssid_dw1;
-+
-+	/*
-+	 * Setup offsets of all active beacons in BCN_OFFSET{0,1} registers.
-+	 */
-+	for (i = 0; i < queue->limit; i++) {
-+		entry = &queue->entries[i];
-+		if (!test_bit(ENTRY_BCN_ENABLED, &entry->flags))
-+			continue;
-+		off = rt2800_get_beacon_offset(rt2x00dev, entry->entry_idx);
-+		reg |= off << (8 * bcn_num);
-+		bcn_num++;
-+	}
-+
-+	WARN_ON_ONCE(bcn_num != rt2x00dev->intf_beaconing);
-+
-+	rt2800_register_write(rt2x00dev, BCN_OFFSET0, (u32) reg);
-+	rt2800_register_write(rt2x00dev, BCN_OFFSET1, (u32) (reg >> 32));
-+
-+	/*
-+	 * H/W sends up to MAC_BSSID_DW1_BSS_BCN_NUM + 1 consecutive beacons.
-+	 */
-+	rt2800_register_read(rt2x00dev, MAC_BSSID_DW1, &bssid_dw1);
-+	rt2x00_set_field32(&bssid_dw1, MAC_BSSID_DW1_BSS_BCN_NUM,
-+			   bcn_num > 0 ? bcn_num - 1 : 0);
-+	rt2800_register_write(rt2x00dev, MAC_BSSID_DW1, bssid_dw1);
-+}
-+
- void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc)
- {
- 	struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
-@@ -1003,6 +1037,12 @@ void rt2800_write_beacon(struct queue_en
- 
- 	rt2800_register_multiwrite(rt2x00dev, beacon_base, entry->skb->data,
- 				   entry->skb->len + padding_len);
-+	__set_bit(ENTRY_BCN_ENABLED, &entry->flags);
-+
-+	/*
-+	 * Change global beacons settings.
-+	 */
-+	rt2800_update_beacons_setup(rt2x00dev);
- 
- 	/*
- 	 * Restore beaconing state.
-@@ -1053,8 +1093,13 @@ void rt2800_clear_beacon(struct queue_en
- 	 * Clear beacon.
- 	 */
- 	rt2800_clear_beacon_register(rt2x00dev, entry->entry_idx);
-+	__clear_bit(ENTRY_BCN_ENABLED, &entry->flags);
- 
- 	/*
-+	 * Change global beacons settings.
-+	 */
-+	rt2800_update_beacons_setup(rt2x00dev);
-+	/*
- 	 * Restore beaconing state.
- 	 */
- 	rt2800_register_write(rt2x00dev, BCN_TIME_CFG, orig_reg);
-@@ -1556,7 +1601,7 @@ void rt2800_config_intf(struct rt2x00_de
- 		if (!is_zero_ether_addr((const u8 *)conf->bssid)) {
- 			reg = le32_to_cpu(conf->bssid[1]);
- 			rt2x00_set_field32(&reg, MAC_BSSID_DW1_BSS_ID_MASK, 3);
--			rt2x00_set_field32(&reg, MAC_BSSID_DW1_BSS_BCN_NUM, 7);
-+			rt2x00_set_field32(&reg, MAC_BSSID_DW1_BSS_BCN_NUM, 0);
- 			conf->bssid[1] = cpu_to_le32(reg);
- 		}
- 
-@@ -4517,28 +4562,6 @@ static int rt2800_init_registers(struct 
- 	if (ret)
- 		return ret;
- 
--	rt2800_register_read(rt2x00dev, BCN_OFFSET0, &reg);
--	rt2x00_set_field32(&reg, BCN_OFFSET0_BCN0,
--			   rt2800_get_beacon_offset(rt2x00dev, 0));
--	rt2x00_set_field32(&reg, BCN_OFFSET0_BCN1,
--			   rt2800_get_beacon_offset(rt2x00dev, 1));
--	rt2x00_set_field32(&reg, BCN_OFFSET0_BCN2,
--			   rt2800_get_beacon_offset(rt2x00dev, 2));
--	rt2x00_set_field32(&reg, BCN_OFFSET0_BCN3,
--			   rt2800_get_beacon_offset(rt2x00dev, 3));
--	rt2800_register_write(rt2x00dev, BCN_OFFSET0, reg);
--
--	rt2800_register_read(rt2x00dev, BCN_OFFSET1, &reg);
--	rt2x00_set_field32(&reg, BCN_OFFSET1_BCN4,
--			   rt2800_get_beacon_offset(rt2x00dev, 4));
--	rt2x00_set_field32(&reg, BCN_OFFSET1_BCN5,
--			   rt2800_get_beacon_offset(rt2x00dev, 5));
--	rt2x00_set_field32(&reg, BCN_OFFSET1_BCN6,
--			   rt2800_get_beacon_offset(rt2x00dev, 6));
--	rt2x00_set_field32(&reg, BCN_OFFSET1_BCN7,
--			   rt2800_get_beacon_offset(rt2x00dev, 7));
--	rt2800_register_write(rt2x00dev, BCN_OFFSET1, reg);
--
- 	rt2800_register_write(rt2x00dev, LEGACY_BASIC_RATE, 0x0000013f);
- 	rt2800_register_write(rt2x00dev, HT_BASIC_RATE, 0x00008003);
- 
---- a/drivers/net/wireless/rt2x00/rt2x00dev.c
-+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
-@@ -141,8 +141,11 @@ static void rt2x00lib_intf_scheduled_ite
- 	if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
- 		return;
- 
--	if (test_and_clear_bit(DELAYED_UPDATE_BEACON, &intf->delayed_flags))
-+	if (test_and_clear_bit(DELAYED_UPDATE_BEACON, &intf->delayed_flags)) {
-+		mutex_lock(&intf->beacon_skb_mutex);
- 		rt2x00queue_update_beacon(rt2x00dev, vif);
-+		mutex_unlock(&intf->beacon_skb_mutex);
-+	}
- }
- 
- static void rt2x00lib_intf_scheduled(struct work_struct *work)
-@@ -216,7 +219,7 @@ static void rt2x00lib_beaconupdate_iter(
- 	 * never be called for USB devices.
- 	 */
- 	WARN_ON(rt2x00_is_usb(rt2x00dev));
--	rt2x00queue_update_beacon_locked(rt2x00dev, vif);
-+	rt2x00queue_update_beacon(rt2x00dev, vif);
- }
- 
- void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev)
---- a/drivers/net/wireless/rt2x00/rt2x00mac.c
-+++ b/drivers/net/wireless/rt2x00/rt2x00mac.c
-@@ -487,6 +487,8 @@ int rt2x00mac_set_key(struct ieee80211_h
- 	crypto.cipher = rt2x00crypto_key_to_cipher(key);
- 	if (crypto.cipher == CIPHER_NONE)
- 		return -EOPNOTSUPP;
-+	if (crypto.cipher == CIPHER_TKIP && rt2x00_is_usb(rt2x00dev))
-+		return -EOPNOTSUPP;
- 
- 	crypto.cmd = cmd;
- 
-@@ -624,25 +626,24 @@ void rt2x00mac_bss_info_changed(struct i
- 	 * Start/stop beaconing.
- 	 */
- 	if (changes & BSS_CHANGED_BEACON_ENABLED) {
-+		mutex_lock(&intf->beacon_skb_mutex);
- 		if (!bss_conf->enable_beacon && intf->enable_beacon) {
- 			rt2x00dev->intf_beaconing--;
- 			intf->enable_beacon = false;
--			/*
--			 * Clear beacon in the H/W for this vif. This is needed
--			 * to disable beaconing on this particular interface
--			 * and keep it running on other interfaces.
--			 */
--			rt2x00queue_clear_beacon(rt2x00dev, vif);
- 
- 			if (rt2x00dev->intf_beaconing == 0) {
- 				/*
- 				 * Last beaconing interface disabled
- 				 * -> stop beacon queue.
- 				 */
--				mutex_lock(&intf->beacon_skb_mutex);
- 				rt2x00queue_stop_queue(rt2x00dev->bcn);
--				mutex_unlock(&intf->beacon_skb_mutex);
- 			}
-+			/*
-+			 * Clear beacon in the H/W for this vif. This is needed
-+			 * to disable beaconing on this particular interface
-+			 * and keep it running on other interfaces.
-+			 */
-+			rt2x00queue_clear_beacon(rt2x00dev, vif);
- 		} else if (bss_conf->enable_beacon && !intf->enable_beacon) {
- 			rt2x00dev->intf_beaconing++;
- 			intf->enable_beacon = true;
-@@ -658,11 +659,10 @@ void rt2x00mac_bss_info_changed(struct i
- 				 * First beaconing interface enabled
- 				 * -> start beacon queue.
- 				 */
--				mutex_lock(&intf->beacon_skb_mutex);
- 				rt2x00queue_start_queue(rt2x00dev->bcn);
--				mutex_unlock(&intf->beacon_skb_mutex);
- 			}
- 		}
-+		mutex_unlock(&intf->beacon_skb_mutex);
- 	}
- 
- 	/*
---- a/drivers/net/wireless/rt2x00/rt2x00queue.c
-+++ b/drivers/net/wireless/rt2x00/rt2x00queue.c
-@@ -754,8 +754,6 @@ int rt2x00queue_clear_beacon(struct rt2x
- 	if (unlikely(!intf->beacon))
- 		return -ENOBUFS;
- 
--	mutex_lock(&intf->beacon_skb_mutex);
--
- 	/*
- 	 * Clean up the beacon skb.
- 	 */
-@@ -768,13 +766,11 @@ int rt2x00queue_clear_beacon(struct rt2x
- 	if (rt2x00dev->ops->lib->clear_beacon)
- 		rt2x00dev->ops->lib->clear_beacon(intf->beacon);
- 
--	mutex_unlock(&intf->beacon_skb_mutex);
--
- 	return 0;
- }
- 
--int rt2x00queue_update_beacon_locked(struct rt2x00_dev *rt2x00dev,
--				     struct ieee80211_vif *vif)
-+int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev,
-+			      struct ieee80211_vif *vif)
- {
- 	struct rt2x00_intf *intf = vif_to_intf(vif);
- 	struct skb_frame_desc *skbdesc;
-@@ -815,19 +811,6 @@ int rt2x00queue_update_beacon_locked(str
- 
- }
- 
--int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev,
--			      struct ieee80211_vif *vif)
--{
--	struct rt2x00_intf *intf = vif_to_intf(vif);
--	int ret;
--
--	mutex_lock(&intf->beacon_skb_mutex);
--	ret = rt2x00queue_update_beacon_locked(rt2x00dev, vif);
--	mutex_unlock(&intf->beacon_skb_mutex);
--
--	return ret;
--}
--
- bool rt2x00queue_for_each_entry(struct data_queue *queue,
- 				enum queue_index start,
- 				enum queue_index end,
---- a/drivers/net/wireless/rt2x00/rt2x00queue.h
-+++ b/drivers/net/wireless/rt2x00/rt2x00queue.h
-@@ -353,6 +353,7 @@ struct txentry_desc {
-  */
- enum queue_entry_flags {
- 	ENTRY_BCN_ASSIGNED,
-+	ENTRY_BCN_ENABLED,
- 	ENTRY_OWNER_DEVICE_DATA,
- 	ENTRY_DATA_PENDING,
- 	ENTRY_DATA_IO_FAILED,
---- a/drivers/net/wireless/ath/ath9k/main.c
-+++ b/drivers/net/wireless/ath/ath9k/main.c
-@@ -1757,7 +1757,6 @@ out:
- void ath9k_update_p2p_ps(struct ath_softc *sc, struct ieee80211_vif *vif)
- {
- 	struct ath_vif *avp = (void *)vif->drv_priv;
--	unsigned long flags;
- 	u32 tsf;
- 
- 	if (!sc->p2p_ps_timer)
-@@ -1767,14 +1766,9 @@ void ath9k_update_p2p_ps(struct ath_soft
- 		return;
- 
- 	sc->p2p_ps_vif = avp;
--
--	spin_lock_irqsave(&sc->sc_pm_lock, flags);
--	if (!(sc->ps_flags & PS_BEACON_SYNC)) {
--		tsf = ath9k_hw_gettsf32(sc->sc_ah);
--		ieee80211_parse_p2p_noa(&vif->bss_conf.p2p_noa_attr, &avp->noa, tsf);
--		ath9k_update_p2p_ps_timer(sc, avp);
--	}
--	spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
-+	tsf = ath9k_hw_gettsf32(sc->sc_ah);
-+	ieee80211_parse_p2p_noa(&vif->bss_conf.p2p_noa_attr, &avp->noa, tsf);
-+	ath9k_update_p2p_ps_timer(sc, avp);
- }
- 
- static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
-@@ -1791,6 +1785,7 @@ static void ath9k_bss_info_changed(struc
- 	struct ath_hw *ah = sc->sc_ah;
- 	struct ath_common *common = ath9k_hw_common(ah);
- 	struct ath_vif *avp = (void *)vif->drv_priv;
-+	unsigned long flags;
- 	int slottime;
- 
- 	ath9k_ps_wakeup(sc);
-@@ -1853,7 +1848,10 @@ static void ath9k_bss_info_changed(struc
- 
- 	if (changed & BSS_CHANGED_P2P_PS) {
- 		spin_lock_bh(&sc->sc_pcu_lock);
--		ath9k_update_p2p_ps(sc, vif);
-+		spin_lock_irqsave(&sc->sc_pm_lock, flags);
-+		if (!(sc->ps_flags & PS_BEACON_SYNC))
-+			ath9k_update_p2p_ps(sc, vif);
-+		spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
- 		spin_unlock_bh(&sc->sc_pcu_lock);
- 	}
- 
-@@ -2232,14 +2230,6 @@ static void ath9k_sw_scan_complete(struc
- 	clear_bit(ATH_OP_SCANNING, &common->op_flags);
- }
- 
--static void ath9k_channel_switch_beacon(struct ieee80211_hw *hw,
--					struct ieee80211_vif *vif,
--					struct cfg80211_chan_def *chandef)
--{
--	/* depend on vif->csa_active only */
--	return;
--}
--
- struct ieee80211_ops ath9k_ops = {
- 	.tx 		    = ath9k_tx,
- 	.start 		    = ath9k_start,
-@@ -2287,5 +2277,4 @@ struct ieee80211_ops ath9k_ops = {
- #endif
- 	.sw_scan_start	    = ath9k_sw_scan_start,
- 	.sw_scan_complete   = ath9k_sw_scan_complete,
--	.channel_switch_beacon     = ath9k_channel_switch_beacon,
- };
---- a/drivers/net/wireless/ath/ath10k/mac.c
-+++ b/drivers/net/wireless/ath/ath10k/mac.c
-@@ -4142,14 +4142,6 @@ static int ath10k_set_bitrate_mask(struc
- 					   fixed_nss, force_sgi);
- }
- 
--static void ath10k_channel_switch_beacon(struct ieee80211_hw *hw,
--					 struct ieee80211_vif *vif,
--					 struct cfg80211_chan_def *chandef)
--{
--	/* there's no need to do anything here. vif->csa_active is enough */
--	return;
--}
--
- static void ath10k_sta_rc_update(struct ieee80211_hw *hw,
- 				 struct ieee80211_vif *vif,
- 				 struct ieee80211_sta *sta,
-@@ -4256,7 +4248,6 @@ static const struct ieee80211_ops ath10k
- 	.restart_complete		= ath10k_restart_complete,
- 	.get_survey			= ath10k_get_survey,
- 	.set_bitrate_mask		= ath10k_set_bitrate_mask,
--	.channel_switch_beacon		= ath10k_channel_switch_beacon,
- 	.sta_rc_update			= ath10k_sta_rc_update,
- 	.get_tsf			= ath10k_get_tsf,
- #ifdef CONFIG_PM
---- a/net/mac80211/cfg.c
-+++ b/net/mac80211/cfg.c
-@@ -468,327 +468,6 @@ void sta_set_rate_info_rx(struct sta_inf
- 		rinfo->flags |= RATE_INFO_FLAGS_160_MHZ_WIDTH;
- }
- 
--static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
--{
--	struct ieee80211_sub_if_data *sdata = sta->sdata;
--	struct ieee80211_local *local = sdata->local;
--	struct rate_control_ref *ref = local->rate_ctrl;
--	struct timespec uptime;
--	u64 packets = 0;
--	u32 thr = 0;
--	int i, ac;
--
--	sinfo->generation = sdata->local->sta_generation;
--
--	sinfo->filled = STATION_INFO_INACTIVE_TIME |
--			STATION_INFO_RX_BYTES64 |
--			STATION_INFO_TX_BYTES64 |
--			STATION_INFO_RX_PACKETS |
--			STATION_INFO_TX_PACKETS |
--			STATION_INFO_TX_RETRIES |
--			STATION_INFO_TX_FAILED |
--			STATION_INFO_TX_BITRATE |
--			STATION_INFO_RX_BITRATE |
--			STATION_INFO_RX_DROP_MISC |
--			STATION_INFO_BSS_PARAM |
--			STATION_INFO_CONNECTED_TIME |
--			STATION_INFO_STA_FLAGS |
--			STATION_INFO_BEACON_LOSS_COUNT;
--
--	do_posix_clock_monotonic_gettime(&uptime);
--	sinfo->connected_time = uptime.tv_sec - sta->last_connected;
--
--	sinfo->inactive_time = jiffies_to_msecs(jiffies - sta->last_rx);
--	sinfo->tx_bytes = 0;
--	for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
--		sinfo->tx_bytes += sta->tx_bytes[ac];
--		packets += sta->tx_packets[ac];
--	}
--	sinfo->tx_packets = packets;
--	sinfo->rx_bytes = sta->rx_bytes;
--	sinfo->rx_packets = sta->rx_packets;
--	sinfo->tx_retries = sta->tx_retry_count;
--	sinfo->tx_failed = sta->tx_retry_failed;
--	sinfo->rx_dropped_misc = sta->rx_dropped;
--	sinfo->beacon_loss_count = sta->beacon_loss_count;
--
--	if ((sta->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) ||
--	    (sta->local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC)) {
--		sinfo->filled |= STATION_INFO_SIGNAL | STATION_INFO_SIGNAL_AVG;
--		if (!local->ops->get_rssi ||
--		    drv_get_rssi(local, sdata, &sta->sta, &sinfo->signal))
--			sinfo->signal = (s8)sta->last_signal;
--		sinfo->signal_avg = (s8) -ewma_read(&sta->avg_signal);
--	}
--	if (sta->chains) {
--		sinfo->filled |= STATION_INFO_CHAIN_SIGNAL |
--				 STATION_INFO_CHAIN_SIGNAL_AVG;
--
--		sinfo->chains = sta->chains;
--		for (i = 0; i < ARRAY_SIZE(sinfo->chain_signal); i++) {
--			sinfo->chain_signal[i] = sta->chain_signal_last[i];
--			sinfo->chain_signal_avg[i] =
--				(s8) -ewma_read(&sta->chain_signal_avg[i]);
--		}
--	}
--
--	sta_set_rate_info_tx(sta, &sta->last_tx_rate, &sinfo->txrate);
--	sta_set_rate_info_rx(sta, &sinfo->rxrate);
--
--	if (ieee80211_vif_is_mesh(&sdata->vif)) {
--#ifdef CPTCFG_MAC80211_MESH
--		sinfo->filled |= STATION_INFO_LLID |
--				 STATION_INFO_PLID |
--				 STATION_INFO_PLINK_STATE |
--				 STATION_INFO_LOCAL_PM |
--				 STATION_INFO_PEER_PM |
--				 STATION_INFO_NONPEER_PM;
--
--		sinfo->llid = sta->llid;
--		sinfo->plid = sta->plid;
--		sinfo->plink_state = sta->plink_state;
--		if (test_sta_flag(sta, WLAN_STA_TOFFSET_KNOWN)) {
--			sinfo->filled |= STATION_INFO_T_OFFSET;
--			sinfo->t_offset = sta->t_offset;
--		}
--		sinfo->local_pm = sta->local_pm;
--		sinfo->peer_pm = sta->peer_pm;
--		sinfo->nonpeer_pm = sta->nonpeer_pm;
--#endif
--	}
--
--	sinfo->bss_param.flags = 0;
--	if (sdata->vif.bss_conf.use_cts_prot)
--		sinfo->bss_param.flags |= BSS_PARAM_FLAGS_CTS_PROT;
--	if (sdata->vif.bss_conf.use_short_preamble)
--		sinfo->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_PREAMBLE;
--	if (sdata->vif.bss_conf.use_short_slot)
--		sinfo->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_SLOT_TIME;
--	sinfo->bss_param.dtim_period = sdata->local->hw.conf.ps_dtim_period;
--	sinfo->bss_param.beacon_interval = sdata->vif.bss_conf.beacon_int;
--
--	sinfo->sta_flags.set = 0;
--	sinfo->sta_flags.mask = BIT(NL80211_STA_FLAG_AUTHORIZED) |
--				BIT(NL80211_STA_FLAG_SHORT_PREAMBLE) |
--				BIT(NL80211_STA_FLAG_WME) |
--				BIT(NL80211_STA_FLAG_MFP) |
--				BIT(NL80211_STA_FLAG_AUTHENTICATED) |
--				BIT(NL80211_STA_FLAG_ASSOCIATED) |
--				BIT(NL80211_STA_FLAG_TDLS_PEER);
--	if (test_sta_flag(sta, WLAN_STA_AUTHORIZED))
--		sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_AUTHORIZED);
--	if (test_sta_flag(sta, WLAN_STA_SHORT_PREAMBLE))
--		sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_SHORT_PREAMBLE);
--	if (test_sta_flag(sta, WLAN_STA_WME))
--		sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_WME);
--	if (test_sta_flag(sta, WLAN_STA_MFP))
--		sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_MFP);
--	if (test_sta_flag(sta, WLAN_STA_AUTH))
--		sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_AUTHENTICATED);
--	if (test_sta_flag(sta, WLAN_STA_ASSOC))
--		sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_ASSOCIATED);
--	if (test_sta_flag(sta, WLAN_STA_TDLS_PEER))
--		sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_TDLS_PEER);
--
--	/* check if the driver has a SW RC implementation */
--	if (ref && ref->ops->get_expected_throughput)
--		thr = ref->ops->get_expected_throughput(sta->rate_ctrl_priv);
--	else
--		thr = drv_get_expected_throughput(local, &sta->sta);
--
--	if (thr != 0) {
--		sinfo->filled |= STATION_INFO_EXPECTED_THROUGHPUT;
--		sinfo->expected_throughput = thr;
--	}
--}
--
--static const char ieee80211_gstrings_sta_stats[][ETH_GSTRING_LEN] = {
--	"rx_packets", "rx_bytes", "wep_weak_iv_count",
--	"rx_duplicates", "rx_fragments", "rx_dropped",
--	"tx_packets", "tx_bytes", "tx_fragments",
--	"tx_filtered", "tx_retry_failed", "tx_retries",
--	"beacon_loss", "sta_state", "txrate", "rxrate", "signal",
--	"channel", "noise", "ch_time", "ch_time_busy",
--	"ch_time_ext_busy", "ch_time_rx", "ch_time_tx"
--};
--#define STA_STATS_LEN	ARRAY_SIZE(ieee80211_gstrings_sta_stats)
--
--static int ieee80211_get_et_sset_count(struct wiphy *wiphy,
--				       struct net_device *dev,
--				       int sset)
--{
--	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
--	int rv = 0;
--
--	if (sset == ETH_SS_STATS)
--		rv += STA_STATS_LEN;
--
--	rv += drv_get_et_sset_count(sdata, sset);
--
--	if (rv == 0)
--		return -EOPNOTSUPP;
--	return rv;
--}
--
--static void ieee80211_get_et_stats(struct wiphy *wiphy,
--				   struct net_device *dev,
--				   struct ethtool_stats *stats,
--				   u64 *data)
--{
--	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
--	struct ieee80211_chanctx_conf *chanctx_conf;
--	struct ieee80211_channel *channel;
--	struct sta_info *sta;
--	struct ieee80211_local *local = sdata->local;
--	struct station_info sinfo;
--	struct survey_info survey;
--	int i, q;
--#define STA_STATS_SURVEY_LEN 7
--
--	memset(data, 0, sizeof(u64) * STA_STATS_LEN);
--
--#define ADD_STA_STATS(sta)				\
--	do {						\
--		data[i++] += sta->rx_packets;		\
--		data[i++] += sta->rx_bytes;		\
--		data[i++] += sta->wep_weak_iv_count;	\
--		data[i++] += sta->num_duplicates;	\
--		data[i++] += sta->rx_fragments;		\
--		data[i++] += sta->rx_dropped;		\
--							\
--		data[i++] += sinfo.tx_packets;		\
--		data[i++] += sinfo.tx_bytes;		\
--		data[i++] += sta->tx_fragments;		\
--		data[i++] += sta->tx_filtered_count;	\
--		data[i++] += sta->tx_retry_failed;	\
--		data[i++] += sta->tx_retry_count;	\
--		data[i++] += sta->beacon_loss_count;	\
--	} while (0)
--
--	/* For Managed stations, find the single station based on BSSID
--	 * and use that.  For interface types, iterate through all available
--	 * stations and add stats for any station that is assigned to this
--	 * network device.
--	 */
--
--	mutex_lock(&local->sta_mtx);
--
--	if (sdata->vif.type == NL80211_IFTYPE_STATION) {
--		sta = sta_info_get_bss(sdata, sdata->u.mgd.bssid);
--
--		if (!(sta && !WARN_ON(sta->sdata->dev != dev)))
--			goto do_survey;
--
--		sinfo.filled = 0;
--		sta_set_sinfo(sta, &sinfo);
--
--		i = 0;
--		ADD_STA_STATS(sta);
--
--		data[i++] = sta->sta_state;
--
--
--		if (sinfo.filled & STATION_INFO_TX_BITRATE)
--			data[i] = 100000 *
--				cfg80211_calculate_bitrate(&sinfo.txrate);
--		i++;
--		if (sinfo.filled & STATION_INFO_RX_BITRATE)
--			data[i] = 100000 *
--				cfg80211_calculate_bitrate(&sinfo.rxrate);
--		i++;
--
--		if (sinfo.filled & STATION_INFO_SIGNAL_AVG)
--			data[i] = (u8)sinfo.signal_avg;
--		i++;
--	} else {
--		list_for_each_entry(sta, &local->sta_list, list) {
--			/* Make sure this station belongs to the proper dev */
--			if (sta->sdata->dev != dev)
--				continue;
--
--			sinfo.filled = 0;
--			sta_set_sinfo(sta, &sinfo);
--			i = 0;
--			ADD_STA_STATS(sta);
--		}
--	}
--
--do_survey:
--	i = STA_STATS_LEN - STA_STATS_SURVEY_LEN;
--	/* Get survey stats for current channel */
--	survey.filled = 0;
--
--	rcu_read_lock();
--	chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
--	if (chanctx_conf)
--		channel = chanctx_conf->def.chan;
--	else
--		channel = NULL;
--	rcu_read_unlock();
--
--	if (channel) {
--		q = 0;
--		do {
--			survey.filled = 0;
--			if (drv_get_survey(local, q, &survey) != 0) {
--				survey.filled = 0;
--				break;
--			}
--			q++;
--		} while (channel != survey.channel);
--	}
--
--	if (survey.filled)
--		data[i++] = survey.channel->center_freq;
--	else
--		data[i++] = 0;
--	if (survey.filled & SURVEY_INFO_NOISE_DBM)
--		data[i++] = (u8)survey.noise;
--	else
--		data[i++] = -1LL;
--	if (survey.filled & SURVEY_INFO_CHANNEL_TIME)
--		data[i++] = survey.channel_time;
--	else
--		data[i++] = -1LL;
--	if (survey.filled & SURVEY_INFO_CHANNEL_TIME_BUSY)
--		data[i++] = survey.channel_time_busy;
--	else
--		data[i++] = -1LL;
--	if (survey.filled & SURVEY_INFO_CHANNEL_TIME_EXT_BUSY)
--		data[i++] = survey.channel_time_ext_busy;
--	else
--		data[i++] = -1LL;
--	if (survey.filled & SURVEY_INFO_CHANNEL_TIME_RX)
--		data[i++] = survey.channel_time_rx;
--	else
--		data[i++] = -1LL;
--	if (survey.filled & SURVEY_INFO_CHANNEL_TIME_TX)
--		data[i++] = survey.channel_time_tx;
--	else
--		data[i++] = -1LL;
--
--	mutex_unlock(&local->sta_mtx);
--
--	if (WARN_ON(i != STA_STATS_LEN))
--		return;
--
--	drv_get_et_stats(sdata, stats, &(data[STA_STATS_LEN]));
--}
--
--static void ieee80211_get_et_strings(struct wiphy *wiphy,
--				     struct net_device *dev,
--				     u32 sset, u8 *data)
--{
--	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
--	int sz_sta_stats = 0;
--
--	if (sset == ETH_SS_STATS) {
--		sz_sta_stats = sizeof(ieee80211_gstrings_sta_stats);
--		memcpy(data, ieee80211_gstrings_sta_stats, sz_sta_stats);
--	}
--	drv_get_et_strings(sdata, sset, &(data[sz_sta_stats]));
--}
--
- static int ieee80211_dump_station(struct wiphy *wiphy, struct net_device *dev,
- 				  int idx, u8 *mac, struct station_info *sinfo)
- {
-@@ -875,7 +554,8 @@ static int ieee80211_set_monitor_channel
- }
- 
- static int ieee80211_set_probe_resp(struct ieee80211_sub_if_data *sdata,
--				    const u8 *resp, size_t resp_len)
-+				    const u8 *resp, size_t resp_len,
-+				    const struct ieee80211_csa_settings *csa)
- {
- 	struct probe_resp *new, *old;
- 
-@@ -891,6 +571,11 @@ static int ieee80211_set_probe_resp(stru
- 	new->len = resp_len;
- 	memcpy(new->data, resp, resp_len);
- 
-+	if (csa)
-+		memcpy(new->csa_counter_offsets, csa->counter_offsets_presp,
-+		       csa->n_counter_offsets_presp *
-+		       sizeof(new->csa_counter_offsets[0]));
-+
- 	rcu_assign_pointer(sdata->u.ap.probe_resp, new);
- 	if (old)
- 		kfree_rcu(old, rcu_head);
-@@ -899,7 +584,8 @@ static int ieee80211_set_probe_resp(stru
- }
- 
- static int ieee80211_assign_beacon(struct ieee80211_sub_if_data *sdata,
--				   struct cfg80211_beacon_data *params)
-+				   struct cfg80211_beacon_data *params,
-+				   const struct ieee80211_csa_settings *csa)
- {
- 	struct beacon_data *new, *old;
- 	int new_head_len, new_tail_len;
-@@ -943,6 +629,13 @@ static int ieee80211_assign_beacon(struc
- 	new->head_len = new_head_len;
- 	new->tail_len = new_tail_len;
- 
-+	if (csa) {
-+		new->csa_current_counter = csa->count;
-+		memcpy(new->csa_counter_offsets, csa->counter_offsets_beacon,
-+		       csa->n_counter_offsets_beacon *
-+		       sizeof(new->csa_counter_offsets[0]));
-+	}
-+
- 	/* copy in head */
- 	if (params->head)
- 		memcpy(new->head, params->head, new_head_len);
-@@ -957,7 +650,7 @@ static int ieee80211_assign_beacon(struc
- 			memcpy(new->tail, old->tail, new_tail_len);
- 
- 	err = ieee80211_set_probe_resp(sdata, params->probe_resp,
--				       params->probe_resp_len);
-+				       params->probe_resp_len, csa);
- 	if (err < 0)
- 		return err;
- 	if (err == 0)
-@@ -1042,7 +735,7 @@ static int ieee80211_start_ap(struct wip
- 		sdata->vif.bss_conf.p2p_noa_attr.oppps_ctwindow |=
- 					IEEE80211_P2P_OPPPS_ENABLE_BIT;
- 
--	err = ieee80211_assign_beacon(sdata, &params->beacon);
-+	err = ieee80211_assign_beacon(sdata, &params->beacon, NULL);
- 	if (err < 0) {
- 		ieee80211_vif_release_channel(sdata);
- 		return err;
-@@ -1090,7 +783,7 @@ static int ieee80211_change_beacon(struc
- 	if (!old)
- 		return -ENOENT;
- 
--	err = ieee80211_assign_beacon(sdata, params);
-+	err = ieee80211_assign_beacon(sdata, params, NULL);
- 	if (err < 0)
- 		return err;
- 	ieee80211_bss_info_change_notify(sdata, err);
-@@ -3073,7 +2766,8 @@ static int ieee80211_set_after_csa_beaco
- 
- 	switch (sdata->vif.type) {
- 	case NL80211_IFTYPE_AP:
--		err = ieee80211_assign_beacon(sdata, sdata->u.ap.next_beacon);
-+		err = ieee80211_assign_beacon(sdata, sdata->u.ap.next_beacon,
-+					      NULL);
- 		kfree(sdata->u.ap.next_beacon);
- 		sdata->u.ap.next_beacon = NULL;
- 
-@@ -3176,6 +2870,7 @@ static int ieee80211_set_csa_beacon(stru
- 				    struct cfg80211_csa_settings *params,
- 				    u32 *changed)
- {
-+	struct ieee80211_csa_settings csa = {};
- 	int err;
- 
- 	switch (sdata->vif.type) {
-@@ -3210,20 +2905,13 @@ static int ieee80211_set_csa_beacon(stru
- 		     IEEE80211_MAX_CSA_COUNTERS_NUM))
- 			return -EINVAL;
- 
--		/* make sure we don't have garbage in other counters */
--		memset(sdata->csa_counter_offset_beacon, 0,
--		       sizeof(sdata->csa_counter_offset_beacon));
--		memset(sdata->csa_counter_offset_presp, 0,
--		       sizeof(sdata->csa_counter_offset_presp));
--
--		memcpy(sdata->csa_counter_offset_beacon,
--		       params->counter_offsets_beacon,
--		       params->n_counter_offsets_beacon * sizeof(u16));
--		memcpy(sdata->csa_counter_offset_presp,
--		       params->counter_offsets_presp,
--		       params->n_counter_offsets_presp * sizeof(u16));
-+		csa.counter_offsets_beacon = params->counter_offsets_beacon;
-+		csa.counter_offsets_presp = params->counter_offsets_presp;
-+		csa.n_counter_offsets_beacon = params->n_counter_offsets_beacon;
-+		csa.n_counter_offsets_presp = params->n_counter_offsets_presp;
-+		csa.count = params->count;
- 
--		err = ieee80211_assign_beacon(sdata, &params->beacon_csa);
-+		err = ieee80211_assign_beacon(sdata, &params->beacon_csa, &csa);
- 		if (err < 0) {
- 			kfree(sdata->u.ap.next_beacon);
- 			return err;
-@@ -3367,7 +3055,6 @@ __ieee80211_channel_switch(struct wiphy 
- 	sdata->csa_radar_required = params->radar_required;
- 	sdata->csa_chandef = params->chandef;
- 	sdata->csa_block_tx = params->block_tx;
--	sdata->csa_current_counter = params->count;
- 	sdata->vif.csa_active = true;
- 
- 	if (sdata->csa_block_tx)
-@@ -3515,10 +3202,23 @@ static int ieee80211_mgmt_tx(struct wiph
- 	     sdata->vif.type == NL80211_IFTYPE_ADHOC) &&
- 	    params->n_csa_offsets) {
- 		int i;
--		u8 c = sdata->csa_current_counter;
-+		struct beacon_data *beacon = NULL;
-+
-+		rcu_read_lock();
- 
--		for (i = 0; i < params->n_csa_offsets; i++)
--			data[params->csa_offsets[i]] = c;
-+		if (sdata->vif.type == NL80211_IFTYPE_AP)
-+			beacon = rcu_dereference(sdata->u.ap.beacon);
-+		else if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
-+			beacon = rcu_dereference(sdata->u.ibss.presp);
-+		else if (ieee80211_vif_is_mesh(&sdata->vif))
-+			beacon = rcu_dereference(sdata->u.mesh.beacon);
-+
-+		if (beacon)
-+			for (i = 0; i < params->n_csa_offsets; i++)
-+				data[params->csa_offsets[i]] =
-+					beacon->csa_current_counter;
-+
-+		rcu_read_unlock();
- 	}
- 
- 	IEEE80211_SKB_CB(skb)->flags = flags;
-@@ -3598,21 +3298,6 @@ static int ieee80211_get_antenna(struct 
- 	return drv_get_antenna(local, tx_ant, rx_ant);
- }
- 
--static int ieee80211_set_ringparam(struct wiphy *wiphy, u32 tx, u32 rx)
--{
--	struct ieee80211_local *local = wiphy_priv(wiphy);
--
--	return drv_set_ringparam(local, tx, rx);
--}
--
--static void ieee80211_get_ringparam(struct wiphy *wiphy,
--				    u32 *tx, u32 *tx_max, u32 *rx, u32 *rx_max)
--{
--	struct ieee80211_local *local = wiphy_priv(wiphy);
--
--	drv_get_ringparam(local, tx, tx_max, rx, rx_max);
--}
--
- static int ieee80211_set_rekey_data(struct wiphy *wiphy,
- 				    struct net_device *dev,
- 				    struct cfg80211_gtk_rekey_data *data)
-@@ -3844,8 +3529,6 @@ const struct cfg80211_ops mac80211_confi
- 	.mgmt_frame_register = ieee80211_mgmt_frame_register,
- 	.set_antenna = ieee80211_set_antenna,
- 	.get_antenna = ieee80211_get_antenna,
--	.set_ringparam = ieee80211_set_ringparam,
--	.get_ringparam = ieee80211_get_ringparam,
- 	.set_rekey_data = ieee80211_set_rekey_data,
- 	.tdls_oper = ieee80211_tdls_oper,
- 	.tdls_mgmt = ieee80211_tdls_mgmt,
-@@ -3854,9 +3537,6 @@ const struct cfg80211_ops mac80211_confi
- #ifdef CONFIG_PM
- 	.set_wakeup = ieee80211_set_wakeup,
- #endif
--	.get_et_sset_count = ieee80211_get_et_sset_count,
--	.get_et_stats = ieee80211_get_et_stats,
--	.get_et_strings = ieee80211_get_et_strings,
- 	.get_channel = ieee80211_cfg_get_channel,
- 	.start_radar_detection = ieee80211_start_radar_detection,
- 	.channel_switch = ieee80211_channel_switch,
---- a/net/mac80211/debugfs_sta.c
-+++ b/net/mac80211/debugfs_sta.c
-@@ -587,7 +587,6 @@ void ieee80211_sta_debugfs_add(struct st
- 	DEBUGFS_ADD_COUNTER(tx_filtered, tx_filtered_count);
- 	DEBUGFS_ADD_COUNTER(tx_retry_failed, tx_retry_failed);
- 	DEBUGFS_ADD_COUNTER(tx_retry_count, tx_retry_count);
--	DEBUGFS_ADD_COUNTER(wep_weak_iv_count, wep_weak_iv_count);
- 
- 	if (sizeof(sta->driver_buffered_tids) == sizeof(u32))
- 		debugfs_create_x32("driver_buffered_tids", 0400,
---- a/net/mac80211/wep.c
-+++ b/net/mac80211/wep.c
-@@ -271,22 +271,6 @@ static int ieee80211_wep_decrypt(struct 
- 	return ret;
- }
- 
--
--static bool ieee80211_wep_is_weak_iv(struct sk_buff *skb,
--				     struct ieee80211_key *key)
--{
--	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
--	unsigned int hdrlen;
--	u8 *ivpos;
--	u32 iv;
--
--	hdrlen = ieee80211_hdrlen(hdr->frame_control);
--	ivpos = skb->data + hdrlen;
--	iv = (ivpos[0] << 16) | (ivpos[1] << 8) | ivpos[2];
--
--	return ieee80211_wep_weak_iv(iv, key->conf.keylen);
--}
--
- ieee80211_rx_result
- ieee80211_crypto_wep_decrypt(struct ieee80211_rx_data *rx)
- {
-@@ -301,16 +285,12 @@ ieee80211_crypto_wep_decrypt(struct ieee
- 	if (!(status->flag & RX_FLAG_DECRYPTED)) {
- 		if (skb_linearize(rx->skb))
- 			return RX_DROP_UNUSABLE;
--		if (rx->sta && ieee80211_wep_is_weak_iv(rx->skb, rx->key))
--			rx->sta->wep_weak_iv_count++;
- 		if (ieee80211_wep_decrypt(rx->local, rx->skb, rx->key))
- 			return RX_DROP_UNUSABLE;
- 	} else if (!(status->flag & RX_FLAG_IV_STRIPPED)) {
- 		if (!pskb_may_pull(rx->skb, ieee80211_hdrlen(fc) +
- 					    IEEE80211_WEP_IV_LEN))
- 			return RX_DROP_UNUSABLE;
--		if (rx->sta && ieee80211_wep_is_weak_iv(rx->skb, rx->key))
--			rx->sta->wep_weak_iv_count++;
- 		ieee80211_wep_remove_iv(rx->local, rx->skb, rx->key);
- 		/* remove ICV */
- 		if (pskb_trim(rx->skb, rx->skb->len - IEEE80211_WEP_ICV_LEN))
---- a/include/net/cfg80211.h
-+++ b/include/net/cfg80211.h
-@@ -2278,16 +2278,6 @@ struct cfg80211_qos_map {
-  *
-  * @set_noack_map: Set the NoAck Map for the TIDs.
-  *
-- * @get_et_sset_count:  Ethtool API to get string-set count.
-- *	See @ethtool_ops.get_sset_count
-- *
-- * @get_et_stats:  Ethtool API to get a set of u64 stats.
-- *	See @ethtool_ops.get_ethtool_stats
-- *
-- * @get_et_strings:  Ethtool API to get a set of strings to describe stats
-- *	and perhaps other supported types of ethtool data-sets.
-- *	See @ethtool_ops.get_strings
-- *
-  * @get_channel: Get the current operating channel for the virtual interface.
-  *	For monitor interfaces, it should return %NULL unless there's a single
-  *	current monitoring channel.
-@@ -2529,13 +2519,6 @@ struct cfg80211_ops {
- 				  struct net_device *dev,
- 				  u16 noack_map);
- 
--	int	(*get_et_sset_count)(struct wiphy *wiphy,
--				     struct net_device *dev, int sset);
--	void	(*get_et_stats)(struct wiphy *wiphy, struct net_device *dev,
--				struct ethtool_stats *stats, u64 *data);
--	void	(*get_et_strings)(struct wiphy *wiphy, struct net_device *dev,
--				  u32 sset, u8 *data);
--
- 	int	(*get_channel)(struct wiphy *wiphy,
- 			       struct wireless_dev *wdev,
- 			       struct cfg80211_chan_def *chandef);
-@@ -4846,6 +4829,10 @@ void cfg80211_stop_iface(struct wiphy *w
-  */
- void cfg80211_shutdown_all_interfaces(struct wiphy *wiphy);
- 
-+
-+/* ethtool helper */
-+void cfg80211_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info);
-+
- /* Logging, debugging and troubleshooting/diagnostic helpers. */
- 
- /* wiphy_printk helpers, similar to dev_printk */
---- a/net/mac80211/Makefile
-+++ b/net/mac80211/Makefile
-@@ -17,6 +17,7 @@ mac80211-y := \
- 	aes_ccm.o \
- 	aes_cmac.o \
- 	cfg.o \
-+	ethtool.o \
- 	rx.o \
- 	spectmgmt.o \
- 	tx.o \
---- a/net/mac80211/ieee80211_i.h
-+++ b/net/mac80211/ieee80211_i.h
-@@ -229,16 +229,29 @@ struct ieee80211_rx_data {
- 	u16 tkip_iv16;
- };
- 
-+struct ieee80211_csa_settings {
-+	const u16 *counter_offsets_beacon;
-+	const u16 *counter_offsets_presp;
-+
-+	int n_counter_offsets_beacon;
-+	int n_counter_offsets_presp;
-+
-+	u8 count;
-+};
-+
- struct beacon_data {
- 	u8 *head, *tail;
- 	int head_len, tail_len;
- 	struct ieee80211_meshconf_ie *meshconf;
-+	u16 csa_counter_offsets[IEEE80211_MAX_CSA_COUNTERS_NUM];
-+	u8 csa_current_counter;
- 	struct rcu_head rcu_head;
- };
- 
- struct probe_resp {
- 	struct rcu_head rcu_head;
- 	int len;
-+	u16 csa_counter_offsets[IEEE80211_MAX_CSA_COUNTERS_NUM];
- 	u8 data[0];
- };
- 
-@@ -754,8 +767,6 @@ struct ieee80211_sub_if_data {
- 	struct mac80211_qos_map __rcu *qos_map;
- 
- 	struct work_struct csa_finalize_work;
--	u16 csa_counter_offset_beacon[IEEE80211_MAX_CSA_COUNTERS_NUM];
--	u16 csa_counter_offset_presp[IEEE80211_MAX_CSA_COUNTERS_NUM];
- 	bool csa_radar_required;
- 	bool csa_block_tx; /* write-protected by sdata_lock and local->mtx */
- 	struct cfg80211_chan_def csa_chandef;
-@@ -767,7 +778,6 @@ struct ieee80211_sub_if_data {
- 	struct ieee80211_chanctx *reserved_chanctx;
- 	struct cfg80211_chan_def reserved_chandef;
- 	bool reserved_radar_required;
--	u8 csa_current_counter;
- 
- 	/* used to reconfigure hardware SM PS */
- 	struct work_struct recalc_smps;
-@@ -1850,6 +1860,8 @@ int ieee80211_tdls_oper(struct wiphy *wi
- 			const u8 *peer, enum nl80211_tdls_operation oper);
- 
- 
-+extern const struct ethtool_ops ieee80211_ethtool_ops;
-+
- #ifdef CPTCFG_MAC80211_NOINLINE
- #define debug_noinline noinline
- #else
---- a/net/mac80211/iface.c
-+++ b/net/mac80211/iface.c
-@@ -399,6 +399,7 @@ int ieee80211_add_virtual_monitor(struct
- 	sdata->vif.type = NL80211_IFTYPE_MONITOR;
- 	snprintf(sdata->name, IFNAMSIZ, "%s-monitor",
- 		 wiphy_name(local->hw.wiphy));
-+	sdata->wdev.iftype = NL80211_IFTYPE_MONITOR;
- 
- 	sdata->encrypt_headroom = IEEE80211_ENCRYPT_HEADROOM;
- 
-@@ -1303,6 +1304,7 @@ static void ieee80211_setup_sdata(struct
- 	sdata->control_port_protocol = cpu_to_be16(ETH_P_PAE);
- 	sdata->control_port_no_encrypt = false;
- 	sdata->encrypt_headroom = IEEE80211_ENCRYPT_HEADROOM;
-+	sdata->vif.bss_conf.idle = true;
- 
- 	sdata->noack_map = 0;
- 
-@@ -1721,6 +1723,8 @@ int ieee80211_if_add(struct ieee80211_lo
- 
- 		ndev->features |= local->hw.netdev_features;
- 
-+		netdev_set_default_ethtool_ops(ndev, &ieee80211_ethtool_ops);
-+
- 		ret = register_netdevice(ndev);
- 		if (ret) {
- 			free_netdev(ndev);
---- a/net/wireless/core.c
-+++ b/net/wireless/core.c
-@@ -25,7 +25,6 @@
- #include "sysfs.h"
- #include "debugfs.h"
- #include "wext-compat.h"
--#include "ethtool.h"
- #include "rdev-ops.h"
- 
- /* name for sysfs, %d is appended */
-@@ -940,8 +939,6 @@ static int cfg80211_netdev_notifier_call
- 		/* allow mac80211 to determine the timeout */
- 		wdev->ps_timeout = -1;
- 
--		netdev_set_default_ethtool_ops(dev, &cfg80211_ethtool_ops);
--
- 		if ((wdev->iftype == NL80211_IFTYPE_STATION ||
- 		     wdev->iftype == NL80211_IFTYPE_P2P_CLIENT ||
- 		     wdev->iftype == NL80211_IFTYPE_ADHOC) && !wdev->use_4addr)
---- a/net/wireless/ethtool.c
-+++ b/net/wireless/ethtool.c
-@@ -1,11 +1,9 @@
- #include <linux/utsname.h>
- #include <net/cfg80211.h>
- #include "core.h"
--#include "ethtool.h"
- #include "rdev-ops.h"
- 
--static void cfg80211_get_drvinfo(struct net_device *dev,
--					struct ethtool_drvinfo *info)
-+void cfg80211_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
- {
- 	struct wireless_dev *wdev = dev->ieee80211_ptr;
- 
-@@ -23,84 +21,4 @@ static void cfg80211_get_drvinfo(struct 
- 	strlcpy(info->bus_info, dev_name(wiphy_dev(wdev->wiphy)),
- 		sizeof(info->bus_info));
- }
--
--static int cfg80211_get_regs_len(struct net_device *dev)
--{
--	/* For now, return 0... */
--	return 0;
--}
--
--static void cfg80211_get_regs(struct net_device *dev, struct ethtool_regs *regs,
--			void *data)
--{
--	struct wireless_dev *wdev = dev->ieee80211_ptr;
--
--	regs->version = wdev->wiphy->hw_version;
--	regs->len = 0;
--}
--
--static void cfg80211_get_ringparam(struct net_device *dev,
--				   struct ethtool_ringparam *rp)
--{
--	struct wireless_dev *wdev = dev->ieee80211_ptr;
--	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
--
--	memset(rp, 0, sizeof(*rp));
--
--	if (rdev->ops->get_ringparam)
--		rdev_get_ringparam(rdev, &rp->tx_pending, &rp->tx_max_pending,
--				   &rp->rx_pending, &rp->rx_max_pending);
--}
--
--static int cfg80211_set_ringparam(struct net_device *dev,
--				  struct ethtool_ringparam *rp)
--{
--	struct wireless_dev *wdev = dev->ieee80211_ptr;
--	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
--
--	if (rp->rx_mini_pending != 0 || rp->rx_jumbo_pending != 0)
--		return -EINVAL;
--
--	if (rdev->ops->set_ringparam)
--		return rdev_set_ringparam(rdev, rp->tx_pending, rp->rx_pending);
--
--	return -ENOTSUPP;
--}
--
--static int cfg80211_get_sset_count(struct net_device *dev, int sset)
--{
--	struct wireless_dev *wdev = dev->ieee80211_ptr;
--	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
--	if (rdev->ops->get_et_sset_count)
--		return rdev_get_et_sset_count(rdev, dev, sset);
--	return -EOPNOTSUPP;
--}
--
--static void cfg80211_get_stats(struct net_device *dev,
--			       struct ethtool_stats *stats, u64 *data)
--{
--	struct wireless_dev *wdev = dev->ieee80211_ptr;
--	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
--	if (rdev->ops->get_et_stats)
--		rdev_get_et_stats(rdev, dev, stats, data);
--}
--
--static void cfg80211_get_strings(struct net_device *dev, u32 sset, u8 *data)
--{
--	struct wireless_dev *wdev = dev->ieee80211_ptr;
--	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
--	if (rdev->ops->get_et_strings)
--		rdev_get_et_strings(rdev, dev, sset, data);
--}
--
--const struct ethtool_ops cfg80211_ethtool_ops = {
--	.get_drvinfo = cfg80211_get_drvinfo,
--	.get_regs_len = cfg80211_get_regs_len,
--	.get_regs = cfg80211_get_regs,
--	.get_link = ethtool_op_get_link,
--	.get_ringparam = cfg80211_get_ringparam,
--	.set_ringparam = cfg80211_set_ringparam,
--	.get_strings = cfg80211_get_strings,
--	.get_ethtool_stats = cfg80211_get_stats,
--	.get_sset_count = cfg80211_get_sset_count,
--};
-+EXPORT_SYMBOL(cfg80211_get_drvinfo);
---- a/net/wireless/ethtool.h
-+++ /dev/null
-@@ -1,6 +0,0 @@
--#ifndef __CFG80211_ETHTOOL__
--#define __CFG80211_ETHTOOL__
--
--extern const struct ethtool_ops cfg80211_ethtool_ops;
--
--#endif /* __CFG80211_ETHTOOL__ */
---- a/net/wireless/rdev-ops.h
-+++ b/net/wireless/rdev-ops.h
-@@ -714,25 +714,6 @@ static inline int rdev_get_antenna(struc
- 	return ret;
- }
- 
--static inline int rdev_set_ringparam(struct cfg80211_registered_device *rdev,
--				     u32 tx, u32 rx)
--{
--	int ret;
--	trace_rdev_set_ringparam(&rdev->wiphy, tx, rx);
--	ret = rdev->ops->set_ringparam(&rdev->wiphy, tx, rx);
--	trace_rdev_return_int(&rdev->wiphy, ret);
--	return ret;
--}
--
--static inline void rdev_get_ringparam(struct cfg80211_registered_device *rdev,
--				      u32 *tx, u32 *tx_max, u32 *rx,
--				      u32 *rx_max)
--{
--	trace_rdev_get_ringparam(&rdev->wiphy);
--	rdev->ops->get_ringparam(&rdev->wiphy, tx, tx_max, rx, rx_max);
--	trace_rdev_return_void_tx_rx(&rdev->wiphy, *tx, *tx_max, *rx, *rx_max);
--}
--
- static inline int
- rdev_sched_scan_start(struct cfg80211_registered_device *rdev,
- 		      struct net_device *dev,
-@@ -816,35 +797,6 @@ static inline int rdev_set_noack_map(str
- }
- 
- static inline int
--rdev_get_et_sset_count(struct cfg80211_registered_device *rdev,
--		       struct net_device *dev, int sset)
--{
--	int ret;
--	trace_rdev_get_et_sset_count(&rdev->wiphy, dev, sset);
--	ret = rdev->ops->get_et_sset_count(&rdev->wiphy, dev, sset);
--	trace_rdev_return_int(&rdev->wiphy, ret);
--	return ret;
--}
--
--static inline void rdev_get_et_stats(struct cfg80211_registered_device *rdev,
--				     struct net_device *dev,
--				     struct ethtool_stats *stats, u64 *data)
--{
--	trace_rdev_get_et_stats(&rdev->wiphy, dev);
--	rdev->ops->get_et_stats(&rdev->wiphy, dev, stats, data);
--	trace_rdev_return_void(&rdev->wiphy);
--}
--
--static inline void rdev_get_et_strings(struct cfg80211_registered_device *rdev,
--				       struct net_device *dev, u32 sset,
--				       u8 *data)
--{
--	trace_rdev_get_et_strings(&rdev->wiphy, dev, sset);
--	rdev->ops->get_et_strings(&rdev->wiphy, dev, sset, data);
--	trace_rdev_return_void(&rdev->wiphy);
--}
--
--static inline int
- rdev_get_channel(struct cfg80211_registered_device *rdev,
- 		 struct wireless_dev *wdev,
- 		 struct cfg80211_chan_def *chandef)
---- a/net/wireless/trace.h
-+++ b/net/wireless/trace.h
-@@ -298,11 +298,6 @@ DEFINE_EVENT(wiphy_only_evt, rdev_return
- 	TP_ARGS(wiphy)
- );
- 
--DEFINE_EVENT(wiphy_only_evt, rdev_get_ringparam,
--	TP_PROTO(struct wiphy *wiphy),
--	TP_ARGS(wiphy)
--);
--
- DEFINE_EVENT(wiphy_only_evt, rdev_get_antenna,
- 	TP_PROTO(struct wiphy *wiphy),
- 	TP_ARGS(wiphy)
-@@ -580,11 +575,6 @@ DEFINE_EVENT(wiphy_netdev_evt, rdev_stop
- 	TP_ARGS(wiphy, netdev)
- );
- 
--DEFINE_EVENT(wiphy_netdev_evt, rdev_get_et_stats,
--	TP_PROTO(struct wiphy *wiphy, struct net_device *netdev),
--	TP_ARGS(wiphy, netdev)
--);
--
- DEFINE_EVENT(wiphy_netdev_evt, rdev_sched_scan_stop,
- 	TP_PROTO(struct wiphy *wiphy, struct net_device *netdev),
- 	TP_ARGS(wiphy, netdev)
-@@ -1439,11 +1429,6 @@ DECLARE_EVENT_CLASS(tx_rx_evt,
- 		  WIPHY_PR_ARG, __entry->tx, __entry->rx)
- );
- 
--DEFINE_EVENT(tx_rx_evt, rdev_set_ringparam,
--	TP_PROTO(struct wiphy *wiphy, u32 tx, u32 rx),
--	TP_ARGS(wiphy, rx, tx)
--);
--
- DEFINE_EVENT(tx_rx_evt, rdev_set_antenna,
- 	TP_PROTO(struct wiphy *wiphy, u32 tx, u32 rx),
- 	TP_ARGS(wiphy, rx, tx)
-@@ -1725,40 +1710,6 @@ TRACE_EVENT(rdev_set_noack_map,
- 		  WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->noack_map)
- );
- 
--TRACE_EVENT(rdev_get_et_sset_count,
--	TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, int sset),
--	TP_ARGS(wiphy, netdev, sset),
--	TP_STRUCT__entry(
--		WIPHY_ENTRY
--		NETDEV_ENTRY
--		__field(int, sset)
--	),
--	TP_fast_assign(
--		WIPHY_ASSIGN;
--		NETDEV_ASSIGN;
--		__entry->sset = sset;
--	),
--	TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", sset: %d",
--		  WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->sset)
--);
--
--TRACE_EVENT(rdev_get_et_strings,
--	TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, u32 sset),
--	TP_ARGS(wiphy, netdev, sset),
--	TP_STRUCT__entry(
--		WIPHY_ENTRY
--		NETDEV_ENTRY
--		__field(u32, sset)
--	),
--	TP_fast_assign(
--		WIPHY_ASSIGN;
--		NETDEV_ASSIGN;
--		__entry->sset = sset;
--	),
--	TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", sset: %u",
--		  WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->sset)
--);
--
- DEFINE_EVENT(wiphy_wdev_evt, rdev_get_channel,
- 	TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev),
- 	TP_ARGS(wiphy, wdev)
+commit c11113bc25df22898fb995d3205bdc4f27c98073
+Author: Felix Fietkau <[email protected]>
+Date:   Sat Sep 27 18:04:58 2014 +0200
+
+    ath5k: add missing include for debug code
+    
+    Needed for calling vmalloc()/vfree()
+    
+    Signed-off-by: Felix Fietkau <[email protected]>
+
+commit 83f76a9f9a42773c7eef90bb86b4b2c16b0b3755
+Author: Felix Fietkau <[email protected]>
+Date:   Sat Sep 27 15:58:51 2014 +0200
+
+    ath5k: fix AHB kconfig dependency
+    
+    Signed-off-by: Felix Fietkau <[email protected]>
+
+commit ddd67f2a5cfd73fad4b78190025402d419b9f0a9
+Author: Felix Fietkau <[email protected]>
+Date:   Sat Sep 27 15:57:09 2014 +0200
+
+    Revert "ath5k: Remove AHB bus support"
+    
+    This reverts commit 093ec3c5337434f40d77c1af06c139da3e5ba6dc.
+
+--- a/drivers/net/wireless/ath/ath5k/Kconfig
++++ b/drivers/net/wireless/ath/ath5k/Kconfig
+@@ -2,12 +2,14 @@ config ATH5K
+ 	tristate "Atheros 5xxx wireless cards support"
+ 	depends on m
+ 	depends on PCI && MAC80211
++	depends on (PCI || ATHEROS_AR231X) && MAC80211
+ 	select ATH_COMMON
+ 	select MAC80211_LEDS
+ 	select BACKPORT_LEDS_CLASS
+ 	select BACKPORT_NEW_LEDS
+ 	select BACKPORT_AVERAGE
+-	select ATH5K_PCI
++	select ATH5K_AHB if ATHEROS_AR231X
++	select ATH5K_PCI if !ATHEROS_AR231X
+ 	---help---
+ 	  This module adds support for wireless adapters based on
+ 	  Atheros 5xxx chipset.
+@@ -52,9 +54,16 @@ config ATH5K_TRACER
+ 
+ 	  If unsure, say N.
+ 
++config ATH5K_AHB
++	bool "Atheros 5xxx AHB bus support"
++	depends on ATHEROS_AR231X
++	---help---
++	  This adds support for WiSoC type chipsets of the 5xxx Atheros
++	  family.
++
+ config ATH5K_PCI
+ 	bool "Atheros 5xxx PCI bus support"
+-	depends on PCI
++	depends on !ATHEROS_AR231X
+ 	---help---
+ 	  This adds support for PCI type chipsets of the 5xxx Atheros
+ 	  family.
 --- /dev/null
-+++ b/net/mac80211/ethtool.c
-@@ -0,0 +1,244 @@
++++ b/drivers/net/wireless/ath/ath5k/ahb.c
+@@ -0,0 +1,234 @@
 +/*
-+ * mac80211 ethtool hooks for cfg80211
++ * Copyright (c) 2008-2009 Atheros Communications Inc.
++ * Copyright (c) 2009 Gabor Juhos <[email protected]>
++ * Copyright (c) 2009 Imre Kaloz <[email protected]>
 + *
-+ * Copied from cfg.c - originally
-+ * Copyright 2006-2010	Johannes Berg <[email protected]>
-+ * Copyright 2014	Intel Corporation (Author: Johannes Berg)
++ * 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.
 + *
-+ * This file is GPLv2 as found in COPYING.
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
++ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
++ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
++ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 + */
-+#include <linux/types.h>
-+#include <net/cfg80211.h>
-+#include "ieee80211_i.h"
-+#include "sta_info.h"
-+#include "driver-ops.h"
 +
-+static int ieee80211_set_ringparam(struct net_device *dev,
-+				   struct ethtool_ringparam *rp)
++#include <linux/nl80211.h>
++#include <linux/platform_device.h>
++#include <linux/etherdevice.h>
++#include <linux/export.h>
++#include <ar231x_platform.h>
++#include "ath5k.h"
++#include "debug.h"
++#include "base.h"
++#include "reg.h"
++
++/* return bus cachesize in 4B word units */
++static void ath5k_ahb_read_cachesize(struct ath_common *common, int *csz)
 +{
-+	struct ieee80211_local *local = wiphy_priv(dev->ieee80211_ptr->wiphy);
-+
-+	if (rp->rx_mini_pending != 0 || rp->rx_jumbo_pending != 0)
-+		return -EINVAL;
-+
-+	return drv_set_ringparam(local, rp->tx_pending, rp->rx_pending);
++	*csz = L1_CACHE_BYTES >> 2;
 +}
 +
-+static void ieee80211_get_ringparam(struct net_device *dev,
-+				    struct ethtool_ringparam *rp)
++static bool
++ath5k_ahb_eeprom_read(struct ath_common *common, u32 off, u16 *data)
 +{
-+	struct ieee80211_local *local = wiphy_priv(dev->ieee80211_ptr->wiphy);
++	struct ath5k_hw *ah = common->priv;
++	struct platform_device *pdev = to_platform_device(ah->dev);
++	struct ar231x_board_config *bcfg = dev_get_platdata(&pdev->dev);
++	u16 *eeprom, *eeprom_end;
 +
-+	memset(rp, 0, sizeof(*rp));
++	eeprom = (u16 *) bcfg->radio;
++	eeprom_end = ((void *) bcfg->config) + BOARD_CONFIG_BUFSZ;
 +
-+	drv_get_ringparam(local, &rp->tx_pending, &rp->tx_max_pending,
-+			  &rp->rx_pending, &rp->rx_max_pending);
-+}
++	eeprom += off;
++	if (eeprom > eeprom_end)
++		return false;
 +
-+static const char ieee80211_gstrings_sta_stats[][ETH_GSTRING_LEN] = {
-+	"rx_packets", "rx_bytes",
-+	"rx_duplicates", "rx_fragments", "rx_dropped",
-+	"tx_packets", "tx_bytes", "tx_fragments",
-+	"tx_filtered", "tx_retry_failed", "tx_retries",
-+	"beacon_loss", "sta_state", "txrate", "rxrate", "signal",
-+	"channel", "noise", "ch_time", "ch_time_busy",
-+	"ch_time_ext_busy", "ch_time_rx", "ch_time_tx"
-+};
-+#define STA_STATS_LEN	ARRAY_SIZE(ieee80211_gstrings_sta_stats)
++	*data = *eeprom;
++	return true;
++}
 +
-+static int ieee80211_get_sset_count(struct net_device *dev, int sset)
++int ath5k_hw_read_srev(struct ath5k_hw *ah)
 +{
-+	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-+	int rv = 0;
-+
-+	if (sset == ETH_SS_STATS)
-+		rv += STA_STATS_LEN;
-+
-+	rv += drv_get_et_sset_count(sdata, sset);
-+
-+	if (rv == 0)
-+		return -EOPNOTSUPP;
-+	return rv;
++	struct platform_device *pdev = to_platform_device(ah->dev);
++	struct ar231x_board_config *bcfg = dev_get_platdata(&pdev->dev);
++	ah->ah_mac_srev = bcfg->devid;
++	return 0;
 +}
 +
-+static void ieee80211_get_stats(struct net_device *dev,
-+				struct ethtool_stats *stats,
-+				u64 *data)
++static int ath5k_ahb_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac)
 +{
-+	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-+	struct ieee80211_chanctx_conf *chanctx_conf;
-+	struct ieee80211_channel *channel;
-+	struct sta_info *sta;
-+	struct ieee80211_local *local = sdata->local;
-+	struct station_info sinfo;
-+	struct survey_info survey;
-+	int i, q;
-+#define STA_STATS_SURVEY_LEN 7
-+
-+	memset(data, 0, sizeof(u64) * STA_STATS_LEN);
++	struct platform_device *pdev = to_platform_device(ah->dev);
++	struct ar231x_board_config *bcfg = dev_get_platdata(&pdev->dev);
++	u8 *cfg_mac;
 +
-+#define ADD_STA_STATS(sta)				\
-+	do {						\
-+		data[i++] += sta->rx_packets;		\
-+		data[i++] += sta->rx_bytes;		\
-+		data[i++] += sta->num_duplicates;	\
-+		data[i++] += sta->rx_fragments;		\
-+		data[i++] += sta->rx_dropped;		\
-+							\
-+		data[i++] += sinfo.tx_packets;		\
-+		data[i++] += sinfo.tx_bytes;		\
-+		data[i++] += sta->tx_fragments;		\
-+		data[i++] += sta->tx_filtered_count;	\
-+		data[i++] += sta->tx_retry_failed;	\
-+		data[i++] += sta->tx_retry_count;	\
-+		data[i++] += sta->beacon_loss_count;	\
-+	} while (0)
-+
-+	/* For Managed stations, find the single station based on BSSID
-+	 * and use that.  For interface types, iterate through all available
-+	 * stations and add stats for any station that is assigned to this
-+	 * network device.
-+	 */
++	if (to_platform_device(ah->dev)->id == 0)
++		cfg_mac = bcfg->config->wlan0_mac;
++	else
++		cfg_mac = bcfg->config->wlan1_mac;
 +
-+	mutex_lock(&local->sta_mtx);
++	memcpy(mac, cfg_mac, ETH_ALEN);
++	return 0;
++}
 +
-+	if (sdata->vif.type == NL80211_IFTYPE_STATION) {
-+		sta = sta_info_get_bss(sdata, sdata->u.mgd.bssid);
++static const struct ath_bus_ops ath_ahb_bus_ops = {
++	.ath_bus_type = ATH_AHB,
++	.read_cachesize = ath5k_ahb_read_cachesize,
++	.eeprom_read = ath5k_ahb_eeprom_read,
++	.eeprom_read_mac = ath5k_ahb_eeprom_read_mac,
++};
 +
-+		if (!(sta && !WARN_ON(sta->sdata->dev != dev)))
-+			goto do_survey;
++/*Initialization*/
++static int ath_ahb_probe(struct platform_device *pdev)
++{
++	struct ar231x_board_config *bcfg = dev_get_platdata(&pdev->dev);
++	struct ath5k_hw *ah;
++	struct ieee80211_hw *hw;
++	struct resource *res;
++	void __iomem *mem;
++	int irq;
++	int ret = 0;
++	u32 reg;
++
++	if (!dev_get_platdata(&pdev->dev)) {
++		dev_err(&pdev->dev, "no platform data specified\n");
++		ret = -EINVAL;
++		goto err_out;
++	}
 +
-+		sinfo.filled = 0;
-+		sta_set_sinfo(sta, &sinfo);
++	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++	if (res == NULL) {
++		dev_err(&pdev->dev, "no memory resource found\n");
++		ret = -ENXIO;
++		goto err_out;
++	}
 +
-+		i = 0;
-+		ADD_STA_STATS(sta);
++	mem = ioremap_nocache(res->start, resource_size(res));
++	if (mem == NULL) {
++		dev_err(&pdev->dev, "ioremap failed\n");
++		ret = -ENOMEM;
++		goto err_out;
++	}
 +
-+		data[i++] = sta->sta_state;
++	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
++	if (res == NULL) {
++		dev_err(&pdev->dev, "no IRQ resource found\n");
++		ret = -ENXIO;
++		goto err_iounmap;
++	}
 +
++	irq = res->start;
 +
-+		if (sinfo.filled & STATION_INFO_TX_BITRATE)
-+			data[i] = 100000 *
-+				cfg80211_calculate_bitrate(&sinfo.txrate);
-+		i++;
-+		if (sinfo.filled & STATION_INFO_RX_BITRATE)
-+			data[i] = 100000 *
-+				cfg80211_calculate_bitrate(&sinfo.rxrate);
-+		i++;
++	hw = ieee80211_alloc_hw(sizeof(struct ath5k_hw), &ath5k_hw_ops);
++	if (hw == NULL) {
++		dev_err(&pdev->dev, "no memory for ieee80211_hw\n");
++		ret = -ENOMEM;
++		goto err_iounmap;
++	}
 +
-+		if (sinfo.filled & STATION_INFO_SIGNAL_AVG)
-+			data[i] = (u8)sinfo.signal_avg;
-+		i++;
++	ah = hw->priv;
++	ah->hw = hw;
++	ah->dev = &pdev->dev;
++	ah->iobase = mem;
++	ah->irq = irq;
++	ah->devid = bcfg->devid;
++
++	if (bcfg->devid >= AR5K_SREV_AR2315_R6) {
++		/* Enable WMAC AHB arbitration */
++		reg = ioread32((void __iomem *) AR5K_AR2315_AHB_ARB_CTL);
++		reg |= AR5K_AR2315_AHB_ARB_CTL_WLAN;
++		iowrite32(reg, (void __iomem *) AR5K_AR2315_AHB_ARB_CTL);
++
++		/* Enable global WMAC swapping */
++		reg = ioread32((void __iomem *) AR5K_AR2315_BYTESWAP);
++		reg |= AR5K_AR2315_BYTESWAP_WMAC;
++		iowrite32(reg, (void __iomem *) AR5K_AR2315_BYTESWAP);
 +	} else {
-+		list_for_each_entry(sta, &local->sta_list, list) {
-+			/* Make sure this station belongs to the proper dev */
-+			if (sta->sdata->dev != dev)
-+				continue;
++		/* Enable WMAC DMA access (assuming 5312 or 231x*/
++		/* TODO: check other platforms */
++		reg = ioread32((void __iomem *) AR5K_AR5312_ENABLE);
++		if (to_platform_device(ah->dev)->id == 0)
++			reg |= AR5K_AR5312_ENABLE_WLAN0;
++		else
++			reg |= AR5K_AR5312_ENABLE_WLAN1;
++		iowrite32(reg, (void __iomem *) AR5K_AR5312_ENABLE);
 +
-+			sinfo.filled = 0;
-+			sta_set_sinfo(sta, &sinfo);
-+			i = 0;
-+			ADD_STA_STATS(sta);
-+		}
++		/*
++		 * On a dual-band AR5312, the multiband radio is only
++		 * used as pass-through. Disable 2 GHz support in the
++		 * driver for it
++		 */
++		if (to_platform_device(ah->dev)->id == 0 &&
++		    (bcfg->config->flags & (BD_WLAN0 | BD_WLAN1)) ==
++		     (BD_WLAN1 | BD_WLAN0))
++			ah->ah_capabilities.cap_needs_2GHz_ovr = true;
++		else
++			ah->ah_capabilities.cap_needs_2GHz_ovr = false;
 +	}
 +
-+do_survey:
-+	i = STA_STATS_LEN - STA_STATS_SURVEY_LEN;
-+	/* Get survey stats for current channel */
-+	survey.filled = 0;
-+
-+	rcu_read_lock();
-+	chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
-+	if (chanctx_conf)
-+		channel = chanctx_conf->def.chan;
-+	else
-+		channel = NULL;
-+	rcu_read_unlock();
-+
-+	if (channel) {
-+		q = 0;
-+		do {
-+			survey.filled = 0;
-+			if (drv_get_survey(local, q, &survey) != 0) {
-+				survey.filled = 0;
-+				break;
-+			}
-+			q++;
-+		} while (channel != survey.channel);
++	ret = ath5k_init_ah(ah, &ath_ahb_bus_ops);
++	if (ret != 0) {
++		dev_err(&pdev->dev, "failed to attach device, err=%d\n", ret);
++		ret = -ENODEV;
++		goto err_free_hw;
 +	}
 +
-+	if (survey.filled)
-+		data[i++] = survey.channel->center_freq;
-+	else
-+		data[i++] = 0;
-+	if (survey.filled & SURVEY_INFO_NOISE_DBM)
-+		data[i++] = (u8)survey.noise;
-+	else
-+		data[i++] = -1LL;
-+	if (survey.filled & SURVEY_INFO_CHANNEL_TIME)
-+		data[i++] = survey.channel_time;
-+	else
-+		data[i++] = -1LL;
-+	if (survey.filled & SURVEY_INFO_CHANNEL_TIME_BUSY)
-+		data[i++] = survey.channel_time_busy;
-+	else
-+		data[i++] = -1LL;
-+	if (survey.filled & SURVEY_INFO_CHANNEL_TIME_EXT_BUSY)
-+		data[i++] = survey.channel_time_ext_busy;
-+	else
-+		data[i++] = -1LL;
-+	if (survey.filled & SURVEY_INFO_CHANNEL_TIME_RX)
-+		data[i++] = survey.channel_time_rx;
-+	else
-+		data[i++] = -1LL;
-+	if (survey.filled & SURVEY_INFO_CHANNEL_TIME_TX)
-+		data[i++] = survey.channel_time_tx;
-+	else
-+		data[i++] = -1LL;
-+
-+	mutex_unlock(&local->sta_mtx);
++	platform_set_drvdata(pdev, hw);
 +
-+	if (WARN_ON(i != STA_STATS_LEN))
-+		return;
++	return 0;
 +
-+	drv_get_et_stats(sdata, stats, &(data[STA_STATS_LEN]));
++ err_free_hw:
++	ieee80211_free_hw(hw);
++ err_iounmap:
++        iounmap(mem);
++ err_out:
++	return ret;
 +}
 +
-+static void ieee80211_get_strings(struct net_device *dev, u32 sset, u8 *data)
++static int ath_ahb_remove(struct platform_device *pdev)
 +{
-+	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-+	int sz_sta_stats = 0;
++	struct ar231x_board_config *bcfg = dev_get_platdata(&pdev->dev);
++	struct ieee80211_hw *hw = platform_get_drvdata(pdev);
++	struct ath5k_hw *ah;
++	u32 reg;
 +
-+	if (sset == ETH_SS_STATS) {
-+		sz_sta_stats = sizeof(ieee80211_gstrings_sta_stats);
-+		memcpy(data, ieee80211_gstrings_sta_stats, sz_sta_stats);
-+	}
-+	drv_get_et_strings(sdata, sset, &(data[sz_sta_stats]));
-+}
++	if (!hw)
++		return 0;
 +
-+static int ieee80211_get_regs_len(struct net_device *dev)
-+{
-+	return 0;
-+}
++	ah = hw->priv;
 +
-+static void ieee80211_get_regs(struct net_device *dev,
-+			       struct ethtool_regs *regs,
-+			       void *data)
-+{
-+	struct wireless_dev *wdev = dev->ieee80211_ptr;
++	if (bcfg->devid >= AR5K_SREV_AR2315_R6) {
++		/* Disable WMAC AHB arbitration */
++		reg = ioread32((void __iomem *) AR5K_AR2315_AHB_ARB_CTL);
++		reg &= ~AR5K_AR2315_AHB_ARB_CTL_WLAN;
++		iowrite32(reg, (void __iomem *) AR5K_AR2315_AHB_ARB_CTL);
++	} else {
++		/*Stop DMA access */
++		reg = ioread32((void __iomem *) AR5K_AR5312_ENABLE);
++		if (to_platform_device(ah->dev)->id == 0)
++			reg &= ~AR5K_AR5312_ENABLE_WLAN0;
++		else
++			reg &= ~AR5K_AR5312_ENABLE_WLAN1;
++		iowrite32(reg, (void __iomem *) AR5K_AR5312_ENABLE);
++	}
 +
-+	regs->version = wdev->wiphy->hw_version;
-+	regs->len = 0;
++	ath5k_deinit_ah(ah);
++	iounmap(ah->iobase);
++	ieee80211_free_hw(hw);
++
++	return 0;
 +}
 +
-+const struct ethtool_ops ieee80211_ethtool_ops = {
-+	.get_drvinfo = cfg80211_get_drvinfo,
-+	.get_regs_len = ieee80211_get_regs_len,
-+	.get_regs = ieee80211_get_regs,
-+	.get_link = ethtool_op_get_link,
-+	.get_ringparam = ieee80211_get_ringparam,
-+	.set_ringparam = ieee80211_set_ringparam,
-+	.get_strings = ieee80211_get_strings,
-+	.get_ethtool_stats = ieee80211_get_stats,
-+	.get_sset_count = ieee80211_get_sset_count,
++static struct platform_driver ath_ahb_driver = {
++	.probe      = ath_ahb_probe,
++	.remove     = ath_ahb_remove,
++	.driver		= {
++		.name	= "ar231x-wmac",
++		.owner	= THIS_MODULE,
++	},
 +};
---- a/net/mac80211/ibss.c
-+++ b/net/mac80211/ibss.c
-@@ -143,7 +143,7 @@ ieee80211_ibss_build_presp(struct ieee80
- 		*pos++ = csa_settings->block_tx ? 1 : 0;
- 		*pos++ = ieee80211_frequency_to_channel(
- 				csa_settings->chandef.chan->center_freq);
--		sdata->csa_counter_offset_beacon[0] = (pos - presp->head);
-+		presp->csa_counter_offsets[0] = (pos - presp->head);
- 		*pos++ = csa_settings->count;
- 	}
- 
-@@ -1677,6 +1677,7 @@ int ieee80211_ibss_join(struct ieee80211
- 	sdata->u.ibss.control_port = params->control_port;
- 	sdata->u.ibss.userspace_handles_dfs = params->userspace_handles_dfs;
- 	sdata->u.ibss.basic_rates = params->basic_rates;
-+	sdata->u.ibss.last_scan_completed = jiffies;
- 
- 	/* fix basic_rates if channel does not support these rates */
- 	rate_flags = ieee80211_chandef_rate_flags(&params->chandef);
---- a/net/mac80211/mesh.c
-+++ b/net/mac80211/mesh.c
-@@ -679,7 +679,7 @@ ieee80211_mesh_build_beacon(struct ieee8
- 		*pos++ = 0x0;
- 		*pos++ = ieee80211_frequency_to_channel(
- 				csa->settings.chandef.chan->center_freq);
--		sdata->csa_counter_offset_beacon[0] = hdr_len + 6;
-+		bcn->csa_counter_offsets[0] = hdr_len + 6;
- 		*pos++ = csa->settings.count;
- 		*pos++ = WLAN_EID_CHAN_SWITCH_PARAM;
- 		*pos++ = 6;
---- a/net/wireless/genregdb.awk
-+++ b/net/wireless/genregdb.awk
-@@ -65,17 +65,7 @@ function parse_reg_rule()
- 	sub(/,/, "", units)
- 	dfs_cac = $9
- 	if (units == "mW") {
--		if (power == 100) {
--			power = 20
--		} else if (power == 200) {
--			power = 23
--		} else if (power == 500) {
--			power = 27
--		} else if (power == 1000) {
--			power = 30
--		} else {
--			print "Unknown power value in database!"
--		}
-+		power = 10 * log(power)/log(10)
- 	} else {
- 		dfs_cac = $8
- 	}
-@@ -114,7 +104,7 @@ function parse_reg_rule()
- 
- 	}
- 	flags = flags "0"
--	printf "\t\tREG_RULE_EXT(%d, %d, %d, %d, %d, %d, %s),\n", start, end, bw, gain, power, dfs_cac, flags
-+	printf "\t\tREG_RULE_EXT(%d, %d, %d, %d, %.0f, %d, %s),\n", start, end, bw, gain, power, dfs_cac, flags
- 	rules++
- }
- 
---- a/net/mac80211/debugfs_netdev.c
-+++ b/net/mac80211/debugfs_netdev.c
-@@ -34,8 +34,7 @@ static ssize_t ieee80211_if_read(
- 	ssize_t ret = -EINVAL;
- 
- 	read_lock(&dev_base_lock);
--	if (sdata->dev->reg_state == NETREG_REGISTERED)
--		ret = (*format)(sdata, buf, sizeof(buf));
-+	ret = (*format)(sdata, buf, sizeof(buf));
- 	read_unlock(&dev_base_lock);
- 
- 	if (ret >= 0)
-@@ -62,8 +61,7 @@ static ssize_t ieee80211_if_write(
- 
- 	ret = -ENODEV;
- 	rtnl_lock();
--	if (sdata->dev->reg_state == NETREG_REGISTERED)
--		ret = (*write)(sdata, buf, count);
-+	ret = (*write)(sdata, buf, count);
- 	rtnl_unlock();
- 
- 	return ret;
---- a/drivers/net/wireless/b43/xmit.c
-+++ b/drivers/net/wireless/b43/xmit.c
-@@ -811,9 +811,13 @@ void b43_rx(struct b43_wldev *dev, struc
- 		break;
- 	case B43_PHYTYPE_G:
- 		status.band = IEEE80211_BAND_2GHZ;
--		/* chanid is the radio channel cookie value as used
--		 * to tune the radio. */
--		status.freq = chanid + 2400;
-+		/* Somewhere between 478.104 and 508.1084 firmware for G-PHY
-+		 * has been modified to be compatible with N-PHY and others.
-+		 */
-+		if (dev->fw.rev >= 508)
-+			status.freq = ieee80211_channel_to_frequency(chanid, status.band);
-+		else
-+			status.freq = chanid + 2400;
- 		break;
- 	case B43_PHYTYPE_N:
- 	case B43_PHYTYPE_LP:
---- a/drivers/net/wireless/b43/main.c
-+++ b/drivers/net/wireless/b43/main.c
-@@ -5216,6 +5216,7 @@ static int b43_wireless_core_attach(stru
- 	/* We don't support 5 GHz on some PHYs yet */
- 	switch (dev->phy.type) {
- 	case B43_PHYTYPE_A:
-+	case B43_PHYTYPE_G:
- 	case B43_PHYTYPE_N:
- 	case B43_PHYTYPE_LP:
- 	case B43_PHYTYPE_HT:
---- a/net/wireless/reg.c
-+++ b/net/wireless/reg.c
-@@ -935,7 +935,7 @@ freq_reg_info_regd(struct wiphy *wiphy, 
- 		if (!band_rule_found)
- 			band_rule_found = freq_in_rule_band(fr, center_freq);
- 
--		bw_fits = reg_does_bw_fit(fr, center_freq, MHZ_TO_KHZ(5));
-+		bw_fits = reg_does_bw_fit(fr, center_freq, MHZ_TO_KHZ(20));
- 
- 		if (band_rule_found && bw_fits)
- 			return rr;
-@@ -1019,10 +1019,10 @@ static void chan_reg_rule_print_dbg(cons
- }
- #endif
- 
--/* Find an ieee80211_reg_rule such that a 5MHz channel with frequency
-- * chan->center_freq fits there.
-- * If there is no such reg_rule, disable the channel, otherwise set the
-- * flags corresponding to the bandwidths allowed in the particular reg_rule
-+/*
-+ * Note that right now we assume the desired channel bandwidth
-+ * is always 20 MHz for each individual channel (HT40 uses 20 MHz
-+ * per channel, the primary and the extension channel).
-  */
- static void handle_channel(struct wiphy *wiphy,
- 			   enum nl80211_reg_initiator initiator,
-@@ -1083,12 +1083,8 @@ static void handle_channel(struct wiphy 
- 	if (reg_rule->flags & NL80211_RRF_AUTO_BW)
- 		max_bandwidth_khz = reg_get_max_bandwidth(regd, reg_rule);
- 
--	if (max_bandwidth_khz < MHZ_TO_KHZ(10))
--		bw_flags = IEEE80211_CHAN_NO_10MHZ;
--	if (max_bandwidth_khz < MHZ_TO_KHZ(20))
--		bw_flags |= IEEE80211_CHAN_NO_20MHZ;
- 	if (max_bandwidth_khz < MHZ_TO_KHZ(40))
--		bw_flags |= IEEE80211_CHAN_NO_HT40;
-+		bw_flags = IEEE80211_CHAN_NO_HT40;
- 	if (max_bandwidth_khz < MHZ_TO_KHZ(80))
- 		bw_flags |= IEEE80211_CHAN_NO_80MHZ;
- 	if (max_bandwidth_khz < MHZ_TO_KHZ(160))
-@@ -1522,12 +1518,8 @@ static void handle_channel_custom(struct
- 	if (reg_rule->flags & NL80211_RRF_AUTO_BW)
- 		max_bandwidth_khz = reg_get_max_bandwidth(regd, reg_rule);
- 
--	if (max_bandwidth_khz < MHZ_TO_KHZ(10))
--		bw_flags = IEEE80211_CHAN_NO_10MHZ;
--	if (max_bandwidth_khz < MHZ_TO_KHZ(20))
--		bw_flags |= IEEE80211_CHAN_NO_20MHZ;
- 	if (max_bandwidth_khz < MHZ_TO_KHZ(40))
--		bw_flags |= IEEE80211_CHAN_NO_HT40;
-+		bw_flags = IEEE80211_CHAN_NO_HT40;
- 	if (max_bandwidth_khz < MHZ_TO_KHZ(80))
- 		bw_flags |= IEEE80211_CHAN_NO_80MHZ;
- 	if (max_bandwidth_khz < MHZ_TO_KHZ(160))
---- a/drivers/net/wireless/ath/ath9k/ath9k.h
-+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
-@@ -185,7 +185,8 @@ struct ath_atx_ac {
- 
- struct ath_frame_info {
- 	struct ath_buf *bf;
--	int framelen;
-+	u16 framelen;
-+	s8 txq;
- 	enum ath9k_key_type keytype;
- 	u8 keyix;
- 	u8 rtscts_rate;
---- a/drivers/net/wireless/ath/ath9k/xmit.c
-+++ b/drivers/net/wireless/ath/ath9k/xmit.c
-@@ -147,15 +147,13 @@ static void ath_set_rates(struct ieee802
- static void ath_txq_skb_done(struct ath_softc *sc, struct ath_txq *txq,
- 			     struct sk_buff *skb)
- {
--	int q;
--
--	q = skb_get_queue_mapping(skb);
--	if (txq == sc->tx.uapsdq)
--		txq = sc->tx.txq_map[q];
-+	struct ath_frame_info *fi = get_frame_info(skb);
-+	int q = fi->txq;
- 
--	if (txq != sc->tx.txq_map[q])
-+	if (q < 0)
- 		return;
- 
-+	txq = sc->tx.txq_map[q];
- 	if (WARN_ON(--txq->pending_frames < 0))
- 		txq->pending_frames = 0;
- 
-@@ -887,6 +885,15 @@ ath_tx_get_tid_subframe(struct ath_softc
- 
- 		tx_info = IEEE80211_SKB_CB(skb);
- 		tx_info->flags &= ~IEEE80211_TX_CTL_CLEAR_PS_FILT;
 +
-+		/*
-+		 * No aggregation session is running, but there may be frames
-+		 * from a previous session or a failed attempt in the queue.
-+		 * Send them out as normal data frames
-+		 */
-+		if (!tid->active)
-+			tx_info->flags &= ~IEEE80211_TX_CTL_AMPDU;
-+
- 		if (!(tx_info->flags & IEEE80211_TX_CTL_AMPDU)) {
- 			bf->bf_state.bf_type = 0;
- 			return bf;
-@@ -1999,6 +2006,7 @@ static void setup_frame_info(struct ieee
- 		an = (struct ath_node *) sta->drv_priv;
- 
- 	memset(fi, 0, sizeof(*fi));
-+	fi->txq = -1;
- 	if (hw_key)
- 		fi->keyix = hw_key->hw_key_idx;
- 	else if (an && ieee80211_is_data(hdr->frame_control) && an->ps_key > 0)
-@@ -2150,6 +2158,7 @@ int ath_tx_start(struct ieee80211_hw *hw
- 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
- 	struct ieee80211_sta *sta = txctl->sta;
- 	struct ieee80211_vif *vif = info->control.vif;
-+	struct ath_frame_info *fi = get_frame_info(skb);
- 	struct ath_softc *sc = hw->priv;
- 	struct ath_txq *txq = txctl->txq;
- 	struct ath_atx_tid *tid = NULL;
-@@ -2170,11 +2179,13 @@ int ath_tx_start(struct ieee80211_hw *hw
- 	q = skb_get_queue_mapping(skb);
- 
- 	ath_txq_lock(sc, txq);
--	if (txq == sc->tx.txq_map[q] &&
--	    ++txq->pending_frames > sc->tx.txq_max_pending[q] &&
--	    !txq->stopped) {
--		ieee80211_stop_queue(sc->hw, q);
--		txq->stopped = true;
-+	if (txq == sc->tx.txq_map[q]) {
-+		fi->txq = q;
-+		if (++txq->pending_frames > sc->tx.txq_max_pending[q] &&
-+		    !txq->stopped) {
-+			ieee80211_stop_queue(sc->hw, q);
-+			txq->stopped = true;
-+		}
- 	}
- 
- 	if (txctl->an && ieee80211_is_data_present(hdr->frame_control))
---- a/net/mac80211/chan.c
-+++ b/net/mac80211/chan.c
-@@ -521,6 +521,8 @@ static void ieee80211_recalc_chanctx_cha
- 			continue;
- 		if (rcu_access_pointer(sdata->vif.chanctx_conf) != conf)
- 			continue;
-+		if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
-+			continue;
- 
- 		if (!compat)
- 			compat = &sdata->vif.bss_conf.chandef;
---- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c
-+++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
-@@ -1004,9 +1004,11 @@ static bool ar5008_hw_ani_control_new(st
- 	case ATH9K_ANI_FIRSTEP_LEVEL:{
- 		u32 level = param;
- 
--		value = level;
-+		value = level * 2;
- 		REG_RMW_FIELD(ah, AR_PHY_FIND_SIG,
- 			      AR_PHY_FIND_SIG_FIRSTEP, value);
-+		REG_RMW_FIELD(ah, AR_PHY_FIND_SIG_LOW,
-+			      AR_PHY_FIND_SIG_FIRSTEP_LOW, value);
- 
- 		if (level != aniState->firstepLevel) {
- 			ath_dbg(common, ANI,
-@@ -1040,9 +1042,8 @@ static bool ar5008_hw_ani_control_new(st
- 		REG_RMW_FIELD(ah, AR_PHY_TIMING5,
- 			      AR_PHY_TIMING5_CYCPWR_THR1, value);
- 
--		if (IS_CHAN_HT40(ah->curchan))
--			REG_RMW_FIELD(ah, AR_PHY_EXT_CCA,
--				      AR_PHY_EXT_TIMING5_CYCPWR_THR1, value);
-+		REG_RMW_FIELD(ah, AR_PHY_EXT_CCA,
-+				  AR_PHY_EXT_TIMING5_CYCPWR_THR1, value - 1);
- 
- 		if (level != aniState->spurImmunityLevel) {
- 			ath_dbg(common, ANI,
---- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
-+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
-@@ -517,6 +517,23 @@ static void ar9003_hw_spur_mitigate(stru
- 	ar9003_hw_spur_mitigate_ofdm(ah, chan);
++module_platform_driver(ath_ahb_driver);
+--- a/drivers/net/wireless/ath/ath5k/ath5k.h
++++ b/drivers/net/wireless/ath/ath5k/ath5k.h
+@@ -1647,6 +1647,32 @@ static inline struct ath_regulatory *ath
+ 	return &(ath5k_hw_common(ah)->regulatory);
  }
  
-+static u32 ar9003_hw_compute_pll_control_soc(struct ath_hw *ah,
-+					     struct ath9k_channel *chan)
-+{
-+	u32 pll;
++#ifdef CONFIG_ATHEROS_AR231X
++#define AR5K_AR2315_PCI_BASE	((void __iomem *)0xb0100000)
 +
-+	pll = SM(0x5, AR_RTC_9300_SOC_PLL_REFDIV);
-+
-+	if (chan && IS_CHAN_HALF_RATE(chan))
-+		pll |= SM(0x1, AR_RTC_9300_SOC_PLL_CLKSEL);
-+	else if (chan && IS_CHAN_QUARTER_RATE(chan))
-+		pll |= SM(0x2, AR_RTC_9300_SOC_PLL_CLKSEL);
++static inline void __iomem *ath5k_ahb_reg(struct ath5k_hw *ah, u16 reg)
++{
++	/* On AR2315 and AR2317 the PCI clock domain registers
++	 * are outside of the WMAC register space */
++	if (unlikely((reg >= 0x4000) && (reg < 0x5000) &&
++	    (ah->ah_mac_srev >= AR5K_SREV_AR2315_R6)))
++		return AR5K_AR2315_PCI_BASE + reg;
 +
-+	pll |= SM(0x2c, AR_RTC_9300_SOC_PLL_DIV_INT);
++	return ah->iobase + reg;
++}
 +
-+	return pll;
++static inline u32 ath5k_hw_reg_read(struct ath5k_hw *ah, u16 reg)
++{
++	return ioread32(ath5k_ahb_reg(ah, reg));
 +}
 +
- static u32 ar9003_hw_compute_pll_control(struct ath_hw *ah,
- 					 struct ath9k_channel *chan)
- {
-@@ -1779,7 +1796,12 @@ void ar9003_hw_attach_phy_ops(struct ath
- 
- 	priv_ops->rf_set_freq = ar9003_hw_set_channel;
- 	priv_ops->spur_mitigate_freq = ar9003_hw_spur_mitigate;
--	priv_ops->compute_pll_control = ar9003_hw_compute_pll_control;
++static inline void ath5k_hw_reg_write(struct ath5k_hw *ah, u32 val, u16 reg)
++{
++	iowrite32(val, ath5k_ahb_reg(ah, reg));
++}
 +
-+	if (AR_SREV_9340(ah) || AR_SREV_9550(ah) || AR_SREV_9531(ah))
-+		priv_ops->compute_pll_control = ar9003_hw_compute_pll_control_soc;
-+	else
-+		priv_ops->compute_pll_control = ar9003_hw_compute_pll_control;
++#else
 +
- 	priv_ops->set_channel_regs = ar9003_hw_set_channel_regs;
- 	priv_ops->init_bb = ar9003_hw_init_bb;
- 	priv_ops->process_ini = ar9003_hw_process_ini;
---- a/drivers/net/wireless/ath/ath9k/hw.c
-+++ b/drivers/net/wireless/ath/ath9k/hw.c
-@@ -702,6 +702,8 @@ static void ath9k_hw_init_pll(struct ath
+ static inline u32 ath5k_hw_reg_read(struct ath5k_hw *ah, u16 reg)
  {
- 	u32 pll;
+ 	return ioread32(ah->iobase + reg);
+@@ -1657,6 +1683,8 @@ static inline void ath5k_hw_reg_write(st
+ 	iowrite32(val, ah->iobase + reg);
+ }
  
-+	pll = ath9k_hw_compute_pll_control(ah, chan);
++#endif
 +
- 	if (AR_SREV_9485(ah) || AR_SREV_9565(ah)) {
- 		/* program BB PLL ki and kd value, ki=0x4, kd=0x40 */
- 		REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2,
-@@ -752,7 +754,8 @@ static void ath9k_hw_init_pll(struct ath
- 		REG_RMW_FIELD(ah, AR_CH0_DDR_DPLL3,
- 			      AR_CH0_DPLL3_PHASE_SHIFT, 0x1);
- 
--		REG_WRITE(ah, AR_RTC_PLL_CONTROL, 0x1142c);
-+		REG_WRITE(ah, AR_RTC_PLL_CONTROL,
-+			  pll | AR_RTC_9300_PLL_BYPASS);
- 		udelay(1000);
- 
- 		/* program refdiv, nint, frac to RTC register */
-@@ -768,7 +771,8 @@ static void ath9k_hw_init_pll(struct ath
- 	} else if (AR_SREV_9340(ah) || AR_SREV_9550(ah) || AR_SREV_9531(ah)) {
- 		u32 regval, pll2_divint, pll2_divfrac, refdiv;
- 
--		REG_WRITE(ah, AR_RTC_PLL_CONTROL, 0x1142c);
-+		REG_WRITE(ah, AR_RTC_PLL_CONTROL,
-+			  pll | AR_RTC_9300_SOC_PLL_BYPASS);
- 		udelay(1000);
- 
- 		REG_SET_BIT(ah, AR_PHY_PLL_MODE, 0x1 << 16);
-@@ -840,7 +844,6 @@ static void ath9k_hw_init_pll(struct ath
- 		udelay(1000);
- 	}
- 
--	pll = ath9k_hw_compute_pll_control(ah, chan);
- 	if (AR_SREV_9565(ah))
- 		pll |= 0x40000;
- 	REG_WRITE(ah, AR_RTC_PLL_CONTROL, pll);
---- a/drivers/net/wireless/ath/ath9k/reg.h
-+++ b/drivers/net/wireless/ath/ath9k/reg.h
-@@ -1236,12 +1236,23 @@ enum {
- #define AR_CH0_DPLL3_PHASE_SHIFT_S   23
- #define AR_PHY_CCA_NOM_VAL_2GHZ      -118
+ static inline enum ath_bus_type ath5k_get_bus_type(struct ath5k_hw *ah)
+ {
+ 	return ath5k_hw_common(ah)->bus_ops->ath_bus_type;
+--- a/drivers/net/wireless/ath/ath5k/base.c
++++ b/drivers/net/wireless/ath/ath5k/base.c
+@@ -99,6 +99,15 @@ static int ath5k_reset(struct ath5k_hw *
+ 
+ /* Known SREVs */
+ static const struct ath5k_srev_name srev_names[] = {
++#ifdef CONFIG_ATHEROS_AR231X
++	{ "5312",	AR5K_VERSION_MAC,	AR5K_SREV_AR5312_R2 },
++	{ "5312",	AR5K_VERSION_MAC,	AR5K_SREV_AR5312_R7 },
++	{ "2313",	AR5K_VERSION_MAC,	AR5K_SREV_AR2313_R8 },
++	{ "2315",	AR5K_VERSION_MAC,	AR5K_SREV_AR2315_R6 },
++	{ "2315",	AR5K_VERSION_MAC,	AR5K_SREV_AR2315_R7 },
++	{ "2317",	AR5K_VERSION_MAC,	AR5K_SREV_AR2317_R1 },
++	{ "2317",	AR5K_VERSION_MAC,	AR5K_SREV_AR2317_R2 },
++#else
+ 	{ "5210",	AR5K_VERSION_MAC,	AR5K_SREV_AR5210 },
+ 	{ "5311",	AR5K_VERSION_MAC,	AR5K_SREV_AR5311 },
+ 	{ "5311A",	AR5K_VERSION_MAC,	AR5K_SREV_AR5311A },
+@@ -117,6 +126,7 @@ static const struct ath5k_srev_name srev
+ 	{ "5418",	AR5K_VERSION_MAC,	AR5K_SREV_AR5418 },
+ 	{ "2425",	AR5K_VERSION_MAC,	AR5K_SREV_AR2425 },
+ 	{ "2417",	AR5K_VERSION_MAC,	AR5K_SREV_AR2417 },
++#endif
+ 	{ "xxxxx",	AR5K_VERSION_MAC,	AR5K_SREV_UNKNOWN },
+ 	{ "5110",	AR5K_VERSION_RAD,	AR5K_SREV_RAD_5110 },
+ 	{ "5111",	AR5K_VERSION_RAD,	AR5K_SREV_RAD_5111 },
+@@ -132,6 +142,10 @@ static const struct ath5k_srev_name srev
+ 	{ "5413",	AR5K_VERSION_RAD,	AR5K_SREV_RAD_5413 },
+ 	{ "5424",	AR5K_VERSION_RAD,	AR5K_SREV_RAD_5424 },
+ 	{ "5133",	AR5K_VERSION_RAD,	AR5K_SREV_RAD_5133 },
++#ifdef CONFIG_ATHEROS_AR231X
++	{ "2316",	AR5K_VERSION_RAD,	AR5K_SREV_RAD_2316 },
++	{ "2317",	AR5K_VERSION_RAD,	AR5K_SREV_RAD_2317 },
++#endif
+ 	{ "xxxxx",	AR5K_VERSION_RAD,	AR5K_SREV_UNKNOWN },
+ };
  
-+#define AR_RTC_9300_SOC_PLL_DIV_INT          0x0000003f
-+#define AR_RTC_9300_SOC_PLL_DIV_INT_S        0
-+#define AR_RTC_9300_SOC_PLL_DIV_FRAC         0x000fffc0
-+#define AR_RTC_9300_SOC_PLL_DIV_FRAC_S       6
-+#define AR_RTC_9300_SOC_PLL_REFDIV           0x01f00000
-+#define AR_RTC_9300_SOC_PLL_REFDIV_S         20
-+#define AR_RTC_9300_SOC_PLL_CLKSEL           0x06000000
-+#define AR_RTC_9300_SOC_PLL_CLKSEL_S         25
-+#define AR_RTC_9300_SOC_PLL_BYPASS           0x08000000
-+
- #define AR_RTC_9300_PLL_DIV          0x000003ff
- #define AR_RTC_9300_PLL_DIV_S        0
- #define AR_RTC_9300_PLL_REFDIV       0x00003C00
- #define AR_RTC_9300_PLL_REFDIV_S     10
- #define AR_RTC_9300_PLL_CLKSEL       0x0000C000
- #define AR_RTC_9300_PLL_CLKSEL_S     14
-+#define AR_RTC_9300_PLL_BYPASS       0x00010000
+--- a/drivers/net/wireless/ath/ath5k/led.c
++++ b/drivers/net/wireless/ath/ath5k/led.c
+@@ -163,14 +163,20 @@ int ath5k_init_leds(struct ath5k_hw *ah)
+ {
+ 	int ret = 0;
+ 	struct ieee80211_hw *hw = ah->hw;
++#ifndef CONFIG_ATHEROS_AR231X
+ 	struct pci_dev *pdev = ah->pdev;
++#endif
+ 	char name[ATH5K_LED_MAX_NAME_LEN + 1];
+ 	const struct pci_device_id *match;
  
- #define AR_RTC_9160_PLL_DIV	0x000003ff
- #define AR_RTC_9160_PLL_DIV_S   0
---- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
-+++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
-@@ -978,7 +978,7 @@ static bool ath9k_rx_prepare(struct ath9
- 	struct ath_hw *ah = common->ah;
- 	struct ath_htc_rx_status *rxstatus;
- 	struct ath_rx_status rx_stats;
--	bool decrypt_error;
-+	bool decrypt_error = false;
+ 	if (!ah->pdev)
+ 		return 0;
  
- 	if (skb->len < HTC_RX_FRAME_HEADER_SIZE) {
- 		ath_err(common, "Corrupted RX frame, dropping (len: %d)\n",
++#ifdef CONFIG_ATHEROS_AR231X
++	match = NULL;
++#else
+ 	match = pci_match_id(&ath5k_led_devices[0], pdev);
++#endif
+ 	if (match) {
+ 		__set_bit(ATH_STAT_LEDSOFT, ah->status);
+ 		ah->led_pin = ATH_PIN(match->driver_data);
+--- a/drivers/net/wireless/ath/ath5k/debug.c
++++ b/drivers/net/wireless/ath/ath5k/debug.c
+@@ -65,6 +65,7 @@
+ 
+ #include <linux/seq_file.h>
+ #include <linux/list.h>
++#include <linux/vmalloc.h>
+ #include "debug.h"
+ #include "ath5k.h"
+ #include "reg.h"

+ 1 - 1
package/kernel/mac80211/patches/310-ap_scan.patch

@@ -1,6 +1,6 @@
 --- a/net/mac80211/cfg.c
 +++ b/net/mac80211/cfg.c
-@@ -1903,7 +1903,7 @@ static int ieee80211_scan(struct wiphy *
+@@ -1895,7 +1895,7 @@ static int ieee80211_scan(struct wiphy *
  		 * the  frames sent while scanning on other channel will be
  		 * lost)
  		 */

+ 1 - 1
package/kernel/mac80211/patches/400-ath_move_debug_code.patch

@@ -12,7 +12,7 @@
  ccflags-y += -D__CHECK_ENDIAN__
 --- a/drivers/net/wireless/ath/ath.h
 +++ b/drivers/net/wireless/ath/ath.h
-@@ -295,13 +295,6 @@ void _ath_dbg(struct ath_common *common,
+@@ -299,13 +299,6 @@ void _ath_dbg(struct ath_common *common,
  #endif /* CPTCFG_ATH_DEBUG */
  
  /** Returns string describing opmode, or NULL if unknown mode. */

+ 1 - 1
package/kernel/mac80211/patches/403-ath_regd_optional.patch

@@ -58,7 +58,7 @@
  	---help---
 --- a/.local-symbols
 +++ b/.local-symbols
-@@ -116,6 +116,7 @@ RTL8187_LEDS=
+@@ -112,6 +112,7 @@ RTL8187_LEDS=
  ATH_COMMON=
  ATH_CARDS=
  ATH_DEBUG=

+ 2 - 2
package/kernel/mac80211/patches/405-regd_no_assoc_hints.patch

@@ -1,6 +1,6 @@
 --- a/net/wireless/reg.c
 +++ b/net/wireless/reg.c
-@@ -2072,6 +2072,8 @@ void regulatory_hint_country_ie(struct w
+@@ -2112,6 +2112,8 @@ void regulatory_hint_country_ie(struct w
  	enum environment_cap env = ENVIRON_ANY;
  	struct regulatory_request *request = NULL, *lr;
  
@@ -9,7 +9,7 @@
  	/* IE len must be evenly divisible by 2 */
  	if (country_ie_len & 0x01)
  		return;
-@@ -2268,6 +2270,7 @@ static void restore_regulatory_settings(
+@@ -2308,6 +2310,7 @@ static void restore_regulatory_settings(
  
  void regulatory_hint_disconnect(void)
  {

+ 2 - 2
package/kernel/mac80211/patches/410-ath9k_allow_adhoc_and_ap.patch

@@ -1,10 +1,10 @@
 --- a/drivers/net/wireless/ath/ath9k/init.c
 +++ b/drivers/net/wireless/ath/ath9k/init.c
-@@ -655,6 +655,7 @@ static const struct ieee80211_iface_limi
+@@ -670,6 +670,7 @@ static const struct ieee80211_iface_limi
  				 BIT(NL80211_IFTYPE_AP) },
  	{ .max = 1,	.types = BIT(NL80211_IFTYPE_P2P_CLIENT) |
  				 BIT(NL80211_IFTYPE_P2P_GO) },
 +	{ .max = 1,	.types = BIT(NL80211_IFTYPE_ADHOC) },
  };
  
- static const struct ieee80211_iface_limit if_dfs_limits[] = {
+ static const struct ieee80211_iface_limit wds_limits[] = {

+ 3 - 3
package/kernel/mac80211/patches/411-ath5k_allow_adhoc_and_ap.patch

@@ -18,7 +18,7 @@
  		goto end;
 --- a/drivers/net/wireless/ath/ath5k/base.c
 +++ b/drivers/net/wireless/ath/ath5k/base.c
-@@ -1937,7 +1937,7 @@ ath5k_beacon_send(struct ath5k_hw *ah)
+@@ -1962,7 +1962,7 @@ ath5k_beacon_send(struct ath5k_hw *ah)
  	}
  
  	if ((ah->opmode == NL80211_IFTYPE_AP && ah->num_ap_vifs +
@@ -27,7 +27,7 @@
  			ah->opmode == NL80211_IFTYPE_MESH_POINT) {
  		u64 tsf = ath5k_hw_get_tsf64(ah);
  		u32 tsftu = TSF_TO_TU(tsf);
-@@ -2023,7 +2023,7 @@ ath5k_beacon_update_timers(struct ath5k_
+@@ -2048,7 +2048,7 @@ ath5k_beacon_update_timers(struct ath5k_
  
  	intval = ah->bintval & AR5K_BEACON_PERIOD;
  	if (ah->opmode == NL80211_IFTYPE_AP && ah->num_ap_vifs
@@ -36,7 +36,7 @@
  		intval /= ATH_BCBUF;	/* staggered multi-bss beacons */
  		if (intval < 15)
  			ATH5K_WARN(ah, "intval %u is too low, min 15\n",
-@@ -2490,6 +2490,7 @@ static const struct ieee80211_iface_limi
+@@ -2515,6 +2515,7 @@ static const struct ieee80211_iface_limi
  				 BIT(NL80211_IFTYPE_MESH_POINT) |
  #endif
  				 BIT(NL80211_IFTYPE_AP) },

+ 1 - 1
package/kernel/mac80211/patches/432-ath5k_add_pciids.patch

@@ -1,6 +1,6 @@
 --- a/drivers/net/wireless/ath/ath5k/pci.c
 +++ b/drivers/net/wireless/ath/ath5k/pci.c
-@@ -48,6 +48,8 @@ static DEFINE_PCI_DEVICE_TABLE(ath5k_pci
+@@ -48,6 +48,8 @@ static const struct pci_device_id ath5k_
  	{ PCI_VDEVICE(ATHEROS, 0x001b) }, /* 5413 Eagle */
  	{ PCI_VDEVICE(ATHEROS, 0x001c) }, /* PCI-E cards */
  	{ PCI_VDEVICE(ATHEROS, 0x001d) }, /* 2417 Nala */

+ 3 - 3
package/kernel/mac80211/patches/440-ath5k_channel_bw_debugfs.patch

@@ -11,7 +11,7 @@ drivers/net/wireless/ath/ath5k/debug.c |   86 ++++++++++++++++++++++++++++++++
 
 --- a/drivers/net/wireless/ath/ath5k/debug.c
 +++ b/drivers/net/wireless/ath/ath5k/debug.c
-@@ -821,6 +821,97 @@ static const struct file_operations fops
+@@ -822,6 +822,97 @@ static const struct file_operations fops
  	.llseek = default_llseek,
  };
  
@@ -109,7 +109,7 @@ drivers/net/wireless/ath/ath5k/debug.c |   86 ++++++++++++++++++++++++++++++++
  
  /* debugfs: queues etc */
  
-@@ -914,6 +1005,9 @@ ath5k_debug_init_device(struct ath5k_hw 
+@@ -1009,6 +1100,9 @@ ath5k_debug_init_device(struct ath5k_hw 
  	debugfs_create_file("beacon", S_IWUSR | S_IRUSR, phydir, ah,
  			    &fops_beacon);
  
@@ -121,7 +121,7 @@ drivers/net/wireless/ath/ath5k/debug.c |   86 ++++++++++++++++++++++++++++++++
  	debugfs_create_file("antenna", S_IWUSR | S_IRUSR, phydir, ah,
 --- a/drivers/net/wireless/ath/ath5k/ath5k.h
 +++ b/drivers/net/wireless/ath/ath5k/ath5k.h
-@@ -1369,6 +1369,7 @@ struct ath5k_hw {
+@@ -1370,6 +1370,7 @@ struct ath5k_hw {
  	u8			ah_coverage_class;
  	bool			ah_ack_bitrate_high;
  	u8			ah_bwmode;

+ 2 - 2
package/kernel/mac80211/patches/500-ath9k_eeprom_debugfs.patch

@@ -1,6 +1,6 @@
 --- a/drivers/net/wireless/ath/ath9k/debug.c
 +++ b/drivers/net/wireless/ath/ath9k/debug.c
-@@ -1289,6 +1289,53 @@ void ath9k_deinit_debug(struct ath_softc
+@@ -1318,6 +1318,53 @@ void ath9k_deinit_debug(struct ath_softc
  	ath9k_spectral_deinit_debug(sc);
  }
  
@@ -54,7 +54,7 @@
  int ath9k_init_debug(struct ath_hw *ah)
  {
  	struct ath_common *common = ath9k_hw_common(ah);
-@@ -1308,6 +1355,8 @@ int ath9k_init_debug(struct ath_hw *ah)
+@@ -1337,6 +1384,8 @@ int ath9k_init_debug(struct ath_hw *ah)
  	ath9k_tx99_init_debug(sc);
  	ath9k_spectral_init_debug(sc);
  

+ 2 - 2
package/kernel/mac80211/patches/501-ath9k-eeprom_endianess.patch

@@ -71,7 +71,7 @@
  
 --- a/drivers/net/wireless/ath/ath9k/hw.h
 +++ b/drivers/net/wireless/ath/ath9k/hw.h
-@@ -724,6 +724,7 @@ enum ath_cal_list {
+@@ -725,6 +725,7 @@ enum ath_cal_list {
  #define AH_USE_EEPROM   0x1
  #define AH_UNPLUGGED    0x2 /* The card has been physically removed. */
  #define AH_FASTCC       0x4
@@ -81,7 +81,7 @@
  	struct ath_ops reg_ops;
 --- a/drivers/net/wireless/ath/ath9k/init.c
 +++ b/drivers/net/wireless/ath/ath9k/init.c
-@@ -518,6 +518,8 @@ static int ath9k_init_softc(u16 devid, s
+@@ -528,6 +528,8 @@ static int ath9k_init_softc(u16 devid, s
  		ah->is_clk_25mhz = pdata->is_clk_25mhz;
  		ah->get_mac_revision = pdata->get_mac_revision;
  		ah->external_reset = pdata->external_reset;

+ 1 - 1
package/kernel/mac80211/patches/502-ath9k_ahb_init.patch

@@ -1,6 +1,6 @@
 --- a/drivers/net/wireless/ath/ath9k/init.c
 +++ b/drivers/net/wireless/ath/ath9k/init.c
-@@ -904,23 +904,23 @@ static int __init ath9k_init(void)
+@@ -976,23 +976,23 @@ static int __init ath9k_init(void)
  {
  	int error;
  

+ 1 - 1
package/kernel/mac80211/patches/511-ath9k_reduce_rxbuf.patch

@@ -1,6 +1,6 @@
 --- a/drivers/net/wireless/ath/ath9k/ath9k.h
 +++ b/drivers/net/wireless/ath/ath9k/ath9k.h
-@@ -89,7 +89,7 @@ int ath_descdma_setup(struct ath_softc *
+@@ -88,7 +88,7 @@ int ath_descdma_setup(struct ath_softc *
  		(_l) &= ((_sz) - 1);		\
  	} while (0)
  

+ 3 - 3
package/kernel/mac80211/patches/512-ath9k_channelbw_debugfs.patch

@@ -1,6 +1,6 @@
 --- a/drivers/net/wireless/ath/ath9k/debug.c
 +++ b/drivers/net/wireless/ath/ath9k/debug.c
-@@ -1336,6 +1336,52 @@ static const struct file_operations fops
+@@ -1365,6 +1365,52 @@ static const struct file_operations fops
  	.owner = THIS_MODULE
  };
  
@@ -53,7 +53,7 @@
  int ath9k_init_debug(struct ath_hw *ah)
  {
  	struct ath_common *common = ath9k_hw_common(ah);
-@@ -1357,6 +1403,8 @@ int ath9k_init_debug(struct ath_hw *ah)
+@@ -1386,6 +1432,8 @@ int ath9k_init_debug(struct ath_hw *ah)
  
  	debugfs_create_file("eeprom", S_IRUSR, sc->debug.debugfs_phy, sc,
  			    &fops_eeprom);
@@ -64,7 +64,7 @@
  	debugfs_create_file("interrupt", S_IRUSR, sc->debug.debugfs_phy, sc,
 --- a/drivers/net/wireless/ath/ath.h
 +++ b/drivers/net/wireless/ath/ath.h
-@@ -140,6 +140,7 @@ struct ath_common {
+@@ -141,6 +141,7 @@ struct ath_common {
  	int debug_mask;
  	enum ath_device_state state;
  	unsigned long op_flags;

+ 2 - 2
package/kernel/mac80211/patches/513-ath9k_add_pci_ids.patch

@@ -10,7 +10,7 @@
  	case AR5416_AR9100_DEVID:
 --- a/drivers/net/wireless/ath/ath9k/hw.h
 +++ b/drivers/net/wireless/ath/ath9k/hw.h
-@@ -34,6 +34,7 @@
+@@ -35,6 +35,7 @@
  
  #define ATHEROS_VENDOR_ID	0x168c
  
@@ -20,7 +20,7 @@
  #define AR9160_DEVID_PCI	0x0027
 --- a/drivers/net/wireless/ath/ath9k/pci.c
 +++ b/drivers/net/wireless/ath/ath9k/pci.c
-@@ -658,6 +658,7 @@ static DEFINE_PCI_DEVICE_TABLE(ath_pci_i
+@@ -658,6 +658,7 @@ static const struct pci_device_id ath_pc
  	{ PCI_VDEVICE(ATHEROS, 0x0036),
  	  .driver_data = ATH9K_PCI_BT_ANT_DIV },
  

+ 3 - 3
package/kernel/mac80211/patches/520-mac80211_cur_txpower.patch

@@ -1,6 +1,6 @@
 --- a/include/net/mac80211.h
 +++ b/include/net/mac80211.h
-@@ -1718,6 +1718,7 @@ struct ieee80211_hw {
+@@ -1754,6 +1754,7 @@ struct ieee80211_hw {
  	u8 max_tx_aggregation_subframes;
  	u8 offchannel_tx_hw_queue;
  	u8 radiotap_mcs_details;
@@ -10,7 +10,7 @@
  	u8 uapsd_queues;
 --- a/net/mac80211/cfg.c
 +++ b/net/mac80211/cfg.c
-@@ -2084,7 +2084,9 @@ static int ieee80211_get_tx_power(struct
+@@ -2081,7 +2081,9 @@ static int ieee80211_get_tx_power(struct
  	struct ieee80211_local *local = wiphy_priv(wiphy);
  	struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
  
@@ -23,7 +23,7 @@
  		*dbm = sdata->vif.bss_conf.txpower;
 --- a/net/mac80211/main.c
 +++ b/net/mac80211/main.c
-@@ -156,6 +156,7 @@ static u32 ieee80211_hw_conf_chan(struct
+@@ -157,6 +157,7 @@ static u32 ieee80211_hw_conf_chan(struct
  
  	if (local->hw.conf.power_level != power) {
  		changed |= IEEE80211_CONF_CHANGE_POWER;

+ 5 - 5
package/kernel/mac80211/patches/521-ath9k_cur_txpower.patch

@@ -1,7 +1,7 @@
 --- a/drivers/net/wireless/ath/ath9k/main.c
 +++ b/drivers/net/wireless/ath/ath9k/main.c
-@@ -310,8 +310,12 @@ static int ath_reset_internal(struct ath
- 	    (sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL))
+@@ -323,8 +323,12 @@ int ath_reset_internal(struct ath_softc 
+ 	    sc->cur_chan->offchannel)
  		ath9k_mci_set_txpower(sc, true, false);
  
 -	if (!ath_complete_reset(sc, true))
@@ -14,10 +14,10 @@
  
  out:
  	spin_unlock_bh(&sc->sc_pcu_lock);
-@@ -1405,6 +1409,7 @@ static int ath9k_config(struct ieee80211
- 		sc->config.txpowlimit = 2 * conf->power_level;
+@@ -1453,6 +1457,7 @@ static int ath9k_config(struct ieee80211
+ 		sc->cur_chan->txpower = 2 * conf->power_level;
  		ath9k_cmn_update_txpow(ah, sc->curtxpow,
- 				       sc->config.txpowlimit, &sc->curtxpow);
+ 				       sc->cur_chan->txpower, &sc->curtxpow);
 +		hw->cur_power_level = sc->curtxpow / 2;
  	}
  

+ 21 - 21
package/kernel/mac80211/patches/522-mac80211_configure_antenna_gain.patch

@@ -1,6 +1,6 @@
 --- a/include/net/cfg80211.h
 +++ b/include/net/cfg80211.h
-@@ -2207,6 +2207,7 @@ struct cfg80211_qos_map {
+@@ -2214,6 +2214,7 @@ struct cfg80211_qos_map {
   *	(as advertised by the nl80211 feature flag.)
   * @get_tx_power: store the current TX power into the dbm variable;
   *	return 0 if successful
@@ -8,7 +8,7 @@
   *
   * @set_wds_peer: set the WDS peer for a WDS interface
   *
-@@ -2431,6 +2432,7 @@ struct cfg80211_ops {
+@@ -2450,6 +2451,7 @@ struct cfg80211_ops {
  				enum nl80211_tx_power_setting type, int mbm);
  	int	(*get_tx_power)(struct wiphy *wiphy, struct wireless_dev *wdev,
  				int *dbm);
@@ -18,7 +18,7 @@
  				const u8 *addr);
 --- a/include/net/mac80211.h
 +++ b/include/net/mac80211.h
-@@ -1032,6 +1032,7 @@ enum ieee80211_smps_mode {
+@@ -1075,6 +1075,7 @@ enum ieee80211_smps_mode {
   *
   * @power_level: requested transmit power (in dBm), backward compatibility
   *	value only that is set to the minimum of all interfaces
@@ -26,7 +26,7 @@
   *
   * @chandef: the channel definition to tune to
   * @radar_enabled: whether radar detection is enabled
-@@ -1053,6 +1054,7 @@ struct ieee80211_conf {
+@@ -1096,6 +1097,7 @@ struct ieee80211_conf {
  	u32 flags;
  	int power_level, dynamic_ps_timeout;
  	int max_sleep_period;
@@ -36,9 +36,9 @@
  	u8 ps_dtim_period;
 --- a/include/uapi/linux/nl80211.h
 +++ b/include/uapi/linux/nl80211.h
-@@ -1591,6 +1591,9 @@ enum nl80211_commands {
-  *	creation then the new interface will be owned by the netlink socket
-  *	that created it and will be destroyed when the socket is closed
+@@ -1638,6 +1638,9 @@ enum nl80211_commands {
+  * @NL80211_ATTR_SMPS_MODE: SMPS mode to use (ap mode). see
+  *	&enum nl80211_smps_mode.
   *
 + * @NL80211_ATTR_WIPHY_ANTENNA_GAIN: Configured antenna gain. Used to reduce
 + *	transmit power to stay within regulatory limits. u32, dBi.
@@ -46,9 +46,9 @@
   * @NL80211_ATTR_MAX: highest attribute number currently defined
   * @__NL80211_ATTR_AFTER_LAST: internal use
   */
-@@ -1931,6 +1934,8 @@ enum nl80211_attrs {
- 	NL80211_ATTR_CSA_C_OFFSETS_TX,
- 	NL80211_ATTR_MAX_CSA_COUNTERS,
+@@ -1990,6 +1993,8 @@ enum nl80211_attrs {
+ 
+ 	NL80211_ATTR_SMPS_MODE,
  
 +	NL80211_ATTR_WIPHY_ANTENNA_GAIN,
 +
@@ -57,7 +57,7 @@
  	__NL80211_ATTR_AFTER_LAST,
 --- a/net/mac80211/cfg.c
 +++ b/net/mac80211/cfg.c
-@@ -2094,6 +2094,19 @@ static int ieee80211_get_tx_power(struct
+@@ -2091,6 +2091,19 @@ static int ieee80211_get_tx_power(struct
  	return 0;
  }
  
@@ -77,7 +77,7 @@
  static int ieee80211_set_wds_peer(struct wiphy *wiphy, struct net_device *dev,
  				  const u8 *addr)
  {
-@@ -3517,6 +3530,7 @@ const struct cfg80211_ops mac80211_confi
+@@ -3572,6 +3585,7 @@ const struct cfg80211_ops mac80211_confi
  	.set_wiphy_params = ieee80211_set_wiphy_params,
  	.set_tx_power = ieee80211_set_tx_power,
  	.get_tx_power = ieee80211_get_tx_power,
@@ -87,7 +87,7 @@
  	CFG80211_TESTMODE_CMD(ieee80211_testmode_cmd)
 --- a/net/mac80211/ieee80211_i.h
 +++ b/net/mac80211/ieee80211_i.h
-@@ -1243,6 +1243,7 @@ struct ieee80211_local {
+@@ -1280,6 +1280,7 @@ struct ieee80211_local {
  	int dynamic_ps_forced_timeout;
  
  	int user_power_level; /* in dBm, for all interfaces */
@@ -97,7 +97,7 @@
  
 --- a/net/mac80211/main.c
 +++ b/net/mac80211/main.c
-@@ -97,7 +97,7 @@ static u32 ieee80211_hw_conf_chan(struct
+@@ -98,7 +98,7 @@ static u32 ieee80211_hw_conf_chan(struct
  	struct ieee80211_sub_if_data *sdata;
  	struct cfg80211_chan_def chandef = {};
  	u32 changed = 0;
@@ -106,7 +106,7 @@
  	u32 offchannel_flag;
  
  	offchannel_flag = local->hw.conf.flags & IEEE80211_CONF_OFFCHANNEL;
-@@ -154,6 +154,12 @@ static u32 ieee80211_hw_conf_chan(struct
+@@ -155,6 +155,12 @@ static u32 ieee80211_hw_conf_chan(struct
  	}
  	rcu_read_unlock();
  
@@ -119,7 +119,7 @@
  	if (local->hw.conf.power_level != power) {
  		changed |= IEEE80211_CONF_CHANGE_POWER;
  		local->hw.cur_power_level = power;
-@@ -584,6 +590,7 @@ struct ieee80211_hw *ieee80211_alloc_hw(
+@@ -586,6 +592,7 @@ struct ieee80211_hw *ieee80211_alloc_hw(
  					 IEEE80211_RADIOTAP_MCS_HAVE_BW;
  	local->hw.radiotap_vht_details = IEEE80211_RADIOTAP_VHT_KNOWN_GI |
  					 IEEE80211_RADIOTAP_VHT_KNOWN_BANDWIDTH;
@@ -129,15 +129,15 @@
  	local->user_power_level = IEEE80211_UNSET_POWER_LEVEL;
 --- a/net/wireless/nl80211.c
 +++ b/net/wireless/nl80211.c
-@@ -387,6 +387,7 @@ static const struct nla_policy nl80211_p
- 	[NL80211_ATTR_TDLS_PEER_CAPABILITY] = { .type = NLA_U32 },
- 	[NL80211_ATTR_IFACE_SOCKET_OWNER] = { .type = NLA_FLAG },
- 	[NL80211_ATTR_CSA_C_OFFSETS_TX] = { .type = NLA_BINARY },
+@@ -395,6 +395,7 @@ static const struct nla_policy nl80211_p
+ 	[NL80211_ATTR_USER_PRIO] = { .type = NLA_U8 },
+ 	[NL80211_ATTR_ADMITTED_TIME] = { .type = NLA_U16 },
+ 	[NL80211_ATTR_SMPS_MODE] = { .type = NLA_U8 },
 +	[NL80211_ATTR_WIPHY_ANTENNA_GAIN] = { .type = NLA_U32 },
  };
  
  /* policy for the key attributes */
-@@ -2162,6 +2163,20 @@ static int nl80211_set_wiphy(struct sk_b
+@@ -2179,6 +2180,20 @@ static int nl80211_set_wiphy(struct sk_b
  			return result;
  	}
  

+ 0 - 34
package/kernel/mac80211/patches/523-ath9k_use_configured_antenna_gain.patch

@@ -1,34 +0,0 @@
---- a/drivers/net/wireless/ath/ath.h
-+++ b/drivers/net/wireless/ath/ath.h
-@@ -83,6 +83,7 @@ struct ath_regulatory {
- 	u16 max_power_level;
- 	u16 current_rd;
- 	int16_t power_limit;
-+	int16_t max_antenna_gain;
- 	struct reg_dmn_pair_mapping *regpair;
- };
- 
---- a/drivers/net/wireless/ath/ath9k/hw.c
-+++ b/drivers/net/wireless/ath/ath9k/hw.c
-@@ -2724,7 +2724,7 @@ void ath9k_hw_apply_txpower(struct ath_h
- 	channel = chan->chan;
- 	chan_pwr = min_t(int, channel->max_power * 2, MAX_RATE_POWER);
- 	new_pwr = min_t(int, chan_pwr, reg->power_limit);
--	max_gain = chan_pwr - new_pwr + channel->max_antenna_gain * 2;
-+	max_gain = chan_pwr - new_pwr + reg->max_antenna_gain * 2;
- 
- 	ant_gain = get_antenna_gain(ah, chan);
- 	if (ant_gain > max_gain)
---- a/drivers/net/wireless/ath/ath9k/main.c
-+++ b/drivers/net/wireless/ath/ath9k/main.c
-@@ -1405,7 +1405,10 @@ static int ath9k_config(struct ieee80211
- 	}
- 
- 	if (changed & IEEE80211_CONF_CHANGE_POWER) {
-+		struct ath_regulatory *reg = ath9k_hw_regulatory(ah);
-+
- 		ath_dbg(common, CONFIG, "Set power: %d\n", conf->power_level);
-+		reg->max_antenna_gain = conf->max_antenna_gain;
- 		sc->config.txpowlimit = 2 * conf->power_level;
- 		ath9k_cmn_update_txpow(ah, sc->curtxpow,
- 				       sc->config.txpowlimit, &sc->curtxpow);

+ 10 - 10
package/kernel/mac80211/patches/530-ath9k_extra_leds.patch

@@ -1,6 +1,6 @@
 --- a/drivers/net/wireless/ath/ath9k/ath9k.h
 +++ b/drivers/net/wireless/ath/ath9k/ath9k.h
-@@ -565,6 +565,9 @@ static inline int ath9k_dump_btcoex(stru
+@@ -799,6 +799,9 @@ static inline int ath9k_dump_btcoex(stru
  void ath_init_leds(struct ath_softc *sc);
  void ath_deinit_leds(struct ath_softc *sc);
  void ath_fill_led_pin(struct ath_softc *sc);
@@ -10,9 +10,9 @@
  #else
  static inline void ath_init_leds(struct ath_softc *sc)
  {
-@@ -703,6 +706,13 @@ void ath_ant_comb_scan(struct ath_softc 
- #define PS_BEACON_SYNC            BIT(4)
- #define PS_WAIT_FOR_ANI           BIT(5)
+@@ -939,6 +942,13 @@ void ath_ant_comb_scan(struct ath_softc 
+ 
+ #define ATH9K_NUM_CHANCTX  2 /* supports 2 operating channels */
  
 +struct ath_led {
 +	struct list_head list;
@@ -24,8 +24,8 @@
  struct ath_softc {
  	struct ieee80211_hw *hw;
  	struct device *dev;
-@@ -745,9 +755,8 @@ struct ath_softc {
- 	struct ath_beacon beacon;
+@@ -990,9 +1000,8 @@ struct ath_softc {
+ 	spinlock_t chan_lock;
  
  #ifdef CPTCFG_MAC80211_LEDS
 -	bool led_registered;
@@ -35,7 +35,7 @@
 +	struct list_head leds;
  #endif
  
- 	struct ath9k_hw_cal_data caldata;
+ #ifdef CPTCFG_ATH9K_DEBUGFS
 --- a/drivers/net/wireless/ath/ath9k/gpio.c
 +++ b/drivers/net/wireless/ath/ath9k/gpio.c
 @@ -24,40 +24,102 @@
@@ -162,7 +162,7 @@
  void ath_fill_led_pin(struct ath_softc *sc)
 --- a/drivers/net/wireless/ath/ath9k/init.c
 +++ b/drivers/net/wireless/ath/ath9k/init.c
-@@ -815,7 +815,7 @@ int ath9k_init_device(u16 devid, struct 
+@@ -889,7 +889,7 @@ int ath9k_init_device(u16 devid, struct 
  
  #ifdef CPTCFG_MAC80211_LEDS
  	/* must be initialized before ieee80211_register_hw */
@@ -173,7 +173,7 @@
  #endif
 --- a/drivers/net/wireless/ath/ath9k/debug.c
 +++ b/drivers/net/wireless/ath/ath9k/debug.c
-@@ -1381,6 +1381,61 @@ static const struct file_operations fops
+@@ -1410,6 +1410,61 @@ static const struct file_operations fops
  	.llseek = default_llseek,
  };
  
@@ -235,7 +235,7 @@
  
  int ath9k_init_debug(struct ath_hw *ah)
  {
-@@ -1405,6 +1460,10 @@ int ath9k_init_debug(struct ath_hw *ah)
+@@ -1434,6 +1489,10 @@ int ath9k_init_debug(struct ath_hw *ah)
  			    &fops_eeprom);
  	debugfs_create_file("chanbw", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
  			    sc, &fops_chanbw);

+ 9 - 9
package/kernel/mac80211/patches/542-ath9k_debugfs_diag.patch

@@ -1,6 +1,6 @@
 --- a/drivers/net/wireless/ath/ath9k/debug.c
 +++ b/drivers/net/wireless/ath/ath9k/debug.c
-@@ -1437,6 +1437,50 @@ static const struct file_operations fops
+@@ -1466,6 +1466,50 @@ static const struct file_operations fops
  #endif
  
  
@@ -51,7 +51,7 @@
  int ath9k_init_debug(struct ath_hw *ah)
  {
  	struct ath_common *common = ath9k_hw_common(ah);
-@@ -1464,6 +1508,8 @@ int ath9k_init_debug(struct ath_hw *ah)
+@@ -1493,6 +1537,8 @@ int ath9k_init_debug(struct ath_hw *ah)
  	debugfs_create_file("gpio_led", S_IWUSR,
  			   sc->debug.debugfs_phy, sc, &fops_gpio_led);
  #endif
@@ -62,7 +62,7 @@
  	debugfs_create_file("interrupt", S_IRUSR, sc->debug.debugfs_phy, sc,
 --- a/drivers/net/wireless/ath/ath9k/hw.h
 +++ b/drivers/net/wireless/ath/ath9k/hw.h
-@@ -482,6 +482,12 @@ enum {
+@@ -483,6 +483,12 @@ enum {
  	ATH9K_RESET_COLD,
  };
  
@@ -75,7 +75,7 @@
  struct ath9k_hw_version {
  	u32 magic;
  	u16 devid;
-@@ -762,6 +768,8 @@ struct ath_hw {
+@@ -763,6 +769,8 @@ struct ath_hw {
  	u32 rfkill_polarity;
  	u32 ah_flags;
  
@@ -84,7 +84,7 @@
  	bool reset_power_on;
  	bool htc_reset_init;
  
-@@ -1013,6 +1021,7 @@ void ath9k_hw_check_nav(struct ath_hw *a
+@@ -1017,6 +1025,7 @@ void ath9k_hw_check_nav(struct ath_hw *a
  bool ath9k_hw_check_alive(struct ath_hw *ah);
  
  bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode);
@@ -94,9 +94,9 @@
  struct ath_gen_timer *ath_gen_timer_alloc(struct ath_hw *ah,
 --- a/drivers/net/wireless/ath/ath9k/hw.c
 +++ b/drivers/net/wireless/ath/ath9k/hw.c
-@@ -1738,6 +1738,20 @@ fail:
- 	return -EINVAL;
+@@ -1763,6 +1763,20 @@ u32 ath9k_hw_get_tsf_offset(struct times
  }
+ EXPORT_SYMBOL(ath9k_hw_get_tsf_offset);
  
 +void ath9k_hw_update_diag(struct ath_hw *ah)
 +{
@@ -115,7 +115,7 @@
  int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
  		   struct ath9k_hw_cal_data *caldata, bool fastcc)
  {
-@@ -1943,6 +1957,7 @@ int ath9k_hw_reset(struct ath_hw *ah, st
+@@ -1965,6 +1979,7 @@ int ath9k_hw_reset(struct ath_hw *ah, st
  		ar9003_hw_disable_phy_restart(ah);
  
  	ath9k_hw_apply_gpio_override(ah);
@@ -125,7 +125,7 @@
  		REG_SET_BIT(ah, AR_BTCOEX_WL_LNADIV, AR_BTCOEX_WL_LNADIV_FORCE_ON);
 --- a/drivers/net/wireless/ath/ath9k/main.c
 +++ b/drivers/net/wireless/ath/ath9k/main.c
-@@ -606,6 +606,11 @@ irqreturn_t ath_isr(int irq, void *dev)
+@@ -531,6 +531,11 @@ irqreturn_t ath_isr(int irq, void *dev)
  	ath9k_debug_sync_cause(sc, sync_cause);
  	status &= ah->imask;	/* discard unasked-for bits */
  

+ 4 - 4
package/kernel/mac80211/patches/543-ath9k-allow-to-disable-bands-via-platform-data.patch

@@ -11,7 +11,7 @@
  	int (*external_reset)(void);
 --- a/drivers/net/wireless/ath/ath9k/hw.c
 +++ b/drivers/net/wireless/ath/ath9k/hw.c
-@@ -2331,17 +2331,25 @@ int ath9k_hw_fill_cap_info(struct ath_hw
+@@ -2359,17 +2359,25 @@ int ath9k_hw_fill_cap_info(struct ath_hw
  	}
  
  	eeval = ah->eep_ops->get_eeprom(ah, EEP_OP_MODE);
@@ -47,7 +47,7 @@
  	    AR_SREV_9285(ah) ||
 --- a/drivers/net/wireless/ath/ath9k/hw.h
 +++ b/drivers/net/wireless/ath/ath9k/hw.h
-@@ -932,6 +932,8 @@ struct ath_hw {
+@@ -933,6 +933,8 @@ struct ath_hw {
  	bool is_clk_25mhz;
  	int (*get_mac_revision)(void);
  	int (*external_reset)(void);
@@ -55,10 +55,10 @@
 +	bool disable_5ghz;
  
  	const struct firmware *eeprom_blob;
- };
+ 
 --- a/drivers/net/wireless/ath/ath9k/init.c
 +++ b/drivers/net/wireless/ath/ath9k/init.c
-@@ -518,6 +518,8 @@ static int ath9k_init_softc(u16 devid, s
+@@ -528,6 +528,8 @@ static int ath9k_init_softc(u16 devid, s
  		ah->is_clk_25mhz = pdata->is_clk_25mhz;
  		ah->get_mac_revision = pdata->get_mac_revision;
  		ah->external_reset = pdata->external_reset;

+ 9 - 9
package/kernel/mac80211/patches/550-ath9k_entropy_from_adc.patch

@@ -1,6 +1,6 @@
 --- a/drivers/net/wireless/ath/ath9k/hw.h
 +++ b/drivers/net/wireless/ath/ath9k/hw.h
-@@ -678,6 +678,7 @@ struct ath_spec_scan {
+@@ -679,6 +679,7 @@ struct ath_spec_scan {
   * @config_pci_powersave:
   * @calibrate: periodic calibration for NF, ANI, IQ, ADC gain, ADC-DC
   *
@@ -8,7 +8,7 @@
   * @spectral_scan_config: set parameters for spectral scan and enable/disable it
   * @spectral_scan_trigger: trigger a spectral scan run
   * @spectral_scan_wait: wait for a spectral scan run to finish
-@@ -701,6 +702,7 @@ struct ath_hw_ops {
+@@ -702,6 +703,7 @@ struct ath_hw_ops {
  			struct ath_hw_antcomb_conf *antconf);
  	void (*antdiv_comb_conf_set)(struct ath_hw *ah,
  			struct ath_hw_antcomb_conf *antconf);
@@ -18,7 +18,7 @@
  	void (*spectral_scan_trigger)(struct ath_hw *ah);
 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
 +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
-@@ -1781,6 +1781,26 @@ static void ar9003_hw_tx99_set_txpower(s
+@@ -1766,6 +1766,26 @@ static void ar9003_hw_tx99_set_txpower(s
  		  ATH9K_POW_SM(p_pwr_array[ALL_TARGET_HT40_14],  0));
  }
  
@@ -45,7 +45,7 @@
  void ar9003_hw_attach_phy_ops(struct ath_hw *ah)
  {
  	struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
-@@ -1816,6 +1836,7 @@ void ar9003_hw_attach_phy_ops(struct ath
+@@ -1796,6 +1816,7 @@ void ar9003_hw_attach_phy_ops(struct ath
  	priv_ops->set_radar_params = ar9003_hw_set_radar_params;
  	priv_ops->fast_chan_change = ar9003_hw_fast_chan_change;
  
@@ -55,7 +55,7 @@
  	ops->spectral_scan_config = ar9003_hw_spectral_scan_config;
 --- a/drivers/net/wireless/ath/ath9k/init.c
 +++ b/drivers/net/wireless/ath/ath9k/init.c
-@@ -646,7 +646,8 @@ static void ath9k_init_txpower_limits(st
+@@ -662,7 +662,8 @@ static void ath9k_init_txpower_limits(st
  	if (ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ)
  		ath9k_init_band_txpower(sc, IEEE80211_BAND_5GHZ);
  
@@ -65,7 +65,7 @@
  }
  
  static const struct ieee80211_iface_limit if_limits[] = {
-@@ -774,6 +775,18 @@ static void ath9k_set_hw_capab(struct at
+@@ -848,6 +849,18 @@ static void ath9k_set_hw_capab(struct at
  	SET_IEEE80211_PERM_ADDR(hw, common->macaddr);
  }
  
@@ -84,7 +84,7 @@
  int ath9k_init_device(u16 devid, struct ath_softc *sc,
  		    const struct ath_bus_ops *bus_ops)
  {
-@@ -822,6 +835,8 @@ int ath9k_init_device(u16 devid, struct 
+@@ -896,6 +909,8 @@ int ath9k_init_device(u16 devid, struct 
  		ARRAY_SIZE(ath9k_tpt_blink));
  #endif
  
@@ -110,7 +110,7 @@
  static inline void ath9k_hw_set_bt_ant_diversity(struct ath_hw *ah, bool enable)
 --- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c
 +++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
-@@ -1232,9 +1232,30 @@ static void ar5008_hw_set_radar_conf(str
+@@ -1231,9 +1231,30 @@ static void ar5008_hw_set_radar_conf(str
  	conf->radar_inband = 8;
  }
  
@@ -141,7 +141,7 @@
  	static const u32 ar5416_cca_regs[6] = {
  		AR_PHY_CCA,
  		AR_PHY_CH1_CCA,
-@@ -1249,6 +1270,8 @@ int ar5008_hw_attach_phy_ops(struct ath_
+@@ -1248,6 +1269,8 @@ int ar5008_hw_attach_phy_ops(struct ath_
  	if (ret)
  	    return ret;
  

+ 6 - 6
package/kernel/mac80211/patches/551-ath9k-ar933x-usb-hang-workaround.patch

@@ -20,7 +20,7 @@
  /******************/
  /* Chip Revisions */
  /******************/
-@@ -1340,6 +1353,9 @@ static bool ath9k_hw_set_reset(struct at
+@@ -1348,6 +1361,9 @@ static bool ath9k_hw_set_reset(struct at
  	if (AR_SREV_9100(ah))
  		udelay(50);
  
@@ -30,7 +30,7 @@
  	return true;
  }
  
-@@ -1439,6 +1455,9 @@ static bool ath9k_hw_chip_reset(struct a
+@@ -1447,6 +1463,9 @@ static bool ath9k_hw_chip_reset(struct a
  		ar9003_hw_internal_regulator_apply(ah);
  	ath9k_hw_init_pll(ah, chan);
  
@@ -40,7 +40,7 @@
  	return true;
  }
  
-@@ -1733,8 +1752,14 @@ static int ath9k_hw_do_fastcc(struct ath
+@@ -1741,8 +1760,14 @@ static int ath9k_hw_do_fastcc(struct ath
  	if (AR_SREV_9271(ah))
  		ar9002_hw_load_ani_reg(ah, chan);
  
@@ -55,9 +55,9 @@
  	return -EINVAL;
  }
  
-@@ -1962,6 +1987,9 @@ int ath9k_hw_reset(struct ath_hw *ah, st
- 	if (AR_SREV_9565(ah) && common->bt_ant_diversity)
- 		REG_SET_BIT(ah, AR_BTCOEX_WL_LNADIV, AR_BTCOEX_WL_LNADIV_FORCE_ON);
+@@ -1990,6 +2015,9 @@ int ath9k_hw_reset(struct ath_hw *ah, st
+ 		ath9k_hw_set_radar_params(ah);
+ 	}
  
 +	if (AR_SREV_9330(ah) || AR_SREV_9340(ah))
 +		ath9k_hw_disable_pll_lock_detect(ah);

+ 18 - 18
package/kernel/mac80211/patches/560-ath9k_pcoem_optional.patch

@@ -1,8 +1,8 @@
 --- a/drivers/net/wireless/ath/ath9k/Kconfig
 +++ b/drivers/net/wireless/ath/ath9k/Kconfig
-@@ -133,6 +133,11 @@ config ATH9K_RFKILL
- 	  seconds. Turn off to save power, but enable it if you have
- 	  a platform that can toggle the RF-Kill GPIO.
+@@ -151,6 +151,11 @@ config ATH9K_CHANNEL_CONTEXT
+ 	 for multi-channel concurrency. Enable this if P2P PowerSave support
+ 	 is required.
  
 +config ATH9K_PCOEM
 +	bool "Atheros ath9k support for PC OEM cards" if EXPERT
@@ -14,7 +14,7 @@
         depends on m
 --- a/drivers/net/wireless/ath/ath9k/Makefile
 +++ b/drivers/net/wireless/ath/ath9k/Makefile
-@@ -31,7 +31,6 @@ ath9k_hw-y:=	\
+@@ -32,7 +32,6 @@ ath9k_hw-y:=	\
  		ar5008_phy.o \
  		ar9002_calib.o \
  		ar9003_calib.o \
@@ -22,15 +22,15 @@
  		calib.o \
  		eeprom.o \
  		eeprom_def.o \
-@@ -48,6 +47,8 @@ ath9k_hw-$(CPTCFG_ATH9K_WOW) += ar9003_w
- 
+@@ -50,6 +49,8 @@ ath9k_hw-$(CPTCFG_ATH9K_WOW) += ar9003_w
  ath9k_hw-$(CPTCFG_ATH9K_BTCOEX_SUPPORT) += btcoex.o \
  					   ar9003_mci.o
+ 
 +ath9k_hw-$(CPTCFG_ATH9K_PCOEM) += ar9003_rtt.o
 +
- obj-$(CPTCFG_ATH9K_HW) += ath9k_hw.o
+ ath9k_hw-$(CPTCFG_ATH9K_DYNACK) += dynack.o
  
- obj-$(CPTCFG_ATH9K_COMMON) += ath9k_common.o
+ obj-$(CPTCFG_ATH9K_HW) += ath9k_hw.o
 --- a/drivers/net/wireless/ath/ath9k/ar9003_rtt.h
 +++ b/drivers/net/wireless/ath/ath9k/ar9003_rtt.h
 @@ -17,6 +17,7 @@
@@ -84,7 +84,7 @@
  #endif
 --- a/drivers/net/wireless/ath/ath9k/hw.h
 +++ b/drivers/net/wireless/ath/ath9k/hw.h
-@@ -244,13 +244,20 @@ enum ath9k_hw_caps {
+@@ -245,13 +245,20 @@ enum ath9k_hw_caps {
  	ATH9K_HW_CAP_2GHZ			= BIT(11),
  	ATH9K_HW_CAP_5GHZ			= BIT(12),
  	ATH9K_HW_CAP_APM			= BIT(13),
@@ -112,7 +112,7 @@
  /*
 --- a/drivers/net/wireless/ath/ath9k/init.c
 +++ b/drivers/net/wireless/ath/ath9k/init.c
-@@ -355,6 +355,9 @@ static void ath9k_init_pcoem_platform(st
+@@ -362,6 +362,9 @@ static void ath9k_init_pcoem_platform(st
  	struct ath9k_hw_capabilities *pCap = &ah->caps;
  	struct ath_common *common = ath9k_hw_common(ah);
  
@@ -124,7 +124,7 @@
  
 --- a/drivers/net/wireless/ath/ath9k/pci.c
 +++ b/drivers/net/wireless/ath/ath9k/pci.c
-@@ -30,6 +30,7 @@ static DEFINE_PCI_DEVICE_TABLE(ath_pci_i
+@@ -30,6 +30,7 @@ static const struct pci_device_id ath_pc
  	{ PCI_VDEVICE(ATHEROS, 0x0029) }, /* PCI   */
  	{ PCI_VDEVICE(ATHEROS, 0x002A) }, /* PCI-E */
  
@@ -132,7 +132,7 @@
  	{ PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
  			 0x002A,
  			 PCI_VENDOR_ID_AZWAVE,
-@@ -82,6 +83,7 @@ static DEFINE_PCI_DEVICE_TABLE(ath_pci_i
+@@ -82,6 +83,7 @@ static const struct pci_device_id ath_pc
  			 PCI_VENDOR_ID_AZWAVE,
  			 0x2C37),
  	  .driver_data = ATH9K_PCI_BT_ANT_DIV },
@@ -140,7 +140,7 @@
  
  	{ PCI_VDEVICE(ATHEROS, 0x002B) }, /* PCI-E */
  	{ PCI_VDEVICE(ATHEROS, 0x002C) }, /* PCI-E 802.11n bonded out */
-@@ -102,6 +104,7 @@ static DEFINE_PCI_DEVICE_TABLE(ath_pci_i
+@@ -102,6 +104,7 @@ static const struct pci_device_id ath_pc
  
  	{ PCI_VDEVICE(ATHEROS, 0x0030) }, /* PCI-E  AR9300 */
  
@@ -148,7 +148,7 @@
  	/* PCI-E CUS198 */
  	{ PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
  			 0x0032,
-@@ -294,10 +297,12 @@ static DEFINE_PCI_DEVICE_TABLE(ath_pci_i
+@@ -294,10 +297,12 @@ static const struct pci_device_id ath_pc
  			 PCI_VENDOR_ID_ASUSTEK,
  			 0x850D),
  	  .driver_data = ATH9K_PCI_NO_PLL_PWRSAVE },
@@ -161,7 +161,7 @@
  	/* PCI-E CUS217 */
  	{ PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
  			 0x0034,
-@@ -657,6 +662,7 @@ static DEFINE_PCI_DEVICE_TABLE(ath_pci_i
+@@ -657,6 +662,7 @@ static const struct pci_device_id ath_pc
  	/* PCI-E AR9565 (WB335) */
  	{ PCI_VDEVICE(ATHEROS, 0x0036),
  	  .driver_data = ATH9K_PCI_BT_ANT_DIV },
@@ -171,7 +171,7 @@
  	{ 0 }
 --- a/drivers/net/wireless/ath/ath9k/reg.h
 +++ b/drivers/net/wireless/ath/ath9k/reg.h
-@@ -891,10 +891,21 @@
+@@ -892,10 +892,21 @@
  	(AR_SREV_9330((_ah)) && \
  	 ((_ah)->hw_version.macRev == AR_SREV_REVISION_9330_12))
  
@@ -194,7 +194,7 @@
  	 ((_ah)->hw_version.macRev >= AR_SREV_REVISION_9485_11))
  #define AR_SREV_9485_OR_LATER(_ah) \
  	(((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9485))
-@@ -910,34 +921,30 @@
+@@ -911,34 +922,30 @@
      (AR_SREV_9285_12_OR_LATER(_ah) && \
       ((REG_READ(_ah, AR_AN_SYNTH9) & 0x7) == 0x1))
  
@@ -239,7 +239,7 @@
  #define AR_SREV_9550(_ah) \
 --- a/.local-symbols
 +++ b/.local-symbols
-@@ -129,6 +129,7 @@ ATH9K_HW=
+@@ -124,6 +124,7 @@ ATH9K_HW=
  ATH9K_COMMON=
  ATH9K_DFS_DEBUGFS=
  ATH9K_BTCOEX_SUPPORT=

+ 1 - 1
package/kernel/mac80211/patches/561-ath9k_remove_gain_tables.patch

@@ -1,6 +1,6 @@
 --- a/drivers/net/wireless/ath/ath9k/ar9003_hw.c
 +++ b/drivers/net/wireless/ath/ath9k/ar9003_hw.c
-@@ -663,9 +663,6 @@ static void ar9003_tx_gain_table_mode5(s
+@@ -670,9 +670,6 @@ static void ar9003_tx_gain_table_mode5(s
  	if (AR_SREV_9485_11_OR_LATER(ah))
  		INIT_INI_ARRAY(&ah->iniModesTxGain,
  			ar9485Modes_green_ob_db_tx_gain_1_1);

+ 2 - 2
package/kernel/mac80211/patches/562-ath9k_ani_ws_detect.patch

@@ -79,7 +79,7 @@
  /**
   * ar9003_hw_set_channel - set channel on single-chip device
   * @ah: atheros hardware structure
-@@ -971,11 +957,6 @@ static bool ar9003_hw_ani_control(struct
+@@ -954,11 +940,6 @@ static bool ar9003_hw_ani_control(struct
  	struct ath_common *common = ath9k_hw_common(ah);
  	struct ath9k_channel *chan = ah->curchan;
  	struct ar5416AniState *aniState = &ah->ani;
@@ -91,7 +91,7 @@
  	s32 value, value2;
  
  	switch (cmd & ah->ani_function) {
-@@ -989,61 +970,6 @@ static bool ar9003_hw_ani_control(struct
+@@ -972,61 +953,6 @@ static bool ar9003_hw_ani_control(struct
  		 */
  		u32 on = param ? 1 : 0;
  

+ 1 - 1
package/kernel/mac80211/patches/563-ath9k_rxorn_intr_fix.patch

@@ -1,6 +1,6 @@
 --- a/drivers/net/wireless/ath/ath9k/main.c
 +++ b/drivers/net/wireless/ath/ath9k/main.c
-@@ -628,8 +628,7 @@ irqreturn_t ath_isr(int irq, void *dev)
+@@ -553,8 +553,7 @@ irqreturn_t ath_isr(int irq, void *dev)
  	 * If a FATAL or RXORN interrupt is received, we have to reset the
  	 * chip immediately.
  	 */

+ 1 - 1
package/kernel/mac80211/patches/564-ath9k_cleanup_reset_debug.patch

@@ -1,6 +1,6 @@
 --- a/drivers/net/wireless/ath/ath9k/debug.c
 +++ b/drivers/net/wireless/ath/ath9k/debug.c
-@@ -846,36 +846,30 @@ static ssize_t read_file_reset(struct fi
+@@ -852,36 +852,30 @@ static ssize_t read_file_reset(struct fi
  			       size_t count, loff_t *ppos)
  {
  	struct ath_softc *sc = file->private_data;

+ 2 - 2
package/kernel/mac80211/patches/565-ath9k_restart_after_nfcal_failure.patch

@@ -117,7 +117,7 @@
  		ath9k_hw_start_nfcal(ah, false);
 --- a/drivers/net/wireless/ath/ath9k/hw.h
 +++ b/drivers/net/wireless/ath/ath9k/hw.h
-@@ -695,10 +695,8 @@ struct ath_hw_ops {
+@@ -696,10 +696,8 @@ struct ath_hw_ops {
  				     bool power_off);
  	void (*rx_enable)(struct ath_hw *ah);
  	void (*set_desc_link)(void *ds, u32 link);
@@ -142,7 +142,7 @@
  
 --- a/drivers/net/wireless/ath/ath9k/debug.c
 +++ b/drivers/net/wireless/ath/ath9k/debug.c
-@@ -857,6 +857,7 @@ static ssize_t read_file_reset(struct fi
+@@ -863,6 +863,7 @@ static ssize_t read_file_reset(struct fi
  		[RESET_TYPE_MAC_HANG] = "MAC Hang",
  		[RESET_TYPE_BEACON_STUCK] = "Stuck Beacon",
  		[RESET_TYPE_MCI] = "MCI Reset",

+ 1 - 1
package/kernel/mac80211/patches/567-ath9k_fix_init_nfcal.patch

@@ -10,7 +10,7 @@
  		set_bit(NFCAL_PENDING, &ah->caldata->cal_flags);
 --- a/drivers/net/wireless/ath/ath9k/hw.c
 +++ b/drivers/net/wireless/ath/ath9k/hw.c
-@@ -1972,8 +1972,10 @@ int ath9k_hw_reset(struct ath_hw *ah, st
+@@ -1994,8 +1994,10 @@ int ath9k_hw_reset(struct ath_hw *ah, st
  	if (ath9k_hw_mci_is_enabled(ah))
  		ar9003_mci_check_bt(ah);
  

+ 1 - 1
package/kernel/mac80211/patches/600-0001-rt2x00-rt2800lib-move-rt2800_drv_data-declaration-in.patch

@@ -22,7 +22,7 @@ Changes since v1: ---
 
 --- a/drivers/net/wireless/rt2x00/rt2800.h
 +++ b/drivers/net/wireless/rt2x00/rt2800.h
-@@ -2958,17 +2958,4 @@ enum rt2800_eeprom_word {
+@@ -2960,17 +2960,4 @@ enum rt2800_eeprom_word {
   */
  #define BCN_TBTT_OFFSET 64
  

+ 2 - 2
package/kernel/mac80211/patches/600-0002-rt2x00-rt2800lib-introduce-RT2800_HAS_HIGH_SHARED_ME.patch

@@ -24,7 +24,7 @@ Changes since v1:
 
 --- a/drivers/net/wireless/rt2x00/rt2800lib.c
 +++ b/drivers/net/wireless/rt2x00/rt2800lib.c
-@@ -7734,6 +7734,7 @@ static int rt2800_probe_rt(struct rt2x00
+@@ -7740,6 +7740,7 @@ static int rt2800_probe_rt(struct rt2x00
  
  int rt2800_probe_hw(struct rt2x00_dev *rt2x00dev)
  {
@@ -32,7 +32,7 @@ Changes since v1:
  	int retval;
  	u32 reg;
  
-@@ -7741,6 +7742,9 @@ int rt2800_probe_hw(struct rt2x00_dev *r
+@@ -7747,6 +7748,9 @@ int rt2800_probe_hw(struct rt2x00_dev *r
  	if (retval)
  		return retval;
  

+ 11 - 11
package/kernel/mac80211/patches/600-0003-rt2x00-rt2800-serialize-shared-memory-access.patch

@@ -187,7 +187,7 @@ Changes since v1: ---
  	}
  
  	/*
-@@ -4898,14 +4931,19 @@ static int rt2800_init_registers(struct 
+@@ -4901,14 +4934,19 @@ static int rt2800_init_registers(struct 
  	/*
  	 * ASIC will keep garbage value after boot, clear encryption keys.
  	 */
@@ -207,7 +207,7 @@ Changes since v1: ---
  	}
  
  	/*
-@@ -5031,8 +5069,10 @@ static int rt2800_wait_bbp_ready(struct 
+@@ -5034,8 +5072,10 @@ static int rt2800_wait_bbp_ready(struct 
  	 * BBP was enabled after firmware was loaded,
  	 * but we need to reactivate it now.
  	 */
@@ -218,7 +218,7 @@ Changes since v1: ---
  	msleep(1);
  
  	for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
-@@ -6728,11 +6768,19 @@ int rt2800_enable_radio(struct rt2x00_de
+@@ -6731,11 +6771,19 @@ int rt2800_enable_radio(struct rt2x00_de
  	/*
  	 * Send signal during boot time to initialize firmware.
  	 */
@@ -239,7 +239,7 @@ Changes since v1: ---
  	msleep(1);
  
  	/*
-@@ -7738,6 +7786,8 @@ int rt2800_probe_hw(struct rt2x00_dev *r
+@@ -7744,6 +7792,8 @@ int rt2800_probe_hw(struct rt2x00_dev *r
  	int retval;
  	u32 reg;
  
@@ -248,7 +248,7 @@ Changes since v1: ---
  	retval = rt2800_probe_rt(rt2x00dev);
  	if (retval)
  		return retval;
-@@ -7817,8 +7867,11 @@ void rt2800_get_tkip_seq(struct ieee8021
+@@ -7823,8 +7873,11 @@ void rt2800_get_tkip_seq(struct ieee8021
  	u32 offset;
  
  	offset = MAC_IVEIV_ENTRY(hw_key_idx);
@@ -486,9 +486,9 @@ Changes since v1: ---
  /*
   * Queue handlers.
   */
-@@ -260,8 +281,10 @@ static int rt2800usb_write_firmware(stru
- 	rt2x00usb_register_multiwrite(rt2x00dev, FIRMWARE_IMAGE_BASE,
- 				      data + offset, length);
+@@ -294,8 +315,10 @@ static int rt2800usb_write_firmware(stru
+ 					      data + offset, length);
+ 	}
  
 +	rt2800_shared_mem_lock(rt2x00dev);
  	rt2x00usb_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0);
@@ -497,7 +497,7 @@ Changes since v1: ---
  
  	/*
  	 * Send firmware request to device to load firmware,
-@@ -276,7 +299,10 @@ static int rt2800usb_write_firmware(stru
+@@ -310,7 +333,10 @@ static int rt2800usb_write_firmware(stru
  	}
  
  	msleep(10);
@@ -508,7 +508,7 @@ Changes since v1: ---
  
  	return 0;
  }
-@@ -294,8 +320,10 @@ static int rt2800usb_init_registers(stru
+@@ -328,8 +354,10 @@ static int rt2800usb_init_registers(stru
  	if (rt2800_wait_csr_ready(rt2x00dev))
  		return -EBUSY;
  
@@ -519,7 +519,7 @@ Changes since v1: ---
  
  	reg = 0;
  	rt2x00_set_field32(&reg, MAC_SYS_CTRL_RESET_CSR, 1);
-@@ -810,6 +838,9 @@ static const struct rt2800_ops rt2800usb
+@@ -859,6 +887,9 @@ static const struct rt2800_ops rt2800usb
  	.drv_write_firmware	= rt2800usb_write_firmware,
  	.drv_init_registers	= rt2800usb_init_registers,
  	.drv_get_txwi		= rt2800usb_get_txwi,

+ 2 - 2
package/kernel/mac80211/patches/600-0004-rt2x00-rt2800lib-fix-beacon-generation-on-RT3593.patch

@@ -29,7 +29,7 @@ Changes since v1: ---
 
 --- a/drivers/net/wireless/rt2x00/rt2800.h
 +++ b/drivers/net/wireless/rt2x00/rt2800.h
-@@ -572,6 +572,7 @@
+@@ -574,6 +574,7 @@
  #define PBF_SYS_CTRL			0x0400
  #define PBF_SYS_CTRL_READY		FIELD32(0x00000080)
  #define PBF_SYS_CTRL_HOST_RAM_WRITE	FIELD32(0x00010000)
@@ -37,7 +37,7 @@ Changes since v1: ---
  
  /*
   * HOST-MCU shared memory
-@@ -2024,6 +2025,8 @@ struct mac_iveiv_entry {
+@@ -2026,6 +2027,8 @@ struct mac_iveiv_entry {
  	  (((__index) < 6) ? (HW_BEACON_BASE4 + ((__index - 4) * 0x0200)) : \
  	  (HW_BEACON_BASE6 - ((__index - 6) * 0x0200))))
  

+ 3 - 3
package/kernel/mac80211/patches/600-0005-rt2x00-rt2800lib-add-hw_beacon_count-field-to-struct.patch

@@ -24,7 +24,7 @@ Signed-off-by: Gabor Juhos <[email protected]>
 
 --- a/drivers/net/wireless/rt2x00/rt2800lib.c
 +++ b/drivers/net/wireless/rt2x00/rt2800lib.c
-@@ -4628,6 +4628,7 @@ EXPORT_SYMBOL_GPL(rt2800_link_tuner);
+@@ -4631,6 +4631,7 @@ EXPORT_SYMBOL_GPL(rt2800_link_tuner);
   */
  static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
  {
@@ -32,7 +32,7 @@ Signed-off-by: Gabor Juhos <[email protected]>
  	u32 reg;
  	u16 eeprom;
  	unsigned int i;
-@@ -4993,7 +4994,7 @@ static int rt2800_init_registers(struct 
+@@ -4996,7 +4997,7 @@ static int rt2800_init_registers(struct 
  	/*
  	 * Clear all beacons
  	 */
@@ -41,7 +41,7 @@ Signed-off-by: Gabor Juhos <[email protected]>
  		rt2800_clear_beacon_register(rt2x00dev, i);
  
  	if (rt2x00_is_usb(rt2x00dev)) {
-@@ -7839,6 +7840,8 @@ int rt2800_probe_hw(struct rt2x00_dev *r
+@@ -7845,6 +7846,8 @@ int rt2800_probe_hw(struct rt2x00_dev *r
  	if (rt2x00_rt(rt2x00dev, RT3593))
  		__set_bit(RT2800_HAS_HIGH_SHARED_MEM, &drv_data->rt2800_flags);
  

+ 2 - 2
package/kernel/mac80211/patches/600-0006-rt2x00-rt2800lib-init-additional-beacon-offset-regis.patch

@@ -11,7 +11,7 @@ Signed-off-by: Gabor Juhos <[email protected]>
 
 --- a/drivers/net/wireless/rt2x00/rt2800.h
 +++ b/drivers/net/wireless/rt2x00/rt2800.h
-@@ -627,6 +627,20 @@
+@@ -629,6 +629,20 @@
   */
  #define PBF_DBG				0x043c
  
@@ -34,7 +34,7 @@ Signed-off-by: Gabor Juhos <[email protected]>
   */
 --- a/drivers/net/wireless/rt2x00/rt2800lib.c
 +++ b/drivers/net/wireless/rt2x00/rt2800lib.c
-@@ -4640,6 +4640,30 @@ static int rt2800_init_registers(struct 
+@@ -4643,6 +4643,30 @@ static int rt2800_init_registers(struct 
  	if (ret)
  		return ret;
  

+ 1 - 1
package/kernel/mac80211/patches/600-0007-rt2x00-rt2800lib-fix-max-supported-beacon-count-for-.patch

@@ -10,7 +10,7 @@ Signed-off-by: Gabor Juhos <[email protected]>
 
 --- a/drivers/net/wireless/rt2x00/rt2800lib.c
 +++ b/drivers/net/wireless/rt2x00/rt2800lib.c
-@@ -7864,7 +7864,10 @@ int rt2800_probe_hw(struct rt2x00_dev *r
+@@ -7870,7 +7870,10 @@ int rt2800_probe_hw(struct rt2x00_dev *r
  	if (rt2x00_rt(rt2x00dev, RT3593))
  		__set_bit(RT2800_HAS_HIGH_SHARED_MEM, &drv_data->rt2800_flags);
  

+ 1 - 1
package/kernel/mac80211/patches/600-0009-rt2x00-rt2800lib-enable-support-for-RT3883.patch

@@ -10,7 +10,7 @@ Signed-off-by: Gabor Juhos <[email protected]>
 
 --- a/drivers/net/wireless/rt2x00/rt2800lib.c
 +++ b/drivers/net/wireless/rt2x00/rt2800lib.c
-@@ -7834,6 +7834,7 @@ static int rt2800_probe_rt(struct rt2x00
+@@ -7840,6 +7840,7 @@ static int rt2800_probe_rt(struct rt2x00
  	case RT3390:
  	case RT3572:
  	case RT3593:

+ 4 - 4
package/kernel/mac80211/patches/600-0010-rt2x00-rt2800lib-add-rf_vals-for-RF3853.patch

@@ -21,17 +21,17 @@ Signed-off-by: Gabor Juhos <[email protected]>
   * RF5592 2.4G/5G 2T2R
   * RF3070 2.4G 1T1R
   * RF5360 2.4G 1T1R
-@@ -71,6 +72,7 @@
+@@ -72,6 +73,7 @@
  #define RF5592				0x000f
  #define RF3070				0x3070
  #define RF3290				0x3290
 +#define RF3853				0x3853
  #define RF5360				0x5360
+ #define RF5362				0x5362
  #define RF5370				0x5370
- #define RF5372				0x5372
 --- a/drivers/net/wireless/rt2x00/rt2800lib.c
 +++ b/drivers/net/wireless/rt2x00/rt2800lib.c
-@@ -7454,6 +7454,66 @@ static const struct rf_channel rf_vals_3
+@@ -7458,6 +7458,66 @@ static const struct rf_channel rf_vals_3
  	{173, 0x61, 0, 9},
  };
  
@@ -98,7 +98,7 @@ Signed-off-by: Gabor Juhos <[email protected]>
  static const struct rf_channel rf_vals_5592_xtal20[] = {
  	/* Channel, N, K, mod, R */
  	{1, 482, 4, 10, 3},
-@@ -7682,6 +7742,11 @@ static int rt2800_probe_hw_mode(struct r
+@@ -7687,6 +7747,11 @@ static int rt2800_probe_hw_mode(struct r
  		spec->channels = rf_vals_3x;
  		break;
  

+ 4 - 4
package/kernel/mac80211/patches/600-0011-rt2x00-rt2800lib-enable-VCO-calibration-for-RF3853.patch

@@ -10,19 +10,19 @@ Signed-off-by: Gabor Juhos <[email protected]>
 
 --- a/drivers/net/wireless/rt2x00/rt2800lib.c
 +++ b/drivers/net/wireless/rt2x00/rt2800lib.c
-@@ -4393,6 +4393,7 @@ void rt2800_vco_calibration(struct rt2x0
+@@ -4395,6 +4395,7 @@ void rt2800_vco_calibration(struct rt2x0
  	case RF3053:
  	case RF3070:
  	case RF3290:
 +	case RF3853:
  	case RF5360:
+ 	case RF5362:
  	case RF5370:
- 	case RF5372:
-@@ -7861,6 +7862,7 @@ static int rt2800_probe_hw_mode(struct r
+@@ -7866,6 +7867,7 @@ static int rt2800_probe_hw_mode(struct r
  	case RF3053:
  	case RF3070:
  	case RF3290:
 +	case RF3853:
  	case RF5360:
+ 	case RF5362:
  	case RF5370:
- 	case RF5372:

+ 1 - 1
package/kernel/mac80211/patches/600-0012-rt2x00-rt2800lib-add-channel-configuration-function-.patch

@@ -232,4 +232,4 @@ Signed-off-by: Gabor Juhos <[email protected]>
 +		break;
  	case RF3070:
  	case RF5360:
- 	case RF5370:
+ 	case RF5362:

+ 2 - 2
package/kernel/mac80211/patches/600-0013-rt2x00-rt2800lib-enable-RF3853-support.patch

@@ -10,11 +10,11 @@ Signed-off-by: Gabor Juhos <[email protected]>
 
 --- a/drivers/net/wireless/rt2x00/rt2800lib.c
 +++ b/drivers/net/wireless/rt2x00/rt2800lib.c
-@@ -7420,6 +7420,7 @@ static int rt2800_init_eeprom(struct rt2
+@@ -7423,6 +7423,7 @@ static int rt2800_init_eeprom(struct rt2
  	case RF3290:
  	case RF3320:
  	case RF3322:
 +	case RF3853:
  	case RF5360:
+ 	case RF5362:
  	case RF5370:
- 	case RF5372:

+ 4 - 4
package/kernel/mac80211/patches/600-0014-rt2x00-rt2800lib-add-MAC-register-initialization-for.patch

@@ -12,7 +12,7 @@ Signed-off-by: Gabor Juhos <[email protected]>
 
 --- a/drivers/net/wireless/rt2x00/rt2800.h
 +++ b/drivers/net/wireless/rt2x00/rt2800.h
-@@ -1586,6 +1586,20 @@
+@@ -1588,6 +1588,20 @@
  #define TX_PWR_CFG_9_STBC7_CH2		FIELD32(0x00000f00)
  
  /*
@@ -35,7 +35,7 @@ Signed-off-by: Gabor Juhos <[email protected]>
  #define RX_FILTER_CFG			0x1400
 --- a/drivers/net/wireless/rt2x00/rt2800lib.c
 +++ b/drivers/net/wireless/rt2x00/rt2800lib.c
-@@ -4995,6 +4995,12 @@ static int rt2800_init_registers(struct 
+@@ -4998,6 +4998,12 @@ static int rt2800_init_registers(struct 
  			rt2800_register_write(rt2x00dev, TX_SW_CFG2,
  					      0x00000000);
  		}
@@ -48,7 +48,7 @@ Signed-off-by: Gabor Juhos <[email protected]>
  	} else if (rt2x00_rt(rt2x00dev, RT5390) ||
  		   rt2x00_rt(rt2x00dev, RT5392) ||
  		   rt2x00_rt(rt2x00dev, RT5592)) {
-@@ -5025,9 +5031,11 @@ static int rt2800_init_registers(struct 
+@@ -5028,9 +5034,11 @@ static int rt2800_init_registers(struct 
  
  	rt2800_register_read(rt2x00dev, MAX_LEN_CFG, &reg);
  	rt2x00_set_field32(&reg, MAX_LEN_CFG_MAX_MPDU, AGGREGATION_SIZE);
@@ -63,7 +63,7 @@ Signed-off-by: Gabor Juhos <[email protected]>
  		rt2x00_set_field32(&reg, MAX_LEN_CFG_MAX_PSDU, 2);
  	else
  		rt2x00_set_field32(&reg, MAX_LEN_CFG_MAX_PSDU, 1);
-@@ -5180,6 +5188,11 @@ static int rt2800_init_registers(struct 
+@@ -5183,6 +5191,11 @@ static int rt2800_init_registers(struct 
  	reg = rt2x00_rt(rt2x00dev, RT5592) ? 0x00000082 : 0x00000002;
  	rt2800_register_write(rt2x00dev, TXOP_HLDR_ET, reg);
  

+ 2 - 2
package/kernel/mac80211/patches/600-0016-rt2x00-rt2800lib-add-BBP-register-initialization-for.patch

@@ -11,7 +11,7 @@ Signed-off-by: Gabor Juhos <[email protected]>
 
 --- a/drivers/net/wireless/rt2x00/rt2800lib.c
 +++ b/drivers/net/wireless/rt2x00/rt2800lib.c
-@@ -5798,6 +5798,47 @@ static void rt2800_init_bbp_3593(struct 
+@@ -5801,6 +5801,47 @@ static void rt2800_init_bbp_3593(struct 
  		rt2800_bbp_write(rt2x00dev, 103, 0xc0);
  }
  
@@ -59,7 +59,7 @@ Signed-off-by: Gabor Juhos <[email protected]>
  static void rt2800_init_bbp_53xx(struct rt2x00_dev *rt2x00dev)
  {
  	int ant, div_mode;
-@@ -6016,6 +6057,9 @@ static void rt2800_init_bbp(struct rt2x0
+@@ -6019,6 +6060,9 @@ static void rt2800_init_bbp(struct rt2x0
  	case RT3593:
  		rt2800_init_bbp_3593(rt2x00dev);
  		return;

+ 3 - 3
package/kernel/mac80211/patches/600-0017-rt2x00-rt2800lib-add-RFCSR-initialization-for-RT3883.patch

@@ -11,7 +11,7 @@ Signed-off-by: Gabor Juhos <[email protected]>
 
 --- a/drivers/net/wireless/rt2x00/rt2800.h
 +++ b/drivers/net/wireless/rt2x00/rt2800.h
-@@ -2169,6 +2169,7 @@ struct mac_iveiv_entry {
+@@ -2171,6 +2171,7 @@ struct mac_iveiv_entry {
  /*
   * RFCSR 2:
   */
@@ -21,7 +21,7 @@ Signed-off-by: Gabor Juhos <[email protected]>
  /*
 --- a/drivers/net/wireless/rt2x00/rt2800lib.c
 +++ b/drivers/net/wireless/rt2x00/rt2800lib.c
-@@ -6833,6 +6833,144 @@ static void rt2800_init_rfcsr_3593(struc
+@@ -6836,6 +6836,144 @@ static void rt2800_init_rfcsr_3593(struc
  	/* TODO: enable stream mode support */
  }
  
@@ -166,7 +166,7 @@ Signed-off-by: Gabor Juhos <[email protected]>
  static void rt2800_init_rfcsr_5390(struct rt2x00_dev *rt2x00dev)
  {
  	rt2800_rf_init_calibration(rt2x00dev, 2);
-@@ -7064,6 +7202,9 @@ static void rt2800_init_rfcsr(struct rt2
+@@ -7067,6 +7205,9 @@ static void rt2800_init_rfcsr(struct rt2
  	case RT3390:
  		rt2800_init_rfcsr_3390(rt2x00dev);
  		break;

+ 1 - 1
package/kernel/mac80211/patches/600-0019-rt2x00-rt2800lib-force-rf-type-to-RF3853-on-RT3883.patch

@@ -10,7 +10,7 @@ Signed-off-by: Gabor Juhos <[email protected]>
 
 --- a/drivers/net/wireless/rt2x00/rt2800lib.c
 +++ b/drivers/net/wireless/rt2x00/rt2800lib.c
-@@ -7601,6 +7601,8 @@ static int rt2800_init_eeprom(struct rt2
+@@ -7604,6 +7604,8 @@ static int rt2800_init_eeprom(struct rt2
  	    rt2x00_rt(rt2x00dev, RT5390) ||
  	    rt2x00_rt(rt2x00dev, RT5392))
  		rt2800_eeprom_read(rt2x00dev, EEPROM_CHIP_ID, &rf);

+ 4 - 4
package/kernel/mac80211/patches/600-0020-rt2x00-rt2800lib-add-channel-configuration-code-for-.patch

@@ -60,7 +60,7 @@ Signed-off-by: Gabor Juhos <[email protected]>
  	switch (rt2x00dev->chip.rf) {
  	case RF2020:
  	case RF3020:
-@@ -3528,6 +3564,15 @@ static void rt2800_config_channel(struct
+@@ -3530,6 +3566,15 @@ static void rt2800_config_channel(struct
  		rt2800_bbp_write(rt2x00dev, 63, 0x37 - rt2x00dev->lna_gain);
  		rt2800_bbp_write(rt2x00dev, 64, 0x37 - rt2x00dev->lna_gain);
  		rt2800_bbp_write(rt2x00dev, 77, 0x98);
@@ -76,7 +76,7 @@ Signed-off-by: Gabor Juhos <[email protected]>
  	} else {
  		rt2800_bbp_write(rt2x00dev, 62, 0x37 - rt2x00dev->lna_gain);
  		rt2800_bbp_write(rt2x00dev, 63, 0x37 - rt2x00dev->lna_gain);
-@@ -3540,6 +3585,7 @@ static void rt2800_config_channel(struct
+@@ -3542,6 +3587,7 @@ static void rt2800_config_channel(struct
  		    !rt2x00_rt(rt2x00dev, RT5392)) {
  			if (rt2x00_has_cap_external_lna_bg(rt2x00dev)) {
  				rt2800_bbp_write(rt2x00dev, 82, 0x62);
@@ -84,7 +84,7 @@ Signed-off-by: Gabor Juhos <[email protected]>
  				rt2800_bbp_write(rt2x00dev, 75, 0x46);
  			} else {
  				if (rt2x00_rt(rt2x00dev, RT3593))
-@@ -3548,19 +3594,22 @@ static void rt2800_config_channel(struct
+@@ -3550,19 +3596,22 @@ static void rt2800_config_channel(struct
  					rt2800_bbp_write(rt2x00dev, 82, 0x84);
  				rt2800_bbp_write(rt2x00dev, 75, 0x50);
  			}
@@ -110,7 +110,7 @@ Signed-off-by: Gabor Juhos <[email protected]>
  			rt2800_bbp_write(rt2x00dev, 83, 0x9a);
  
  		if (rt2x00_has_cap_external_lna_a(rt2x00dev))
-@@ -3685,6 +3734,23 @@ static void rt2800_config_channel(struct
+@@ -3687,6 +3736,23 @@ static void rt2800_config_channel(struct
  		usleep_range(1000, 1500);
  	}
  

+ 1 - 1
package/kernel/mac80211/patches/600-0022-rt2x00-rt2800lib-use-correct-txpower-calculation-fun.patch

@@ -11,7 +11,7 @@ Signed-off-by: Gabor Juhos <[email protected]>
 
 --- a/drivers/net/wireless/rt2x00/rt2800lib.c
 +++ b/drivers/net/wireless/rt2x00/rt2800lib.c
-@@ -4626,7 +4626,8 @@ static void rt2800_config_txpower(struct
+@@ -4628,7 +4628,8 @@ static void rt2800_config_txpower(struct
  				  struct ieee80211_channel *chan,
  				  int power_level)
  {

+ 2 - 2
package/kernel/mac80211/patches/600-0023-rt2x00-rt2800lib-hardcode-txmixer-gain-values-to-zer.patch

@@ -11,7 +11,7 @@ Signed-off-by: Gabor Juhos <[email protected]>
 
 --- a/drivers/net/wireless/rt2x00/rt2800lib.c
 +++ b/drivers/net/wireless/rt2x00/rt2800lib.c
-@@ -7483,7 +7483,8 @@ static u8 rt2800_get_txmixer_gain_24g(st
+@@ -7486,7 +7486,8 @@ static u8 rt2800_get_txmixer_gain_24g(st
  {
  	u16 word;
  
@@ -21,7 +21,7 @@ Signed-off-by: Gabor Juhos <[email protected]>
  		return 0;
  
  	rt2800_eeprom_read(rt2x00dev, EEPROM_TXMIXER_GAIN_BG, &word);
-@@ -7497,7 +7498,8 @@ static u8 rt2800_get_txmixer_gain_5g(str
+@@ -7500,7 +7501,8 @@ static u8 rt2800_get_txmixer_gain_5g(str
  {
  	u16 word;
  

+ 1 - 1
package/kernel/mac80211/patches/600-0026-rt2x00-rt2800lib-use-correct-beacon-count-for-RT3883.patch

@@ -10,7 +10,7 @@ Signed-off-by: Gabor Juhos <[email protected]>
 
 --- a/drivers/net/wireless/rt2x00/rt2800lib.c
 +++ b/drivers/net/wireless/rt2x00/rt2800lib.c
-@@ -8415,7 +8415,8 @@ int rt2800_probe_hw(struct rt2x00_dev *r
+@@ -8421,7 +8421,8 @@ int rt2800_probe_hw(struct rt2x00_dev *r
  	if (rt2x00_rt(rt2x00dev, RT3593))
  		__set_bit(RT2800_HAS_HIGH_SHARED_MEM, &drv_data->rt2800_flags);
  

+ 3 - 3
package/kernel/mac80211/patches/600-0029-rt2x00-rt2800lib-fix-VGC-setup-for-RT3883.patch

@@ -10,7 +10,7 @@ Signed-off-by: Gabor Juhos <[email protected]>
 
 --- a/drivers/net/wireless/rt2x00/rt2800lib.c
 +++ b/drivers/net/wireless/rt2x00/rt2800lib.c
-@@ -4825,7 +4825,8 @@ static u8 rt2800_get_default_vgc(struct 
+@@ -4828,7 +4828,8 @@ static u8 rt2800_get_default_vgc(struct 
  		else
  			vgc = 0x2e + rt2x00dev->lna_gain;
  	} else { /* 5GHZ band */
@@ -20,7 +20,7 @@ Signed-off-by: Gabor Juhos <[email protected]>
  			vgc = 0x20 + (rt2x00dev->lna_gain * 5) / 3;
  		else if (rt2x00_rt(rt2x00dev, RT5592))
  			vgc = 0x24 + (2 * rt2x00dev->lna_gain);
-@@ -4845,7 +4846,8 @@ static inline void rt2800_set_vgc(struct
+@@ -4848,7 +4849,8 @@ static inline void rt2800_set_vgc(struct
  {
  	if (qual->vgc_level != vgc_level) {
  		if (rt2x00_rt(rt2x00dev, RT3572) ||
@@ -30,7 +30,7 @@ Signed-off-by: Gabor Juhos <[email protected]>
  			rt2800_bbp_write_with_rx_chain(rt2x00dev, 66,
  						       vgc_level);
  		} else if (rt2x00_rt(rt2x00dev, RT5592)) {
-@@ -4892,6 +4894,11 @@ void rt2800_link_tuner(struct rt2x00_dev
+@@ -4895,6 +4897,11 @@ void rt2800_link_tuner(struct rt2x00_dev
  		}
  		break;
  

+ 3 - 3
package/kernel/mac80211/patches/600-0030-rt2x00-rt2800lib-fix-EEPROM-LNA-validation-for-RT388.patch

@@ -10,7 +10,7 @@ Signed-off-by: Gabor Juhos <[email protected]>
 
 --- a/drivers/net/wireless/rt2x00/rt2800lib.c
 +++ b/drivers/net/wireless/rt2x00/rt2800lib.c
-@@ -7620,7 +7620,8 @@ static int rt2800_validate_eeprom(struct
+@@ -7623,7 +7623,8 @@ static int rt2800_validate_eeprom(struct
  	rt2800_eeprom_read(rt2x00dev, EEPROM_RSSI_BG2, &word);
  	if (abs(rt2x00_get_field16(word, EEPROM_RSSI_BG2_OFFSET2)) > 10)
  		rt2x00_set_field16(&word, EEPROM_RSSI_BG2_OFFSET2, 0);
@@ -20,7 +20,7 @@ Signed-off-by: Gabor Juhos <[email protected]>
  		if (rt2x00_get_field16(word, EEPROM_RSSI_BG2_LNA_A1) == 0x00 ||
  		    rt2x00_get_field16(word, EEPROM_RSSI_BG2_LNA_A1) == 0xff)
  			rt2x00_set_field16(&word, EEPROM_RSSI_BG2_LNA_A1,
-@@ -7640,7 +7641,8 @@ static int rt2800_validate_eeprom(struct
+@@ -7643,7 +7644,8 @@ static int rt2800_validate_eeprom(struct
  	rt2800_eeprom_read(rt2x00dev, EEPROM_RSSI_A2, &word);
  	if (abs(rt2x00_get_field16(word, EEPROM_RSSI_A2_OFFSET2)) > 10)
  		rt2x00_set_field16(&word, EEPROM_RSSI_A2_OFFSET2, 0);
@@ -30,7 +30,7 @@ Signed-off-by: Gabor Juhos <[email protected]>
  		if (rt2x00_get_field16(word, EEPROM_RSSI_A2_LNA_A2) == 0x00 ||
  		    rt2x00_get_field16(word, EEPROM_RSSI_A2_LNA_A2) == 0xff)
  			rt2x00_set_field16(&word, EEPROM_RSSI_A2_LNA_A2,
-@@ -7648,7 +7650,8 @@ static int rt2800_validate_eeprom(struct
+@@ -7651,7 +7653,8 @@ static int rt2800_validate_eeprom(struct
  	}
  	rt2800_eeprom_write(rt2x00dev, EEPROM_RSSI_A2, word);
  

+ 1 - 1
package/kernel/mac80211/patches/600-0031-rt2x00-rt2800lib-fix-txpower-compensation-for-RT3883.patch

@@ -10,7 +10,7 @@ Signed-off-by: Gabor Juhos <[email protected]>
 
 --- a/drivers/net/wireless/rt2x00/rt2800lib.c
 +++ b/drivers/net/wireless/rt2x00/rt2800lib.c
-@@ -4003,6 +4003,9 @@ static u8 rt2800_compensate_txpower(stru
+@@ -4005,6 +4005,9 @@ static u8 rt2800_compensate_txpower(stru
  	if (rt2x00_rt(rt2x00dev, RT3593))
  		return min_t(u8, txpower, 0xc);
  

+ 1 - 1
package/kernel/mac80211/patches/600-0032-rt2x00-rt2800lib-enable-RT2800_HAS_HIGH_SHARED_MEM-f.patch

@@ -11,7 +11,7 @@ Signed-off-by: Gabor Juhos <[email protected]>
 
 --- a/drivers/net/wireless/rt2x00/rt2800lib.c
 +++ b/drivers/net/wireless/rt2x00/rt2800lib.c
-@@ -8428,7 +8428,8 @@ int rt2800_probe_hw(struct rt2x00_dev *r
+@@ -8434,7 +8434,8 @@ int rt2800_probe_hw(struct rt2x00_dev *r
  	if (retval)
  		return retval;
  

+ 1 - 1
package/kernel/mac80211/patches/600-0034-rt2x00-rt2800mmio-add-a-workaround-for-spurious-TX_F.patch

@@ -122,7 +122,7 @@ Signed-off-by: Gabor Juhos <[email protected]>
  		 */
 --- a/drivers/net/wireless/rt2x00/rt2x00.h
 +++ b/drivers/net/wireless/rt2x00/rt2x00.h
-@@ -986,6 +986,11 @@ struct rt2x00_dev {
+@@ -987,6 +987,11 @@ struct rt2x00_dev {
  	int rf_channel;
  
  	/*

+ 8 - 8
package/kernel/mac80211/patches/603-rt2x00-introduce-rt2x00eeprom.patch

@@ -1,6 +1,6 @@
 --- a/.local-symbols
 +++ b/.local-symbols
-@@ -281,6 +281,7 @@ RT2X00_LIB_FIRMWARE=
+@@ -284,6 +284,7 @@ RT2X00_LIB_FIRMWARE=
  RT2X00_LIB_CRYPTO=
  RT2X00_LIB_LEDS=
  RT2X00_LIB_DEBUGFS=
@@ -105,15 +105,15 @@
  	.drv_init_registers	= rt2800mmio_init_registers,
 --- a/drivers/net/wireless/rt2x00/rt2x00.h
 +++ b/drivers/net/wireless/rt2x00/rt2x00.h
-@@ -694,6 +694,7 @@ enum rt2x00_capability_flags {
- 	REQUIRE_SW_SEQNO,
+@@ -695,6 +695,7 @@ enum rt2x00_capability_flags {
  	REQUIRE_HT_TX_DESC,
  	REQUIRE_PS_AUTOWAKE,
+ 	REQUIRE_DELAYED_RFKILL,
 +	REQUIRE_EEPROM_FILE,
  
  	/*
  	 * Capabilities
-@@ -963,6 +964,11 @@ struct rt2x00_dev {
+@@ -964,6 +965,11 @@ struct rt2x00_dev {
  	const struct firmware *fw;
  
  	/*
@@ -127,7 +127,7 @@
  	DECLARE_KFIFO_PTR(txstatus_fifo, u32);
 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c
 +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
-@@ -1327,6 +1327,10 @@ int rt2x00lib_probe_dev(struct rt2x00_de
+@@ -1334,6 +1334,10 @@ int rt2x00lib_probe_dev(struct rt2x00_de
  	INIT_DELAYED_WORK(&rt2x00dev->autowakeup_work, rt2x00lib_autowakeup);
  	INIT_WORK(&rt2x00dev->sleep_work, rt2x00lib_sleep);
  
@@ -138,10 +138,10 @@
  	/*
  	 * Let the driver probe the device to detect the capabilities.
  	 */
-@@ -1457,6 +1461,11 @@ void rt2x00lib_remove_dev(struct rt2x00_
+@@ -1474,6 +1478,11 @@ void rt2x00lib_remove_dev(struct rt2x00_
+ 	 * Free the driver data.
  	 */
- 	if (rt2x00dev->drv_data)
- 		kfree(rt2x00dev->drv_data);
+ 	kfree(rt2x00dev->drv_data);
 +
 +	/*
 +	 * Free EEPROM image.

+ 1 - 1
package/kernel/mac80211/patches/608-add_platform_data_mac_addr.patch

@@ -31,7 +31,7 @@
  {
 --- a/drivers/net/wireless/rt2x00/rt2x00.h
 +++ b/drivers/net/wireless/rt2x00/rt2x00.h
-@@ -1406,6 +1406,7 @@ static inline void rt2x00debug_dump_fram
+@@ -1407,6 +1407,7 @@ static inline void rt2x00debug_dump_fram
   */
  u32 rt2x00lib_get_bssidx(struct rt2x00_dev *rt2x00dev,
  			 struct ieee80211_vif *vif);

+ 13 - 13
package/kernel/mac80211/patches/610-rt2x00-fix-rt3352-ext-pa.patch

@@ -1,6 +1,6 @@
 --- a/drivers/net/wireless/rt2x00/rt2800lib.c
 +++ b/drivers/net/wireless/rt2x00/rt2800lib.c
-@@ -3550,11 +3550,18 @@ static void rt2800_config_channel(struct
+@@ -3552,11 +3552,18 @@ static void rt2800_config_channel(struct
  	/*
  	 * Change BBP settings
  	 */
@@ -19,7 +19,7 @@
  	} else if (rt2x00_rt(rt2x00dev, RT3593)) {
  		if (rf->channel > 14) {
  			/* Disable CCK Packet detection on 5GHz */
-@@ -6608,6 +6615,12 @@ static void rt2800_init_rfcsr_3290(struc
+@@ -6611,6 +6618,12 @@ static void rt2800_init_rfcsr_3290(struc
  
  static void rt2800_init_rfcsr_3352(struct rt2x00_dev *rt2x00dev)
  {
@@ -32,7 +32,7 @@
  	rt2800_rf_init_calibration(rt2x00dev, 30);
  
  	rt2800_rfcsr_write(rt2x00dev, 0, 0xf0);
-@@ -6643,15 +6656,30 @@ static void rt2800_init_rfcsr_3352(struc
+@@ -6646,15 +6659,30 @@ static void rt2800_init_rfcsr_3352(struc
  	rt2800_rfcsr_write(rt2x00dev, 31, 0x80);
  	rt2800_rfcsr_write(rt2x00dev, 32, 0x80);
  	rt2800_rfcsr_write(rt2x00dev, 33, 0x00);
@@ -66,7 +66,7 @@
  	rt2800_rfcsr_write(rt2x00dev, 43, 0xdb);
  	rt2800_rfcsr_write(rt2x00dev, 44, 0xdb);
  	rt2800_rfcsr_write(rt2x00dev, 45, 0xdb);
-@@ -6659,15 +6687,20 @@ static void rt2800_init_rfcsr_3352(struc
+@@ -6662,15 +6690,20 @@ static void rt2800_init_rfcsr_3352(struc
  	rt2800_rfcsr_write(rt2x00dev, 47, 0x0d);
  	rt2800_rfcsr_write(rt2x00dev, 48, 0x14);
  	rt2800_rfcsr_write(rt2x00dev, 49, 0x00);
@@ -96,7 +96,7 @@
  	rt2800_rfcsr_write(rt2x00dev, 59, 0x00);
  	rt2800_rfcsr_write(rt2x00dev, 60, 0x00);
  	rt2800_rfcsr_write(rt2x00dev, 61, 0x00);
-@@ -7688,6 +7721,7 @@ static int rt2800_init_eeprom(struct rt2
+@@ -7691,6 +7724,7 @@ static int rt2800_init_eeprom(struct rt2
  	 * RT53xx: defined in "EEPROM_CHIP_ID" field
  	 */
  	if (rt2x00_rt(rt2x00dev, RT3290) ||
@@ -104,7 +104,7 @@
  	    rt2x00_rt(rt2x00dev, RT5390) ||
  	    rt2x00_rt(rt2x00dev, RT5392))
  		rt2800_eeprom_read(rt2x00dev, EEPROM_CHIP_ID, &rf);
-@@ -7782,7 +7816,8 @@ static int rt2800_init_eeprom(struct rt2
+@@ -7786,7 +7820,8 @@ static int rt2800_init_eeprom(struct rt2
  	/*
  	 * Detect if this device has Bluetooth co-existence.
  	 */
@@ -114,7 +114,7 @@
  		__set_bit(CAPABILITY_BT_COEXIST, &rt2x00dev->cap_flags);
  
  	/*
-@@ -7811,6 +7846,22 @@ static int rt2800_init_eeprom(struct rt2
+@@ -7815,6 +7850,22 @@ static int rt2800_init_eeprom(struct rt2
  					EIRP_MAX_TX_POWER_LIMIT)
  		__set_bit(CAPABILITY_POWER_LIMIT, &rt2x00dev->cap_flags);
  
@@ -139,7 +139,7 @@
  
 --- a/drivers/net/wireless/rt2x00/rt2800.h
 +++ b/drivers/net/wireless/rt2x00/rt2800.h
-@@ -2333,6 +2333,12 @@ struct mac_iveiv_entry {
+@@ -2335,6 +2335,12 @@ struct mac_iveiv_entry {
  #define RFCSR36_RF_BS			FIELD8(0x80)
  
  /*
@@ -152,7 +152,7 @@
   * RFCSR 38:
   */
  #define RFCSR38_RX_LO1_EN		FIELD8(0x20)
-@@ -2344,6 +2350,18 @@ struct mac_iveiv_entry {
+@@ -2346,6 +2352,18 @@ struct mac_iveiv_entry {
  #define RFCSR39_RX_LO2_EN		FIELD8(0x80)
  
  /*
@@ -171,7 +171,7 @@
   * RFCSR 49:
   */
  #define RFCSR49_TX			FIELD8(0x3f)
-@@ -2356,6 +2374,8 @@ struct mac_iveiv_entry {
+@@ -2358,6 +2376,8 @@ struct mac_iveiv_entry {
   * RFCSR 50:
   */
  #define RFCSR50_TX			FIELD8(0x3f)
@@ -180,7 +180,7 @@
  #define RFCSR50_EP			FIELD8(0xc0)
  /* bits for RT3593 */
  #define RFCSR50_TX_LO1_EN		FIELD8(0x20)
-@@ -2503,6 +2523,8 @@ enum rt2800_eeprom_word {
+@@ -2505,6 +2525,8 @@ enum rt2800_eeprom_word {
   * INTERNAL_TX_ALC: 0: disable, 1: enable
   * BT_COEXIST: 0: disable, 1: enable
   * DAC_TEST: 0: disable, 1: enable
@@ -189,7 +189,7 @@
   */
  #define EEPROM_NIC_CONF1_HW_RADIO		FIELD16(0x0001)
  #define EEPROM_NIC_CONF1_EXTERNAL_TX_ALC	FIELD16(0x0002)
-@@ -2519,6 +2541,8 @@ enum rt2800_eeprom_word {
+@@ -2521,6 +2543,8 @@ enum rt2800_eeprom_word {
  #define EEPROM_NIC_CONF1_INTERNAL_TX_ALC	FIELD16(0x2000)
  #define EEPROM_NIC_CONF1_BT_COEXIST		FIELD16(0x4000)
  #define EEPROM_NIC_CONF1_DAC_TEST		FIELD16(0x8000)
@@ -200,7 +200,7 @@
   * EEPROM frequency
 --- a/drivers/net/wireless/rt2x00/rt2x00.h
 +++ b/drivers/net/wireless/rt2x00/rt2x00.h
-@@ -714,6 +714,8 @@ enum rt2x00_capability_flags {
+@@ -715,6 +715,8 @@ enum rt2x00_capability_flags {
  	CAPABILITY_DOUBLE_ANTENNA,
  	CAPABILITY_BT_COEXIST,
  	CAPABILITY_VCO_RECALIBRATION,

+ 4 - 4
package/kernel/mac80211/patches/611-rt2x00-rf_vals-rt3352-xtal20.patch

@@ -1,6 +1,6 @@
 --- a/drivers/net/wireless/rt2x00/rt2800lib.c
 +++ b/drivers/net/wireless/rt2x00/rt2800lib.c
-@@ -8198,6 +8198,27 @@ static const struct rf_channel rf_vals_5
+@@ -8202,6 +8202,27 @@ static const struct rf_channel rf_vals_5
  	{196, 83, 0, 12, 1},
  };
  
@@ -28,7 +28,7 @@
  static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
  {
  	struct hw_mode_spec *spec = &rt2x00dev->spec;
-@@ -8285,7 +8306,10 @@ static int rt2800_probe_hw_mode(struct r
+@@ -8290,7 +8311,10 @@ static int rt2800_probe_hw_mode(struct r
  	case RF5390:
  	case RF5392:
  		spec->num_channels = 14;
@@ -40,7 +40,7 @@
  		break;
  
  	case RF3052:
-@@ -8468,6 +8492,19 @@ static int rt2800_probe_rt(struct rt2x00
+@@ -8474,6 +8498,19 @@ static int rt2800_probe_rt(struct rt2x00
  	return 0;
  }
  
@@ -60,7 +60,7 @@
  int rt2800_probe_hw(struct rt2x00_dev *rt2x00dev)
  {
  	struct rt2800_drv_data *drv_data = rt2x00dev->drv_data;
-@@ -8510,6 +8547,15 @@ int rt2800_probe_hw(struct rt2x00_dev *r
+@@ -8516,6 +8553,15 @@ int rt2800_probe_hw(struct rt2x00_dev *r
  	rt2800_register_write(rt2x00dev, GPIO_CTRL, reg);
  
  	/*

+ 1 - 1
package/kernel/mac80211/patches/615-rt2x00-fix_20mhz_clk.patch

@@ -8,7 +8,7 @@
  
  #include "rt2x00.h"
  #include "rt2800lib.h"
-@@ -8494,13 +8495,14 @@ static int rt2800_probe_rt(struct rt2x00
+@@ -8500,13 +8501,14 @@ static int rt2800_probe_rt(struct rt2x00
  
  int rt2800_probe_clk(struct rt2x00_dev *rt2x00dev)
  {

+ 24 - 24
package/kernel/mac80211/patches/616-rt2x00-support-rt5350.patch

@@ -1,13 +1,13 @@
 --- a/drivers/net/wireless/rt2x00/rt2800.h
 +++ b/drivers/net/wireless/rt2x00/rt2800.h
-@@ -73,6 +73,7 @@
+@@ -74,6 +74,7 @@
  #define RF3070				0x3070
  #define RF3290				0x3290
  #define RF3853				0x3853
 +#define RF5350				0x5350
  #define RF5360				0x5360
+ #define RF5362				0x5362
  #define RF5370				0x5370
- #define RF5372				0x5372
 --- a/drivers/net/wireless/rt2x00/rt2800lib.c
 +++ b/drivers/net/wireless/rt2x00/rt2800lib.c
 @@ -3038,6 +3038,13 @@ static void rt2800_config_channel_rf53xx
@@ -30,17 +30,17 @@
  	case RF3070:
 +	case RF5350:
  	case RF5360:
+ 	case RF5362:
  	case RF5370:
- 	case RF5372:
-@@ -3533,6 +3541,7 @@ static void rt2800_config_channel(struct
+@@ -3534,6 +3542,7 @@ static void rt2800_config_channel(struct
  	if (rt2x00_rf(rt2x00dev, RF3070) ||
  	    rt2x00_rf(rt2x00dev, RF3290) ||
  	    rt2x00_rf(rt2x00dev, RF3322) ||
 +	    rt2x00_rf(rt2x00dev, RF5350) ||
  	    rt2x00_rf(rt2x00dev, RF5360) ||
+ 	    rt2x00_rf(rt2x00dev, RF5362) ||
  	    rt2x00_rf(rt2x00dev, RF5370) ||
- 	    rt2x00_rf(rt2x00dev, RF5372) ||
-@@ -3810,7 +3819,8 @@ static void rt2800_config_channel(struct
+@@ -3812,7 +3821,8 @@ static void rt2800_config_channel(struct
  	/*
  	 * Clear update flag
  	 */
@@ -50,15 +50,15 @@
  		rt2800_bbp_read(rt2x00dev, 49, &bbp);
  		rt2x00_set_field8(&bbp, BBP49_UPDATE_FLAG, 0);
  		rt2800_bbp_write(rt2x00dev, 49, bbp);
-@@ -4689,6 +4699,7 @@ void rt2800_vco_calibration(struct rt2x0
+@@ -4691,6 +4701,7 @@ void rt2800_vco_calibration(struct rt2x0
  	case RF3070:
  	case RF3290:
  	case RF3853:
 +	case RF5350:
  	case RF5360:
+ 	case RF5362:
  	case RF5370:
- 	case RF5372:
-@@ -5101,6 +5112,8 @@ static int rt2800_init_registers(struct 
+@@ -5104,6 +5115,8 @@ static int rt2800_init_registers(struct 
  		rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000404);
  		rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606);
  		rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000000);
@@ -67,7 +67,7 @@
  	} else {
  		rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000000);
  		rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606);
-@@ -5756,9 +5769,13 @@ static void rt2800_init_bbp_3352(struct 
+@@ -5759,9 +5772,13 @@ static void rt2800_init_bbp_3352(struct 
  
  	rt2800_bbp_write(rt2x00dev, 82, 0x62);
  
@@ -84,7 +84,7 @@
  
  	rt2800_bbp_write(rt2x00dev, 86, 0x38);
  
-@@ -5772,9 +5789,13 @@ static void rt2800_init_bbp_3352(struct 
+@@ -5775,9 +5792,13 @@ static void rt2800_init_bbp_3352(struct 
  
  	rt2800_bbp_write(rt2x00dev, 104, 0x92);
  
@@ -101,7 +101,7 @@
  
  	rt2800_bbp_write(rt2x00dev, 120, 0x50);
  
-@@ -5799,6 +5820,13 @@ static void rt2800_init_bbp_3352(struct 
+@@ -5802,6 +5823,13 @@ static void rt2800_init_bbp_3352(struct 
  	rt2800_bbp_write(rt2x00dev, 143, 0xa2);
  
  	rt2800_bbp_write(rt2x00dev, 148, 0xc8);
@@ -115,7 +115,7 @@
  }
  
  static void rt2800_init_bbp_3390(struct rt2x00_dev *rt2x00dev)
-@@ -6140,6 +6168,7 @@ static void rt2800_init_bbp(struct rt2x0
+@@ -6143,6 +6171,7 @@ static void rt2800_init_bbp(struct rt2x0
  		rt2800_init_bbp_3290(rt2x00dev);
  		break;
  	case RT3352:
@@ -123,7 +123,7 @@
  		rt2800_init_bbp_3352(rt2x00dev);
  		break;
  	case RT3390:
-@@ -7091,6 +7120,76 @@ static void rt2800_init_rfcsr_3883(struc
+@@ -7094,6 +7123,76 @@ static void rt2800_init_rfcsr_3883(struc
  	rt2800_rfcsr_write(rt2x00dev, 20, rfcsr);
  }
  
@@ -200,7 +200,7 @@
  static void rt2800_init_rfcsr_5390(struct rt2x00_dev *rt2x00dev)
  {
  	rt2800_rf_init_calibration(rt2x00dev, 2);
-@@ -7331,6 +7430,9 @@ static void rt2800_init_rfcsr(struct rt2
+@@ -7334,6 +7433,9 @@ static void rt2800_init_rfcsr(struct rt2
  	case RT3593:
  		rt2800_init_rfcsr_3593(rt2x00dev);
  		break;
@@ -210,7 +210,7 @@
  	case RT5390:
  		rt2800_init_rfcsr_5390(rt2x00dev);
  		break;
-@@ -7590,6 +7692,12 @@ static int rt2800_validate_eeprom(struct
+@@ -7593,6 +7695,12 @@ static int rt2800_validate_eeprom(struct
  		rt2x00_set_field16(&word, EEPROM_NIC_CONF0_RF_TYPE, RF2820);
  		rt2800_eeprom_write(rt2x00dev, EEPROM_NIC_CONF0, word);
  		rt2x00_eeprom_dbg(rt2x00dev, "Antenna: 0x%04x\n", word);
@@ -223,7 +223,7 @@
  	} else if (rt2x00_rt(rt2x00dev, RT2860) ||
  		   rt2x00_rt(rt2x00dev, RT2872)) {
  		/*
-@@ -7728,6 +7836,8 @@ static int rt2800_init_eeprom(struct rt2
+@@ -7731,6 +7839,8 @@ static int rt2800_init_eeprom(struct rt2
  		rt2800_eeprom_read(rt2x00dev, EEPROM_CHIP_ID, &rf);
  	else if (rt2x00_rt(rt2x00dev, RT3883))
  		rf = RF3853;
@@ -232,31 +232,31 @@
  	else
  		rf = rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RF_TYPE);
  
-@@ -7747,6 +7857,7 @@ static int rt2800_init_eeprom(struct rt2
+@@ -7750,6 +7860,7 @@ static int rt2800_init_eeprom(struct rt2
  	case RF3320:
  	case RF3322:
  	case RF3853:
 +	case RF5350:
  	case RF5360:
+ 	case RF5362:
  	case RF5370:
- 	case RF5372:
-@@ -8301,6 +8412,7 @@ static int rt2800_probe_hw_mode(struct r
+@@ -8305,6 +8416,7 @@ static int rt2800_probe_hw_mode(struct r
  	case RF3290:
  	case RF3320:
  	case RF3322:
 +	case RF5350:
  	case RF5360:
+ 	case RF5362:
  	case RF5370:
- 	case RF5372:
-@@ -8439,6 +8551,7 @@ static int rt2800_probe_hw_mode(struct r
+@@ -8444,6 +8556,7 @@ static int rt2800_probe_hw_mode(struct r
  	case RF3070:
  	case RF3290:
  	case RF3853:
 +	case RF5350:
  	case RF5360:
+ 	case RF5362:
  	case RF5370:
- 	case RF5372:
-@@ -8478,6 +8591,7 @@ static int rt2800_probe_rt(struct rt2x00
+@@ -8484,6 +8597,7 @@ static int rt2800_probe_rt(struct rt2x00
  	case RT3572:
  	case RT3593:
  	case RT3883:

+ 1 - 1
package/kernel/mac80211/patches/619-rt2x00-change-led-polarity-from-OF.patch

@@ -8,7 +8,7 @@
  
  #include "rt2x00.h"
  #include "rt2800lib.h"
-@@ -7946,6 +7947,17 @@ static int rt2800_init_eeprom(struct rt2
+@@ -7950,6 +7951,17 @@ static int rt2800_init_eeprom(struct rt2
  	rt2800_init_led(rt2x00dev, &rt2x00dev->led_assoc, LED_TYPE_ASSOC);
  	rt2800_init_led(rt2x00dev, &rt2x00dev->led_qual, LED_TYPE_QUALITY);
  

+ 1 - 1
package/kernel/mac80211/patches/620-rt2x00-add-AP+STA-support.patch

@@ -1,6 +1,6 @@
 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c
 +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
-@@ -1265,7 +1265,7 @@ static inline void rt2x00lib_set_if_comb
+@@ -1283,7 +1283,7 @@ static inline void rt2x00lib_set_if_comb
  	 */
  	if_limit = &rt2x00dev->if_limits_ap;
  	if_limit->max = rt2x00dev->ops->max_ap_intf;

+ 1 - 1
package/kernel/mac80211/patches/620-rt2x00-rt3352-rf-id.patch

@@ -1,6 +1,6 @@
 --- a/drivers/net/wireless/rt2x00/rt2800lib.c
 +++ b/drivers/net/wireless/rt2x00/rt2800lib.c
-@@ -7831,10 +7831,11 @@ static int rt2800_init_eeprom(struct rt2
+@@ -7834,10 +7834,11 @@ static int rt2800_init_eeprom(struct rt2
  	 * RT53xx: defined in "EEPROM_CHIP_ID" field
  	 */
  	if (rt2x00_rt(rt2x00dev, RT3290) ||

+ 6 - 10
package/kernel/mac80211/patches/621-rt2x00-ht20_40_fix.patch

@@ -1,8 +1,6 @@
-Index: compat-wireless-2014-05-22/drivers/net/wireless/rt2x00/rt2800.h
-===================================================================
---- compat-wireless-2014-05-22.orig/drivers/net/wireless/rt2x00/rt2800.h	2014-08-31 05:04:55.600142409 +0200
-+++ compat-wireless-2014-05-22/drivers/net/wireless/rt2x00/rt2800.h	2014-08-31 05:11:02.068145882 +0200
-@@ -2346,6 +2346,8 @@
+--- a/drivers/net/wireless/rt2x00/rt2800.h
++++ b/drivers/net/wireless/rt2x00/rt2800.h
+@@ -2321,6 +2321,8 @@ struct mac_iveiv_entry {
  #define RFCSR30_RX_H20M			FIELD8(0x04)
  #define RFCSR30_RX_VCM			FIELD8(0x18)
  #define RFCSR30_RF_CALIBRATION		FIELD8(0x80)
@@ -11,11 +9,9 @@ Index: compat-wireless-2014-05-22/drivers/net/wireless/rt2x00/rt2800.h
  
  /*
   * RFCSR 31:
-Index: compat-wireless-2014-05-22/drivers/net/wireless/rt2x00/rt2800lib.c
-===================================================================
---- compat-wireless-2014-05-22.orig/drivers/net/wireless/rt2x00/rt2800lib.c	2014-08-31 05:04:55.604142409 +0200
-+++ compat-wireless-2014-05-22/drivers/net/wireless/rt2x00/rt2800lib.c	2014-08-31 05:15:02.176148157 +0200
-@@ -3928,8 +3928,13 @@
+--- a/drivers/net/wireless/rt2x00/rt2800lib.c
++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
+@@ -3551,8 +3551,13 @@ static void rt2800_config_channel(struct
  	    rt2x00_rf(rt2x00dev, RF5390) ||
  	    rt2x00_rf(rt2x00dev, RF5392)) {
  		rt2800_rfcsr_read(rt2x00dev, 30, &rfcsr);

+ 2 - 2
package/kernel/mac80211/patches/700-mwl8k-missing-pci-id-for-WNR854T.patch

@@ -1,9 +1,9 @@
 --- a/drivers/net/wireless/mwl8k.c
 +++ b/drivers/net/wireless/mwl8k.c
-@@ -5682,6 +5682,7 @@ MODULE_FIRMWARE("mwl8k/fmimage_8366.fw")
+@@ -5675,6 +5675,7 @@ MODULE_FIRMWARE("mwl8k/fmimage_8366.fw")
  MODULE_FIRMWARE(MWL8K_8366_AP_FW(MWL8K_8366_AP_FW_API));
  
- static DEFINE_PCI_DEVICE_TABLE(mwl8k_pci_id_table) = {
+ static const struct pci_device_id mwl8k_pci_id_table[] = {
 +	{ PCI_VDEVICE(MARVELL, 0x2a02), .driver_data = MWL8363, },
  	{ PCI_VDEVICE(MARVELL, 0x2a0a), .driver_data = MWL8363, },
  	{ PCI_VDEVICE(MARVELL, 0x2a0c), .driver_data = MWL8363, },

+ 0 - 5202
package/kernel/mac80211/patches/800-b43-backports-form-wireless-testing-master-master-20.patch

@@ -1,5202 +0,0 @@
-backport b43 patches from wireless testing
-
-This brings b43 up to wireless-testing/master master-2014-07-29-1
-
---- a/drivers/net/wireless/b43/main.c
-+++ b/drivers/net/wireless/b43/main.c
-@@ -122,7 +122,11 @@ static const struct bcma_device_id b43_b
- 	BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x11, BCMA_ANY_CLASS),
- 	BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x17, BCMA_ANY_CLASS),
- 	BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x18, BCMA_ANY_CLASS),
-+	BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x1C, BCMA_ANY_CLASS),
- 	BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x1D, BCMA_ANY_CLASS),
-+	BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x1E, BCMA_ANY_CLASS),
-+	BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x28, BCMA_ANY_CLASS),
-+	BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x2A, BCMA_ANY_CLASS),
- 	BCMA_CORETABLE_END
- };
- MODULE_DEVICE_TABLE(bcma, b43_bcma_tbl);
-@@ -206,6 +210,9 @@ static struct ieee80211_channel b43_2ghz
- 	CHAN2G(13, 2472, 0),
- 	CHAN2G(14, 2484, 0),
- };
-+
-+/* No support for the last 3 channels (12, 13, 14) */
-+#define b43_2ghz_chantable_limited_size		11
- #undef CHAN2G
- 
- #define CHAN4G(_channel, _flags) {				\
-@@ -283,6 +290,14 @@ static struct ieee80211_channel b43_5ghz
- 	CHAN5G(182, 0),
- };
- 
-+static struct ieee80211_channel b43_5ghz_nphy_chantable_limited[] = {
-+	CHAN5G(36, 0),		CHAN5G(40, 0),
-+	CHAN5G(44, 0),		CHAN5G(48, 0),
-+	CHAN5G(149, 0),		CHAN5G(153, 0),
-+	CHAN5G(157, 0),		CHAN5G(161, 0),
-+	CHAN5G(165, 0),
-+};
-+
- static struct ieee80211_channel b43_5ghz_aphy_chantable[] = {
- 	CHAN5G(34, 0),		CHAN5G(36, 0),
- 	CHAN5G(38, 0),		CHAN5G(40, 0),
-@@ -315,6 +330,14 @@ static struct ieee80211_supported_band b
- 	.n_bitrates	= b43_a_ratetable_size,
- };
- 
-+static struct ieee80211_supported_band b43_band_5GHz_nphy_limited = {
-+	.band		= IEEE80211_BAND_5GHZ,
-+	.channels	= b43_5ghz_nphy_chantable_limited,
-+	.n_channels	= ARRAY_SIZE(b43_5ghz_nphy_chantable_limited),
-+	.bitrates	= b43_a_ratetable,
-+	.n_bitrates	= b43_a_ratetable_size,
-+};
-+
- static struct ieee80211_supported_band b43_band_5GHz_aphy = {
- 	.band		= IEEE80211_BAND_5GHZ,
- 	.channels	= b43_5ghz_aphy_chantable,
-@@ -331,6 +354,14 @@ static struct ieee80211_supported_band b
- 	.n_bitrates	= b43_g_ratetable_size,
- };
- 
-+static struct ieee80211_supported_band b43_band_2ghz_limited = {
-+	.band		= IEEE80211_BAND_2GHZ,
-+	.channels	= b43_2ghz_chantable,
-+	.n_channels	= b43_2ghz_chantable_limited_size,
-+	.bitrates	= b43_g_ratetable,
-+	.n_bitrates	= b43_g_ratetable_size,
-+};
-+
- static void b43_wireless_core_exit(struct b43_wldev *dev);
- static int b43_wireless_core_init(struct b43_wldev *dev);
- static struct b43_wldev * b43_wireless_core_stop(struct b43_wldev *dev);
-@@ -2201,52 +2232,82 @@ err_format:
- 	return -EPROTO;
- }
- 
-+/* http://bcm-v4.sipsolutions.net/802.11/Init/Firmware */
- static int b43_try_request_fw(struct b43_request_fw_context *ctx)
- {
- 	struct b43_wldev *dev = ctx->dev;
- 	struct b43_firmware *fw = &ctx->dev->fw;
-+	struct b43_phy *phy = &dev->phy;
- 	const u8 rev = ctx->dev->dev->core_rev;
- 	const char *filename;
--	u32 tmshigh;
- 	int err;
- 
--	/* Files for HT and LCN were found by trying one by one */
--
- 	/* Get microcode */
--	if ((rev >= 5) && (rev <= 10)) {
--		filename = "ucode5";
--	} else if ((rev >= 11) && (rev <= 12)) {
--		filename = "ucode11";
--	} else if (rev == 13) {
--		filename = "ucode13";
--	} else if (rev == 14) {
--		filename = "ucode14";
--	} else if (rev == 15) {
-+	filename = NULL;
-+	switch (rev) {
-+	case 42:
-+		if (phy->type == B43_PHYTYPE_AC)
-+			filename = "ucode42";
-+		break;
-+	case 40:
-+		if (phy->type == B43_PHYTYPE_AC)
-+			filename = "ucode40";
-+		break;
-+	case 33:
-+		if (phy->type == B43_PHYTYPE_LCN40)
-+			filename = "ucode33_lcn40";
-+		break;
-+	case 30:
-+		if (phy->type == B43_PHYTYPE_N)
-+			filename = "ucode30_mimo";
-+		break;
-+	case 29:
-+		if (phy->type == B43_PHYTYPE_HT)
-+			filename = "ucode29_mimo";
-+		break;
-+	case 26:
-+		if (phy->type == B43_PHYTYPE_HT)
-+			filename = "ucode26_mimo";
-+		break;
-+	case 28:
-+	case 25:
-+		if (phy->type == B43_PHYTYPE_N)
-+			filename = "ucode25_mimo";
-+		else if (phy->type == B43_PHYTYPE_LCN)
-+			filename = "ucode25_lcn";
-+		break;
-+	case 24:
-+		if (phy->type == B43_PHYTYPE_LCN)
-+			filename = "ucode24_lcn";
-+		break;
-+	case 23:
-+		if (phy->type == B43_PHYTYPE_N)
-+			filename = "ucode16_mimo";
-+		break;
-+	case 16 ... 19:
-+		if (phy->type == B43_PHYTYPE_N)
-+			filename = "ucode16_mimo";
-+		else if (phy->type == B43_PHYTYPE_LP)
-+			filename = "ucode16_lp";
-+		break;
-+	case 15:
- 		filename = "ucode15";
--	} else {
--		switch (dev->phy.type) {
--		case B43_PHYTYPE_N:
--			if (rev >= 16)
--				filename = "ucode16_mimo";
--			else
--				goto err_no_ucode;
--			break;
--		case B43_PHYTYPE_HT:
--			if (rev == 29)
--				filename = "ucode29_mimo";
--			else
--				goto err_no_ucode;
--			break;
--		case B43_PHYTYPE_LCN:
--			if (rev == 24)
--				filename = "ucode24_mimo";
--			else
--				goto err_no_ucode;
--			break;
--		default:
--			goto err_no_ucode;
--		}
-+		break;
-+	case 14:
-+		filename = "ucode14";
-+		break;
-+	case 13:
-+		filename = "ucode13";
-+		break;
-+	case 11 ... 12:
-+		filename = "ucode11";
-+		break;
-+	case 5 ... 10:
-+		filename = "ucode5";
-+		break;
- 	}
-+	if (!filename)
-+		goto err_no_ucode;
- 	err = b43_do_request_fw(ctx, filename, &fw->ucode, true);
- 	if (err)
- 		goto err_load;
-@@ -2268,117 +2329,121 @@ static int b43_try_request_fw(struct b43
- 		goto err_load;
- 
- 	/* Get initvals */
-+	filename = NULL;
- 	switch (dev->phy.type) {
--	case B43_PHYTYPE_A:
--		if ((rev >= 5) && (rev <= 10)) {
--			tmshigh = ssb_read32(dev->dev->sdev, SSB_TMSHIGH);
--			if (tmshigh & B43_TMSHIGH_HAVE_2GHZ_PHY)
--				filename = "a0g1initvals5";
--			else
--				filename = "a0g0initvals5";
--		} else
--			goto err_no_initvals;
--		break;
- 	case B43_PHYTYPE_G:
--		if ((rev >= 5) && (rev <= 10))
--			filename = "b0g0initvals5";
--		else if (rev >= 13)
-+		if (rev == 13)
- 			filename = "b0g0initvals13";
--		else
--			goto err_no_initvals;
-+		else if (rev >= 5 && rev <= 10)
-+			filename = "b0g0initvals5";
- 		break;
- 	case B43_PHYTYPE_N:
--		if (rev >= 16)
-+		if (rev == 30)
-+			filename = "n16initvals30";
-+		else if (rev == 28 || rev == 25)
-+			filename = "n0initvals25";
-+		else if (rev == 24)
-+			filename = "n0initvals24";
-+		else if (rev == 23)
-+			filename = "n0initvals16"; /* What about n0initvals22? */
-+		else if (rev >= 16 && rev <= 18)
- 			filename = "n0initvals16";
--		else if ((rev >= 11) && (rev <= 12))
-+		else if (rev >= 11 && rev <= 12)
- 			filename = "n0initvals11";
--		else
--			goto err_no_initvals;
- 		break;
- 	case B43_PHYTYPE_LP:
--		if (rev == 13)
--			filename = "lp0initvals13";
-+		if (rev >= 16 && rev <= 18)
-+			filename = "lp0initvals16";
-+		else if (rev == 15)
-+			filename = "lp0initvals15";
- 		else if (rev == 14)
- 			filename = "lp0initvals14";
--		else if (rev >= 15)
--			filename = "lp0initvals15";
--		else
--			goto err_no_initvals;
-+		else if (rev == 13)
-+			filename = "lp0initvals13";
- 		break;
- 	case B43_PHYTYPE_HT:
- 		if (rev == 29)
- 			filename = "ht0initvals29";
--		else
--			goto err_no_initvals;
-+		else if (rev == 26)
-+			filename = "ht0initvals26";
- 		break;
- 	case B43_PHYTYPE_LCN:
- 		if (rev == 24)
- 			filename = "lcn0initvals24";
--		else
--			goto err_no_initvals;
- 		break;
--	default:
--		goto err_no_initvals;
-+	case B43_PHYTYPE_LCN40:
-+		if (rev == 33)
-+			filename = "lcn400initvals33";
-+		break;
-+	case B43_PHYTYPE_AC:
-+		if (rev == 42)
-+			filename = "ac1initvals42";
-+		else if (rev == 40)
-+			filename = "ac0initvals40";
-+		break;
- 	}
-+	if (!filename)
-+		goto err_no_initvals;
- 	err = b43_do_request_fw(ctx, filename, &fw->initvals, false);
- 	if (err)
- 		goto err_load;
- 
- 	/* Get bandswitch initvals */
-+	filename = NULL;
- 	switch (dev->phy.type) {
--	case B43_PHYTYPE_A:
--		if ((rev >= 5) && (rev <= 10)) {
--			tmshigh = ssb_read32(dev->dev->sdev, SSB_TMSHIGH);
--			if (tmshigh & B43_TMSHIGH_HAVE_2GHZ_PHY)
--				filename = "a0g1bsinitvals5";
--			else
--				filename = "a0g0bsinitvals5";
--		} else if (rev >= 11)
--			filename = NULL;
--		else
--			goto err_no_initvals;
--		break;
- 	case B43_PHYTYPE_G:
--		if ((rev >= 5) && (rev <= 10))
-+		if (rev == 13)
-+			filename = "b0g0bsinitvals13";
-+		else if (rev >= 5 && rev <= 10)
- 			filename = "b0g0bsinitvals5";
--		else if (rev >= 11)
--			filename = NULL;
--		else
--			goto err_no_initvals;
- 		break;
- 	case B43_PHYTYPE_N:
--		if (rev >= 16)
-+		if (rev == 30)
-+			filename = "n16bsinitvals30";
-+		else if (rev == 28 || rev == 25)
-+			filename = "n0bsinitvals25";
-+		else if (rev == 24)
-+			filename = "n0bsinitvals24";
-+		else if (rev == 23)
-+			filename = "n0bsinitvals16"; /* What about n0bsinitvals22? */
-+		else if (rev >= 16 && rev <= 18)
- 			filename = "n0bsinitvals16";
--		else if ((rev >= 11) && (rev <= 12))
-+		else if (rev >= 11 && rev <= 12)
- 			filename = "n0bsinitvals11";
--		else
--			goto err_no_initvals;
- 		break;
- 	case B43_PHYTYPE_LP:
--		if (rev == 13)
--			filename = "lp0bsinitvals13";
-+		if (rev >= 16 && rev <= 18)
-+			filename = "lp0bsinitvals16";
-+		else if (rev == 15)
-+			filename = "lp0bsinitvals15";
- 		else if (rev == 14)
- 			filename = "lp0bsinitvals14";
--		else if (rev >= 15)
--			filename = "lp0bsinitvals15";
--		else
--			goto err_no_initvals;
-+		else if (rev == 13)
-+			filename = "lp0bsinitvals13";
- 		break;
- 	case B43_PHYTYPE_HT:
- 		if (rev == 29)
- 			filename = "ht0bsinitvals29";
--		else
--			goto err_no_initvals;
-+		else if (rev == 26)
-+			filename = "ht0bsinitvals26";
- 		break;
- 	case B43_PHYTYPE_LCN:
- 		if (rev == 24)
- 			filename = "lcn0bsinitvals24";
--		else
--			goto err_no_initvals;
- 		break;
--	default:
--		goto err_no_initvals;
-+	case B43_PHYTYPE_LCN40:
-+		if (rev == 33)
-+			filename = "lcn400bsinitvals33";
-+		break;
-+	case B43_PHYTYPE_AC:
-+		if (rev == 42)
-+			filename = "ac1bsinitvals42";
-+		else if (rev == 40)
-+			filename = "ac0bsinitvals40";
-+		break;
- 	}
-+	if (!filename)
-+		goto err_no_initvals;
- 	err = b43_do_request_fw(ctx, filename, &fw->initvals_band, false);
- 	if (err)
- 		goto err_load;
-@@ -2915,6 +2980,46 @@ void b43_mac_phy_clock_set(struct b43_wl
- 	}
- }
- 
-+/* brcms_b_switch_macfreq */
-+void b43_mac_switch_freq(struct b43_wldev *dev, u8 spurmode)
-+{
-+	u16 chip_id = dev->dev->chip_id;
-+
-+	if (chip_id == BCMA_CHIP_ID_BCM43131 ||
-+	    chip_id == BCMA_CHIP_ID_BCM43217 ||
-+	    chip_id == BCMA_CHIP_ID_BCM43222 ||
-+	    chip_id == BCMA_CHIP_ID_BCM43224 ||
-+	    chip_id == BCMA_CHIP_ID_BCM43225 ||
-+	    chip_id == BCMA_CHIP_ID_BCM43227 ||
-+	    chip_id == BCMA_CHIP_ID_BCM43228) {
-+		switch (spurmode) {
-+		case 2: /* 126 Mhz */
-+			b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_LOW, 0x2082);
-+			b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_HIGH, 0x8);
-+			break;
-+		case 1: /* 123 Mhz */
-+			b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_LOW, 0x5341);
-+			b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_HIGH, 0x8);
-+			break;
-+		default: /* 120 Mhz */
-+			b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_LOW, 0x8889);
-+			b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_HIGH, 0x8);
-+			break;
-+		}
-+	} else if (dev->phy.type == B43_PHYTYPE_LCN) {
-+		switch (spurmode) {
-+		case 1: /* 82 Mhz */
-+			b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_LOW, 0x7CE0);
-+			b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_HIGH, 0xC);
-+			break;
-+		default: /* 80 Mhz */
-+			b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_LOW, 0xCCCD);
-+			b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_HIGH, 0xC);
-+			break;
-+		}
-+	}
-+}
-+
- static void b43_adjust_opmode(struct b43_wldev *dev)
- {
- 	struct b43_wl *wl = dev->wl;
-@@ -3742,7 +3847,9 @@ static int b43_switch_band(struct b43_wl
- 	b43dbg(dev->wl, "Switching to %s GHz band\n",
- 	       band_to_string(chan->band));
- 
--	b43_software_rfkill(dev, true);
-+	/* Some new devices don't need disabling radio for band switching */
-+	if (!(phy->type == B43_PHYTYPE_N && phy->rev >= 3))
-+		b43_software_rfkill(dev, true);
- 
- 	phy->gmode = gmode;
- 	b43_phy_put_into_reset(dev);
-@@ -3796,38 +3903,29 @@ static void b43_set_retry_limits(struct
- static int b43_op_config(struct ieee80211_hw *hw, u32 changed)
- {
- 	struct b43_wl *wl = hw_to_b43_wl(hw);
--	struct b43_wldev *dev;
--	struct b43_phy *phy;
-+	struct b43_wldev *dev = wl->current_dev;
-+	struct b43_phy *phy = &dev->phy;
- 	struct ieee80211_conf *conf = &hw->conf;
- 	int antenna;
- 	int err = 0;
--	bool reload_bss = false;
- 
- 	mutex_lock(&wl->mutex);
--
--	dev = wl->current_dev;
--
- 	b43_mac_suspend(dev);
- 
--	/* Switch the band (if necessary). This might change the active core. */
--	err = b43_switch_band(dev, conf->chandef.chan);
--	if (err)
--		goto out_unlock_mutex;
-+	if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
-+		phy->chandef = &conf->chandef;
-+		phy->channel = conf->chandef.chan->hw_value;
- 
--	/* Need to reload all settings if the core changed */
--	if (dev != wl->current_dev) {
--		dev = wl->current_dev;
--		changed = ~0;
--		reload_bss = true;
--	}
-+		/* Switch the band (if necessary). */
-+		err = b43_switch_band(dev, conf->chandef.chan);
-+		if (err)
-+			goto out_mac_enable;
- 
--	phy = &dev->phy;
--
--	if (conf_is_ht(conf))
--		phy->is_40mhz =
--			(conf_is_ht40_minus(conf) || conf_is_ht40_plus(conf));
--	else
--		phy->is_40mhz = false;
-+		/* Switch to the requested channel.
-+		 * The firmware takes care of races with the TX handler.
-+		 */
-+		b43_switch_channel(dev, phy->channel);
-+	}
- 
- 	if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS)
- 		b43_set_retry_limits(dev, conf->short_frame_max_tx_count,
-@@ -3836,11 +3934,6 @@ static int b43_op_config(struct ieee8021
- 	if (!changed)
- 		goto out_mac_enable;
- 
--	/* Switch to the requested channel.
--	 * The firmware takes care of races with the TX handler. */
--	if (conf->chandef.chan->hw_value != phy->channel)
--		b43_switch_channel(dev, conf->chandef.chan->hw_value);
--
- 	dev->wl->radiotap_enabled = !!(conf->flags & IEEE80211_CONF_MONITOR);
- 
- 	/* Adjust the desired TX power level. */
-@@ -3876,12 +3969,8 @@ static int b43_op_config(struct ieee8021
- 
- out_mac_enable:
- 	b43_mac_enable(dev);
--out_unlock_mutex:
- 	mutex_unlock(&wl->mutex);
- 
--	if (wl->vif && reload_bss)
--		b43_op_bss_info_changed(hw, wl->vif, &wl->vif->bss_conf, ~0);
--
- 	return err;
- }
- 
-@@ -4307,13 +4396,15 @@ static char *b43_phy_name(struct b43_wld
- static int b43_phy_versioning(struct b43_wldev *dev)
- {
- 	struct b43_phy *phy = &dev->phy;
-+	const u8 core_rev = dev->dev->core_rev;
- 	u32 tmp;
- 	u8 analog_type;
- 	u8 phy_type;
- 	u8 phy_rev;
- 	u16 radio_manuf;
--	u16 radio_ver;
-+	u16 radio_id;
- 	u16 radio_rev;
-+	u8 radio_ver;
- 	int unsupported = 0;
- 
- 	/* Get PHY versioning */
-@@ -4321,23 +4412,23 @@ static int b43_phy_versioning(struct b43
- 	analog_type = (tmp & B43_PHYVER_ANALOG) >> B43_PHYVER_ANALOG_SHIFT;
- 	phy_type = (tmp & B43_PHYVER_TYPE) >> B43_PHYVER_TYPE_SHIFT;
- 	phy_rev = (tmp & B43_PHYVER_VERSION);
-+
-+	/* LCNXN is continuation of N which run out of revisions */
-+	if (phy_type == B43_PHYTYPE_LCNXN) {
-+		phy_type = B43_PHYTYPE_N;
-+		phy_rev += 16;
-+	}
-+
- 	switch (phy_type) {
--	case B43_PHYTYPE_A:
--		if (phy_rev >= 4)
--			unsupported = 1;
--		break;
--	case B43_PHYTYPE_B:
--		if (phy_rev != 2 && phy_rev != 4 && phy_rev != 6
--		    && phy_rev != 7)
--			unsupported = 1;
--		break;
-+#ifdef CPTCFG_B43_PHY_G
- 	case B43_PHYTYPE_G:
- 		if (phy_rev > 9)
- 			unsupported = 1;
- 		break;
-+#endif
- #ifdef CPTCFG_B43_PHY_N
- 	case B43_PHYTYPE_N:
--		if (phy_rev > 9)
-+		if (phy_rev >= 19)
- 			unsupported = 1;
- 		break;
- #endif
-@@ -4372,7 +4463,17 @@ static int b43_phy_versioning(struct b43
- 		analog_type, phy_type, b43_phy_name(dev, phy_type), phy_rev);
- 
- 	/* Get RADIO versioning */
--	if (dev->dev->core_rev >= 24) {
-+	if (core_rev == 40 || core_rev == 42) {
-+		radio_manuf = 0x17F;
-+
-+		b43_write16(dev, B43_MMIO_RADIO24_CONTROL, 0);
-+		radio_rev = b43_read16(dev, B43_MMIO_RADIO24_DATA);
-+
-+		b43_write16(dev, B43_MMIO_RADIO24_CONTROL, 1);
-+		radio_id = b43_read16(dev, B43_MMIO_RADIO24_DATA);
-+
-+		radio_ver = 0; /* Is there version somewhere? */
-+	} else if (core_rev >= 24) {
- 		u16 radio24[3];
- 
- 		for (tmp = 0; tmp < 3; tmp++) {
-@@ -4380,12 +4481,10 @@ static int b43_phy_versioning(struct b43
- 			radio24[tmp] = b43_read16(dev, B43_MMIO_RADIO24_DATA);
- 		}
- 
--		/* Broadcom uses "id" for our "ver" and has separated "ver" */
--		/* radio_ver = (radio24[0] & 0xF0) >> 4; */
--
- 		radio_manuf = 0x17F;
--		radio_ver = (radio24[2] << 8) | radio24[1];
-+		radio_id = (radio24[2] << 8) | radio24[1];
- 		radio_rev = (radio24[0] & 0xF);
-+		radio_ver = (radio24[0] & 0xF0) >> 4;
- 	} else {
- 		if (dev->dev->chip_id == 0x4317) {
- 			if (dev->dev->chip_rev == 0)
-@@ -4404,15 +4503,16 @@ static int b43_phy_versioning(struct b43
- 				<< 16;
- 		}
- 		radio_manuf = (tmp & 0x00000FFF);
--		radio_ver = (tmp & 0x0FFFF000) >> 12;
-+		radio_id = (tmp & 0x0FFFF000) >> 12;
- 		radio_rev = (tmp & 0xF0000000) >> 28;
-+		radio_ver = 0; /* Probably not available on old hw */
- 	}
- 
- 	if (radio_manuf != 0x17F /* Broadcom */)
- 		unsupported = 1;
- 	switch (phy_type) {
- 	case B43_PHYTYPE_A:
--		if (radio_ver != 0x2060)
-+		if (radio_id != 0x2060)
- 			unsupported = 1;
- 		if (radio_rev != 1)
- 			unsupported = 1;
-@@ -4420,43 +4520,49 @@ static int b43_phy_versioning(struct b43
- 			unsupported = 1;
- 		break;
- 	case B43_PHYTYPE_B:
--		if ((radio_ver & 0xFFF0) != 0x2050)
-+		if ((radio_id & 0xFFF0) != 0x2050)
- 			unsupported = 1;
- 		break;
- 	case B43_PHYTYPE_G:
--		if (radio_ver != 0x2050)
-+		if (radio_id != 0x2050)
- 			unsupported = 1;
- 		break;
- 	case B43_PHYTYPE_N:
--		if (radio_ver != 0x2055 && radio_ver != 0x2056)
-+		if (radio_id != 0x2055 && radio_id != 0x2056 &&
-+		    radio_id != 0x2057)
-+			unsupported = 1;
-+		if (radio_id == 0x2057 &&
-+		    !(radio_rev == 9 || radio_rev == 14))
- 			unsupported = 1;
- 		break;
- 	case B43_PHYTYPE_LP:
--		if (radio_ver != 0x2062 && radio_ver != 0x2063)
-+		if (radio_id != 0x2062 && radio_id != 0x2063)
- 			unsupported = 1;
- 		break;
- 	case B43_PHYTYPE_HT:
--		if (radio_ver != 0x2059)
-+		if (radio_id != 0x2059)
- 			unsupported = 1;
- 		break;
- 	case B43_PHYTYPE_LCN:
--		if (radio_ver != 0x2064)
-+		if (radio_id != 0x2064)
- 			unsupported = 1;
- 		break;
- 	default:
- 		B43_WARN_ON(1);
- 	}
- 	if (unsupported) {
--		b43err(dev->wl, "FOUND UNSUPPORTED RADIO "
--		       "(Manuf 0x%X, Version 0x%X, Revision %u)\n",
--		       radio_manuf, radio_ver, radio_rev);
-+		b43err(dev->wl,
-+		       "FOUND UNSUPPORTED RADIO (Manuf 0x%X, ID 0x%X, Revision %u, Version %u)\n",
-+		       radio_manuf, radio_id, radio_rev, radio_ver);
- 		return -EOPNOTSUPP;
- 	}
--	b43dbg(dev->wl, "Found Radio: Manuf 0x%X, Version 0x%X, Revision %u\n",
--	       radio_manuf, radio_ver, radio_rev);
-+	b43info(dev->wl,
-+		"Found Radio: Manuf 0x%X, ID 0x%X, Revision %u, Version %u\n",
-+		radio_manuf, radio_id, radio_rev, radio_ver);
- 
-+	/* FIXME: b43 treats "id" as "ver" and ignores the real "ver" */
- 	phy->radio_manuf = radio_manuf;
--	phy->radio_ver = radio_ver;
-+	phy->radio_ver = radio_id;
- 	phy->radio_rev = radio_rev;
- 
- 	phy->analog = analog_type;
-@@ -5064,12 +5170,24 @@ static int b43_setup_bands(struct b43_wl
- 			   bool have_2ghz_phy, bool have_5ghz_phy)
- {
- 	struct ieee80211_hw *hw = dev->wl->hw;
-+	struct b43_phy *phy = &dev->phy;
-+	bool limited_2g;
-+	bool limited_5g;
-+
-+	/* We don't support all 2 GHz channels on some devices */
-+	limited_2g = phy->radio_ver == 0x2057 &&
-+		     (phy->radio_rev == 9 || phy->radio_rev == 14);
-+	limited_5g = phy->radio_ver == 0x2057 &&
-+		     phy->radio_rev == 9;
- 
- 	if (have_2ghz_phy)
--		hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &b43_band_2GHz;
-+		hw->wiphy->bands[IEEE80211_BAND_2GHZ] = limited_2g ?
-+			&b43_band_2ghz_limited : &b43_band_2GHz;
- 	if (dev->phy.type == B43_PHYTYPE_N) {
- 		if (have_5ghz_phy)
--			hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &b43_band_5GHz_nphy;
-+			hw->wiphy->bands[IEEE80211_BAND_5GHZ] = limited_5g ?
-+				&b43_band_5GHz_nphy_limited :
-+				&b43_band_5GHz_nphy;
- 	} else {
- 		if (have_5ghz_phy)
- 			hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &b43_band_5GHz_aphy;
-@@ -5164,6 +5282,7 @@ static void b43_supported_bands(struct b
- static int b43_wireless_core_attach(struct b43_wldev *dev)
- {
- 	struct b43_wl *wl = dev->wl;
-+	struct b43_phy *phy = &dev->phy;
- 	int err;
- 	u32 tmp;
- 	bool have_2ghz_phy = false, have_5ghz_phy = false;
-@@ -5181,6 +5300,8 @@ static int b43_wireless_core_attach(stru
- 		goto out;
- 	}
- 
-+	phy->do_full_init = true;
-+
- 	/* Try to guess supported bands for the first init needs */
- 	switch (dev->dev->bus_type) {
- #ifdef CPTCFG_B43_BCMA
-@@ -5214,14 +5335,15 @@ static int b43_wireless_core_attach(stru
- 	b43_supported_bands(dev, &have_2ghz_phy, &have_5ghz_phy);
- 
- 	/* We don't support 5 GHz on some PHYs yet */
--	switch (dev->phy.type) {
--	case B43_PHYTYPE_A:
--	case B43_PHYTYPE_G:
--	case B43_PHYTYPE_N:
--	case B43_PHYTYPE_LP:
--	case B43_PHYTYPE_HT:
--		b43warn(wl, "5 GHz band is unsupported on this PHY\n");
--		have_5ghz_phy = false;
-+	if (have_5ghz_phy) {
-+		switch (dev->phy.type) {
-+		case B43_PHYTYPE_A:
-+		case B43_PHYTYPE_G:
-+		case B43_PHYTYPE_LP:
-+		case B43_PHYTYPE_HT:
-+			b43warn(wl, "5 GHz band is unsupported on this PHY\n");
-+			have_5ghz_phy = false;
-+		}
- 	}
- 
- 	if (!have_2ghz_phy && !have_5ghz_phy) {
---- a/drivers/net/wireless/b43/main.h
-+++ b/drivers/net/wireless/b43/main.h
-@@ -99,6 +99,7 @@ void b43_power_saving_ctl_bits(struct b4
- void b43_mac_suspend(struct b43_wldev *dev);
- void b43_mac_enable(struct b43_wldev *dev);
- void b43_mac_phy_clock_set(struct b43_wldev *dev, bool on);
-+void b43_mac_switch_freq(struct b43_wldev *dev, u8 spurmode);
- 
- 
- struct b43_request_fw_context;
---- a/drivers/net/wireless/b43/phy_common.c
-+++ b/drivers/net/wireless/b43/phy_common.c
-@@ -45,11 +45,10 @@ int b43_phy_allocate(struct b43_wldev *d
- 	phy->ops = NULL;
- 
- 	switch (phy->type) {
--	case B43_PHYTYPE_A:
--		phy->ops = &b43_phyops_a;
--		break;
- 	case B43_PHYTYPE_G:
-+#ifdef CPTCFG_B43_PHY_G
- 		phy->ops = &b43_phyops_g;
-+#endif
- 		break;
- 	case B43_PHYTYPE_N:
- #ifdef CPTCFG_B43_PHY_N
-@@ -94,18 +93,25 @@ int b43_phy_init(struct b43_wldev *dev)
- 	const struct b43_phy_operations *ops = phy->ops;
- 	int err;
- 
--	phy->channel = ops->get_default_chan(dev);
-+	/* During PHY init we need to use some channel. On the first init this
-+	 * function is called *before* b43_op_config, so our pointer is NULL.
-+	 */
-+	if (!phy->chandef) {
-+		phy->chandef = &dev->wl->hw->conf.chandef;
-+		phy->channel = phy->chandef->chan->hw_value;
-+	}
- 
- 	phy->ops->switch_analog(dev, true);
- 	b43_software_rfkill(dev, false);
-+
- 	err = ops->init(dev);
- 	if (err) {
- 		b43err(dev->wl, "PHY init failed\n");
- 		goto err_block_rf;
- 	}
--	/* Make sure to switch hardware and firmware (SHM) to
--	 * the default channel. */
--	err = b43_switch_channel(dev, ops->get_default_chan(dev));
-+	phy->do_full_init = false;
-+
-+	err = b43_switch_channel(dev, phy->channel);
- 	if (err) {
- 		b43err(dev->wl, "PHY init: Channel switch to default failed\n");
- 		goto err_phy_exit;
-@@ -114,6 +120,7 @@ int b43_phy_init(struct b43_wldev *dev)
- 	return 0;
- 
- err_phy_exit:
-+	phy->do_full_init = true;
- 	if (ops->exit)
- 		ops->exit(dev);
- err_block_rf:
-@@ -127,6 +134,7 @@ void b43_phy_exit(struct b43_wldev *dev)
- 	const struct b43_phy_operations *ops = dev->phy.ops;
- 
- 	b43_software_rfkill(dev, true);
-+	dev->phy.do_full_init = true;
- 	if (ops->exit)
- 		ops->exit(dev);
- }
-@@ -403,9 +411,6 @@ int b43_switch_channel(struct b43_wldev
- 	u16 channelcookie, savedcookie;
- 	int err;
- 
--	if (new_channel == B43_DEFAULT_CHANNEL)
--		new_channel = phy->ops->get_default_chan(dev);
--
- 	/* First we set the channel radio code to prevent the
- 	 * firmware from sending ghost packets.
- 	 */
-@@ -423,7 +428,6 @@ int b43_switch_channel(struct b43_wldev
- 	if (err)
- 		goto err_restore_cookie;
- 
--	dev->phy.channel = new_channel;
- 	/* Wait for the radio to tune to the channel and stabilize. */
- 	msleep(8);
- 
-@@ -542,10 +546,9 @@ void b43_phyop_switch_analog_generic(str
- }
- 
- 
--bool b43_channel_type_is_40mhz(enum nl80211_channel_type channel_type)
-+bool b43_is_40mhz(struct b43_wldev *dev)
- {
--	return (channel_type == NL80211_CHAN_HT40MINUS ||
--		channel_type == NL80211_CHAN_HT40PLUS);
-+	return dev->phy.chandef->width == NL80211_CHAN_WIDTH_40;
- }
- 
- /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/BmacPhyClkFgc */
---- a/drivers/net/wireless/b43/phy_common.h
-+++ b/drivers/net/wireless/b43/phy_common.h
-@@ -228,12 +228,12 @@ struct b43_phy {
- 	bool supports_2ghz;
- 	bool supports_5ghz;
- 
--	/* HT info */
--	bool is_40mhz;
--
- 	/* Is GMODE (2 GHz mode) bit enabled? */
- 	bool gmode;
- 
-+	/* After power reset full init has to be performed */
-+	bool do_full_init;
-+
- 	/* Analog Type */
- 	u8 analog;
- 	/* B43_PHYTYPE_ */
-@@ -264,9 +264,8 @@ struct b43_phy {
- 	unsigned long next_txpwr_check_time;
- 
- 	/* Current channel */
-+	struct cfg80211_chan_def *chandef;
- 	unsigned int channel;
--	u16 channel_freq;
--	enum nl80211_channel_type channel_type;
- 
- 	/* PHY TX errors counter. */
- 	atomic_t txerr_cnt;
-@@ -397,10 +396,6 @@ void b43_phy_take_out_of_reset(struct b4
-  * b43_switch_channel - Switch to another channel
-  */
- int b43_switch_channel(struct b43_wldev *dev, unsigned int new_channel);
--/**
-- * B43_DEFAULT_CHANNEL - Switch to the default channel.
-- */
--#define B43_DEFAULT_CHANNEL	UINT_MAX
- 
- /**
-  * b43_software_rfkill - Turn the radio ON or OFF in software.
-@@ -451,7 +446,7 @@ int b43_phy_shm_tssi_read(struct b43_wld
-  */
- void b43_phyop_switch_analog_generic(struct b43_wldev *dev, bool on);
- 
--bool b43_channel_type_is_40mhz(enum nl80211_channel_type channel_type);
-+bool b43_is_40mhz(struct b43_wldev *dev);
- 
- void b43_phy_force_clock(struct b43_wldev *dev, bool force);
- 
---- a/drivers/net/wireless/b43/phy_lcn.c
-+++ b/drivers/net/wireless/b43/phy_lcn.c
-@@ -54,39 +54,6 @@ enum lcn_sense_type {
- 	B43_SENSE_VBAT,
- };
- 
--/* In theory it's PHY common function, move if needed */
--/* brcms_b_switch_macfreq */
--static void b43_phy_switch_macfreq(struct b43_wldev *dev, u8 spurmode)
--{
--	if (dev->dev->chip_id == 43224 || dev->dev->chip_id == 43225) {
--		switch (spurmode) {
--		case 2:		/* 126 Mhz */
--			b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_LOW, 0x2082);
--			b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_HIGH, 0x8);
--			break;
--		case 1:		/* 123 Mhz */
--			b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_LOW, 0x5341);
--			b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_HIGH, 0x8);
--			break;
--		default:	/* 120 Mhz */
--			b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_LOW, 0x8889);
--			b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_HIGH, 0x8);
--			break;
--		}
--	} else if (dev->phy.type == B43_PHYTYPE_LCN) {
--		switch (spurmode) {
--		case 1:		/* 82 Mhz */
--			b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_LOW, 0x7CE0);
--			b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_HIGH, 0xC);
--			break;
--		default:	/* 80 Mhz */
--			b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_LOW, 0xCCCD);
--			b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_HIGH, 0xC);
--			break;
--		}
--	}
--}
--
- /**************************************************
-  * Radio 2064.
-  **************************************************/
-@@ -609,7 +576,7 @@ static void b43_phy_lcn_txrx_spur_avoida
- 		b43_phy_write(dev, 0x93b, ((0 << 13) + 23));
- 		b43_phy_write(dev, 0x93c, ((0 << 13) + 1989));
- 	}
--	b43_phy_switch_macfreq(dev, enable);
-+	b43_mac_switch_freq(dev, enable);
- }
- 
- /**************************************************
---- a/drivers/net/wireless/b43/phy_n.c
-+++ b/drivers/net/wireless/b43/phy_n.c
-@@ -36,6 +36,7 @@
- #include "main.h"
- 
- struct nphy_txgains {
-+	u16 tx_lpf[2];
- 	u16 txgm[2];
- 	u16 pga[2];
- 	u16 pad[2];
-@@ -43,6 +44,7 @@ struct nphy_txgains {
- };
- 
- struct nphy_iqcal_params {
-+	u16 tx_lpf;
- 	u16 txgm;
- 	u16 pga;
- 	u16 pad;
-@@ -69,6 +71,14 @@ enum b43_nphy_rf_sequence {
- 	B43_RFSEQ_UPDATE_GAINU,
- };
- 
-+enum n_rf_ctl_over_cmd {
-+	N_RF_CTL_OVER_CMD_RXRF_PU = 0,
-+	N_RF_CTL_OVER_CMD_RX_PU = 1,
-+	N_RF_CTL_OVER_CMD_TX_PU = 2,
-+	N_RF_CTL_OVER_CMD_RX_GAIN = 3,
-+	N_RF_CTL_OVER_CMD_TX_GAIN = 4,
-+};
-+
- enum n_intc_override {
- 	N_INTC_OVERRIDE_OFF = 0,
- 	N_INTC_OVERRIDE_TRSW = 1,
-@@ -140,11 +150,19 @@ ok:
- 	b43_phy_write(dev, B43_NPHY_RFSEQMODE, seq_mode);
- }
- 
-+static void b43_nphy_rf_ctl_override_rev19(struct b43_wldev *dev, u16 field,
-+					   u16 value, u8 core, bool off,
-+					   u8 override_id)
-+{
-+	/* TODO */
-+}
-+
- /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RFCtrlOverrideRev7 */
- static void b43_nphy_rf_ctl_override_rev7(struct b43_wldev *dev, u16 field,
- 					  u16 value, u8 core, bool off,
- 					  u8 override)
- {
-+	struct b43_phy *phy = &dev->phy;
- 	const struct nphy_rf_control_override_rev7 *e;
- 	u16 en_addrs[3][2] = {
- 		{ 0x0E7, 0x0EC }, { 0x342, 0x343 }, { 0x346, 0x347 }
-@@ -154,6 +172,11 @@ static void b43_nphy_rf_ctl_override_rev
- 	u16 val_addr;
- 	u8 i;
- 
-+	if (phy->rev >= 19 || phy->rev < 3) {
-+		B43_WARN_ON(1);
-+		return;
-+	}
-+
- 	/* Remember: we can get NULL! */
- 	e = b43_nphy_get_rf_ctl_over_rev7(dev, field, override);
- 
-@@ -181,6 +204,50 @@ static void b43_nphy_rf_ctl_override_rev
- 	}
- }
- 
-+/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RFCtrlOverideOneToMany */
-+static void b43_nphy_rf_ctl_override_one_to_many(struct b43_wldev *dev,
-+						 enum n_rf_ctl_over_cmd cmd,
-+						 u16 value, u8 core, bool off)
-+{
-+	struct b43_phy *phy = &dev->phy;
-+	u16 tmp;
-+
-+	B43_WARN_ON(phy->rev < 7);
-+
-+	switch (cmd) {
-+	case N_RF_CTL_OVER_CMD_RXRF_PU:
-+		b43_nphy_rf_ctl_override_rev7(dev, 0x20, value, core, off, 1);
-+		b43_nphy_rf_ctl_override_rev7(dev, 0x10, value, core, off, 1);
-+		b43_nphy_rf_ctl_override_rev7(dev, 0x08, value, core, off, 1);
-+		break;
-+	case N_RF_CTL_OVER_CMD_RX_PU:
-+		b43_nphy_rf_ctl_override_rev7(dev, 0x4, value, core, off, 1);
-+		b43_nphy_rf_ctl_override_rev7(dev, 0x2, value, core, off, 1);
-+		b43_nphy_rf_ctl_override_rev7(dev, 0x1, value, core, off, 1);
-+		b43_nphy_rf_ctl_override_rev7(dev, 0x2, value, core, off, 2);
-+		b43_nphy_rf_ctl_override_rev7(dev, 0x0800, 0, core, off, 1);
-+		break;
-+	case N_RF_CTL_OVER_CMD_TX_PU:
-+		b43_nphy_rf_ctl_override_rev7(dev, 0x4, value, core, off, 0);
-+		b43_nphy_rf_ctl_override_rev7(dev, 0x2, value, core, off, 1);
-+		b43_nphy_rf_ctl_override_rev7(dev, 0x1, value, core, off, 2);
-+		b43_nphy_rf_ctl_override_rev7(dev, 0x0800, 1, core, off, 1);
-+		break;
-+	case N_RF_CTL_OVER_CMD_RX_GAIN:
-+		tmp = value & 0xFF;
-+		b43_nphy_rf_ctl_override_rev7(dev, 0x0800, tmp, core, off, 0);
-+		tmp = value >> 8;
-+		b43_nphy_rf_ctl_override_rev7(dev, 0x6000, tmp, core, off, 0);
-+		break;
-+	case N_RF_CTL_OVER_CMD_TX_GAIN:
-+		tmp = value & 0x7FFF;
-+		b43_nphy_rf_ctl_override_rev7(dev, 0x1000, tmp, core, off, 0);
-+		tmp = value >> 14;
-+		b43_nphy_rf_ctl_override_rev7(dev, 0x4000, tmp, core, off, 0);
-+		break;
-+	}
-+}
-+
- /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RFCtrlOverride */
- static void b43_nphy_rf_ctl_override(struct b43_wldev *dev, u16 field,
- 				     u16 value, u8 core, bool off)
-@@ -264,6 +331,8 @@ static void b43_nphy_rf_ctl_intc_overrid
- 	u16 reg, tmp, tmp2, val;
- 	int core;
- 
-+	/* TODO: What about rev19+? Revs 3+ and 7+ are a bit similar */
-+
- 	for (core = 0; core < 2; core++) {
- 		if ((core_sel == 1 && core != 0) ||
- 		    (core_sel == 2 && core != 1))
-@@ -274,6 +343,7 @@ static void b43_nphy_rf_ctl_intc_overrid
- 		switch (intc_override) {
- 		case N_INTC_OVERRIDE_OFF:
- 			b43_phy_write(dev, reg, 0);
-+			b43_phy_mask(dev, 0x2ff, ~0x2000);
- 			b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RESET2RX);
- 			break;
- 		case N_INTC_OVERRIDE_TRSW:
-@@ -505,6 +575,14 @@ static void b43_nphy_stay_in_carrier_sea
- 	}
- }
- 
-+/* http://bcm-v4.sipsolutions.net/PHY/N/Read_Lpf_Bw_Ctl */
-+static u16 b43_nphy_read_lpf_ctl(struct b43_wldev *dev, u16 offset)
-+{
-+	if (!offset)
-+		offset = b43_is_40mhz(dev) ? 0x159 : 0x154;
-+	return b43_ntab_read(dev, B43_NTAB16(7, offset)) & 0x7;
-+}
-+
- /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/AdjustLnaGainTbl */
- static void b43_nphy_adjust_lna_gain_table(struct b43_wldev *dev)
- {
-@@ -590,44 +668,270 @@ static void b43_nphy_set_rf_sequence(str
-  * Radio 0x2057
-  **************************************************/
- 
--/* http://bcm-v4.sipsolutions.net/PHY/radio2057_rcal */
-+static void b43_radio_2057_chantab_upload(struct b43_wldev *dev,
-+					  const struct b43_nphy_chantabent_rev7 *e_r7,
-+					  const struct b43_nphy_chantabent_rev7_2g *e_r7_2g)
-+{
-+	if (e_r7_2g) {
-+		b43_radio_write(dev, R2057_VCOCAL_COUNTVAL0, e_r7_2g->radio_vcocal_countval0);
-+		b43_radio_write(dev, R2057_VCOCAL_COUNTVAL1, e_r7_2g->radio_vcocal_countval1);
-+		b43_radio_write(dev, R2057_RFPLL_REFMASTER_SPAREXTALSIZE, e_r7_2g->radio_rfpll_refmaster_sparextalsize);
-+		b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_R1, e_r7_2g->radio_rfpll_loopfilter_r1);
-+		b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_C2, e_r7_2g->radio_rfpll_loopfilter_c2);
-+		b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_C1, e_r7_2g->radio_rfpll_loopfilter_c1);
-+		b43_radio_write(dev, R2057_CP_KPD_IDAC, e_r7_2g->radio_cp_kpd_idac);
-+		b43_radio_write(dev, R2057_RFPLL_MMD0, e_r7_2g->radio_rfpll_mmd0);
-+		b43_radio_write(dev, R2057_RFPLL_MMD1, e_r7_2g->radio_rfpll_mmd1);
-+		b43_radio_write(dev, R2057_VCOBUF_TUNE, e_r7_2g->radio_vcobuf_tune);
-+		b43_radio_write(dev, R2057_LOGEN_MX2G_TUNE, e_r7_2g->radio_logen_mx2g_tune);
-+		b43_radio_write(dev, R2057_LOGEN_INDBUF2G_TUNE, e_r7_2g->radio_logen_indbuf2g_tune);
-+		b43_radio_write(dev, R2057_TXMIX2G_TUNE_BOOST_PU_CORE0, e_r7_2g->radio_txmix2g_tune_boost_pu_core0);
-+		b43_radio_write(dev, R2057_PAD2G_TUNE_PUS_CORE0, e_r7_2g->radio_pad2g_tune_pus_core0);
-+		b43_radio_write(dev, R2057_LNA2G_TUNE_CORE0, e_r7_2g->radio_lna2g_tune_core0);
-+		b43_radio_write(dev, R2057_TXMIX2G_TUNE_BOOST_PU_CORE1, e_r7_2g->radio_txmix2g_tune_boost_pu_core1);
-+		b43_radio_write(dev, R2057_PAD2G_TUNE_PUS_CORE1, e_r7_2g->radio_pad2g_tune_pus_core1);
-+		b43_radio_write(dev, R2057_LNA2G_TUNE_CORE1, e_r7_2g->radio_lna2g_tune_core1);
-+
-+	} else {
-+		b43_radio_write(dev, R2057_VCOCAL_COUNTVAL0, e_r7->radio_vcocal_countval0);
-+		b43_radio_write(dev, R2057_VCOCAL_COUNTVAL1, e_r7->radio_vcocal_countval1);
-+		b43_radio_write(dev, R2057_RFPLL_REFMASTER_SPAREXTALSIZE, e_r7->radio_rfpll_refmaster_sparextalsize);
-+		b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_R1, e_r7->radio_rfpll_loopfilter_r1);
-+		b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_C2, e_r7->radio_rfpll_loopfilter_c2);
-+		b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_C1, e_r7->radio_rfpll_loopfilter_c1);
-+		b43_radio_write(dev, R2057_CP_KPD_IDAC, e_r7->radio_cp_kpd_idac);
-+		b43_radio_write(dev, R2057_RFPLL_MMD0, e_r7->radio_rfpll_mmd0);
-+		b43_radio_write(dev, R2057_RFPLL_MMD1, e_r7->radio_rfpll_mmd1);
-+		b43_radio_write(dev, R2057_VCOBUF_TUNE, e_r7->radio_vcobuf_tune);
-+		b43_radio_write(dev, R2057_LOGEN_MX2G_TUNE, e_r7->radio_logen_mx2g_tune);
-+		b43_radio_write(dev, R2057_LOGEN_MX5G_TUNE, e_r7->radio_logen_mx5g_tune);
-+		b43_radio_write(dev, R2057_LOGEN_INDBUF2G_TUNE, e_r7->radio_logen_indbuf2g_tune);
-+		b43_radio_write(dev, R2057_LOGEN_INDBUF5G_TUNE, e_r7->radio_logen_indbuf5g_tune);
-+		b43_radio_write(dev, R2057_TXMIX2G_TUNE_BOOST_PU_CORE0, e_r7->radio_txmix2g_tune_boost_pu_core0);
-+		b43_radio_write(dev, R2057_PAD2G_TUNE_PUS_CORE0, e_r7->radio_pad2g_tune_pus_core0);
-+		b43_radio_write(dev, R2057_PGA_BOOST_TUNE_CORE0, e_r7->radio_pga_boost_tune_core0);
-+		b43_radio_write(dev, R2057_TXMIX5G_BOOST_TUNE_CORE0, e_r7->radio_txmix5g_boost_tune_core0);
-+		b43_radio_write(dev, R2057_PAD5G_TUNE_MISC_PUS_CORE0, e_r7->radio_pad5g_tune_misc_pus_core0);
-+		b43_radio_write(dev, R2057_LNA2G_TUNE_CORE0, e_r7->radio_lna2g_tune_core0);
-+		b43_radio_write(dev, R2057_LNA5G_TUNE_CORE0, e_r7->radio_lna5g_tune_core0);
-+		b43_radio_write(dev, R2057_TXMIX2G_TUNE_BOOST_PU_CORE1, e_r7->radio_txmix2g_tune_boost_pu_core1);
-+		b43_radio_write(dev, R2057_PAD2G_TUNE_PUS_CORE1, e_r7->radio_pad2g_tune_pus_core1);
-+		b43_radio_write(dev, R2057_PGA_BOOST_TUNE_CORE1, e_r7->radio_pga_boost_tune_core1);
-+		b43_radio_write(dev, R2057_TXMIX5G_BOOST_TUNE_CORE1, e_r7->radio_txmix5g_boost_tune_core1);
-+		b43_radio_write(dev, R2057_PAD5G_TUNE_MISC_PUS_CORE1, e_r7->radio_pad5g_tune_misc_pus_core1);
-+		b43_radio_write(dev, R2057_LNA2G_TUNE_CORE1, e_r7->radio_lna2g_tune_core1);
-+		b43_radio_write(dev, R2057_LNA5G_TUNE_CORE1, e_r7->radio_lna5g_tune_core1);
-+	}
-+}
-+
-+static void b43_radio_2057_setup(struct b43_wldev *dev,
-+				 const struct b43_nphy_chantabent_rev7 *tabent_r7,
-+				 const struct b43_nphy_chantabent_rev7_2g *tabent_r7_2g)
-+{
-+	struct b43_phy *phy = &dev->phy;
-+
-+	b43_radio_2057_chantab_upload(dev, tabent_r7, tabent_r7_2g);
-+
-+	switch (phy->radio_rev) {
-+	case 0 ... 4:
-+	case 6:
-+		if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
-+			b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_R1, 0x3f);
-+			b43_radio_write(dev, R2057_CP_KPD_IDAC, 0x3f);
-+			b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_C1, 0x8);
-+			b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_C2, 0x8);
-+		} else {
-+			b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_R1, 0x1f);
-+			b43_radio_write(dev, R2057_CP_KPD_IDAC, 0x3f);
-+			b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_C1, 0x8);
-+			b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_C2, 0x8);
-+		}
-+		break;
-+	case 9: /* e.g. PHY rev 16 */
-+		b43_radio_write(dev, R2057_LOGEN_PTAT_RESETS, 0x20);
-+		b43_radio_write(dev, R2057_VCOBUF_IDACS, 0x18);
-+		if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) {
-+			b43_radio_write(dev, R2057_LOGEN_PTAT_RESETS, 0x38);
-+			b43_radio_write(dev, R2057_VCOBUF_IDACS, 0x0f);
-+
-+			if (b43_is_40mhz(dev)) {
-+				/* TODO */
-+			} else {
-+				b43_radio_write(dev,
-+						R2057_PAD_BIAS_FILTER_BWS_CORE0,
-+						0x3c);
-+				b43_radio_write(dev,
-+						R2057_PAD_BIAS_FILTER_BWS_CORE1,
-+						0x3c);
-+			}
-+		}
-+		break;
-+	case 14: /* 2 GHz only */
-+		b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_R1, 0x1b);
-+		b43_radio_write(dev, R2057_CP_KPD_IDAC, 0x3f);
-+		b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_C1, 0x1f);
-+		b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_C2, 0x1f);
-+		break;
-+	}
-+
-+	if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
-+		u16 txmix2g_tune_boost_pu = 0;
-+		u16 pad2g_tune_pus = 0;
-+
-+		if (b43_nphy_ipa(dev)) {
-+			switch (phy->radio_rev) {
-+			case 9:
-+				txmix2g_tune_boost_pu = 0x0041;
-+				/* TODO */
-+				break;
-+			case 14:
-+				txmix2g_tune_boost_pu = 0x21;
-+				pad2g_tune_pus = 0x23;
-+				break;
-+			}
-+		}
-+
-+		if (txmix2g_tune_boost_pu)
-+			b43_radio_write(dev, R2057_TXMIX2G_TUNE_BOOST_PU_CORE0,
-+					txmix2g_tune_boost_pu);
-+		if (pad2g_tune_pus)
-+			b43_radio_write(dev, R2057_PAD2G_TUNE_PUS_CORE0,
-+					pad2g_tune_pus);
-+		if (txmix2g_tune_boost_pu)
-+			b43_radio_write(dev, R2057_TXMIX2G_TUNE_BOOST_PU_CORE1,
-+					txmix2g_tune_boost_pu);
-+		if (pad2g_tune_pus)
-+			b43_radio_write(dev, R2057_PAD2G_TUNE_PUS_CORE1,
-+					pad2g_tune_pus);
-+	}
-+
-+	usleep_range(50, 100);
-+
-+	/* VCO calibration */
-+	b43_radio_mask(dev, R2057_RFPLL_MISC_EN, ~0x01);
-+	b43_radio_mask(dev, R2057_RFPLL_MISC_CAL_RESETN, ~0x04);
-+	b43_radio_set(dev, R2057_RFPLL_MISC_CAL_RESETN, 0x4);
-+	b43_radio_set(dev, R2057_RFPLL_MISC_EN, 0x01);
-+	usleep_range(300, 600);
-+}
-+
-+/* Calibrate resistors in LPF of PLL?
-+ * http://bcm-v4.sipsolutions.net/PHY/radio205x_rcal
-+ */
- static u8 b43_radio_2057_rcal(struct b43_wldev *dev)
- {
- 	struct b43_phy *phy = &dev->phy;
-+	u16 saved_regs_phy[12];
-+	u16 saved_regs_phy_rf[6];
-+	u16 saved_regs_radio[2] = { };
-+	static const u16 phy_to_store[] = {
-+		B43_NPHY_RFCTL_RSSIO1, B43_NPHY_RFCTL_RSSIO2,
-+		B43_NPHY_RFCTL_LUT_TRSW_LO1, B43_NPHY_RFCTL_LUT_TRSW_LO2,
-+		B43_NPHY_RFCTL_RXG1, B43_NPHY_RFCTL_RXG2,
-+		B43_NPHY_RFCTL_TXG1, B43_NPHY_RFCTL_TXG2,
-+		B43_NPHY_REV7_RF_CTL_MISC_REG3, B43_NPHY_REV7_RF_CTL_MISC_REG4,
-+		B43_NPHY_REV7_RF_CTL_MISC_REG5, B43_NPHY_REV7_RF_CTL_MISC_REG6,
-+	};
-+	static const u16 phy_to_store_rf[] = {
-+		B43_NPHY_REV3_RFCTL_OVER0, B43_NPHY_REV3_RFCTL_OVER1,
-+		B43_NPHY_REV7_RF_CTL_OVER3, B43_NPHY_REV7_RF_CTL_OVER4,
-+		B43_NPHY_REV7_RF_CTL_OVER5, B43_NPHY_REV7_RF_CTL_OVER6,
-+	};
- 	u16 tmp;
-+	int i;
- 
--	if (phy->radio_rev == 5) {
--		b43_phy_mask(dev, 0x342, ~0x2);
-+	/* Save */
-+	for (i = 0; i < ARRAY_SIZE(phy_to_store); i++)
-+		saved_regs_phy[i] = b43_phy_read(dev, phy_to_store[i]);
-+	for (i = 0; i < ARRAY_SIZE(phy_to_store_rf); i++)
-+		saved_regs_phy_rf[i] = b43_phy_read(dev, phy_to_store_rf[i]);
-+
-+	/* Set */
-+	for (i = 0; i < ARRAY_SIZE(phy_to_store); i++)
-+		b43_phy_write(dev, phy_to_store[i], 0);
-+	b43_phy_write(dev, B43_NPHY_REV3_RFCTL_OVER0, 0x07ff);
-+	b43_phy_write(dev, B43_NPHY_REV3_RFCTL_OVER1, 0x07ff);
-+	b43_phy_write(dev, B43_NPHY_REV7_RF_CTL_OVER3, 0x07ff);
-+	b43_phy_write(dev, B43_NPHY_REV7_RF_CTL_OVER4, 0x07ff);
-+	b43_phy_write(dev, B43_NPHY_REV7_RF_CTL_OVER5, 0x007f);
-+	b43_phy_write(dev, B43_NPHY_REV7_RF_CTL_OVER6, 0x007f);
-+
-+	switch (phy->radio_rev) {
-+	case 5:
-+		b43_phy_mask(dev, B43_NPHY_REV7_RF_CTL_OVER3, ~0x2);
- 		udelay(10);
- 		b43_radio_set(dev, R2057_IQTEST_SEL_PU, 0x1);
--		b43_radio_maskset(dev, 0x1ca, ~0x2, 0x1);
-+		b43_radio_maskset(dev, R2057v7_IQTEST_SEL_PU2, ~0x2, 0x1);
-+		break;
-+	case 9:
-+		b43_phy_set(dev, B43_NPHY_REV7_RF_CTL_OVER3, 0x2);
-+		b43_phy_set(dev, B43_NPHY_REV7_RF_CTL_MISC_REG3, 0x2);
-+		saved_regs_radio[0] = b43_radio_read(dev, R2057_IQTEST_SEL_PU);
-+		b43_radio_write(dev, R2057_IQTEST_SEL_PU, 0x11);
-+		break;
-+	case 14:
-+		saved_regs_radio[0] = b43_radio_read(dev, R2057_IQTEST_SEL_PU);
-+		saved_regs_radio[1] = b43_radio_read(dev, R2057v7_IQTEST_SEL_PU2);
-+		b43_phy_set(dev, B43_NPHY_REV7_RF_CTL_MISC_REG3, 0x2);
-+		b43_phy_set(dev, B43_NPHY_REV7_RF_CTL_OVER3, 0x2);
-+		b43_radio_write(dev, R2057v7_IQTEST_SEL_PU2, 0x2);
-+		b43_radio_write(dev, R2057_IQTEST_SEL_PU, 0x1);
-+		break;
- 	}
- 
-+	/* Enable */
- 	b43_radio_set(dev, R2057_RCAL_CONFIG, 0x1);
- 	udelay(10);
--	b43_radio_set(dev, R2057_RCAL_CONFIG, 0x3);
--	if (!b43_radio_wait_value(dev, R2057_RCCAL_N1_1, 1, 1, 100, 1000000)) {
-+
-+	/* Start */
-+	b43_radio_set(dev, R2057_RCAL_CONFIG, 0x2);
-+	usleep_range(100, 200);
-+
-+	/* Stop */
-+	b43_radio_mask(dev, R2057_RCAL_CONFIG, ~0x2);
-+
-+	/* Wait and check for result */
-+	if (!b43_radio_wait_value(dev, R2057_RCAL_STATUS, 1, 1, 100, 1000000)) {
- 		b43err(dev->wl, "Radio 0x2057 rcal timeout\n");
- 		return 0;
- 	}
--	b43_radio_mask(dev, R2057_RCAL_CONFIG, ~0x2);
- 	tmp = b43_radio_read(dev, R2057_RCAL_STATUS) & 0x3E;
-+
-+	/* Disable */
- 	b43_radio_mask(dev, R2057_RCAL_CONFIG, ~0x1);
- 
--	if (phy->radio_rev == 5) {
--		b43_radio_mask(dev, R2057_IPA2G_CASCONV_CORE0, ~0x1);
--		b43_radio_mask(dev, 0x1ca, ~0x2);
--	}
--	if (phy->radio_rev <= 4 || phy->radio_rev == 6) {
-+	/* Restore */
-+	for (i = 0; i < ARRAY_SIZE(phy_to_store_rf); i++)
-+		b43_phy_write(dev, phy_to_store_rf[i], saved_regs_phy_rf[i]);
-+	for (i = 0; i < ARRAY_SIZE(phy_to_store); i++)
-+		b43_phy_write(dev, phy_to_store[i], saved_regs_phy[i]);
-+
-+	switch (phy->radio_rev) {
-+	case 0 ... 4:
-+	case 6:
- 		b43_radio_maskset(dev, R2057_TEMPSENSE_CONFIG, ~0x3C, tmp);
- 		b43_radio_maskset(dev, R2057_BANDGAP_RCAL_TRIM, ~0xF0,
- 				  tmp << 2);
-+		break;
-+	case 5:
-+		b43_radio_mask(dev, R2057_IPA2G_CASCONV_CORE0, ~0x1);
-+		b43_radio_mask(dev, R2057v7_IQTEST_SEL_PU2, ~0x2);
-+		break;
-+	case 9:
-+		b43_radio_write(dev, R2057_IQTEST_SEL_PU, saved_regs_radio[0]);
-+		break;
-+	case 14:
-+		b43_radio_write(dev, R2057_IQTEST_SEL_PU, saved_regs_radio[0]);
-+		b43_radio_write(dev, R2057v7_IQTEST_SEL_PU2, saved_regs_radio[1]);
-+		break;
- 	}
- 
- 	return tmp & 0x3e;
- }
- 
--/* http://bcm-v4.sipsolutions.net/PHY/radio2057_rccal */
-+/* Calibrate the internal RC oscillator?
-+ * http://bcm-v4.sipsolutions.net/PHY/radio2057_rccal
-+ */
- static u16 b43_radio_2057_rccal(struct b43_wldev *dev)
- {
- 	struct b43_phy *phy = &dev->phy;
-@@ -635,49 +939,76 @@ static u16 b43_radio_2057_rccal(struct b
- 			phy->radio_rev == 6);
- 	u16 tmp;
- 
-+	/* Setup cal */
- 	if (special) {
- 		b43_radio_write(dev, R2057_RCCAL_MASTER, 0x61);
- 		b43_radio_write(dev, R2057_RCCAL_TRC0, 0xC0);
- 	} else {
--		b43_radio_write(dev, 0x1AE, 0x61);
--		b43_radio_write(dev, R2057_RCCAL_TRC0, 0xE1);
-+		b43_radio_write(dev, R2057v7_RCCAL_MASTER, 0x61);
-+		b43_radio_write(dev, R2057_RCCAL_TRC0, 0xE9);
- 	}
- 	b43_radio_write(dev, R2057_RCCAL_X1, 0x6E);
-+
-+	/* Start, wait, stop */
- 	b43_radio_write(dev, R2057_RCCAL_START_R1_Q1_P1, 0x55);
--	if (!b43_radio_wait_value(dev, R2057_RCCAL_DONE_OSCCAP, 1, 1, 500,
-+	if (!b43_radio_wait_value(dev, R2057_RCCAL_DONE_OSCCAP, 2, 2, 500,
- 				  5000000))
- 		b43dbg(dev->wl, "Radio 0x2057 rccal timeout\n");
-+	usleep_range(35, 70);
- 	b43_radio_write(dev, R2057_RCCAL_START_R1_Q1_P1, 0x15);
-+	usleep_range(70, 140);
-+
-+	/* Setup cal */
- 	if (special) {
- 		b43_radio_write(dev, R2057_RCCAL_MASTER, 0x69);
- 		b43_radio_write(dev, R2057_RCCAL_TRC0, 0xB0);
- 	} else {
--		b43_radio_write(dev, 0x1AE, 0x69);
-+		b43_radio_write(dev, R2057v7_RCCAL_MASTER, 0x69);
- 		b43_radio_write(dev, R2057_RCCAL_TRC0, 0xD5);
- 	}
- 	b43_radio_write(dev, R2057_RCCAL_X1, 0x6E);
-+
-+	/* Start, wait, stop */
-+	usleep_range(35, 70);
- 	b43_radio_write(dev, R2057_RCCAL_START_R1_Q1_P1, 0x55);
--	if (!b43_radio_wait_value(dev, R2057_RCCAL_DONE_OSCCAP, 1, 1, 500,
-+	usleep_range(70, 140);
-+	if (!b43_radio_wait_value(dev, R2057_RCCAL_DONE_OSCCAP, 2, 2, 500,
- 				  5000000))
- 		b43dbg(dev->wl, "Radio 0x2057 rccal timeout\n");
-+	usleep_range(35, 70);
- 	b43_radio_write(dev, R2057_RCCAL_START_R1_Q1_P1, 0x15);
-+	usleep_range(70, 140);
-+
-+	/* Setup cal */
- 	if (special) {
- 		b43_radio_write(dev, R2057_RCCAL_MASTER, 0x73);
- 		b43_radio_write(dev, R2057_RCCAL_X1, 0x28);
- 		b43_radio_write(dev, R2057_RCCAL_TRC0, 0xB0);
- 	} else {
--		b43_radio_write(dev, 0x1AE, 0x73);
-+		b43_radio_write(dev, R2057v7_RCCAL_MASTER, 0x73);
- 		b43_radio_write(dev, R2057_RCCAL_X1, 0x6E);
- 		b43_radio_write(dev, R2057_RCCAL_TRC0, 0x99);
- 	}
-+
-+	/* Start, wait, stop */
-+	usleep_range(35, 70);
- 	b43_radio_write(dev, R2057_RCCAL_START_R1_Q1_P1, 0x55);
--	if (!b43_radio_wait_value(dev, R2057_RCCAL_DONE_OSCCAP, 1, 1, 500,
-+	usleep_range(70, 140);
-+	if (!b43_radio_wait_value(dev, R2057_RCCAL_DONE_OSCCAP, 2, 2, 500,
- 				  5000000)) {
- 		b43err(dev->wl, "Radio 0x2057 rcal timeout\n");
- 		return 0;
- 	}
- 	tmp = b43_radio_read(dev, R2057_RCCAL_DONE_OSCCAP);
-+	usleep_range(35, 70);
- 	b43_radio_write(dev, R2057_RCCAL_START_R1_Q1_P1, 0x15);
-+	usleep_range(70, 140);
-+
-+	if (special)
-+		b43_radio_mask(dev, R2057_RCCAL_MASTER, ~0x1);
-+	else
-+		b43_radio_mask(dev, R2057v7_RCCAL_MASTER, ~0x1);
-+
- 	return tmp;
- }
- 
-@@ -694,19 +1025,20 @@ static void b43_radio_2057_init_post(str
- {
- 	b43_radio_set(dev, R2057_XTALPUOVR_PINCTRL, 0x1);
- 
-+	if (0) /* FIXME: Is this BCM43217 specific? */
-+		b43_radio_set(dev, R2057_XTALPUOVR_PINCTRL, 0x2);
-+
- 	b43_radio_set(dev, R2057_RFPLL_MISC_CAL_RESETN, 0x78);
- 	b43_radio_set(dev, R2057_XTAL_CONFIG2, 0x80);
- 	mdelay(2);
- 	b43_radio_mask(dev, R2057_RFPLL_MISC_CAL_RESETN, ~0x78);
- 	b43_radio_mask(dev, R2057_XTAL_CONFIG2, ~0x80);
- 
--	if (dev->phy.n->init_por) {
-+	if (dev->phy.do_full_init) {
- 		b43_radio_2057_rcal(dev);
- 		b43_radio_2057_rccal(dev);
- 	}
- 	b43_radio_mask(dev, R2057_RFPLL_MASTER, ~0x8);
--
--	dev->phy.n->init_por = false;
- }
- 
- /* http://bcm-v4.sipsolutions.net/802.11/Radio/2057/Init */
-@@ -800,6 +1132,7 @@ static void b43_chantab_radio_2056_uploa
- static void b43_radio_2056_setup(struct b43_wldev *dev,
- 				const struct b43_nphy_channeltab_entry_rev3 *e)
- {
-+	struct b43_phy *phy = &dev->phy;
- 	struct ssb_sprom *sprom = dev->dev->bus_sprom;
- 	enum ieee80211_band band = b43_current_band(dev->wl);
- 	u16 offset;
-@@ -897,7 +1230,7 @@ static void b43_radio_2056_setup(struct
- 					offset | B2056_TX_MIXG_BOOST_TUNE,
- 					mixg_boost);
- 			} else {
--				bias = dev->phy.is_40mhz ? 0x40 : 0x20;
-+				bias = b43_is_40mhz(dev) ? 0x40 : 0x20;
- 				b43_radio_write(dev,
- 					offset | B2056_TX_INTPAG_IMAIN_STAT,
- 					bias);
-@@ -911,7 +1244,7 @@ static void b43_radio_2056_setup(struct
- 			b43_radio_write(dev, offset | B2056_TX_PA_SPARE1, 0xee);
- 		}
- 	} else if (dev->phy.n->ipa5g_on && band == IEEE80211_BAND_5GHZ) {
--		u16 freq = dev->phy.channel_freq;
-+		u16 freq = phy->chandef->chan->center_freq;
- 		if (freq < 5100) {
- 			paa_boost = 0xA;
- 			pada_boost = 0x77;
-@@ -1028,7 +1361,7 @@ static void b43_radio_init2056_post(stru
- 	b43_radio_mask(dev, B2056_SYN_COM_RESET, ~0x2);
- 	b43_radio_mask(dev, B2056_SYN_PLL_MAST2, ~0xFC);
- 	b43_radio_mask(dev, B2056_SYN_RCCAL_CTRL0, ~0x1);
--	if (dev->phy.n->init_por)
-+	if (dev->phy.do_full_init)
- 		b43_radio_2056_rcal(dev);
- }
- 
-@@ -1041,8 +1374,6 @@ static void b43_radio_init2056(struct b4
- 	b43_radio_init2056_pre(dev);
- 	b2056_upload_inittabs(dev, 0, 0);
- 	b43_radio_init2056_post(dev);
--
--	dev->phy.n->init_por = false;
- }
- 
- /**************************************************
-@@ -1214,8 +1545,7 @@ static u16 b43_nphy_gen_load_samples(str
- 	u16 bw, len, rot, angle;
- 	struct b43_c32 *samples;
- 
--
--	bw = (dev->phy.is_40mhz) ? 40 : 20;
-+	bw = b43_is_40mhz(dev) ? 40 : 20;
- 	len = bw << 3;
- 
- 	if (test) {
-@@ -1224,7 +1554,7 @@ static u16 b43_nphy_gen_load_samples(str
- 		else
- 			bw = 80;
- 
--		if (dev->phy.is_40mhz)
-+		if (b43_is_40mhz(dev))
- 			bw <<= 1;
- 
- 		len = bw << 1;
-@@ -1252,8 +1582,10 @@ static u16 b43_nphy_gen_load_samples(str
- 
- /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RunSamples */
- static void b43_nphy_run_samples(struct b43_wldev *dev, u16 samps, u16 loops,
--					u16 wait, bool iqmode, bool dac_test)
-+				 u16 wait, bool iqmode, bool dac_test,
-+				 bool modify_bbmult)
- {
-+	struct b43_phy *phy = &dev->phy;
- 	struct b43_phy_n *nphy = dev->phy.n;
- 	int i;
- 	u16 seq_mode;
-@@ -1261,17 +1593,35 @@ static void b43_nphy_run_samples(struct
- 
- 	b43_nphy_stay_in_carrier_search(dev, true);
- 
-+	if (phy->rev >= 7) {
-+		bool lpf_bw3, lpf_bw4;
-+
-+		lpf_bw3 = b43_phy_read(dev, B43_NPHY_REV7_RF_CTL_OVER3) & 0x80;
-+		lpf_bw4 = b43_phy_read(dev, B43_NPHY_REV7_RF_CTL_OVER4) & 0x80;
-+
-+		if (lpf_bw3 || lpf_bw4) {
-+			/* TODO */
-+		} else {
-+			u16 value = b43_nphy_read_lpf_ctl(dev, 0);
-+			if (phy->rev >= 19)
-+				b43_nphy_rf_ctl_override_rev19(dev, 0x80, value,
-+							       0, false, 1);
-+			else
-+				b43_nphy_rf_ctl_override_rev7(dev, 0x80, value,
-+							      0, false, 1);
-+			nphy->lpf_bw_overrode_for_sample_play = true;
-+		}
-+	}
-+
- 	if ((nphy->bb_mult_save & 0x80000000) == 0) {
- 		tmp = b43_ntab_read(dev, B43_NTAB16(15, 87));
- 		nphy->bb_mult_save = (tmp & 0xFFFF) | 0x80000000;
- 	}
- 
--	/* TODO: add modify_bbmult argument */
--	if (!dev->phy.is_40mhz)
--		tmp = 0x6464;
--	else
--		tmp = 0x4747;
--	b43_ntab_write(dev, B43_NTAB16(15, 87), tmp);
-+	if (modify_bbmult) {
-+		tmp = !b43_is_40mhz(dev) ? 0x6464 : 0x4747;
-+		b43_ntab_write(dev, B43_NTAB16(15, 87), tmp);
-+	}
- 
- 	b43_phy_write(dev, B43_NPHY_SAMP_DEPCNT, (samps - 1));
- 
-@@ -1289,10 +1639,8 @@ static void b43_nphy_run_samples(struct
- 		b43_phy_mask(dev, B43_NPHY_IQLOCAL_CMDGCTL, 0x7FFF);
- 		b43_phy_set(dev, B43_NPHY_IQLOCAL_CMDGCTL, 0x8000);
- 	} else {
--		if (dac_test)
--			b43_phy_write(dev, B43_NPHY_SAMP_CMD, 5);
--		else
--			b43_phy_write(dev, B43_NPHY_SAMP_CMD, 1);
-+		tmp = dac_test ? 5 : 1;
-+		b43_phy_write(dev, B43_NPHY_SAMP_CMD, tmp);
- 	}
- 	for (i = 0; i < 100; i++) {
- 		if (!(b43_phy_read(dev, B43_NPHY_RFSEQST) & 1)) {
-@@ -1392,6 +1740,12 @@ static void b43_nphy_scale_offset_rssi(s
- 	}
- }
- 
-+static void b43_nphy_rssi_select_rev19(struct b43_wldev *dev, u8 code,
-+				       enum n_rssi_type rssi_type)
-+{
-+	/* TODO */
-+}
-+
- static void b43_nphy_rev3_rssi_select(struct b43_wldev *dev, u8 code,
- 				      enum n_rssi_type rssi_type)
- {
-@@ -1461,13 +1815,15 @@ static void b43_nphy_rev3_rssi_select(st
- 					enum ieee80211_band band =
- 						b43_current_band(dev->wl);
- 
--					if (b43_nphy_ipa(dev))
--						val = (band == IEEE80211_BAND_5GHZ) ? 0xC : 0xE;
--					else
--						val = 0x11;
--					reg = (i == 0) ? 0x2000 : 0x3000;
--					reg |= B2055_PADDRV;
--					b43_radio_write(dev, reg, val);
-+					if (dev->phy.rev < 7) {
-+						if (b43_nphy_ipa(dev))
-+							val = (band == IEEE80211_BAND_5GHZ) ? 0xC : 0xE;
-+						else
-+							val = 0x11;
-+						reg = (i == 0) ? B2056_TX0 : B2056_TX1;
-+						reg |= B2056_TX_TX_SSI_MUX;
-+						b43_radio_write(dev, reg, val);
-+					}
- 
- 					reg = (i == 0) ?
- 						B43_NPHY_AFECTL_OVER1 :
-@@ -1554,7 +1910,9 @@ static void b43_nphy_rev2_rssi_select(st
- static void b43_nphy_rssi_select(struct b43_wldev *dev, u8 code,
- 				 enum n_rssi_type type)
- {
--	if (dev->phy.rev >= 3)
-+	if (dev->phy.rev >= 19)
-+		b43_nphy_rssi_select_rev19(dev, code, type);
-+	else if (dev->phy.rev >= 3)
- 		b43_nphy_rev3_rssi_select(dev, code, type);
- 	else
- 		b43_nphy_rev2_rssi_select(dev, code, type);
-@@ -1598,6 +1956,8 @@ static int b43_nphy_poll_rssi(struct b43
- 	u16 save_regs_phy[9];
- 	u16 s[2];
- 
-+	/* TODO: rev7+ is treated like rev3+, what about rev19+? */
-+
- 	if (dev->phy.rev >= 3) {
- 		save_regs_phy[0] = b43_phy_read(dev, B43_NPHY_AFECTL_C1);
- 		save_regs_phy[1] = b43_phy_read(dev, B43_NPHY_AFECTL_C2);
-@@ -1679,6 +2039,7 @@ static int b43_nphy_poll_rssi(struct b43
- /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSICalRev3 */
- static void b43_nphy_rev3_rssi_cal(struct b43_wldev *dev)
- {
-+	struct b43_phy *phy = &dev->phy;
- 	struct b43_phy_n *nphy = dev->phy.n;
- 
- 	u16 saved_regs_phy_rfctl[2];
-@@ -1696,12 +2057,14 @@ static void b43_nphy_rev3_rssi_cal(struc
- 		B43_NPHY_AFECTL_OVER1, B43_NPHY_AFECTL_OVER,
- 		B43_NPHY_AFECTL_C1, B43_NPHY_AFECTL_C2,
- 		B43_NPHY_TXF_40CO_B1S1, B43_NPHY_RFCTL_OVER,
--		0x342, 0x343, 0x346, 0x347,
-+		B43_NPHY_REV7_RF_CTL_OVER3, B43_NPHY_REV7_RF_CTL_OVER4,
-+		B43_NPHY_REV7_RF_CTL_OVER5, B43_NPHY_REV7_RF_CTL_OVER6,
- 		0x2ff,
- 		B43_NPHY_TXF_40CO_B1S0, B43_NPHY_TXF_40CO_B32S1,
- 		B43_NPHY_RFCTL_CMD,
- 		B43_NPHY_RFCTL_LUT_TRSW_UP1, B43_NPHY_RFCTL_LUT_TRSW_UP2,
--		0x340, 0x341, 0x344, 0x345,
-+		B43_NPHY_REV7_RF_CTL_MISC_REG3, B43_NPHY_REV7_RF_CTL_MISC_REG4,
-+		B43_NPHY_REV7_RF_CTL_MISC_REG5, B43_NPHY_REV7_RF_CTL_MISC_REG6,
- 		B43_NPHY_RFCTL_RSSIO1, B43_NPHY_RFCTL_RSSIO2
- 	};
- 	u16 *regs_to_store;
-@@ -1748,9 +2111,24 @@ static void b43_nphy_rev3_rssi_cal(struc
- 	b43_nphy_rf_ctl_intc_override(dev, N_INTC_OVERRIDE_TRSW, 1, 7);
- 
- 	if (dev->phy.rev >= 7) {
--		/* TODO */
-+		b43_nphy_rf_ctl_override_one_to_many(dev,
-+						     N_RF_CTL_OVER_CMD_RXRF_PU,
-+						     0, 0, false);
-+		b43_nphy_rf_ctl_override_one_to_many(dev,
-+						     N_RF_CTL_OVER_CMD_RX_PU,
-+						     1, 0, false);
-+		b43_nphy_rf_ctl_override_rev7(dev, 0x80, 1, 0, false, 0);
-+		b43_nphy_rf_ctl_override_rev7(dev, 0x40, 1, 0, false, 0);
- 		if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) {
-+			b43_nphy_rf_ctl_override_rev7(dev, 0x20, 0, 0, false,
-+						      0);
-+			b43_nphy_rf_ctl_override_rev7(dev, 0x10, 1, 0, false,
-+						      0);
- 		} else {
-+			b43_nphy_rf_ctl_override_rev7(dev, 0x10, 0, 0, false,
-+						      0);
-+			b43_nphy_rf_ctl_override_rev7(dev, 0x20, 1, 0, false,
-+						      0);
- 		}
- 	} else {
- 		b43_nphy_rf_ctl_override(dev, 0x1, 0, 0, false);
-@@ -1779,7 +2157,10 @@ static void b43_nphy_rev3_rssi_cal(struc
- 		/* Grab RSSI results for every possible VCM */
- 		for (vcm = 0; vcm < 8; vcm++) {
- 			if (dev->phy.rev >= 7)
--				;
-+				b43_radio_maskset(dev,
-+						  core ? R2057_NB_MASTER_CORE1 :
-+							 R2057_NB_MASTER_CORE0,
-+						  ~R2057_VCM_MASK, vcm);
- 			else
- 				b43_radio_maskset(dev, r | B2056_RX_RSSI_MISC,
- 						  0xE3, vcm << 2);
-@@ -1810,7 +2191,10 @@ static void b43_nphy_rev3_rssi_cal(struc
- 
- 		/* Select the best VCM */
- 		if (dev->phy.rev >= 7)
--			;
-+			b43_radio_maskset(dev,
-+					  core ? R2057_NB_MASTER_CORE1 :
-+						 R2057_NB_MASTER_CORE0,
-+					  ~R2057_VCM_MASK, vcm);
- 		else
- 			b43_radio_maskset(dev, r | B2056_RX_RSSI_MISC,
- 					  0xE3, vcm_final << 2);
-@@ -1880,6 +2264,10 @@ static void b43_nphy_rev3_rssi_cal(struc
- 		rssical_phy_regs = nphy->rssical_cache.rssical_phy_regs_5G;
- 	}
- 	if (dev->phy.rev >= 7) {
-+		rssical_radio_regs[0] = b43_radio_read(dev,
-+						       R2057_NB_MASTER_CORE0);
-+		rssical_radio_regs[1] = b43_radio_read(dev,
-+						       R2057_NB_MASTER_CORE1);
- 	} else {
- 		rssical_radio_regs[0] = b43_radio_read(dev, B2056_RX0 |
- 						       B2056_RX_RSSI_MISC);
-@@ -1901,9 +2289,9 @@ static void b43_nphy_rev3_rssi_cal(struc
- 
- 	/* Remember for which channel we store configuration */
- 	if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
--		nphy->rssical_chanspec_2G.center_freq = dev->phy.channel_freq;
-+		nphy->rssical_chanspec_2G.center_freq = phy->chandef->chan->center_freq;
- 	else
--		nphy->rssical_chanspec_5G.center_freq = dev->phy.channel_freq;
-+		nphy->rssical_chanspec_5G.center_freq = phy->chandef->chan->center_freq;
- 
- 	/* End of calibration, restore configuration */
- 	b43_nphy_classifier(dev, 7, class);
-@@ -2080,7 +2468,9 @@ static void b43_nphy_rev2_rssi_cal(struc
-  */
- static void b43_nphy_rssi_cal(struct b43_wldev *dev)
- {
--	if (dev->phy.rev >= 3) {
-+	if (dev->phy.rev >= 19) {
-+		/* TODO */
-+	} else if (dev->phy.rev >= 3) {
- 		b43_nphy_rev3_rssi_cal(dev);
- 	} else {
- 		b43_nphy_rev2_rssi_cal(dev, N_RSSI_NB);
-@@ -2093,7 +2483,21 @@ static void b43_nphy_rssi_cal(struct b43
-  * Workarounds
-  **************************************************/
- 
--static void b43_nphy_gain_ctl_workarounds_rev3plus(struct b43_wldev *dev)
-+static void b43_nphy_gain_ctl_workarounds_rev19(struct b43_wldev *dev)
-+{
-+	/* TODO */
-+}
-+
-+static void b43_nphy_gain_ctl_workarounds_rev7(struct b43_wldev *dev)
-+{
-+	struct b43_phy *phy = &dev->phy;
-+
-+	switch (phy->rev) {
-+	/* TODO */
-+	}
-+}
-+
-+static void b43_nphy_gain_ctl_workarounds_rev3(struct b43_wldev *dev)
- {
- 	struct ssb_sprom *sprom = dev->dev->bus_sprom;
- 
-@@ -2196,7 +2600,7 @@ static void b43_nphy_gain_ctl_workaround
- 	b43_phy_write(dev, B43_NPHY_C1_NBCLIPTHRES, 0x84);
- 	b43_phy_write(dev, B43_NPHY_C2_NBCLIPTHRES, 0x84);
- 
--	if (!dev->phy.is_40mhz) {
-+	if (!b43_is_40mhz(dev)) {
- 		/* Set dwell lengths */
- 		b43_phy_write(dev, B43_NPHY_CLIP1_NBDWELL_LEN, 0x002B);
- 		b43_phy_write(dev, B43_NPHY_CLIP2_NBDWELL_LEN, 0x002B);
-@@ -2210,7 +2614,7 @@ static void b43_nphy_gain_ctl_workaround
- 	b43_phy_maskset(dev, B43_NPHY_C2_CLIPWBTHRES,
- 			~B43_NPHY_C2_CLIPWBTHRES_CLIP2, 21);
- 
--	if (!dev->phy.is_40mhz) {
-+	if (!b43_is_40mhz(dev)) {
- 		b43_phy_maskset(dev, B43_NPHY_C1_CGAINI,
- 			~B43_NPHY_C1_CGAINI_GAINBKOFF, 0x1);
- 		b43_phy_maskset(dev, B43_NPHY_C2_CGAINI,
-@@ -2225,12 +2629,12 @@ static void b43_nphy_gain_ctl_workaround
- 
- 	if (nphy->gain_boost) {
- 		if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ &&
--			dev->phy.is_40mhz)
-+		    b43_is_40mhz(dev))
- 			code = 4;
- 		else
- 			code = 5;
- 	} else {
--		code = dev->phy.is_40mhz ? 6 : 7;
-+		code = b43_is_40mhz(dev) ? 6 : 7;
- 	}
- 
- 	/* Set HPVGA2 index */
-@@ -2290,46 +2694,54 @@ static void b43_nphy_gain_ctl_workaround
- /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/WorkaroundsGainCtrl */
- static void b43_nphy_gain_ctl_workarounds(struct b43_wldev *dev)
- {
--	if (dev->phy.rev >= 7)
--		; /* TODO */
-+	if (dev->phy.rev >= 19)
-+		b43_nphy_gain_ctl_workarounds_rev19(dev);
-+	else if (dev->phy.rev >= 7)
-+		b43_nphy_gain_ctl_workarounds_rev7(dev);
- 	else if (dev->phy.rev >= 3)
--		b43_nphy_gain_ctl_workarounds_rev3plus(dev);
-+		b43_nphy_gain_ctl_workarounds_rev3(dev);
- 	else
- 		b43_nphy_gain_ctl_workarounds_rev1_2(dev);
- }
- 
--/* http://bcm-v4.sipsolutions.net/PHY/N/Read_Lpf_Bw_Ctl */
--static u16 b43_nphy_read_lpf_ctl(struct b43_wldev *dev, u16 offset)
--{
--	if (!offset)
--		offset = (dev->phy.is_40mhz) ? 0x159 : 0x154;
--	return b43_ntab_read(dev, B43_NTAB16(7, offset)) & 0x7;
--}
--
- static void b43_nphy_workarounds_rev7plus(struct b43_wldev *dev)
- {
- 	struct ssb_sprom *sprom = dev->dev->bus_sprom;
- 	struct b43_phy *phy = &dev->phy;
- 
-+	/* TX to RX */
-+	u8 tx2rx_events[7] = { 4, 3, 5, 2, 1, 8, 31, };
-+	u8 tx2rx_delays[7] = { 8, 4, 4, 4, 4, 6, 1, };
-+	/* RX to TX */
- 	u8 rx2tx_events_ipa[9] = { 0x0, 0x1, 0x2, 0x8, 0x5, 0x6, 0xF, 0x3,
- 					0x1F };
- 	u8 rx2tx_delays_ipa[9] = { 8, 6, 6, 4, 4, 16, 43, 1, 1 };
- 
--	u16 ntab7_15e_16e[] = { 0x10f, 0x10f };
-+	static const u16 ntab7_15e_16e[] = { 0, 0x10f, 0x10f };
- 	u8 ntab7_138_146[] = { 0x11, 0x11 };
- 	u8 ntab7_133[] = { 0x77, 0x11, 0x11 };
- 
--	u16 lpf_20, lpf_40, lpf_11b;
--	u16 bcap_val, bcap_val_11b, bcap_val_11n_20, bcap_val_11n_40;
--	u16 scap_val, scap_val_11b, scap_val_11n_20, scap_val_11n_40;
-+	u16 lpf_ofdm_20mhz[2], lpf_ofdm_40mhz[2], lpf_11b[2];
-+	u16 bcap_val;
-+	s16 bcap_val_11b[2], bcap_val_11n_20[2], bcap_val_11n_40[2];
-+	u16 scap_val;
-+	s16 scap_val_11b[2], scap_val_11n_20[2], scap_val_11n_40[2];
- 	bool rccal_ovrd = false;
- 
--	u16 rx2tx_lut_20_11b, rx2tx_lut_20_11n, rx2tx_lut_40_11n;
- 	u16 bias, conv, filt;
- 
-+	u32 noise_tbl[2];
-+
- 	u32 tmp32;
- 	u8 core;
- 
-+	b43_phy_write(dev, B43_NPHY_PHASETR_A0, 0x0125);
-+	b43_phy_write(dev, B43_NPHY_PHASETR_A1, 0x01b3);
-+	b43_phy_write(dev, B43_NPHY_PHASETR_A2, 0x0105);
-+	b43_phy_write(dev, B43_NPHY_PHASETR_B0, 0x016e);
-+	b43_phy_write(dev, B43_NPHY_PHASETR_B1, 0x00cd);
-+	b43_phy_write(dev, B43_NPHY_PHASETR_B2, 0x0020);
-+
- 	if (phy->rev == 7) {
- 		b43_phy_set(dev, B43_NPHY_FINERX2_CGC, 0x10);
- 		b43_phy_maskset(dev, B43_NPHY_FREQGAIN0, 0xFF80, 0x0020);
-@@ -2349,11 +2761,18 @@ static void b43_nphy_workarounds_rev7plu
- 		b43_phy_maskset(dev, B43_NPHY_FREQGAIN7, 0xFF80, 0x0040);
- 		b43_phy_maskset(dev, B43_NPHY_FREQGAIN7, 0x80FF, 0x4000);
- 	}
--	if (phy->rev <= 8) {
-+
-+	if (phy->rev >= 16) {
-+		b43_phy_write(dev, B43_NPHY_FORCEFRONT0, 0x7ff);
-+		b43_phy_write(dev, B43_NPHY_FORCEFRONT1, 0x7ff);
-+	} else if (phy->rev <= 8) {
- 		b43_phy_write(dev, B43_NPHY_FORCEFRONT0, 0x1B0);
- 		b43_phy_write(dev, B43_NPHY_FORCEFRONT1, 0x1B0);
- 	}
--	if (phy->rev >= 8)
-+
-+	if (phy->rev >= 16)
-+		b43_phy_maskset(dev, B43_NPHY_TXTAILCNT, ~0xFF, 0xa0);
-+	else if (phy->rev >= 8)
- 		b43_phy_maskset(dev, B43_NPHY_TXTAILCNT, ~0xFF, 0x72);
- 
- 	b43_ntab_write(dev, B43_NTAB16(8, 0x00), 2);
-@@ -2361,9 +2780,11 @@ static void b43_nphy_workarounds_rev7plu
- 	tmp32 = b43_ntab_read(dev, B43_NTAB32(30, 0));
- 	tmp32 &= 0xffffff;
- 	b43_ntab_write(dev, B43_NTAB32(30, 0), tmp32);
--	b43_ntab_write_bulk(dev, B43_NTAB16(7, 0x15e), 2, ntab7_15e_16e);
--	b43_ntab_write_bulk(dev, B43_NTAB16(7, 0x16e), 2, ntab7_15e_16e);
-+	b43_ntab_write_bulk(dev, B43_NTAB16(7, 0x15d), 3, ntab7_15e_16e);
-+	b43_ntab_write_bulk(dev, B43_NTAB16(7, 0x16d), 3, ntab7_15e_16e);
- 
-+	b43_nphy_set_rf_sequence(dev, 1, tx2rx_events, tx2rx_delays,
-+				 ARRAY_SIZE(tx2rx_events));
- 	if (b43_nphy_ipa(dev))
- 		b43_nphy_set_rf_sequence(dev, 0, rx2tx_events_ipa,
- 				rx2tx_delays_ipa, ARRAY_SIZE(rx2tx_events_ipa));
-@@ -2371,84 +2792,176 @@ static void b43_nphy_workarounds_rev7plu
- 	b43_phy_maskset(dev, B43_NPHY_EPS_OVERRIDEI_0, 0x3FFF, 0x4000);
- 	b43_phy_maskset(dev, B43_NPHY_EPS_OVERRIDEI_1, 0x3FFF, 0x4000);
- 
--	lpf_20 = b43_nphy_read_lpf_ctl(dev, 0x154);
--	lpf_40 = b43_nphy_read_lpf_ctl(dev, 0x159);
--	lpf_11b = b43_nphy_read_lpf_ctl(dev, 0x152);
-+	for (core = 0; core < 2; core++) {
-+		lpf_ofdm_20mhz[core] = b43_nphy_read_lpf_ctl(dev, 0x154 + core * 0x10);
-+		lpf_ofdm_40mhz[core] = b43_nphy_read_lpf_ctl(dev, 0x159 + core * 0x10);
-+		lpf_11b[core] = b43_nphy_read_lpf_ctl(dev, 0x152 + core * 0x10);
-+	}
-+
-+	bcap_val = b43_radio_read(dev, R2057_RCCAL_BCAP_VAL);
-+	scap_val = b43_radio_read(dev, R2057_RCCAL_SCAP_VAL);
-+
- 	if (b43_nphy_ipa(dev)) {
--		if ((phy->radio_rev == 5 && phy->is_40mhz) ||
--		    phy->radio_rev == 7 || phy->radio_rev == 8) {
--			bcap_val = b43_radio_read(dev, 0x16b);
--			scap_val = b43_radio_read(dev, 0x16a);
--			scap_val_11b = scap_val;
--			bcap_val_11b = bcap_val;
--			if (phy->radio_rev == 5 && phy->is_40mhz) {
--				scap_val_11n_20 = scap_val;
--				bcap_val_11n_20 = bcap_val;
--				scap_val_11n_40 = bcap_val_11n_40 = 0xc;
-+		bool ghz2 = b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ;
-+
-+		switch (phy->radio_rev) {
-+		case 5:
-+			/* Check radio version (to be 0) by PHY rev for now */
-+			if (phy->rev == 8 && b43_is_40mhz(dev)) {
-+				for (core = 0; core < 2; core++) {
-+					scap_val_11b[core] = scap_val;
-+					bcap_val_11b[core] = bcap_val;
-+					scap_val_11n_20[core] = scap_val;
-+					bcap_val_11n_20[core] = bcap_val;
-+					scap_val_11n_40[core] = 0xc;
-+					bcap_val_11n_40[core] = 0xc;
-+				}
-+
- 				rccal_ovrd = true;
--			} else { /* Rev 7/8 */
--				lpf_20 = 4;
--				lpf_11b = 1;
-+			}
-+			if (phy->rev == 9) {
-+				/* TODO: Radio version 1 (e.g. BCM5357B0) */
-+			}
-+			break;
-+		case 7:
-+		case 8:
-+			for (core = 0; core < 2; core++) {
-+				scap_val_11b[core] = scap_val;
-+				bcap_val_11b[core] = bcap_val;
-+				lpf_ofdm_20mhz[core] = 4;
-+				lpf_11b[core] = 1;
- 				if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
--					scap_val_11n_20 = 0xc;
--					bcap_val_11n_20 = 0xc;
--					scap_val_11n_40 = 0xa;
--					bcap_val_11n_40 = 0xa;
-+					scap_val_11n_20[core] = 0xc;
-+					bcap_val_11n_20[core] = 0xc;
-+					scap_val_11n_40[core] = 0xa;
-+					bcap_val_11n_40[core] = 0xa;
- 				} else {
--					scap_val_11n_20 = 0x14;
--					bcap_val_11n_20 = 0x14;
--					scap_val_11n_40 = 0xf;
--					bcap_val_11n_40 = 0xf;
-+					scap_val_11n_20[core] = 0x14;
-+					bcap_val_11n_20[core] = 0x14;
-+					scap_val_11n_40[core] = 0xf;
-+					bcap_val_11n_40[core] = 0xf;
- 				}
--				rccal_ovrd = true;
- 			}
-+
-+			rccal_ovrd = true;
-+			break;
-+		case 9:
-+			for (core = 0; core < 2; core++) {
-+				bcap_val_11b[core] = bcap_val;
-+				scap_val_11b[core] = scap_val;
-+				lpf_11b[core] = 1;
-+
-+				if (ghz2) {
-+					bcap_val_11n_20[core] = bcap_val + 13;
-+					scap_val_11n_20[core] = scap_val + 15;
-+				} else {
-+					bcap_val_11n_20[core] = bcap_val + 14;
-+					scap_val_11n_20[core] = scap_val + 15;
-+				}
-+				lpf_ofdm_20mhz[core] = 4;
-+
-+				if (ghz2) {
-+					bcap_val_11n_40[core] = bcap_val - 7;
-+					scap_val_11n_40[core] = scap_val - 5;
-+				} else {
-+					bcap_val_11n_40[core] = bcap_val + 2;
-+					scap_val_11n_40[core] = scap_val + 4;
-+				}
-+				lpf_ofdm_40mhz[core] = 4;
-+			}
-+
-+			rccal_ovrd = true;
-+			break;
-+		case 14:
-+			for (core = 0; core < 2; core++) {
-+				bcap_val_11b[core] = bcap_val;
-+				scap_val_11b[core] = scap_val;
-+				lpf_11b[core] = 1;
-+			}
-+
-+			bcap_val_11n_20[0] = bcap_val + 20;
-+			scap_val_11n_20[0] = scap_val + 20;
-+			lpf_ofdm_20mhz[0] = 3;
-+
-+			bcap_val_11n_20[1] = bcap_val + 16;
-+			scap_val_11n_20[1] = scap_val + 16;
-+			lpf_ofdm_20mhz[1] = 3;
-+
-+			bcap_val_11n_40[0] = bcap_val + 20;
-+			scap_val_11n_40[0] = scap_val + 20;
-+			lpf_ofdm_40mhz[0] = 4;
-+
-+			bcap_val_11n_40[1] = bcap_val + 10;
-+			scap_val_11n_40[1] = scap_val + 10;
-+			lpf_ofdm_40mhz[1] = 4;
-+
-+			rccal_ovrd = true;
-+			break;
- 		}
- 	} else {
- 		if (phy->radio_rev == 5) {
--			lpf_20 = 1;
--			lpf_40 = 3;
--			bcap_val = b43_radio_read(dev, 0x16b);
--			scap_val = b43_radio_read(dev, 0x16a);
--			scap_val_11b = scap_val;
--			bcap_val_11b = bcap_val;
--			scap_val_11n_20 = 0x11;
--			scap_val_11n_40 = 0x11;
--			bcap_val_11n_20 = 0x13;
--			bcap_val_11n_40 = 0x13;
-+			for (core = 0; core < 2; core++) {
-+				lpf_ofdm_20mhz[core] = 1;
-+				lpf_ofdm_40mhz[core] = 3;
-+				scap_val_11b[core] = scap_val;
-+				bcap_val_11b[core] = bcap_val;
-+				scap_val_11n_20[core] = 0x11;
-+				scap_val_11n_40[core] = 0x11;
-+				bcap_val_11n_20[core] = 0x13;
-+				bcap_val_11n_40[core] = 0x13;
-+			}
-+
- 			rccal_ovrd = true;
- 		}
- 	}
- 	if (rccal_ovrd) {
--		rx2tx_lut_20_11b = (bcap_val_11b << 8) |
--				   (scap_val_11b << 3) |
--				   lpf_11b;
--		rx2tx_lut_20_11n = (bcap_val_11n_20 << 8) |
--				   (scap_val_11n_20 << 3) |
--				   lpf_20;
--		rx2tx_lut_40_11n = (bcap_val_11n_40 << 8) |
--				   (scap_val_11n_40 << 3) |
--				   lpf_40;
-+		u16 rx2tx_lut_20_11b[2], rx2tx_lut_20_11n[2], rx2tx_lut_40_11n[2];
-+		u8 rx2tx_lut_extra = 1;
-+
-+		for (core = 0; core < 2; core++) {
-+			bcap_val_11b[core] = clamp_val(bcap_val_11b[core], 0, 0x1f);
-+			scap_val_11b[core] = clamp_val(scap_val_11b[core], 0, 0x1f);
-+			bcap_val_11n_20[core] = clamp_val(bcap_val_11n_20[core], 0, 0x1f);
-+			scap_val_11n_20[core] = clamp_val(scap_val_11n_20[core], 0, 0x1f);
-+			bcap_val_11n_40[core] = clamp_val(bcap_val_11n_40[core], 0, 0x1f);
-+			scap_val_11n_40[core] = clamp_val(scap_val_11n_40[core], 0, 0x1f);
-+
-+			rx2tx_lut_20_11b[core] = (rx2tx_lut_extra << 13) |
-+						 (bcap_val_11b[core] << 8) |
-+						 (scap_val_11b[core] << 3) |
-+						 lpf_11b[core];
-+			rx2tx_lut_20_11n[core] = (rx2tx_lut_extra << 13) |
-+						 (bcap_val_11n_20[core] << 8) |
-+						 (scap_val_11n_20[core] << 3) |
-+						 lpf_ofdm_20mhz[core];
-+			rx2tx_lut_40_11n[core] = (rx2tx_lut_extra << 13) |
-+						 (bcap_val_11n_40[core] << 8) |
-+						 (scap_val_11n_40[core] << 3) |
-+						 lpf_ofdm_40mhz[core];
-+		}
-+
- 		for (core = 0; core < 2; core++) {
- 			b43_ntab_write(dev, B43_NTAB16(7, 0x152 + core * 16),
--				       rx2tx_lut_20_11b);
-+				       rx2tx_lut_20_11b[core]);
- 			b43_ntab_write(dev, B43_NTAB16(7, 0x153 + core * 16),
--				       rx2tx_lut_20_11n);
-+				       rx2tx_lut_20_11n[core]);
- 			b43_ntab_write(dev, B43_NTAB16(7, 0x154 + core * 16),
--				       rx2tx_lut_20_11n);
-+				       rx2tx_lut_20_11n[core]);
- 			b43_ntab_write(dev, B43_NTAB16(7, 0x155 + core * 16),
--				       rx2tx_lut_40_11n);
-+				       rx2tx_lut_40_11n[core]);
- 			b43_ntab_write(dev, B43_NTAB16(7, 0x156 + core * 16),
--				       rx2tx_lut_40_11n);
-+				       rx2tx_lut_40_11n[core]);
- 			b43_ntab_write(dev, B43_NTAB16(7, 0x157 + core * 16),
--				       rx2tx_lut_40_11n);
-+				       rx2tx_lut_40_11n[core]);
- 			b43_ntab_write(dev, B43_NTAB16(7, 0x158 + core * 16),
--				       rx2tx_lut_40_11n);
-+				       rx2tx_lut_40_11n[core]);
- 			b43_ntab_write(dev, B43_NTAB16(7, 0x159 + core * 16),
--				       rx2tx_lut_40_11n);
-+				       rx2tx_lut_40_11n[core]);
- 		}
--		b43_nphy_rf_ctl_override_rev7(dev, 16, 1, 3, false, 2);
- 	}
-+
- 	b43_phy_write(dev, 0x32F, 0x3);
-+
- 	if (phy->radio_rev == 4 || phy->radio_rev == 6)
- 		b43_nphy_rf_ctl_override_rev7(dev, 4, 1, 3, false, 0);
- 
-@@ -2496,7 +3009,8 @@ static void b43_nphy_workarounds_rev7plu
- 								0x7f);
- 				}
- 			}
--			if (phy->radio_rev == 3) {
-+			switch (phy->radio_rev) {
-+			case 3:
- 				for (core = 0; core < 2; core++) {
- 					if (core == 0) {
- 						b43_radio_write(dev, 0x64,
-@@ -2522,17 +3036,34 @@ static void b43_nphy_workarounds_rev7plu
- 								0x3E);
- 					}
- 				}
--			} else if (phy->radio_rev == 7 || phy->radio_rev == 8) {
--				if (!phy->is_40mhz) {
-+				break;
-+			case 7:
-+			case 8:
-+				if (!b43_is_40mhz(dev)) {
- 					b43_radio_write(dev, 0x5F, 0x14);
- 					b43_radio_write(dev, 0xE8, 0x12);
- 				} else {
- 					b43_radio_write(dev, 0x5F, 0x16);
- 					b43_radio_write(dev, 0xE8, 0x16);
- 				}
-+				break;
-+			case 14:
-+				for (core = 0; core < 2; core++) {
-+					int o = core ? 0x85 : 0;
-+
-+					b43_radio_write(dev, o + R2057_IPA2G_CASCONV_CORE0, 0x13);
-+					b43_radio_write(dev, o + R2057_TXMIX2G_TUNE_BOOST_PU_CORE0, 0x21);
-+					b43_radio_write(dev, o + R2057_IPA2G_BIAS_FILTER_CORE0, 0xff);
-+					b43_radio_write(dev, o + R2057_PAD2G_IDACS_CORE0, 0x88);
-+					b43_radio_write(dev, o + R2057_PAD2G_TUNE_PUS_CORE0, 0x23);
-+					b43_radio_write(dev, o + R2057_IPA2G_IMAIN_CORE0, 0x16);
-+					b43_radio_write(dev, o + R2057_PAD_BIAS_FILTER_BWS_CORE0, 0x3e);
-+					b43_radio_write(dev, o + R2057_BACKUP1_CORE0, 0x10);
-+				}
-+				break;
- 			}
- 		} else {
--			u16 freq = phy->channel_freq;
-+			u16 freq = phy->chandef->chan->center_freq;
- 			if ((freq >= 5180 && freq <= 5230) ||
- 			    (freq >= 5745 && freq <= 5805)) {
- 				b43_radio_write(dev, 0x7D, 0xFF);
-@@ -2577,8 +3108,8 @@ static void b43_nphy_workarounds_rev7plu
- 		b43_phy_set(dev, B43_NPHY_AFECTL_OVER1, 0x1);
- 		b43_phy_mask(dev, B43_NPHY_AFECTL_C2, ~0x1);
- 		b43_phy_set(dev, B43_NPHY_AFECTL_OVER, 0x1);
--		b43_ntab_write(dev, B43_NTAB16(8, 0x05), 0x20);
--		b43_ntab_write(dev, B43_NTAB16(8, 0x15), 0x20);
-+		b43_ntab_write(dev, B43_NTAB16(8, 0x05), 0);
-+		b43_ntab_write(dev, B43_NTAB16(8, 0x15), 0);
- 
- 		b43_phy_mask(dev, B43_NPHY_AFECTL_C1, ~0x4);
- 		b43_phy_mask(dev, B43_NPHY_AFECTL_OVER1, ~0x4);
-@@ -2589,20 +3120,20 @@ static void b43_nphy_workarounds_rev7plu
- 	b43_phy_write(dev, B43_NPHY_ENDROP_TLEN, 0x2);
- 
- 	b43_ntab_write(dev, B43_NTAB32(16, 0x100), 20);
--	b43_ntab_write_bulk(dev, B43_NTAB16(7, 0x138), 2, ntab7_138_146);
-+	b43_ntab_write_bulk(dev, B43_NTAB8(7, 0x138), 2, ntab7_138_146);
- 	b43_ntab_write(dev, B43_NTAB16(7, 0x141), 0x77);
--	b43_ntab_write_bulk(dev, B43_NTAB16(7, 0x133), 3, ntab7_133);
--	b43_ntab_write_bulk(dev, B43_NTAB16(7, 0x146), 2, ntab7_138_146);
-+	b43_ntab_write_bulk(dev, B43_NTAB8(7, 0x133), 3, ntab7_133);
-+	b43_ntab_write_bulk(dev, B43_NTAB8(7, 0x146), 2, ntab7_138_146);
- 	b43_ntab_write(dev, B43_NTAB16(7, 0x123), 0x77);
- 	b43_ntab_write(dev, B43_NTAB16(7, 0x12A), 0x77);
- 
--	if (!phy->is_40mhz) {
--		b43_ntab_write(dev, B43_NTAB32(16, 0x03), 0x18D);
--		b43_ntab_write(dev, B43_NTAB32(16, 0x7F), 0x18D);
--	} else {
--		b43_ntab_write(dev, B43_NTAB32(16, 0x03), 0x14D);
--		b43_ntab_write(dev, B43_NTAB32(16, 0x7F), 0x14D);
--	}
-+	b43_ntab_read_bulk(dev, B43_NTAB32(16, 0x02), 1, noise_tbl);
-+	noise_tbl[1] = b43_is_40mhz(dev) ? 0x14D : 0x18D;
-+	b43_ntab_write_bulk(dev, B43_NTAB32(16, 0x02), 2, noise_tbl);
-+
-+	b43_ntab_read_bulk(dev, B43_NTAB32(16, 0x7E), 1, noise_tbl);
-+	noise_tbl[1] = b43_is_40mhz(dev) ? 0x14D : 0x18D;
-+	b43_ntab_write_bulk(dev, B43_NTAB32(16, 0x7E), 2, noise_tbl);
- 
- 	b43_nphy_gain_ctl_workarounds(dev);
- 
-@@ -2695,7 +3226,7 @@ static void b43_nphy_workarounds_rev3plu
- 
- 	b43_phy_maskset(dev, B43_NPHY_SGILTRNOFFSET, 0xF0FF, 0x0700);
- 
--	if (!dev->phy.is_40mhz) {
-+	if (!b43_is_40mhz(dev)) {
- 		b43_ntab_write(dev, B43_NTAB32(16, 3), 0x18D);
- 		b43_ntab_write(dev, B43_NTAB32(16, 127), 0x18D);
- 	} else {
-@@ -2930,6 +3461,7 @@ static void b43_nphy_workarounds(struct
- 	b43_phy_set(dev, B43_NPHY_IQFLIP,
- 		    B43_NPHY_IQFLIP_ADC1 | B43_NPHY_IQFLIP_ADC2);
- 
-+	/* TODO: rev19+ */
- 	if (dev->phy.rev >= 7)
- 		b43_nphy_workarounds_rev7plus(dev);
- 	else if (dev->phy.rev >= 3)
-@@ -2950,12 +3482,13 @@ static void b43_nphy_workarounds(struct
-  * http://bcm-v4.sipsolutions.net/802.11/PHY/N/TXTone
-  */
- static int b43_nphy_tx_tone(struct b43_wldev *dev, u32 freq, u16 max_val,
--				bool iqmode, bool dac_test)
-+			    bool iqmode, bool dac_test, bool modify_bbmult)
- {
- 	u16 samp = b43_nphy_gen_load_samples(dev, freq, max_val, dac_test);
- 	if (samp == 0)
- 		return -1;
--	b43_nphy_run_samples(dev, samp, 0xFFFF, 0, iqmode, dac_test);
-+	b43_nphy_run_samples(dev, samp, 0xFFFF, 0, iqmode, dac_test,
-+			     modify_bbmult);
- 	return 0;
- }
- 
-@@ -2990,6 +3523,7 @@ static void b43_nphy_update_txrx_chain(s
- /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/stop-playback */
- static void b43_nphy_stop_playback(struct b43_wldev *dev)
- {
-+	struct b43_phy *phy = &dev->phy;
- 	struct b43_phy_n *nphy = dev->phy.n;
- 	u16 tmp;
- 
-@@ -3010,6 +3544,15 @@ static void b43_nphy_stop_playback(struc
- 		nphy->bb_mult_save = 0;
- 	}
- 
-+	if (phy->rev >= 7 && nphy->lpf_bw_overrode_for_sample_play) {
-+		if (phy->rev >= 19)
-+			b43_nphy_rf_ctl_override_rev19(dev, 0x80, 0, 0, true,
-+						       1);
-+		else
-+			b43_nphy_rf_ctl_override_rev7(dev, 0x80, 0, 0, true, 1);
-+		nphy->lpf_bw_overrode_for_sample_play = false;
-+	}
-+
- 	if (nphy->hang_avoid)
- 		b43_nphy_stay_in_carrier_search(dev, 0);
- }
-@@ -3019,16 +3562,23 @@ static void b43_nphy_iq_cal_gain_params(
- 					struct nphy_txgains target,
- 					struct nphy_iqcal_params *params)
- {
-+	struct b43_phy *phy = &dev->phy;
- 	int i, j, indx;
- 	u16 gain;
- 
- 	if (dev->phy.rev >= 3) {
-+		params->tx_lpf = target.tx_lpf[core]; /* Rev 7+ */
- 		params->txgm = target.txgm[core];
- 		params->pga = target.pga[core];
- 		params->pad = target.pad[core];
- 		params->ipa = target.ipa[core];
--		params->cal_gain = (params->txgm << 12) | (params->pga << 8) |
--					(params->pad << 4) | (params->ipa);
-+		if (phy->rev >= 19) {
-+			/* TODO */
-+		} else if (phy->rev >= 7) {
-+			params->cal_gain = (params->txgm << 12) | (params->pga << 8) | (params->pad << 3) | (params->ipa) | (params->tx_lpf << 15);
-+		} else {
-+			params->cal_gain = (params->txgm << 12) | (params->pga << 8) | (params->pad << 4) | (params->ipa);
-+		}
- 		for (j = 0; j < 5; j++)
- 			params->ncorr[j] = 0x79;
- 	} else {
-@@ -3069,6 +3619,7 @@ static enum b43_txpwr_result b43_nphy_op
- /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxPwrCtrlEnable */
- static void b43_nphy_tx_power_ctrl(struct b43_wldev *dev, bool enable)
- {
-+	struct b43_phy *phy = &dev->phy;
- 	struct b43_phy_n *nphy = dev->phy.n;
- 	u8 i;
- 	u16 bmask, val, tmp;
-@@ -3118,7 +3669,7 @@ static void b43_nphy_tx_power_ctrl(struc
- 			b43_phy_maskset(dev, B43_NPHY_BPHY_CTL3,
- 				~B43_NPHY_BPHY_CTL3_SCALE, 0x5A);
- 
--		if (dev->phy.rev < 2 && dev->phy.is_40mhz)
-+		if (dev->phy.rev < 2 && b43_is_40mhz(dev))
- 			b43_hf_write(dev, b43_hf_read(dev) | B43_HF_TSSIRPSMW);
- 	} else {
- 		b43_ntab_write_bulk(dev, B43_NTAB16(26, 64), 84,
-@@ -3138,12 +3689,25 @@ static void b43_nphy_tx_power_ctrl(struc
- 		b43_phy_maskset(dev, B43_NPHY_TXPCTL_CMD, ~(bmask), val);
- 
- 		if (band == IEEE80211_BAND_5GHZ) {
--			b43_phy_maskset(dev, B43_NPHY_TXPCTL_CMD,
--					~B43_NPHY_TXPCTL_CMD_INIT, 0x64);
--			if (dev->phy.rev > 1)
-+			if (phy->rev >= 19) {
-+				/* TODO */
-+			} else if (phy->rev >= 7) {
-+				b43_phy_maskset(dev, B43_NPHY_TXPCTL_CMD,
-+						~B43_NPHY_TXPCTL_CMD_INIT,
-+						0x32);
- 				b43_phy_maskset(dev, B43_NPHY_TXPCTL_INIT,
- 						~B43_NPHY_TXPCTL_INIT_PIDXI1,
-+						0x32);
-+			} else {
-+				b43_phy_maskset(dev, B43_NPHY_TXPCTL_CMD,
-+						~B43_NPHY_TXPCTL_CMD_INIT,
- 						0x64);
-+				if (phy->rev > 1)
-+					b43_phy_maskset(dev,
-+							B43_NPHY_TXPCTL_INIT,
-+							~B43_NPHY_TXPCTL_INIT_PIDXI1,
-+							0x64);
-+			}
- 		}
- 
- 		if (dev->phy.rev >= 3) {
-@@ -3160,6 +3724,10 @@ static void b43_nphy_tx_power_ctrl(struc
- 			}
- 		}
- 
-+		if (phy->rev >= 7) {
-+			/* TODO */
-+		}
-+
- 		if (dev->phy.rev >= 3) {
- 			b43_phy_mask(dev, B43_NPHY_AFECTL_OVER1, ~0x100);
- 			b43_phy_mask(dev, B43_NPHY_AFECTL_OVER, ~0x100);
-@@ -3172,7 +3740,7 @@ static void b43_nphy_tx_power_ctrl(struc
- 		else if (dev->phy.rev < 2)
- 			b43_phy_maskset(dev, B43_NPHY_BPHY_CTL3, ~0xFF, 0x40);
- 
--		if (dev->phy.rev < 2 && dev->phy.is_40mhz)
-+		if (dev->phy.rev < 2 && b43_is_40mhz(dev))
- 			b43_hf_write(dev, b43_hf_read(dev) & ~B43_HF_TSSIRPSMW);
- 
- 		if (b43_nphy_ipa(dev)) {
-@@ -3188,18 +3756,20 @@ static void b43_nphy_tx_power_ctrl(struc
- /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxPwrFix */
- static void b43_nphy_tx_power_fix(struct b43_wldev *dev)
- {
-+	struct b43_phy *phy = &dev->phy;
- 	struct b43_phy_n *nphy = dev->phy.n;
- 	struct ssb_sprom *sprom = dev->dev->bus_sprom;
- 
- 	u8 txpi[2], bbmult, i;
- 	u16 tmp, radio_gain, dac_gain;
--	u16 freq = dev->phy.channel_freq;
-+	u16 freq = phy->chandef->chan->center_freq;
- 	u32 txgain;
- 	/* u32 gaintbl; rev3+ */
- 
- 	if (nphy->hang_avoid)
- 		b43_nphy_stay_in_carrier_search(dev, 1);
- 
-+	/* TODO: rev19+ */
- 	if (dev->phy.rev >= 7) {
- 		txpi[0] = txpi[1] = 30;
- 	} else if (dev->phy.rev >= 3) {
-@@ -3238,7 +3808,11 @@ static void b43_nphy_tx_power_fix(struct
- 	*/
- 
- 	for (i = 0; i < 2; i++) {
--		txgain = *(b43_nphy_get_tx_gain_table(dev) + txpi[i]);
-+		const u32 *table = b43_nphy_get_tx_gain_table(dev);
-+
-+		if (!table)
-+			break;
-+		txgain = *(table + txpi[i]);
- 
- 		if (dev->phy.rev >= 3)
- 			radio_gain = (txgain >> 16) & 0x1FFFF;
-@@ -3298,7 +3872,9 @@ static void b43_nphy_ipa_internal_tssi_s
- 	u8 core;
- 	u16 r; /* routing */
- 
--	if (phy->rev >= 7) {
-+	if (phy->rev >= 19) {
-+		/* TODO */
-+	} else if (phy->rev >= 7) {
- 		for (core = 0; core < 2; core++) {
- 			r = core ? 0x190 : 0x170;
- 			if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
-@@ -3381,29 +3957,38 @@ static void b43_nphy_tx_power_ctl_idle_t
- 	u32 tmp;
- 	s32 rssi[4] = { };
- 
--	/* TODO: check if we can transmit */
-+	if (phy->chandef->chan->flags & IEEE80211_CHAN_NO_IR)
-+		return;
- 
- 	if (b43_nphy_ipa(dev))
- 		b43_nphy_ipa_internal_tssi_setup(dev);
- 
--	if (phy->rev >= 7)
--		b43_nphy_rf_ctl_override_rev7(dev, 0x2000, 0, 3, false, 0);
-+	if (phy->rev >= 19)
-+		b43_nphy_rf_ctl_override_rev19(dev, 0x1000, 0, 3, false, 0);
-+	else if (phy->rev >= 7)
-+		b43_nphy_rf_ctl_override_rev7(dev, 0x1000, 0, 3, false, 0);
- 	else if (phy->rev >= 3)
- 		b43_nphy_rf_ctl_override(dev, 0x2000, 0, 3, false);
- 
- 	b43_nphy_stop_playback(dev);
--	b43_nphy_tx_tone(dev, 0xFA0, 0, false, false);
-+	b43_nphy_tx_tone(dev, 4000, 0, false, false, false);
- 	udelay(20);
- 	tmp = b43_nphy_poll_rssi(dev, N_RSSI_TSSI_2G, rssi, 1);
- 	b43_nphy_stop_playback(dev);
-+
- 	b43_nphy_rssi_select(dev, 0, N_RSSI_W1);
- 
--	if (phy->rev >= 7)
--		b43_nphy_rf_ctl_override_rev7(dev, 0x2000, 0, 3, true, 0);
-+	if (phy->rev >= 19)
-+		b43_nphy_rf_ctl_override_rev19(dev, 0x1000, 0, 3, true, 0);
-+	else if (phy->rev >= 7)
-+		b43_nphy_rf_ctl_override_rev7(dev, 0x1000, 0, 3, true, 0);
- 	else if (phy->rev >= 3)
- 		b43_nphy_rf_ctl_override(dev, 0x2000, 0, 3, true);
- 
--	if (phy->rev >= 3) {
-+	if (phy->rev >= 19) {
-+		/* TODO */
-+		return;
-+	} else if (phy->rev >= 3) {
- 		nphy->pwr_ctl_info[0].idle_tssi_5g = (tmp >> 24) & 0xFF;
- 		nphy->pwr_ctl_info[1].idle_tssi_5g = (tmp >> 8) & 0xFF;
- 	} else {
-@@ -3443,21 +4028,21 @@ static void b43_nphy_tx_prepare_adjusted
- 		delta = 0;
- 		switch (stf_mode) {
- 		case 0:
--			if (dev->phy.is_40mhz && dev->phy.rev >= 5) {
-+			if (b43_is_40mhz(dev) && dev->phy.rev >= 5) {
- 				idx = 68;
- 			} else {
- 				delta = 1;
--				idx = dev->phy.is_40mhz ? 52 : 4;
-+				idx = b43_is_40mhz(dev) ? 52 : 4;
- 			}
- 			break;
- 		case 1:
--			idx = dev->phy.is_40mhz ? 76 : 28;
-+			idx = b43_is_40mhz(dev) ? 76 : 28;
- 			break;
- 		case 2:
--			idx = dev->phy.is_40mhz ? 84 : 36;
-+			idx = b43_is_40mhz(dev) ? 84 : 36;
- 			break;
- 		case 3:
--			idx = dev->phy.is_40mhz ? 92 : 44;
-+			idx = b43_is_40mhz(dev) ? 92 : 44;
- 			break;
- 		}
- 
-@@ -3478,6 +4063,7 @@ static void b43_nphy_tx_prepare_adjusted
- /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxPwrCtrlSetup */
- static void b43_nphy_tx_power_ctl_setup(struct b43_wldev *dev)
- {
-+	struct b43_phy *phy = &dev->phy;
- 	struct b43_phy_n *nphy = dev->phy.n;
- 	struct ssb_sprom *sprom = dev->dev->bus_sprom;
- 
-@@ -3487,7 +4073,7 @@ static void b43_nphy_tx_power_ctl_setup(
- 	s32 num, den, pwr;
- 	u32 regval[64];
- 
--	u16 freq = dev->phy.channel_freq;
-+	u16 freq = phy->chandef->chan->center_freq;
- 	u16 tmp;
- 	u16 r; /* routing */
- 	u8 i, c;
-@@ -3594,7 +4180,9 @@ static void b43_nphy_tx_power_ctl_setup(
- 		udelay(1);
- 	}
- 
--	if (dev->phy.rev >= 7) {
-+	if (phy->rev >= 19) {
-+		/* TODO */
-+	} else if (phy->rev >= 7) {
- 		b43_phy_maskset(dev, B43_NPHY_TXPCTL_CMD,
- 				~B43_NPHY_TXPCTL_CMD_INIT, 0x19);
- 		b43_phy_maskset(dev, B43_NPHY_TXPCTL_INIT,
-@@ -3651,27 +4239,36 @@ static void b43_nphy_tx_gain_table_uploa
- 	int i;
- 
- 	table = b43_nphy_get_tx_gain_table(dev);
-+	if (!table)
-+		return;
-+
- 	b43_ntab_write_bulk(dev, B43_NTAB32(26, 192), 128, table);
- 	b43_ntab_write_bulk(dev, B43_NTAB32(27, 192), 128, table);
- 
--	if (phy->rev >= 3) {
-+	if (phy->rev < 3)
-+		return;
-+
- #if 0
--		nphy->gmval = (table[0] >> 16) & 0x7000;
-+	nphy->gmval = (table[0] >> 16) & 0x7000;
- #endif
- 
--		for (i = 0; i < 128; i++) {
-+	for (i = 0; i < 128; i++) {
-+		if (phy->rev >= 19) {
-+			/* TODO */
-+			return;
-+		} else if (phy->rev >= 7) {
-+			/* TODO */
-+			return;
-+		} else {
- 			pga_gain = (table[i] >> 24) & 0xF;
- 			if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
--				rfpwr_offset =
--				 b43_ntab_papd_pga_gain_delta_ipa_2g[pga_gain];
-+				rfpwr_offset = b43_ntab_papd_pga_gain_delta_ipa_2g[pga_gain];
- 			else
--				rfpwr_offset =
--				 0; /* FIXME */
--			b43_ntab_write(dev, B43_NTAB32(26, 576 + i),
--				       rfpwr_offset);
--			b43_ntab_write(dev, B43_NTAB32(27, 576 + i),
--				       rfpwr_offset);
-+				rfpwr_offset = 0; /* FIXME */
- 		}
-+
-+		b43_ntab_write(dev, B43_NTAB32(26, 576 + i), rfpwr_offset);
-+		b43_ntab_write(dev, B43_NTAB32(27, 576 + i), rfpwr_offset);
- 	}
- }
- 
-@@ -3688,7 +4285,9 @@ static void b43_nphy_pa_override(struct
- 		nphy->rfctrl_intc2_save = b43_phy_read(dev,
- 						       B43_NPHY_RFCTL_INTC2);
- 		band = b43_current_band(dev->wl);
--		if (dev->phy.rev >= 3) {
-+		if (dev->phy.rev >= 7) {
-+			tmp = 0x1480;
-+		} else if (dev->phy.rev >= 3) {
- 			if (band == IEEE80211_BAND_5GHZ)
- 				tmp = 0x600;
- 			else
-@@ -3709,21 +4308,28 @@ static void b43_nphy_pa_override(struct
- 	}
- }
- 
--/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxLpFbw */
--static void b43_nphy_tx_lp_fbw(struct b43_wldev *dev)
-+/*
-+ * TX low-pass filter bandwidth setup
-+ * http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxLpFbw
-+ */
-+static void b43_nphy_tx_lpf_bw(struct b43_wldev *dev)
- {
- 	u16 tmp;
- 
--	if (dev->phy.rev >= 3) {
--		if (b43_nphy_ipa(dev)) {
--			tmp = 4;
--			b43_phy_write(dev, B43_NPHY_TXF_40CO_B32S2,
--			      (((((tmp << 3) | tmp) << 3) | tmp) << 3) | tmp);
--		}
-+	if (dev->phy.rev < 3 || dev->phy.rev >= 7)
-+		return;
-+
-+	if (b43_nphy_ipa(dev))
-+		tmp = b43_is_40mhz(dev) ? 5 : 4;
-+	else
-+		tmp = b43_is_40mhz(dev) ? 3 : 1;
-+	b43_phy_write(dev, B43_NPHY_TXF_40CO_B32S2,
-+		      (tmp << 9) | (tmp << 6) | (tmp << 3) | tmp);
- 
--		tmp = 1;
-+	if (b43_nphy_ipa(dev)) {
-+		tmp = b43_is_40mhz(dev) ? 4 : 1;
- 		b43_phy_write(dev, B43_NPHY_TXF_40CO_B1S2,
--			      (((((tmp << 3) | tmp) << 3) | tmp) << 3) | tmp);
-+			      (tmp << 9) | (tmp << 6) | (tmp << 3) | tmp);
- 	}
- }
- 
-@@ -3996,7 +4602,7 @@ static void b43_nphy_spur_workaround(str
- 
- 	if (nphy->gband_spurwar_en) {
- 		/* TODO: N PHY Adjust Analog Pfbw (7) */
--		if (channel == 11 && dev->phy.is_40mhz)
-+		if (channel == 11 && b43_is_40mhz(dev))
- 			; /* TODO: N PHY Adjust Min Noise Var(2, tone, noise)*/
- 		else
- 			; /* TODO: N PHY Adjust Min Noise Var(0, NULL, NULL)*/
-@@ -4128,7 +4734,13 @@ static void b43_nphy_restore_rssi_cal(st
- 		rssical_phy_regs = nphy->rssical_cache.rssical_phy_regs_5G;
- 	}
- 
--	if (dev->phy.rev >= 7) {
-+	if (dev->phy.rev >= 19) {
-+		/* TODO */
-+	} else if (dev->phy.rev >= 7) {
-+		b43_radio_maskset(dev, R2057_NB_MASTER_CORE0, ~R2057_VCM_MASK,
-+				  rssical_radio_regs[0]);
-+		b43_radio_maskset(dev, R2057_NB_MASTER_CORE1, ~R2057_VCM_MASK,
-+				  rssical_radio_regs[1]);
- 	} else {
- 		b43_radio_maskset(dev, B2056_RX0 | B2056_RX_RSSI_MISC, 0xE3,
- 				  rssical_radio_regs[0]);
-@@ -4152,15 +4764,78 @@ static void b43_nphy_restore_rssi_cal(st
- 	b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_RSSI_Y, rssical_phy_regs[11]);
- }
- 
-+static void b43_nphy_tx_cal_radio_setup_rev19(struct b43_wldev *dev)
-+{
-+	/* TODO */
-+}
-+
-+static void b43_nphy_tx_cal_radio_setup_rev7(struct b43_wldev *dev)
-+{
-+	struct b43_phy *phy = &dev->phy;
-+	struct b43_phy_n *nphy = dev->phy.n;
-+	u16 *save = nphy->tx_rx_cal_radio_saveregs;
-+	int core, off;
-+	u16 r, tmp;
-+
-+	for (core = 0; core < 2; core++) {
-+		r = core ? 0x20 : 0;
-+		off = core * 11;
-+
-+		save[off + 0] = b43_radio_read(dev, r + R2057_TX0_TX_SSI_MASTER);
-+		save[off + 1] = b43_radio_read(dev, r + R2057_TX0_IQCAL_VCM_HG);
-+		save[off + 2] = b43_radio_read(dev, r + R2057_TX0_IQCAL_IDAC);
-+		save[off + 3] = b43_radio_read(dev, r + R2057_TX0_TSSI_VCM);
-+		save[off + 4] = 0;
-+		save[off + 5] = b43_radio_read(dev, r + R2057_TX0_TX_SSI_MUX);
-+		if (phy->radio_rev != 5)
-+			save[off + 6] = b43_radio_read(dev, r + R2057_TX0_TSSIA);
-+		save[off + 7] = b43_radio_read(dev, r + R2057_TX0_TSSIG);
-+		save[off + 8] = b43_radio_read(dev, r + R2057_TX0_TSSI_MISC1);
-+
-+		if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) {
-+			b43_radio_write(dev, r + R2057_TX0_TX_SSI_MASTER, 0xA);
-+			b43_radio_write(dev, r + R2057_TX0_IQCAL_VCM_HG, 0x43);
-+			b43_radio_write(dev, r + R2057_TX0_IQCAL_IDAC, 0x55);
-+			b43_radio_write(dev, r + R2057_TX0_TSSI_VCM, 0);
-+			b43_radio_write(dev, r + R2057_TX0_TSSIG, 0);
-+			if (nphy->use_int_tx_iq_lo_cal) {
-+				b43_radio_write(dev, r + R2057_TX0_TX_SSI_MUX, 0x4);
-+				tmp = true ? 0x31 : 0x21; /* TODO */
-+				b43_radio_write(dev, r + R2057_TX0_TSSIA, tmp);
-+			}
-+			b43_radio_write(dev, r + R2057_TX0_TSSI_MISC1, 0x00);
-+		} else {
-+			b43_radio_write(dev, r + R2057_TX0_TX_SSI_MASTER, 0x6);
-+			b43_radio_write(dev, r + R2057_TX0_IQCAL_VCM_HG, 0x43);
-+			b43_radio_write(dev, r + R2057_TX0_IQCAL_IDAC, 0x55);
-+			b43_radio_write(dev, r + R2057_TX0_TSSI_VCM, 0);
-+
-+			if (phy->radio_rev != 5)
-+				b43_radio_write(dev, r + R2057_TX0_TSSIA, 0);
-+			if (nphy->use_int_tx_iq_lo_cal) {
-+				b43_radio_write(dev, r + R2057_TX0_TX_SSI_MUX, 0x6);
-+				tmp = true ? 0x31 : 0x21; /* TODO */
-+				b43_radio_write(dev, r + R2057_TX0_TSSIG, tmp);
-+			}
-+			b43_radio_write(dev, r + R2057_TX0_TSSI_MISC1, 0);
-+		}
-+	}
-+}
-+
- /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxCalRadioSetup */
- static void b43_nphy_tx_cal_radio_setup(struct b43_wldev *dev)
- {
-+	struct b43_phy *phy = &dev->phy;
- 	struct b43_phy_n *nphy = dev->phy.n;
- 	u16 *save = nphy->tx_rx_cal_radio_saveregs;
- 	u16 tmp;
- 	u8 offset, i;
- 
--	if (dev->phy.rev >= 3) {
-+	if (phy->rev >= 19) {
-+		b43_nphy_tx_cal_radio_setup_rev19(dev);
-+	} else if (phy->rev >= 7) {
-+		b43_nphy_tx_cal_radio_setup_rev7(dev);
-+	} else if (phy->rev >= 3) {
- 	    for (i = 0; i < 2; i++) {
- 		tmp = (i == 0) ? 0x2000 : 0x3000;
- 		offset = i * 11;
-@@ -4269,41 +4944,62 @@ static void b43_nphy_update_tx_cal_ladde
- 	}
- }
- 
-+static void b43_nphy_pa_set_tx_dig_filter(struct b43_wldev *dev, u16 offset,
-+					  const s16 *filter)
-+{
-+	int i;
-+
-+	offset = B43_PHY_N(offset);
-+
-+	for (i = 0; i < 15; i++, offset++)
-+		b43_phy_write(dev, offset, filter[i]);
-+}
-+
- /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/ExtPaSetTxDigiFilts */
- static void b43_nphy_ext_pa_set_tx_dig_filters(struct b43_wldev *dev)
- {
--	int i;
--	for (i = 0; i < 15; i++)
--		b43_phy_write(dev, B43_PHY_N(0x2C5 + i),
--				tbl_tx_filter_coef_rev4[2][i]);
-+	b43_nphy_pa_set_tx_dig_filter(dev, 0x2C5,
-+				      tbl_tx_filter_coef_rev4[2]);
- }
- 
- /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/IpaSetTxDigiFilts */
- static void b43_nphy_int_pa_set_tx_dig_filters(struct b43_wldev *dev)
- {
--	int i, j;
- 	/* B43_NPHY_TXF_20CO_S0A1, B43_NPHY_TXF_40CO_S0A1, unknown */
- 	static const u16 offset[] = { 0x186, 0x195, 0x2C5 };
-+	static const s16 dig_filter_phy_rev16[] = {
-+		-375, 136, -407, 208, -1527,
-+		956, 93, 186, 93, 230,
-+		-44, 230, 201, -191, 201,
-+	};
-+	int i;
- 
- 	for (i = 0; i < 3; i++)
--		for (j = 0; j < 15; j++)
--			b43_phy_write(dev, B43_PHY_N(offset[i] + j),
--					tbl_tx_filter_coef_rev4[i][j]);
--
--	if (dev->phy.is_40mhz) {
--		for (j = 0; j < 15; j++)
--			b43_phy_write(dev, B43_PHY_N(offset[0] + j),
--					tbl_tx_filter_coef_rev4[3][j]);
--	} else if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) {
--		for (j = 0; j < 15; j++)
--			b43_phy_write(dev, B43_PHY_N(offset[0] + j),
--					tbl_tx_filter_coef_rev4[5][j]);
--	}
--
--	if (dev->phy.channel == 14)
--		for (j = 0; j < 15; j++)
--			b43_phy_write(dev, B43_PHY_N(offset[0] + j),
--					tbl_tx_filter_coef_rev4[6][j]);
-+		b43_nphy_pa_set_tx_dig_filter(dev, offset[i],
-+					      tbl_tx_filter_coef_rev4[i]);
-+
-+	/* Verified with BCM43227 and BCM43228 */
-+	if (dev->phy.rev == 16)
-+		b43_nphy_pa_set_tx_dig_filter(dev, 0x186, dig_filter_phy_rev16);
-+
-+	/* Verified with BCM43131 and BCM43217 */
-+	if (dev->phy.rev == 17) {
-+		b43_nphy_pa_set_tx_dig_filter(dev, 0x186, dig_filter_phy_rev16);
-+		b43_nphy_pa_set_tx_dig_filter(dev, 0x195,
-+					      tbl_tx_filter_coef_rev4[1]);
-+	}
-+
-+	if (b43_is_40mhz(dev)) {
-+		b43_nphy_pa_set_tx_dig_filter(dev, 0x186,
-+					      tbl_tx_filter_coef_rev4[3]);
-+	} else {
-+		if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ)
-+			b43_nphy_pa_set_tx_dig_filter(dev, 0x186,
-+						      tbl_tx_filter_coef_rev4[5]);
-+		if (dev->phy.channel == 14)
-+			b43_nphy_pa_set_tx_dig_filter(dev, 0x186,
-+						      tbl_tx_filter_coef_rev4[6]);
-+	}
- }
- 
- /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/GetTxGain */
-@@ -4325,7 +5021,13 @@ static struct nphy_txgains b43_nphy_get_
- 			b43_nphy_stay_in_carrier_search(dev, false);
- 
- 		for (i = 0; i < 2; ++i) {
--			if (dev->phy.rev >= 3) {
-+			if (dev->phy.rev >= 7) {
-+				target.ipa[i] = curr_gain[i] & 0x0007;
-+				target.pad[i] = (curr_gain[i] & 0x00F8) >> 3;
-+				target.pga[i] = (curr_gain[i] & 0x0F00) >> 8;
-+				target.txgm[i] = (curr_gain[i] & 0x7000) >> 12;
-+				target.tx_lpf[i] = (curr_gain[i] & 0x8000) >> 15;
-+			} else if (dev->phy.rev >= 3) {
- 				target.ipa[i] = curr_gain[i] & 0x000F;
- 				target.pad[i] = (curr_gain[i] & 0x00F0) >> 4;
- 				target.pga[i] = (curr_gain[i] & 0x0F00) >> 8;
-@@ -4349,7 +5051,16 @@ static struct nphy_txgains b43_nphy_get_
- 
- 		for (i = 0; i < 2; ++i) {
- 			table = b43_nphy_get_tx_gain_table(dev);
--			if (dev->phy.rev >= 3) {
-+			if (!table)
-+				break;
-+
-+			if (dev->phy.rev >= 7) {
-+				target.ipa[i] = (table[index[i]] >> 16) & 0x7;
-+				target.pad[i] = (table[index[i]] >> 19) & 0x1F;
-+				target.pga[i] = (table[index[i]] >> 24) & 0xF;
-+				target.txgm[i] = (table[index[i]] >> 28) & 0x7;
-+				target.tx_lpf[i] = (table[index[i]] >> 31) & 0x1;
-+			} else if (dev->phy.rev >= 3) {
- 				target.ipa[i] = (table[index[i]] >> 16) & 0xF;
- 				target.pad[i] = (table[index[i]] >> 20) & 0xF;
- 				target.pga[i] = (table[index[i]] >> 24) & 0xF;
-@@ -4398,6 +5109,8 @@ static void b43_nphy_tx_cal_phy_cleanup(
- /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxCalPhySetup */
- static void b43_nphy_tx_cal_phy_setup(struct b43_wldev *dev)
- {
-+	struct b43_phy *phy = &dev->phy;
-+	struct b43_phy_n *nphy = dev->phy.n;
- 	u16 *regs = dev->phy.n->tx_rx_cal_phy_saveregs;
- 	u16 tmp;
- 
-@@ -4429,7 +5142,12 @@ static void b43_nphy_tx_cal_phy_setup(st
- 		regs[7] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC1);
- 		regs[8] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC2);
- 
--		b43_nphy_rf_ctl_intc_override(dev, N_INTC_OVERRIDE_PA, 1, 3);
-+		if (!nphy->use_int_tx_iq_lo_cal)
-+			b43_nphy_rf_ctl_intc_override(dev, N_INTC_OVERRIDE_PA,
-+						      1, 3);
-+		else
-+			b43_nphy_rf_ctl_intc_override(dev, N_INTC_OVERRIDE_PA,
-+						      0, 3);
- 		b43_nphy_rf_ctl_intc_override(dev, N_INTC_OVERRIDE_TRSW, 2, 1);
- 		b43_nphy_rf_ctl_intc_override(dev, N_INTC_OVERRIDE_TRSW, 8, 2);
- 
-@@ -4437,6 +5155,33 @@ static void b43_nphy_tx_cal_phy_setup(st
- 		regs[10] = b43_phy_read(dev, B43_NPHY_PAPD_EN1);
- 		b43_phy_mask(dev, B43_NPHY_PAPD_EN0, ~0x0001);
- 		b43_phy_mask(dev, B43_NPHY_PAPD_EN1, ~0x0001);
-+
-+		tmp = b43_nphy_read_lpf_ctl(dev, 0);
-+		if (phy->rev >= 19)
-+			b43_nphy_rf_ctl_override_rev19(dev, 0x80, tmp, 0, false,
-+						       1);
-+		else if (phy->rev >= 7)
-+			b43_nphy_rf_ctl_override_rev7(dev, 0x80, tmp, 0, false,
-+						      1);
-+
-+		if (nphy->use_int_tx_iq_lo_cal && true /* FIXME */) {
-+			if (phy->rev >= 19) {
-+				b43_nphy_rf_ctl_override_rev19(dev, 0x8, 0, 0x3,
-+							       false, 0);
-+			} else if (phy->rev >= 8) {
-+				b43_nphy_rf_ctl_override_rev7(dev, 0x8, 0, 0x3,
-+							      false, 0);
-+			} else if (phy->rev == 7) {
-+				b43_radio_maskset(dev, R2057_OVR_REG0, 1 << 4, 1 << 4);
-+				if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
-+					b43_radio_maskset(dev, R2057_PAD2G_TUNE_PUS_CORE0, ~1, 0);
-+					b43_radio_maskset(dev, R2057_PAD2G_TUNE_PUS_CORE1, ~1, 0);
-+				} else {
-+					b43_radio_maskset(dev, R2057_IPA5G_CASCOFFV_PU_CORE0, ~1, 0);
-+					b43_radio_maskset(dev, R2057_IPA5G_CASCOFFV_PU_CORE1, ~1, 0);
-+				}
-+			}
-+		}
- 	} else {
- 		b43_phy_maskset(dev, B43_NPHY_AFECTL_C1, 0x0FFF, 0xA000);
- 		b43_phy_maskset(dev, B43_NPHY_AFECTL_C2, 0x0FFF, 0xA000);
-@@ -4465,6 +5210,7 @@ static void b43_nphy_tx_cal_phy_setup(st
- /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/SaveCal */
- static void b43_nphy_save_cal(struct b43_wldev *dev)
- {
-+	struct b43_phy *phy = &dev->phy;
- 	struct b43_phy_n *nphy = dev->phy.n;
- 
- 	struct b43_phy_n_iq_comp *rxcal_coeffs = NULL;
-@@ -4489,7 +5235,26 @@ static void b43_nphy_save_cal(struct b43
- 
- 	b43_nphy_rx_iq_coeffs(dev, false, rxcal_coeffs);
- 	/* TODO use some definitions */
--	if (dev->phy.rev >= 3) {
-+	if (phy->rev >= 19) {
-+		/* TODO */
-+	} else if (phy->rev >= 7) {
-+		txcal_radio_regs[0] = b43_radio_read(dev,
-+						     R2057_TX0_LOFT_FINE_I);
-+		txcal_radio_regs[1] = b43_radio_read(dev,
-+						     R2057_TX0_LOFT_FINE_Q);
-+		txcal_radio_regs[4] = b43_radio_read(dev,
-+						     R2057_TX0_LOFT_COARSE_I);
-+		txcal_radio_regs[5] = b43_radio_read(dev,
-+						     R2057_TX0_LOFT_COARSE_Q);
-+		txcal_radio_regs[2] = b43_radio_read(dev,
-+						     R2057_TX1_LOFT_FINE_I);
-+		txcal_radio_regs[3] = b43_radio_read(dev,
-+						     R2057_TX1_LOFT_FINE_Q);
-+		txcal_radio_regs[6] = b43_radio_read(dev,
-+						     R2057_TX1_LOFT_COARSE_I);
-+		txcal_radio_regs[7] = b43_radio_read(dev,
-+						     R2057_TX1_LOFT_COARSE_Q);
-+	} else if (phy->rev >= 3) {
- 		txcal_radio_regs[0] = b43_radio_read(dev, 0x2021);
- 		txcal_radio_regs[1] = b43_radio_read(dev, 0x2022);
- 		txcal_radio_regs[2] = b43_radio_read(dev, 0x3021);
-@@ -4504,8 +5269,9 @@ static void b43_nphy_save_cal(struct b43
- 		txcal_radio_regs[2] = b43_radio_read(dev, 0x8D);
- 		txcal_radio_regs[3] = b43_radio_read(dev, 0xBC);
- 	}
--	iqcal_chanspec->center_freq = dev->phy.channel_freq;
--	iqcal_chanspec->channel_type = dev->phy.channel_type;
-+	iqcal_chanspec->center_freq = dev->phy.chandef->chan->center_freq;
-+	iqcal_chanspec->channel_type =
-+				cfg80211_get_chandef_type(dev->phy.chandef);
- 	b43_ntab_read_bulk(dev, B43_NTAB16(15, 80), 8, table);
- 
- 	if (nphy->hang_avoid)
-@@ -4515,6 +5281,7 @@ static void b43_nphy_save_cal(struct b43
- /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RestoreCal */
- static void b43_nphy_restore_cal(struct b43_wldev *dev)
- {
-+	struct b43_phy *phy = &dev->phy;
- 	struct b43_phy_n *nphy = dev->phy.n;
- 
- 	u16 coef[4];
-@@ -4562,7 +5329,26 @@ static void b43_nphy_restore_cal(struct
- 	}
- 
- 	/* TODO use some definitions */
--	if (dev->phy.rev >= 3) {
-+	if (phy->rev >= 19) {
-+		/* TODO */
-+	} else if (phy->rev >= 7) {
-+		b43_radio_write(dev, R2057_TX0_LOFT_FINE_I,
-+				txcal_radio_regs[0]);
-+		b43_radio_write(dev, R2057_TX0_LOFT_FINE_Q,
-+				txcal_radio_regs[1]);
-+		b43_radio_write(dev, R2057_TX0_LOFT_COARSE_I,
-+				txcal_radio_regs[4]);
-+		b43_radio_write(dev, R2057_TX0_LOFT_COARSE_Q,
-+				txcal_radio_regs[5]);
-+		b43_radio_write(dev, R2057_TX1_LOFT_FINE_I,
-+				txcal_radio_regs[2]);
-+		b43_radio_write(dev, R2057_TX1_LOFT_FINE_Q,
-+				txcal_radio_regs[3]);
-+		b43_radio_write(dev, R2057_TX1_LOFT_COARSE_I,
-+				txcal_radio_regs[6]);
-+		b43_radio_write(dev, R2057_TX1_LOFT_COARSE_Q,
-+				txcal_radio_regs[7]);
-+	} else if (phy->rev >= 3) {
- 		b43_radio_write(dev, 0x2021, txcal_radio_regs[0]);
- 		b43_radio_write(dev, 0x2022, txcal_radio_regs[1]);
- 		b43_radio_write(dev, 0x3021, txcal_radio_regs[2]);
-@@ -4585,6 +5371,7 @@ static int b43_nphy_cal_tx_iq_lo(struct
- 				struct nphy_txgains target,
- 				bool full, bool mphase)
- {
-+	struct b43_phy *phy = &dev->phy;
- 	struct b43_phy_n *nphy = dev->phy.n;
- 	int i;
- 	int error = 0;
-@@ -4625,7 +5412,7 @@ static int b43_nphy_cal_tx_iq_lo(struct
- 		(dev->phy.rev == 5 && nphy->ipa2g_on &&
- 		b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ);
- 	if (phy6or5x) {
--		if (dev->phy.is_40mhz) {
-+		if (b43_is_40mhz(dev)) {
- 			b43_ntab_write_bulk(dev, B43_NTAB16(15, 0), 18,
- 					tbl_tx_iqlo_cal_loft_ladder_40);
- 			b43_ntab_write_bulk(dev, B43_NTAB16(15, 32), 18,
-@@ -4638,18 +5425,24 @@ static int b43_nphy_cal_tx_iq_lo(struct
- 		}
- 	}
- 
--	b43_phy_write(dev, B43_NPHY_IQLOCAL_CMDGCTL, 0x8AA9);
-+	if (phy->rev >= 19) {
-+		/* TODO */
-+	} else if (phy->rev >= 7) {
-+		b43_phy_write(dev, B43_NPHY_IQLOCAL_CMDGCTL, 0x8AD9);
-+	} else {
-+		b43_phy_write(dev, B43_NPHY_IQLOCAL_CMDGCTL, 0x8AA9);
-+	}
- 
--	if (!dev->phy.is_40mhz)
-+	if (!b43_is_40mhz(dev))
- 		freq = 2500;
- 	else
- 		freq = 5000;
- 
- 	if (nphy->mphase_cal_phase_id > 2)
--		b43_nphy_run_samples(dev, (dev->phy.is_40mhz ? 40 : 20) * 8,
--					0xFFFF, 0, true, false);
-+		b43_nphy_run_samples(dev, (b43_is_40mhz(dev) ? 40 : 20) * 8,
-+				     0xFFFF, 0, true, false, false);
- 	else
--		error = b43_nphy_tx_tone(dev, freq, 250, true, false);
-+		error = b43_nphy_tx_tone(dev, freq, 250, true, false, false);
- 
- 	if (error == 0) {
- 		if (nphy->mphase_cal_phase_id > 2) {
-@@ -4777,9 +5570,9 @@ static int b43_nphy_cal_tx_iq_lo(struct
- 						nphy->txiqlocal_bestc);
- 			nphy->txiqlocal_coeffsvalid = true;
- 			nphy->txiqlocal_chanspec.center_freq =
--							dev->phy.channel_freq;
-+						phy->chandef->chan->center_freq;
- 			nphy->txiqlocal_chanspec.channel_type =
--							dev->phy.channel_type;
-+					cfg80211_get_chandef_type(phy->chandef);
- 		} else {
- 			length = 11;
- 			if (dev->phy.rev < 3)
-@@ -4815,8 +5608,8 @@ static void b43_nphy_reapply_tx_cal_coef
- 	bool equal = true;
- 
- 	if (!nphy->txiqlocal_coeffsvalid ||
--	    nphy->txiqlocal_chanspec.center_freq != dev->phy.channel_freq ||
--	    nphy->txiqlocal_chanspec.channel_type != dev->phy.channel_type)
-+	    nphy->txiqlocal_chanspec.center_freq != dev->phy.chandef->chan->center_freq ||
-+	    nphy->txiqlocal_chanspec.channel_type != cfg80211_get_chandef_type(dev->phy.chandef))
- 		return;
- 
- 	b43_ntab_read_bulk(dev, B43_NTAB16(15, 80), 7, buffer);
-@@ -4972,11 +5765,11 @@ static int b43_nphy_rev2_cal_rx_iq(struc
- 			if (playtone) {
- 				ret = b43_nphy_tx_tone(dev, 4000,
- 						(nphy->rxcalparams & 0xFFFF),
--						false, false);
-+						false, false, true);
- 				playtone = false;
- 			} else {
--				b43_nphy_run_samples(dev, 160, 0xFFFF, 0,
--							false, false);
-+				b43_nphy_run_samples(dev, 160, 0xFFFF, 0, false,
-+						     false, true);
- 			}
- 
- 			if (ret == 0) {
-@@ -5032,6 +5825,9 @@ static int b43_nphy_rev3_cal_rx_iq(struc
- static int b43_nphy_cal_rx_iq(struct b43_wldev *dev,
- 			struct nphy_txgains target, u8 type, bool debug)
- {
-+	if (dev->phy.rev >= 7)
-+		type = 0;
-+
- 	if (dev->phy.rev >= 3)
- 		return b43_nphy_rev3_cal_rx_iq(dev, target, type, debug);
- 	else
-@@ -5118,6 +5914,9 @@ static void b43_nphy_bphy_init(struct b4
- /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/SuperSwitchInit */
- static void b43_nphy_superswitch_init(struct b43_wldev *dev, bool init)
- {
-+	if (dev->phy.rev >= 7)
-+		return;
-+
- 	if (dev->phy.rev >= 3) {
- 		if (!init)
- 			return;
-@@ -5193,6 +5992,10 @@ static int b43_phy_initn(struct b43_wlde
- #endif
- 		}
- 	}
-+	nphy->use_int_tx_iq_lo_cal = b43_nphy_ipa(dev) ||
-+		phy->rev >= 7 ||
-+		(phy->rev >= 5 &&
-+		 sprom->boardflags2_hi & B43_BFH2_INTERNDET_TXIQCAL);
- 	nphy->deaf_count = 0;
- 	b43_nphy_tables_init(dev);
- 	nphy->crsminpwr_adjusted = false;
-@@ -5202,6 +6005,16 @@ static int b43_phy_initn(struct b43_wlde
- 	if (dev->phy.rev >= 3) {
- 		b43_phy_write(dev, B43_NPHY_TXF_40CO_B1S1, 0);
- 		b43_phy_write(dev, B43_NPHY_RFCTL_OVER, 0);
-+		if (phy->rev >= 7) {
-+			b43_phy_write(dev, B43_NPHY_REV7_RF_CTL_OVER3, 0);
-+			b43_phy_write(dev, B43_NPHY_REV7_RF_CTL_OVER4, 0);
-+			b43_phy_write(dev, B43_NPHY_REV7_RF_CTL_OVER5, 0);
-+			b43_phy_write(dev, B43_NPHY_REV7_RF_CTL_OVER6, 0);
-+		}
-+		if (phy->rev >= 19) {
-+			/* TODO */
-+		}
-+
- 		b43_phy_write(dev, B43_NPHY_TXF_40CO_B1S0, 0);
- 		b43_phy_write(dev, B43_NPHY_TXF_40CO_B32S1, 0);
- 	} else {
-@@ -5239,7 +6052,9 @@ static int b43_phy_initn(struct b43_wlde
- 	b43_phy_write(dev, B43_NPHY_PLOAD_CSENSE_EXTLEN, 0x50);
- 	b43_phy_write(dev, B43_NPHY_TXRIFS_FRDEL, 0x30);
- 
--	b43_nphy_update_mimo_config(dev, nphy->preamble_override);
-+	if (phy->rev < 8)
-+		b43_nphy_update_mimo_config(dev, nphy->preamble_override);
-+
- 	b43_nphy_update_txrx_chain(dev);
- 
- 	if (phy->rev < 2) {
-@@ -5271,10 +6086,12 @@ static int b43_phy_initn(struct b43_wlde
- 
- 	b43_mac_phy_clock_set(dev, true);
- 
--	b43_nphy_pa_override(dev, false);
--	b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RX2TX);
--	b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RESET2RX);
--	b43_nphy_pa_override(dev, true);
-+	if (phy->rev < 7) {
-+		b43_nphy_pa_override(dev, false);
-+		b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RX2TX);
-+		b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RESET2RX);
-+		b43_nphy_pa_override(dev, true);
-+	}
- 
- 	b43_nphy_classifier(dev, 0, 0);
- 	b43_nphy_read_clip_detection(dev, clip);
-@@ -5348,7 +6165,7 @@ static int b43_phy_initn(struct b43_wlde
- 	b43_phy_write(dev, B43_NPHY_TXMACDELAY, 0x0320);
- 	if (phy->rev >= 3 && phy->rev <= 6)
- 		b43_phy_write(dev, B43_NPHY_PLOAD_CSENSE_EXTLEN, 0x0032);
--	b43_nphy_tx_lp_fbw(dev);
-+	b43_nphy_tx_lpf_bw(dev);
- 	if (phy->rev >= 3)
- 		b43_nphy_spur_workaround(dev);
- 
-@@ -5397,23 +6214,23 @@ static void b43_nphy_channel_setup(struc
- 	struct b43_phy *phy = &dev->phy;
- 	struct b43_phy_n *nphy = dev->phy.n;
- 	int ch = new_channel->hw_value;
--
--	u16 old_band_5ghz;
- 	u16 tmp16;
- 
--	old_band_5ghz =
--		b43_phy_read(dev, B43_NPHY_BANDCTL) & B43_NPHY_BANDCTL_5GHZ;
--	if (new_channel->band == IEEE80211_BAND_5GHZ && !old_band_5ghz) {
-+	if (new_channel->band == IEEE80211_BAND_5GHZ) {
- 		tmp16 = b43_read16(dev, B43_MMIO_PSM_PHY_HDR);
- 		b43_write16(dev, B43_MMIO_PSM_PHY_HDR, tmp16 | 4);
--		b43_phy_set(dev, B43_PHY_B_BBCFG, 0xC000);
-+		/* Put BPHY in the reset */
-+		b43_phy_set(dev, B43_PHY_B_BBCFG,
-+			    B43_PHY_B_BBCFG_RSTCCA | B43_PHY_B_BBCFG_RSTRX);
- 		b43_write16(dev, B43_MMIO_PSM_PHY_HDR, tmp16);
- 		b43_phy_set(dev, B43_NPHY_BANDCTL, B43_NPHY_BANDCTL_5GHZ);
--	} else if (new_channel->band == IEEE80211_BAND_2GHZ && old_band_5ghz) {
-+	} else if (new_channel->band == IEEE80211_BAND_2GHZ) {
- 		b43_phy_mask(dev, B43_NPHY_BANDCTL, ~B43_NPHY_BANDCTL_5GHZ);
- 		tmp16 = b43_read16(dev, B43_MMIO_PSM_PHY_HDR);
- 		b43_write16(dev, B43_MMIO_PSM_PHY_HDR, tmp16 | 4);
--		b43_phy_mask(dev, B43_PHY_B_BBCFG, 0x3FFF);
-+		/* Take BPHY out of the reset */
-+		b43_phy_mask(dev, B43_PHY_B_BBCFG,
-+			     (u16)~(B43_PHY_B_BBCFG_RSTCCA | B43_PHY_B_BBCFG_RSTRX));
- 		b43_write16(dev, B43_MMIO_PSM_PHY_HDR, tmp16);
- 	}
- 
-@@ -5434,35 +6251,49 @@ static void b43_nphy_channel_setup(struc
- 	if (dev->phy.rev < 3)
- 		b43_nphy_adjust_lna_gain_table(dev);
- 
--	b43_nphy_tx_lp_fbw(dev);
-+	b43_nphy_tx_lpf_bw(dev);
- 
- 	if (dev->phy.rev >= 3 &&
- 	    dev->phy.n->spur_avoid != B43_SPUR_AVOID_DISABLE) {
--		bool avoid = false;
-+		u8 spuravoid = 0;
-+
- 		if (dev->phy.n->spur_avoid == B43_SPUR_AVOID_FORCE) {
--			avoid = true;
--		} else if (!b43_channel_type_is_40mhz(phy->channel_type)) {
--			if ((ch >= 5 && ch <= 8) || ch == 13 || ch == 14)
--				avoid = true;
--		} else { /* 40MHz */
--			if (nphy->aband_spurwar_en &&
--			    (ch == 38 || ch == 102 || ch == 118))
--				avoid = dev->dev->chip_id == 0x4716;
--		}
--
--		b43_nphy_pmu_spur_avoid(dev, avoid);
--
--		if (dev->dev->chip_id == 43222 || dev->dev->chip_id == 43224 ||
--		    dev->dev->chip_id == 43225) {
--			b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_LOW,
--				    avoid ? 0x5341 : 0x8889);
--			b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_HIGH, 0x8);
-+			spuravoid = 1;
-+		} else if (phy->rev >= 19) {
-+			/* TODO */
-+		} else if (phy->rev >= 18) {
-+			/* TODO */
-+		} else if (phy->rev >= 17) {
-+			/* TODO: Off for channels 1-11, but check 12-14! */
-+		} else if (phy->rev >= 16) {
-+			/* TODO: Off for 2 GHz, but check 5 GHz! */
-+		} else if (phy->rev >= 7) {
-+			if (!b43_is_40mhz(dev)) { /* 20MHz */
-+				if (ch == 13 || ch == 14 || ch == 153)
-+					spuravoid = 1;
-+			} else { /* 40 MHz */
-+				if (ch == 54)
-+					spuravoid = 1;
-+			}
-+		} else {
-+			if (!b43_is_40mhz(dev)) { /* 20MHz */
-+				if ((ch >= 5 && ch <= 8) || ch == 13 || ch == 14)
-+					spuravoid = 1;
-+			} else { /* 40MHz */
-+				if (nphy->aband_spurwar_en &&
-+				    (ch == 38 || ch == 102 || ch == 118))
-+					spuravoid = dev->dev->chip_id == 0x4716;
-+			}
- 		}
- 
-+		b43_nphy_pmu_spur_avoid(dev, spuravoid);
-+
-+		b43_mac_switch_freq(dev, spuravoid);
-+
- 		if (dev->phy.rev == 3 || dev->phy.rev == 4)
- 			; /* TODO: reset PLL */
- 
--		if (avoid)
-+		if (spuravoid)
- 			b43_phy_set(dev, B43_NPHY_BBCFG, B43_NPHY_BBCFG_RSTRX);
- 		else
- 			b43_phy_mask(dev, B43_NPHY_BBCFG,
-@@ -5488,10 +6319,20 @@ static int b43_nphy_set_channel(struct b
- 
- 	const struct b43_nphy_channeltab_entry_rev2 *tabent_r2 = NULL;
- 	const struct b43_nphy_channeltab_entry_rev3 *tabent_r3 = NULL;
-+	const struct b43_nphy_chantabent_rev7 *tabent_r7 = NULL;
-+	const struct b43_nphy_chantabent_rev7_2g *tabent_r7_2g = NULL;
- 
- 	u8 tmp;
- 
--	if (dev->phy.rev >= 3) {
-+	if (phy->rev >= 19) {
-+		return -ESRCH;
-+		/* TODO */
-+	} else if (phy->rev >= 7) {
-+		r2057_get_chantabent_rev7(dev, channel->center_freq,
-+					  &tabent_r7, &tabent_r7_2g);
-+		if (!tabent_r7 && !tabent_r7_2g)
-+			return -ESRCH;
-+	} else if (phy->rev >= 3) {
- 		tabent_r3 = b43_nphy_get_chantabent_rev3(dev,
- 							channel->center_freq);
- 		if (!tabent_r3)
-@@ -5506,20 +6347,38 @@ static int b43_nphy_set_channel(struct b
- 	/* 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 0
- 	if (b43_channel_type_is_40mhz(phy->channel_type) !=
- 		b43_channel_type_is_40mhz(channel_type))
- 		; /* TODO: BMAC BW Set (channel_type) */
-+#endif
- 
--	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 (channel_type == NL80211_CHAN_HT40PLUS) {
-+		b43_phy_set(dev, B43_NPHY_RXCTL, B43_NPHY_RXCTL_BSELU20);
-+		if (phy->rev >= 7)
-+			b43_phy_set(dev, 0x310, 0x8000);
-+	} else if (channel_type == NL80211_CHAN_HT40MINUS) {
-+		b43_phy_mask(dev, B43_NPHY_RXCTL, ~B43_NPHY_RXCTL_BSELU20);
-+		if (phy->rev >= 7)
-+			b43_phy_mask(dev, 0x310, (u16)~0x8000);
-+	}
- 
--	if (dev->phy.rev >= 3) {
-+	if (phy->rev >= 19) {
-+		/* TODO */
-+	} else if (phy->rev >= 7) {
-+		const struct b43_phy_n_sfo_cfg *phy_regs = tabent_r7 ?
-+			&(tabent_r7->phy_regs) : &(tabent_r7_2g->phy_regs);
-+
-+		if (phy->radio_rev <= 4 || phy->radio_rev == 6) {
-+			tmp = (channel->band == IEEE80211_BAND_5GHZ) ? 2 : 0;
-+			b43_radio_maskset(dev, R2057_TIA_CONFIG_CORE0, ~2, tmp);
-+			b43_radio_maskset(dev, R2057_TIA_CONFIG_CORE1, ~2, tmp);
-+		}
-+
-+		b43_radio_2057_setup(dev, tabent_r7, tabent_r7_2g);
-+		b43_nphy_channel_setup(dev, phy_regs, channel);
-+	} else if (phy->rev >= 3) {
- 		tmp = (channel->band == IEEE80211_BAND_5GHZ) ? 4 : 0;
- 		b43_radio_maskset(dev, 0x08, 0xFFFB, tmp);
- 		b43_radio_2056_setup(dev, tabent_r3);
-@@ -5561,7 +6420,6 @@ static void b43_nphy_op_prepare_structs(
- 	nphy->hang_avoid = (phy->rev == 3 || phy->rev == 4);
- 	nphy->spur_avoid = (phy->rev >= 3) ?
- 				B43_SPUR_AVOID_AUTO : B43_SPUR_AVOID_DISABLE;
--	nphy->init_por = true;
- 	nphy->gain_boost = true; /* this way we follow wl, assume it is true */
- 	nphy->txrx_chain = 2; /* sth different than 0 and 1 for now */
- 	nphy->phyrxchain = 3; /* to avoid b43_nphy_set_rx_core_state like wl */
-@@ -5602,8 +6460,6 @@ static void b43_nphy_op_prepare_structs(
- 		nphy->ipa2g_on = sprom->fem.ghz2.extpa_gain == 2;
- 		nphy->ipa5g_on = sprom->fem.ghz5.extpa_gain == 2;
- 	}
--
--	nphy->init_por = true;
- }
- 
- static void b43_nphy_op_free(struct b43_wldev *dev)
-@@ -5663,7 +6519,7 @@ static void b43_nphy_op_maskset(struct b
- static u16 b43_nphy_op_radio_read(struct b43_wldev *dev, u16 reg)
- {
- 	/* Register 1 is a 32-bit register. */
--	B43_WARN_ON(reg == 1);
-+	B43_WARN_ON(dev->phy.rev < 7 && reg == 1);
- 
- 	if (dev->phy.rev >= 7)
- 		reg |= 0x200; /* Radio 0x2057 */
-@@ -5677,7 +6533,7 @@ static u16 b43_nphy_op_radio_read(struct
- static void b43_nphy_op_radio_write(struct b43_wldev *dev, u16 reg, u16 value)
- {
- 	/* Register 1 is a 32-bit register. */
--	B43_WARN_ON(reg == 1);
-+	B43_WARN_ON(dev->phy.rev < 7 && reg == 1);
- 
- 	b43_write16(dev, B43_MMIO_RADIO_CONTROL, reg);
- 	b43_write16(dev, B43_MMIO_RADIO_DATA_LOW, value);
-@@ -5687,15 +6543,23 @@ static void b43_nphy_op_radio_write(stru
- static void b43_nphy_op_software_rfkill(struct b43_wldev *dev,
- 					bool blocked)
- {
-+	struct b43_phy *phy = &dev->phy;
-+
- 	if (b43_read32(dev, B43_MMIO_MACCTL) & B43_MACCTL_ENABLED)
- 		b43err(dev->wl, "MAC not suspended\n");
- 
- 	if (blocked) {
--		b43_phy_mask(dev, B43_NPHY_RFCTL_CMD,
--				~B43_NPHY_RFCTL_CMD_CHIP0PU);
--		if (dev->phy.rev >= 7) {
-+		if (phy->rev >= 19) {
- 			/* TODO */
--		} else if (dev->phy.rev >= 3) {
-+		} else if (phy->rev >= 8) {
-+			b43_phy_mask(dev, B43_NPHY_RFCTL_CMD,
-+				     ~B43_NPHY_RFCTL_CMD_CHIP0PU);
-+		} else if (phy->rev >= 7) {
-+			/* Nothing needed */
-+		} else if (phy->rev >= 3) {
-+			b43_phy_mask(dev, B43_NPHY_RFCTL_CMD,
-+				     ~B43_NPHY_RFCTL_CMD_CHIP0PU);
-+
- 			b43_radio_mask(dev, 0x09, ~0x2);
- 
- 			b43_radio_write(dev, 0x204D, 0);
-@@ -5713,11 +6577,15 @@ static void b43_nphy_op_software_rfkill(
- 			b43_radio_write(dev, 0x3064, 0);
- 		}
- 	} else {
--		if (dev->phy.rev >= 7) {
--			b43_radio_2057_init(dev);
-+		if (phy->rev >= 19) {
-+			/* TODO */
-+		} else if (phy->rev >= 7) {
-+			if (!dev->phy.radio_on)
-+				b43_radio_2057_init(dev);
- 			b43_switch_channel(dev, dev->phy.channel);
--		} else if (dev->phy.rev >= 3) {
--			b43_radio_init2056(dev);
-+		} else if (phy->rev >= 3) {
-+			if (!dev->phy.radio_on)
-+				b43_radio_init2056(dev);
- 			b43_switch_channel(dev, dev->phy.channel);
- 		} else {
- 			b43_radio_init2055(dev);
-@@ -5728,10 +6596,13 @@ static void b43_nphy_op_software_rfkill(
- /* http://bcm-v4.sipsolutions.net/802.11/PHY/Anacore */
- static void b43_nphy_op_switch_analog(struct b43_wldev *dev, bool on)
- {
-+	struct b43_phy *phy = &dev->phy;
- 	u16 override = on ? 0x0 : 0x7FFF;
- 	u16 core = on ? 0xD : 0x00FD;
- 
--	if (dev->phy.rev >= 3) {
-+	if (phy->rev >= 19) {
-+		/* TODO */
-+	} else if (phy->rev >= 3) {
- 		if (on) {
- 			b43_phy_write(dev, B43_NPHY_AFECTL_C1, core);
- 			b43_phy_write(dev, B43_NPHY_AFECTL_OVER1, override);
---- a/drivers/net/wireless/b43/phy_n.h
-+++ b/drivers/net/wireless/b43/phy_n.h
-@@ -366,11 +366,13 @@
- #define B43_NPHY_TXF_40CO_B1S0			B43_PHY_N(0x0E5) /* TX filter 40 coeff B1 stage 0 */
- #define B43_NPHY_TXF_40CO_B32S1			B43_PHY_N(0x0E6) /* TX filter 40 coeff B32 stage 1 */
- #define B43_NPHY_TXF_40CO_B1S1			B43_PHY_N(0x0E7) /* TX filter 40 coeff B1 stage 1 */
-+#define B43_NPHY_REV3_RFCTL_OVER0		B43_PHY_N(0x0E7)
- #define B43_NPHY_TXF_40CO_B32S2			B43_PHY_N(0x0E8) /* TX filter 40 coeff B32 stage 2 */
- #define B43_NPHY_TXF_40CO_B1S2			B43_PHY_N(0x0E9) /* TX filter 40 coeff B1 stage 2 */
- #define B43_NPHY_BIST_STAT2			B43_PHY_N(0x0EA) /* BIST status 2 */
- #define B43_NPHY_BIST_STAT3			B43_PHY_N(0x0EB) /* BIST status 3 */
- #define B43_NPHY_RFCTL_OVER			B43_PHY_N(0x0EC) /* RF control override */
-+#define B43_NPHY_REV3_RFCTL_OVER1		B43_PHY_N(0x0EC)
- #define B43_NPHY_MIMOCFG			B43_PHY_N(0x0ED) /* MIMO config */
- #define  B43_NPHY_MIMOCFG_GFMIX			0x0004 /* Greenfield or mixed mode */
- #define  B43_NPHY_MIMOCFG_AUTO			0x0100 /* Greenfield/mixed mode auto */
-@@ -857,7 +859,18 @@
- #define B43_NPHY_REV3_C2_CLIP2_GAIN_A		B43_PHY_N(0x2AF)
- #define B43_NPHY_REV3_C2_CLIP2_GAIN_B		B43_PHY_N(0x2B0)
- 
-+#define B43_NPHY_REV7_RF_CTL_MISC_REG3		B43_PHY_N(0x340)
-+#define B43_NPHY_REV7_RF_CTL_MISC_REG4		B43_PHY_N(0x341)
-+#define B43_NPHY_REV7_RF_CTL_OVER3		B43_PHY_N(0x342)
-+#define B43_NPHY_REV7_RF_CTL_OVER4		B43_PHY_N(0x343)
-+#define B43_NPHY_REV7_RF_CTL_MISC_REG5		B43_PHY_N(0x344)
-+#define B43_NPHY_REV7_RF_CTL_MISC_REG6		B43_PHY_N(0x345)
-+#define B43_NPHY_REV7_RF_CTL_OVER5		B43_PHY_N(0x346)
-+#define B43_NPHY_REV7_RF_CTL_OVER6		B43_PHY_N(0x347)
-+
- #define B43_PHY_B_BBCFG				B43_PHY_N_BMODE(0x001) /* BB config */
-+#define  B43_PHY_B_BBCFG_RSTCCA			0x4000 /* Reset CCA */
-+#define  B43_PHY_B_BBCFG_RSTRX			0x8000 /* Reset RX */
- #define B43_PHY_B_TEST				B43_PHY_N_BMODE(0x00A)
- 
- struct b43_wldev;
-@@ -931,11 +944,12 @@ struct b43_phy_n {
- 	u16 papd_epsilon_offset[2];
- 	s32 preamble_override;
- 	u32 bb_mult_save;
--	bool init_por;
- 
- 	bool gain_boost;
- 	bool elna_gain_config;
- 	bool band5g_pwrgain;
-+	bool use_int_tx_iq_lo_cal;
-+	bool lpf_bw_overrode_for_sample_play;
- 
- 	u8 mphase_cal_phase_id;
- 	u16 mphase_txcal_cmdidx;
---- a/drivers/net/wireless/b43/tables_nphy.c
-+++ b/drivers/net/wireless/b43/tables_nphy.c
-@@ -2146,7 +2146,196 @@ static const u16 b43_ntab_antswctl_r3[4]
- 	}
- };
- 
--/* TX gain tables */
-+/* static tables, PHY revision >= 7 */
-+
-+/* Copied from brcmsmac (5.75.11) */
-+static const u32 b43_ntab_tmap_r7[] = {
-+	0x8a88aa80, 0x8aaaaa8a, 0x8a8a8aa8, 0x00000888,
-+	0x88000000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
-+	0xf1111110, 0x11111111, 0x11f11111, 0x00000111,
-+	0x11000000, 0x1111f111, 0x11111111, 0x111111f1,
-+	0x8a88aa80, 0x8aaaaa8a, 0x8a8a8aa8, 0x000aa888,
-+	0x88880000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
-+	0xa1111110, 0x11111111, 0x11c11111, 0x00000111,
-+	0x11000000, 0x1111a111, 0x11111111, 0x111111a1,
-+	0xa2222220, 0x22222222, 0x22c22222, 0x00000222,
-+	0x22000000, 0x2222a222, 0x22222222, 0x222222a2,
-+	0xf1111110, 0x11111111, 0x11f11111, 0x00011111,
-+	0x11110000, 0x1111f111, 0x11111111, 0x111111f1,
-+	0xa8aa88a0, 0xa88888a8, 0xa8a8a88a, 0x00088aaa,
-+	0xaaaa0000, 0xa8a8aa88, 0xa88aaaaa, 0xaaaa8a8a,
-+	0xaaa8aaa0, 0x8aaa8aaa, 0xaa8a8a8a, 0x000aaa88,
-+	0x8aaa0000, 0xaaa8a888, 0x8aa88a8a, 0x8a88a888,
-+	0x08080a00, 0x0a08080a, 0x080a0a08, 0x00080808,
-+	0x080a0000, 0x080a0808, 0x080a0808, 0x0a0a0a08,
-+	0xa0a0a0a0, 0x80a0a080, 0x8080a0a0, 0x00008080,
-+	0x80a00000, 0x80a080a0, 0xa080a0a0, 0x8080a0a0,
-+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
-+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
-+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
-+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
-+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
-+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
-+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
-+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
-+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
-+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
-+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
-+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
-+	0x99999000, 0x9b9b99bb, 0x9bb99999, 0x9999b9b9,
-+	0x9b99bb90, 0x9bbbbb9b, 0x9b9b9bb9, 0x00000999,
-+	0x88000000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
-+	0x8a88aa80, 0x8aaaaa8a, 0x8a8a8aa8, 0x00aaa888,
-+	0x22000000, 0x2222b222, 0x22222222, 0x222222b2,
-+	0xb2222220, 0x22222222, 0x22d22222, 0x00000222,
-+	0x11000000, 0x1111a111, 0x11111111, 0x111111a1,
-+	0xa1111110, 0x11111111, 0x11c11111, 0x00000111,
-+	0x33000000, 0x3333b333, 0x33333333, 0x333333b3,
-+	0xb3333330, 0x33333333, 0x33d33333, 0x00000333,
-+	0x22000000, 0x2222a222, 0x22222222, 0x222222a2,
-+	0xa2222220, 0x22222222, 0x22c22222, 0x00000222,
-+	0x99b99b00, 0x9b9b99bb, 0x9bb99999, 0x9999b9b9,
-+	0x9b99bb99, 0x9bbbbb9b, 0x9b9b9bb9, 0x00000999,
-+	0x88000000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
-+	0x8a88aa88, 0x8aaaaa8a, 0x8a8a8aa8, 0x08aaa888,
-+	0x22222200, 0x2222f222, 0x22222222, 0x222222f2,
-+	0x22222222, 0x22222222, 0x22f22222, 0x00000222,
-+	0x11000000, 0x1111f111, 0x11111111, 0x11111111,
-+	0xf1111111, 0x11111111, 0x11f11111, 0x01111111,
-+	0xbb9bb900, 0xb9b9bb99, 0xb99bbbbb, 0xbbbb9b9b,
-+	0xb9bb99bb, 0xb99999b9, 0xb9b9b99b, 0x00000bbb,
-+	0xaa000000, 0xa8a8aa88, 0xa88aaaaa, 0xaaaa8a8a,
-+	0xa8aa88aa, 0xa88888a8, 0xa8a8a88a, 0x0a888aaa,
-+	0xaa000000, 0xa8a8aa88, 0xa88aaaaa, 0xaaaa8a8a,
-+	0xa8aa88a0, 0xa88888a8, 0xa8a8a88a, 0x00000aaa,
-+	0x88000000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
-+	0x8a88aa80, 0x8aaaaa8a, 0x8a8a8aa8, 0x00000888,
-+	0xbbbbbb00, 0x999bbbbb, 0x9bb99b9b, 0xb9b9b9bb,
-+	0xb9b99bbb, 0xb9b9b9bb, 0xb9bb9b99, 0x00000999,
-+	0x8a000000, 0xaa88a888, 0xa88888aa, 0xa88a8a88,
-+	0xa88aa88a, 0x88a8aaaa, 0xa8aa8aaa, 0x0888a88a,
-+	0x0b0b0b00, 0x090b0b0b, 0x0b090b0b, 0x0909090b,
-+	0x09090b0b, 0x09090b0b, 0x09090b09, 0x00000909,
-+	0x0a000000, 0x0a080808, 0x080a080a, 0x080a0a08,
-+	0x080a080a, 0x0808080a, 0x0a0a0a08, 0x0808080a,
-+	0xb0b0b000, 0x9090b0b0, 0x90b09090, 0xb0b0b090,
-+	0xb0b090b0, 0x90b0b0b0, 0xb0b09090, 0x00000090,
-+	0x80000000, 0xa080a080, 0xa08080a0, 0xa0808080,
-+	0xa080a080, 0x80a0a0a0, 0xa0a080a0, 0x00a0a0a0,
-+	0x22000000, 0x2222f222, 0x22222222, 0x222222f2,
-+	0xf2222220, 0x22222222, 0x22f22222, 0x00000222,
-+	0x11000000, 0x1111f111, 0x11111111, 0x111111f1,
-+	0xf1111110, 0x11111111, 0x11f11111, 0x00000111,
-+	0x33000000, 0x3333f333, 0x33333333, 0x333333f3,
-+	0xf3333330, 0x33333333, 0x33f33333, 0x00000333,
-+	0x22000000, 0x2222f222, 0x22222222, 0x222222f2,
-+	0xf2222220, 0x22222222, 0x22f22222, 0x00000222,
-+	0x99000000, 0x9b9b99bb, 0x9bb99999, 0x9999b9b9,
-+	0x9b99bb90, 0x9bbbbb9b, 0x9b9b9bb9, 0x00000999,
-+	0x88000000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
-+	0x8a88aa80, 0x8aaaaa8a, 0x8a8a8aa8, 0x00000888,
-+	0x88888000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
-+	0x8a88aa80, 0x8aaaaa8a, 0x8a8a8aa8, 0x00000888,
-+	0x88000000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
-+	0x8a88aa80, 0x8aaaaa8a, 0x8a8a8aa8, 0x00aaa888,
-+	0x88a88a00, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
-+	0x8a88aa88, 0x8aaaaa8a, 0x8a8a8aa8, 0x000aa888,
-+	0x88880000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
-+	0x8a88aa88, 0x8aaaaa8a, 0x8a8a8aa8, 0x08aaa888,
-+	0x11000000, 0x1111a111, 0x11111111, 0x111111a1,
-+	0xa1111110, 0x11111111, 0x11c11111, 0x00000111,
-+	0x11000000, 0x1111a111, 0x11111111, 0x111111a1,
-+	0xa1111110, 0x11111111, 0x11c11111, 0x00000111,
-+	0x88000000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
-+	0x8a88aa80, 0x8aaaaa8a, 0x8a8a8aa8, 0x00000888,
-+	0x88000000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
-+	0x8a88aa80, 0x8aaaaa8a, 0x8a8a8aa8, 0x00000888,
-+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
-+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
-+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
-+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
-+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
-+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
-+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
-+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
-+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
-+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
-+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
-+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
-+};
-+
-+/* Extracted from MMIO dump of 6.30.223.141 */
-+static const u32 b43_ntab_noisevar_r7[] = {
-+	0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
-+	0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
-+	0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
-+	0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
-+	0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
-+	0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
-+	0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
-+	0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
-+	0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
-+	0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
-+	0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
-+	0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
-+	0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
-+	0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
-+	0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
-+	0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
-+	0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
-+	0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
-+	0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
-+	0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
-+	0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
-+	0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
-+	0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
-+	0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
-+	0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
-+	0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
-+	0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
-+	0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
-+	0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
-+	0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
-+	0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
-+	0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
-+	0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
-+	0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
-+	0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
-+	0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
-+	0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
-+	0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
-+	0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
-+	0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
-+	0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
-+	0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
-+	0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
-+	0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
-+	0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
-+	0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
-+	0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
-+	0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
-+	0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
-+	0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
-+	0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
-+	0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
-+	0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
-+	0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
-+	0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
-+	0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
-+	0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
-+	0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
-+	0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
-+	0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
-+	0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
-+	0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
-+	0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
-+	0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
-+};
-+
-+/**************************************************
-+ * TX gain tables
-+ **************************************************/
-+
- static const u32 b43_ntab_tx_gain_rev0_1_2[] = {
- 	0x03cc2b44, 0x03cc2b42, 0x03cc2a44, 0x03cc2a42,
- 	0x03cc2944, 0x03c82b44, 0x03c82b42, 0x03c82a44,
-@@ -2182,7 +2371,9 @@ static const u32 b43_ntab_tx_gain_rev0_1
- 	0x03801442, 0x03801344, 0x03801342, 0x00002b00,
- };
- 
--static const u32 b43_ntab_tx_gain_rev3plus_2ghz[] = {
-+/* EPA 2 GHz */
-+
-+static const u32 b43_ntab_tx_gain_epa_rev3_2g[] = {
- 	0x1f410044, 0x1f410042, 0x1f410040, 0x1f41003e,
- 	0x1f41003c, 0x1f41003b, 0x1f410039, 0x1f410037,
- 	0x1e410044, 0x1e410042, 0x1e410040, 0x1e41003e,
-@@ -2217,7 +2408,44 @@ static const u32 b43_ntab_tx_gain_rev3pl
- 	0x1041003c, 0x1041003b, 0x10410039, 0x10410037,
- };
- 
--static const u32 b43_ntab_tx_gain_rev3_5ghz[] = {
-+static const u32 b43_ntab_tx_gain_epa_rev3_hi_pwr_2g[] = {
-+	0x0f410044, 0x0f410042, 0x0f410040, 0x0f41003e,
-+	0x0f41003c, 0x0f41003b, 0x0f410039, 0x0f410037,
-+	0x0e410044, 0x0e410042, 0x0e410040, 0x0e41003e,
-+	0x0e41003c, 0x0e41003b, 0x0e410039, 0x0e410037,
-+	0x0d410044, 0x0d410042, 0x0d410040, 0x0d41003e,
-+	0x0d41003c, 0x0d41003b, 0x0d410039, 0x0d410037,
-+	0x0c410044, 0x0c410042, 0x0c410040, 0x0c41003e,
-+	0x0c41003c, 0x0c41003b, 0x0c410039, 0x0c410037,
-+	0x0b410044, 0x0b410042, 0x0b410040, 0x0b41003e,
-+	0x0b41003c, 0x0b41003b, 0x0b410039, 0x0b410037,
-+	0x0a410044, 0x0a410042, 0x0a410040, 0x0a41003e,
-+	0x0a41003c, 0x0a41003b, 0x0a410039, 0x0a410037,
-+	0x09410044, 0x09410042, 0x09410040, 0x0941003e,
-+	0x0941003c, 0x0941003b, 0x09410039, 0x09410037,
-+	0x08410044, 0x08410042, 0x08410040, 0x0841003e,
-+	0x0841003c, 0x0841003b, 0x08410039, 0x08410037,
-+	0x07410044, 0x07410042, 0x07410040, 0x0741003e,
-+	0x0741003c, 0x0741003b, 0x07410039, 0x07410037,
-+	0x06410044, 0x06410042, 0x06410040, 0x0641003e,
-+	0x0641003c, 0x0641003b, 0x06410039, 0x06410037,
-+	0x05410044, 0x05410042, 0x05410040, 0x0541003e,
-+	0x0541003c, 0x0541003b, 0x05410039, 0x05410037,
-+	0x04410044, 0x04410042, 0x04410040, 0x0441003e,
-+	0x0441003c, 0x0441003b, 0x04410039, 0x04410037,
-+	0x03410044, 0x03410042, 0x03410040, 0x0341003e,
-+	0x0341003c, 0x0341003b, 0x03410039, 0x03410037,
-+	0x02410044, 0x02410042, 0x02410040, 0x0241003e,
-+	0x0241003c, 0x0241003b, 0x02410039, 0x02410037,
-+	0x01410044, 0x01410042, 0x01410040, 0x0141003e,
-+	0x0141003c, 0x0141003b, 0x01410039, 0x01410037,
-+	0x00410044, 0x00410042, 0x00410040, 0x0041003e,
-+	0x0041003c, 0x0041003b, 0x00410039, 0x00410037
-+};
-+
-+/* EPA 5 GHz */
-+
-+static const u32 b43_ntab_tx_gain_epa_rev3_5g[] = {
- 	0xcff70044, 0xcff70042, 0xcff70040, 0xcff7003e,
- 	0xcff7003c, 0xcff7003b, 0xcff70039, 0xcff70037,
- 	0xcef70044, 0xcef70042, 0xcef70040, 0xcef7003e,
-@@ -2252,7 +2480,7 @@ static const u32 b43_ntab_tx_gain_rev3_5
- 	0xc0f7003c, 0xc0f7003b, 0xc0f70039, 0xc0f70037,
- };
- 
--static const u32 b43_ntab_tx_gain_rev4_5ghz[] = {
-+static const u32 b43_ntab_tx_gain_epa_rev4_5g[] = {
- 	0x2ff20044, 0x2ff20042, 0x2ff20040, 0x2ff2003e,
- 	0x2ff2003c, 0x2ff2003b, 0x2ff20039, 0x2ff20037,
- 	0x2ef20044, 0x2ef20042, 0x2ef20040, 0x2ef2003e,
-@@ -2287,7 +2515,42 @@ static const u32 b43_ntab_tx_gain_rev4_5
- 	0x20d2003a, 0x20d20038, 0x20d20036, 0x20d20034,
- };
- 
--static const u32 b43_ntab_tx_gain_rev5plus_5ghz[] = {
-+static const u32 b43_ntab_tx_gain_epa_rev4_hi_pwr_5g[] = {
-+	0x2ff10044, 0x2ff10042, 0x2ff10040, 0x2ff1003e,
-+	0x2ff1003c, 0x2ff1003b, 0x2ff10039, 0x2ff10037,
-+	0x2ef10044, 0x2ef10042, 0x2ef10040, 0x2ef1003e,
-+	0x2ef1003c, 0x2ef1003b, 0x2ef10039, 0x2ef10037,
-+	0x2df10044, 0x2df10042, 0x2df10040, 0x2df1003e,
-+	0x2df1003c, 0x2df1003b, 0x2df10039, 0x2df10037,
-+	0x2cf10044, 0x2cf10042, 0x2cf10040, 0x2cf1003e,
-+	0x2cf1003c, 0x2cf1003b, 0x2cf10039, 0x2cf10037,
-+	0x2bf10044, 0x2bf10042, 0x2bf10040, 0x2bf1003e,
-+	0x2bf1003c, 0x2bf1003b, 0x2bf10039, 0x2bf10037,
-+	0x2af10044, 0x2af10042, 0x2af10040, 0x2af1003e,
-+	0x2af1003c, 0x2af1003b, 0x2af10039, 0x2af10037,
-+	0x29f10044, 0x29f10042, 0x29f10040, 0x29f1003e,
-+	0x29f1003c, 0x29f1003b, 0x29f10039, 0x29f10037,
-+	0x28f10044, 0x28f10042, 0x28f10040, 0x28f1003e,
-+	0x28f1003c, 0x28f1003b, 0x28f10039, 0x28f10037,
-+	0x27f10044, 0x27f10042, 0x27f10040, 0x27f1003e,
-+	0x27f1003c, 0x27f1003b, 0x27f10039, 0x27f10037,
-+	0x26f10044, 0x26f10042, 0x26f10040, 0x26f1003e,
-+	0x26f1003c, 0x26f1003b, 0x26f10039, 0x26f10037,
-+	0x25f10044, 0x25f10042, 0x25f10040, 0x25f1003e,
-+	0x25f1003c, 0x25f1003b, 0x25f10039, 0x25f10037,
-+	0x24f10044, 0x24f10042, 0x24f10040, 0x24f1003e,
-+	0x24f1003c, 0x24f1003b, 0x24f10039, 0x24f10038,
-+	0x23f10041, 0x23f10040, 0x23f1003f, 0x23f1003e,
-+	0x23f1003c, 0x23f1003b, 0x23f10039, 0x23f10037,
-+	0x22f10044, 0x22f10042, 0x22f10040, 0x22f1003e,
-+	0x22f1003c, 0x22f1003b, 0x22f10039, 0x22f10037,
-+	0x21f10044, 0x21f10042, 0x21f10040, 0x21f1003e,
-+	0x21f1003c, 0x21f1003b, 0x21f10039, 0x21f10037,
-+	0x20d10043, 0x20d10041, 0x20d1003e, 0x20d1003c,
-+	0x20d1003a, 0x20d10038, 0x20d10036, 0x20d10034
-+};
-+
-+static const u32 b43_ntab_tx_gain_epa_rev5_5g[] = {
- 	0x0f62004a, 0x0f620048, 0x0f620046, 0x0f620044,
- 	0x0f620042, 0x0f620040, 0x0f62003e, 0x0f62003c,
- 	0x0e620044, 0x0e620042, 0x0e620040, 0x0e62003e,
-@@ -2322,7 +2585,9 @@ static const u32 b43_ntab_tx_gain_rev5pl
- 	0x0062003b, 0x00620039, 0x00620037, 0x00620035,
- };
- 
--static const u32 txpwrctrl_tx_gain_ipa[] = {
-+/* IPA 2 GHz */
-+
-+static const u32 b43_ntab_tx_gain_ipa_rev3_2g[] = {
- 	0x5ff7002d, 0x5ff7002b, 0x5ff7002a, 0x5ff70029,
- 	0x5ff70028, 0x5ff70027, 0x5ff70026, 0x5ff70025,
- 	0x5ef7002d, 0x5ef7002b, 0x5ef7002a, 0x5ef70029,
-@@ -2357,7 +2622,7 @@ static const u32 txpwrctrl_tx_gain_ipa[]
- 	0x50f70028, 0x50f70027, 0x50f70026, 0x50f70025,
- };
- 
--static const u32 txpwrctrl_tx_gain_ipa_rev5[] = {
-+static const u32 b43_ntab_tx_gain_ipa_rev5_2g[] = {
- 	0x1ff7002d, 0x1ff7002b, 0x1ff7002a, 0x1ff70029,
- 	0x1ff70028, 0x1ff70027, 0x1ff70026, 0x1ff70025,
- 	0x1ef7002d, 0x1ef7002b, 0x1ef7002a, 0x1ef70029,
-@@ -2392,7 +2657,7 @@ static const u32 txpwrctrl_tx_gain_ipa_r
- 	0x10f70028, 0x10f70027, 0x10f70026, 0x10f70025,
- };
- 
--static const u32 txpwrctrl_tx_gain_ipa_rev6[] = {
-+static const u32 b43_ntab_tx_gain_ipa_rev6_2g[] = {
- 	0x0ff7002d, 0x0ff7002b, 0x0ff7002a, 0x0ff70029,
- 	0x0ff70028, 0x0ff70027, 0x0ff70026, 0x0ff70025,
- 	0x0ef7002d, 0x0ef7002b, 0x0ef7002a, 0x0ef70029,
-@@ -2427,7 +2692,117 @@ static const u32 txpwrctrl_tx_gain_ipa_r
- 	0x00f70028, 0x00f70027, 0x00f70026, 0x00f70025,
- };
- 
--static const u32 txpwrctrl_tx_gain_ipa_5g[] = {
-+/* Copied from brcmsmac (5.75.11): nphy_tpc_txgain_ipa_2g_2057rev5 */
-+static const u32 b43_ntab_tx_gain_ipa_2057_rev5_2g[] = {
-+	0x30ff0031, 0x30e70031, 0x30e7002e, 0x30cf002e,
-+	0x30bf002e, 0x30af002e, 0x309f002f, 0x307f0033,
-+	0x307f0031, 0x307f002e, 0x3077002e, 0x306f002e,
-+	0x3067002e, 0x305f002f, 0x30570030, 0x3057002d,
-+	0x304f002e, 0x30470031, 0x3047002e, 0x3047002c,
-+	0x30470029, 0x303f002c, 0x303f0029, 0x3037002d,
-+	0x3037002a, 0x30370028, 0x302f002c, 0x302f002a,
-+	0x302f0028, 0x302f0026, 0x3027002c, 0x30270029,
-+	0x30270027, 0x30270025, 0x30270023, 0x301f002c,
-+	0x301f002a, 0x301f0028, 0x301f0025, 0x301f0024,
-+	0x301f0022, 0x301f001f, 0x3017002d, 0x3017002b,
-+	0x30170028, 0x30170026, 0x30170024, 0x30170022,
-+	0x30170020, 0x3017001e, 0x3017001d, 0x3017001b,
-+	0x3017001a, 0x30170018, 0x30170017, 0x30170015,
-+	0x300f002c, 0x300f0029, 0x300f0027, 0x300f0024,
-+	0x300f0022, 0x300f0021, 0x300f001f, 0x300f001d,
-+	0x300f001b, 0x300f001a, 0x300f0018, 0x300f0017,
-+	0x300f0016, 0x300f0015, 0x300f0115, 0x300f0215,
-+	0x300f0315, 0x300f0415, 0x300f0515, 0x300f0615,
-+	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
-+	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
-+	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
-+	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
-+	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
-+	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
-+	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
-+	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
-+	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
-+	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
-+	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
-+	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
-+	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
-+};
-+
-+/* Extracted from MMIO dump of 6.30.223.141 */
-+static const u32 b43_ntab_tx_gain_ipa_2057_rev9_2g[] = {
-+	0x60ff0031, 0x60e7002c, 0x60cf002a, 0x60c70029,
-+	0x60b70029, 0x60a70029, 0x609f002a, 0x6097002b,
-+	0x6087002e, 0x60770031, 0x606f0032, 0x60670034,
-+	0x60670031, 0x605f0033, 0x605f0031, 0x60570033,
-+	0x60570030, 0x6057002d, 0x6057002b, 0x604f002d,
-+	0x604f002b, 0x604f0029, 0x604f0026, 0x60470029,
-+	0x60470027, 0x603f0029, 0x603f0027, 0x603f0025,
-+	0x60370029, 0x60370027, 0x60370024, 0x602f002a,
-+	0x602f0028, 0x602f0026, 0x602f0024, 0x6027002a,
-+	0x60270028, 0x60270026, 0x60270024, 0x60270022,
-+	0x601f002b, 0x601f0029, 0x601f0027, 0x601f0024,
-+	0x601f0022, 0x601f0020, 0x601f001f, 0x601f001d,
-+	0x60170029, 0x60170027, 0x60170025, 0x60170023,
-+	0x60170021, 0x6017001f, 0x6017001d, 0x6017001c,
-+	0x6017001a, 0x60170018, 0x60170018, 0x60170016,
-+	0x60170015, 0x600f0029, 0x600f0027, 0x600f0025,
-+	0x600f0023, 0x600f0021, 0x600f001f, 0x600f001d,
-+	0x600f001c, 0x600f001a, 0x600f0019, 0x600f0018,
-+	0x600f0016, 0x600f0015, 0x600f0115, 0x600f0215,
-+	0x600f0315, 0x600f0415, 0x600f0515, 0x600f0615,
-+	0x600f0715, 0x600f0715, 0x600f0715, 0x600f0715,
-+	0x600f0715, 0x600f0715, 0x600f0715, 0x600f0715,
-+	0x600f0715, 0x600f0715, 0x600f0715, 0x600f0715,
-+	0x600f0715, 0x600f0715, 0x600f0715, 0x600f0715,
-+	0x600f0715, 0x600f0715, 0x600f0715, 0x600f0715,
-+	0x600f0715, 0x600f0715, 0x600f0715, 0x600f0715,
-+	0x600f0715, 0x600f0715, 0x600f0715, 0x600f0715,
-+	0x600f0715, 0x600f0715, 0x600f0715, 0x600f0715,
-+	0x600f0715, 0x600f0715, 0x600f0715, 0x600f0715,
-+	0x600f0715, 0x600f0715, 0x600f0715, 0x600f0715,
-+	0x600f0715, 0x600f0715, 0x600f0715, 0x600f0715,
-+	0x600f0715, 0x600f0715, 0x600f0715, 0x600f0715,
-+};
-+
-+/* Extracted from MMIO dump of 6.30.223.248 */
-+static const u32 b43_ntab_tx_gain_ipa_2057_rev14_2g[] = {
-+	0x50df002e, 0x50cf002d, 0x50bf002c, 0x50b7002b,
-+	0x50af002a, 0x50a70029, 0x509f0029, 0x50970028,
-+	0x508f0027, 0x50870027, 0x507f0027, 0x50770027,
-+	0x506f0027, 0x50670027, 0x505f0028, 0x50570029,
-+	0x504f002b, 0x5047002e, 0x5047002b, 0x50470029,
-+	0x503f002c, 0x503f0029, 0x5037002c, 0x5037002a,
-+	0x50370028, 0x502f002d, 0x502f002b, 0x502f0028,
-+	0x502f0026, 0x5027002d, 0x5027002a, 0x50270028,
-+	0x50270026, 0x50270024, 0x501f002e, 0x501f002b,
-+	0x501f0029, 0x501f0027, 0x501f0024, 0x501f0022,
-+	0x501f0020, 0x501f001f, 0x5017002c, 0x50170029,
-+	0x50170027, 0x50170024, 0x50170022, 0x50170021,
-+	0x5017001f, 0x5017001d, 0x5017001b, 0x5017001a,
-+	0x50170018, 0x50170017, 0x50170015, 0x500f002c,
-+	0x500f002a, 0x500f0027, 0x500f0025, 0x500f0023,
-+	0x500f0022, 0x500f001f, 0x500f001e, 0x500f001c,
-+	0x500f001a, 0x500f0019, 0x500f0018, 0x500f0016,
-+	0x500f0015, 0x500f0015, 0x500f0015, 0x500f0015,
-+	0x500f0015, 0x500f0015, 0x500f0015, 0x500f0015,
-+	0x500f0015, 0x500f0015, 0x500f0015, 0x500f0015,
-+	0x500f0015, 0x500f0015, 0x500f0015, 0x500f0015,
-+	0x500f0015, 0x500f0015, 0x500f0015, 0x500f0015,
-+	0x500f0015, 0x500f0015, 0x500f0015, 0x500f0015,
-+	0x500f0015, 0x500f0015, 0x500f0015, 0x500f0015,
-+	0x500f0015, 0x500f0015, 0x500f0015, 0x500f0015,
-+	0x500f0015, 0x500f0015, 0x500f0015, 0x500f0015,
-+	0x500f0015, 0x500f0015, 0x500f0015, 0x500f0015,
-+	0x500f0015, 0x500f0015, 0x500f0015, 0x500f0015,
-+	0x500f0015, 0x500f0015, 0x500f0015, 0x500f0015,
-+	0x500f0015, 0x500f0015, 0x500f0015, 0x500f0015,
-+	0x500f0015, 0x500f0015, 0x500f0015, 0x500f0015,
-+	0x500f0015, 0x500f0015, 0x500f0015, 0x500f0015,
-+};
-+
-+/* IPA 2 5Hz */
-+
-+static const u32 b43_ntab_tx_gain_ipa_rev3_5g[] = {
- 	0x7ff70035, 0x7ff70033, 0x7ff70032, 0x7ff70031,
- 	0x7ff7002f, 0x7ff7002e, 0x7ff7002d, 0x7ff7002b,
- 	0x7ff7002a, 0x7ff70029, 0x7ff70028, 0x7ff70027,
-@@ -2462,6 +2837,42 @@ static const u32 txpwrctrl_tx_gain_ipa_5
- 	0x70f70021, 0x70f70020, 0x70f70020, 0x70f7001f,
- };
- 
-+/* Extracted from MMIO dump of 6.30.223.141 */
-+static const u32 b43_ntab_tx_gain_ipa_2057_rev9_5g[] = {
-+	0x7f7f0053, 0x7f7f004b, 0x7f7f0044, 0x7f7f003f,
-+	0x7f7f0039, 0x7f7f0035, 0x7f7f0032, 0x7f7f0030,
-+	0x7f7f002d, 0x7e7f0030, 0x7e7f002d, 0x7d7f0032,
-+	0x7d7f002f, 0x7d7f002c, 0x7c7f0032, 0x7c7f0030,
-+	0x7c7f002d, 0x7b7f0030, 0x7b7f002e, 0x7b7f002b,
-+	0x7a7f0032, 0x7a7f0030, 0x7a7f002d, 0x7a7f002b,
-+	0x797f0030, 0x797f002e, 0x797f002b, 0x797f0029,
-+	0x787f0030, 0x787f002d, 0x787f002b, 0x777f0032,
-+	0x777f0030, 0x777f002d, 0x777f002b, 0x767f0031,
-+	0x767f002f, 0x767f002c, 0x767f002a, 0x757f0031,
-+	0x757f002f, 0x757f002c, 0x757f002a, 0x747f0030,
-+	0x747f002d, 0x747f002b, 0x737f0032, 0x737f002f,
-+	0x737f002c, 0x737f002a, 0x727f0030, 0x727f002d,
-+	0x727f002b, 0x727f0029, 0x717f0030, 0x717f002d,
-+	0x717f002b, 0x707f0031, 0x707f002f, 0x707f002c,
-+	0x707f002a, 0x707f0027, 0x707f0025, 0x707f0023,
-+	0x707f0021, 0x707f001f, 0x707f001d, 0x707f001c,
-+	0x707f001a, 0x707f0019, 0x707f0017, 0x707f0016,
-+	0x707f0015, 0x707f0014, 0x707f0012, 0x707f0012,
-+	0x707f0011, 0x707f0010, 0x707f000f, 0x707f000e,
-+	0x707f000d, 0x707f000d, 0x707f000c, 0x707f000b,
-+	0x707f000a, 0x707f000a, 0x707f0009, 0x707f0008,
-+	0x707f0008, 0x707f0008, 0x707f0008, 0x707f0007,
-+	0x707f0007, 0x707f0006, 0x707f0006, 0x707f0006,
-+	0x707f0005, 0x707f0005, 0x707f0005, 0x707f0004,
-+	0x707f0004, 0x707f0004, 0x707f0003, 0x707f0003,
-+	0x707f0003, 0x707f0003, 0x707f0003, 0x707f0003,
-+	0x707f0003, 0x707f0003, 0x707f0003, 0x707f0003,
-+	0x707f0002, 0x707f0002, 0x707f0002, 0x707f0002,
-+	0x707f0002, 0x707f0002, 0x707f0002, 0x707f0002,
-+	0x707f0002, 0x707f0001, 0x707f0001, 0x707f0001,
-+	0x707f0001, 0x707f0001, 0x707f0001, 0x707f0001,
-+};
-+
- const s8 b43_ntab_papd_pga_gain_delta_ipa_2g[] = {
- 	-114, -108, -98, -91, -84, -78, -70, -62,
- 	-54, -46, -39, -31, -23, -15, -8, 0
-@@ -2698,11 +3109,11 @@ static const struct nphy_rf_control_over
- 	{ 0x0010, 0x07A, 0x07D, 0x0010, 4 },
- 	{ 0x0020, 0x07A, 0x07D, 0x0020, 5 },
- 	{ 0x0040, 0x07A, 0x07D, 0x0040, 6 },
--	{ 0x0080, 0x0F8, 0x0FA, 0x0080, 7 },
-+	{ 0x0080, 0x07A, 0x07D, 0x0080, 7 },
- 	{ 0x0400, 0x0F8, 0x0FA, 0x0070, 4 },
- 	{ 0x0800, 0x07B, 0x07E, 0xFFFF, 0 },
- 	{ 0x1000, 0x07C, 0x07F, 0xFFFF, 0 },
--	{ 0x6000, 0x348, 0x349, 0xFFFF, 0 },
-+	{ 0x6000, 0x348, 0x349, 0x00FF, 0 },
- 	{ 0x2000, 0x348, 0x349, 0x000F, 0 },
- };
- 
-@@ -3031,31 +3442,8 @@ void b43_ntab_write_bulk(struct b43_wlde
- 		b43_ntab_write_bulk(dev, offset, ARRAY_SIZE(data), data); \
- 	} while (0)
- 
--static void b43_nphy_tables_init_rev3(struct b43_wldev *dev)
-+static void b43_nphy_tables_init_shared_lut(struct b43_wldev *dev)
- {
--	struct ssb_sprom *sprom = dev->dev->bus_sprom;
--	u8 antswlut;
--
--	if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ)
--		antswlut = sprom->fem.ghz5.antswlut;
--	else
--		antswlut = sprom->fem.ghz2.antswlut;
--
--	/* Static tables */
--	ntab_upload(dev, B43_NTAB_FRAMESTRUCT_R3, b43_ntab_framestruct_r3);
--	ntab_upload(dev, B43_NTAB_PILOT_R3, b43_ntab_pilot_r3);
--	ntab_upload(dev, B43_NTAB_TMAP_R3, b43_ntab_tmap_r3);
--	ntab_upload(dev, B43_NTAB_INTLEVEL_R3, b43_ntab_intlevel_r3);
--	ntab_upload(dev, B43_NTAB_TDTRN_R3, b43_ntab_tdtrn_r3);
--	ntab_upload(dev, B43_NTAB_NOISEVAR_R3, b43_ntab_noisevar_r3);
--	ntab_upload(dev, B43_NTAB_MCS_R3, b43_ntab_mcs_r3);
--	ntab_upload(dev, B43_NTAB_TDI20A0_R3, b43_ntab_tdi20a0_r3);
--	ntab_upload(dev, B43_NTAB_TDI20A1_R3, b43_ntab_tdi20a1_r3);
--	ntab_upload(dev, B43_NTAB_TDI40A0_R3, b43_ntab_tdi40a0_r3);
--	ntab_upload(dev, B43_NTAB_TDI40A1_R3, b43_ntab_tdi40a1_r3);
--	ntab_upload(dev, B43_NTAB_PILOTLT_R3, b43_ntab_pilotlt_r3);
--	ntab_upload(dev, B43_NTAB_CHANEST_R3, b43_ntab_channelest_r3);
--	ntab_upload(dev, B43_NTAB_FRAMELT_R3, b43_ntab_framelookup_r3);
- 	ntab_upload(dev, B43_NTAB_C0_ESTPLT_R3, b43_ntab_estimatepowerlt0_r3);
- 	ntab_upload(dev, B43_NTAB_C1_ESTPLT_R3, b43_ntab_estimatepowerlt1_r3);
- 	ntab_upload(dev, B43_NTAB_C0_ADJPLT_R3, b43_ntab_adjustpower0_r3);
-@@ -3066,6 +3454,107 @@ static void b43_nphy_tables_init_rev3(st
- 	ntab_upload(dev, B43_NTAB_C1_IQLT_R3, b43_ntab_iqlt1_r3);
- 	ntab_upload(dev, B43_NTAB_C0_LOFEEDTH_R3, b43_ntab_loftlt0_r3);
- 	ntab_upload(dev, B43_NTAB_C1_LOFEEDTH_R3, b43_ntab_loftlt1_r3);
-+}
-+
-+static void b43_nphy_tables_init_rev7_volatile(struct b43_wldev *dev)
-+{
-+	struct ssb_sprom *sprom = dev->dev->bus_sprom;
-+	u8 antswlut;
-+	int core, offset, i;
-+
-+	const int antswlut0_offsets[] = { 0, 4, 8, }; /* Offsets for values */
-+	const u8 antswlut0_values[][3] = {
-+		{ 0x2, 0x12, 0x8 }, /* Core 0 */
-+		{ 0x2, 0x18, 0x2 }, /* Core 1 */
-+	};
-+
-+	if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ)
-+		antswlut = sprom->fem.ghz5.antswlut;
-+	else
-+		antswlut = sprom->fem.ghz2.antswlut;
-+
-+	switch (antswlut) {
-+	case 0:
-+		for (core = 0; core < 2; core++) {
-+			for (i = 0; i < ARRAY_SIZE(antswlut0_values[0]); i++) {
-+				offset = core ? 0x20 : 0x00;
-+				offset += antswlut0_offsets[i];
-+				b43_ntab_write(dev, B43_NTAB8(9, offset),
-+					       antswlut0_values[core][i]);
-+			}
-+		}
-+		break;
-+	default:
-+		b43err(dev->wl, "Unsupported antswlut: %d\n", antswlut);
-+		break;
-+	}
-+}
-+
-+static void b43_nphy_tables_init_rev16(struct b43_wldev *dev)
-+{
-+	/* Static tables */
-+	if (dev->phy.do_full_init) {
-+		ntab_upload(dev, B43_NTAB_NOISEVAR_R7, b43_ntab_noisevar_r7);
-+		b43_nphy_tables_init_shared_lut(dev);
-+	}
-+
-+	/* Volatile tables */
-+	b43_nphy_tables_init_rev7_volatile(dev);
-+}
-+
-+static void b43_nphy_tables_init_rev7(struct b43_wldev *dev)
-+{
-+	/* Static tables */
-+	if (dev->phy.do_full_init) {
-+		ntab_upload(dev, B43_NTAB_FRAMESTRUCT_R3, b43_ntab_framestruct_r3);
-+		ntab_upload(dev, B43_NTAB_PILOT_R3, b43_ntab_pilot_r3);
-+		ntab_upload(dev, B43_NTAB_TMAP_R7, b43_ntab_tmap_r7);
-+		ntab_upload(dev, B43_NTAB_INTLEVEL_R3, b43_ntab_intlevel_r3);
-+		ntab_upload(dev, B43_NTAB_TDTRN_R3, b43_ntab_tdtrn_r3);
-+		ntab_upload(dev, B43_NTAB_NOISEVAR_R7, b43_ntab_noisevar_r7);
-+		ntab_upload(dev, B43_NTAB_MCS_R3, b43_ntab_mcs_r3);
-+		ntab_upload(dev, B43_NTAB_TDI20A0_R3, b43_ntab_tdi20a0_r3);
-+		ntab_upload(dev, B43_NTAB_TDI20A1_R3, b43_ntab_tdi20a1_r3);
-+		ntab_upload(dev, B43_NTAB_TDI40A0_R3, b43_ntab_tdi40a0_r3);
-+		ntab_upload(dev, B43_NTAB_TDI40A1_R3, b43_ntab_tdi40a1_r3);
-+		ntab_upload(dev, B43_NTAB_PILOTLT_R3, b43_ntab_pilotlt_r3);
-+		ntab_upload(dev, B43_NTAB_CHANEST_R3, b43_ntab_channelest_r3);
-+		ntab_upload(dev, B43_NTAB_FRAMELT_R3, b43_ntab_framelookup_r3);
-+		b43_nphy_tables_init_shared_lut(dev);
-+	}
-+
-+	/* Volatile tables */
-+	b43_nphy_tables_init_rev7_volatile(dev);
-+}
-+
-+static void b43_nphy_tables_init_rev3(struct b43_wldev *dev)
-+{
-+	struct ssb_sprom *sprom = dev->dev->bus_sprom;
-+	u8 antswlut;
-+
-+	if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ)
-+		antswlut = sprom->fem.ghz5.antswlut;
-+	else
-+		antswlut = sprom->fem.ghz2.antswlut;
-+
-+	/* Static tables */
-+	if (dev->phy.do_full_init) {
-+		ntab_upload(dev, B43_NTAB_FRAMESTRUCT_R3, b43_ntab_framestruct_r3);
-+		ntab_upload(dev, B43_NTAB_PILOT_R3, b43_ntab_pilot_r3);
-+		ntab_upload(dev, B43_NTAB_TMAP_R3, b43_ntab_tmap_r3);
-+		ntab_upload(dev, B43_NTAB_INTLEVEL_R3, b43_ntab_intlevel_r3);
-+		ntab_upload(dev, B43_NTAB_TDTRN_R3, b43_ntab_tdtrn_r3);
-+		ntab_upload(dev, B43_NTAB_NOISEVAR_R3, b43_ntab_noisevar_r3);
-+		ntab_upload(dev, B43_NTAB_MCS_R3, b43_ntab_mcs_r3);
-+		ntab_upload(dev, B43_NTAB_TDI20A0_R3, b43_ntab_tdi20a0_r3);
-+		ntab_upload(dev, B43_NTAB_TDI20A1_R3, b43_ntab_tdi20a1_r3);
-+		ntab_upload(dev, B43_NTAB_TDI40A0_R3, b43_ntab_tdi40a0_r3);
-+		ntab_upload(dev, B43_NTAB_TDI40A1_R3, b43_ntab_tdi40a1_r3);
-+		ntab_upload(dev, B43_NTAB_PILOTLT_R3, b43_ntab_pilotlt_r3);
-+		ntab_upload(dev, B43_NTAB_CHANEST_R3, b43_ntab_channelest_r3);
-+		ntab_upload(dev, B43_NTAB_FRAMELT_R3, b43_ntab_framelookup_r3);
-+		b43_nphy_tables_init_shared_lut(dev);
-+	}
- 
- 	/* Volatile tables */
- 	if (antswlut < ARRAY_SIZE(b43_ntab_antswctl_r3))
-@@ -3078,20 +3567,22 @@ static void b43_nphy_tables_init_rev3(st
- static void b43_nphy_tables_init_rev0(struct b43_wldev *dev)
- {
- 	/* Static tables */
--	ntab_upload(dev, B43_NTAB_FRAMESTRUCT, b43_ntab_framestruct);
--	ntab_upload(dev, B43_NTAB_FRAMELT, b43_ntab_framelookup);
--	ntab_upload(dev, B43_NTAB_TMAP, b43_ntab_tmap);
--	ntab_upload(dev, B43_NTAB_TDTRN, b43_ntab_tdtrn);
--	ntab_upload(dev, B43_NTAB_INTLEVEL, b43_ntab_intlevel);
--	ntab_upload(dev, B43_NTAB_PILOT, b43_ntab_pilot);
--	ntab_upload(dev, B43_NTAB_TDI20A0, b43_ntab_tdi20a0);
--	ntab_upload(dev, B43_NTAB_TDI20A1, b43_ntab_tdi20a1);
--	ntab_upload(dev, B43_NTAB_TDI40A0, b43_ntab_tdi40a0);
--	ntab_upload(dev, B43_NTAB_TDI40A1, b43_ntab_tdi40a1);
--	ntab_upload(dev, B43_NTAB_CHANEST, b43_ntab_channelest);
--	ntab_upload(dev, B43_NTAB_MCS, b43_ntab_mcs);
--	ntab_upload(dev, B43_NTAB_NOISEVAR10, b43_ntab_noisevar10);
--	ntab_upload(dev, B43_NTAB_NOISEVAR11, b43_ntab_noisevar11);
-+	if (dev->phy.do_full_init) {
-+		ntab_upload(dev, B43_NTAB_FRAMESTRUCT, b43_ntab_framestruct);
-+		ntab_upload(dev, B43_NTAB_FRAMELT, b43_ntab_framelookup);
-+		ntab_upload(dev, B43_NTAB_TMAP, b43_ntab_tmap);
-+		ntab_upload(dev, B43_NTAB_TDTRN, b43_ntab_tdtrn);
-+		ntab_upload(dev, B43_NTAB_INTLEVEL, b43_ntab_intlevel);
-+		ntab_upload(dev, B43_NTAB_PILOT, b43_ntab_pilot);
-+		ntab_upload(dev, B43_NTAB_TDI20A0, b43_ntab_tdi20a0);
-+		ntab_upload(dev, B43_NTAB_TDI20A1, b43_ntab_tdi20a1);
-+		ntab_upload(dev, B43_NTAB_TDI40A0, b43_ntab_tdi40a0);
-+		ntab_upload(dev, B43_NTAB_TDI40A1, b43_ntab_tdi40a1);
-+		ntab_upload(dev, B43_NTAB_CHANEST, b43_ntab_channelest);
-+		ntab_upload(dev, B43_NTAB_MCS, b43_ntab_mcs);
-+		ntab_upload(dev, B43_NTAB_NOISEVAR10, b43_ntab_noisevar10);
-+		ntab_upload(dev, B43_NTAB_NOISEVAR11, b43_ntab_noisevar11);
-+	}
- 
- 	/* Volatile tables */
- 	ntab_upload(dev, B43_NTAB_BDI, b43_ntab_bdi);
-@@ -3111,7 +3602,11 @@ static void b43_nphy_tables_init_rev0(st
- /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/InitTables */
- void b43_nphy_tables_init(struct b43_wldev *dev)
- {
--	if (dev->phy.rev >= 3)
-+	if (dev->phy.rev >= 16)
-+		b43_nphy_tables_init_rev16(dev);
-+	else if (dev->phy.rev >= 7)
-+		b43_nphy_tables_init_rev7(dev);
-+	else if (dev->phy.rev >= 3)
- 		b43_nphy_tables_init_rev3(dev);
- 	else
- 		b43_nphy_tables_init_rev0(dev);
-@@ -3120,23 +3615,55 @@ void b43_nphy_tables_init(struct b43_wld
- /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/GetIpaGainTbl */
- static const u32 *b43_nphy_get_ipa_gain_table(struct b43_wldev *dev)
- {
-+	struct b43_phy *phy = &dev->phy;
-+
- 	if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
--		if (dev->phy.rev >= 6) {
--			if (dev->dev->chip_id == 47162)
--				return txpwrctrl_tx_gain_ipa_rev5;
--			return txpwrctrl_tx_gain_ipa_rev6;
--		} else if (dev->phy.rev >= 5) {
--			return txpwrctrl_tx_gain_ipa_rev5;
--		} else {
--			return txpwrctrl_tx_gain_ipa;
-+		switch (phy->rev) {
-+		case 17:
-+			if (phy->radio_rev == 14)
-+				return b43_ntab_tx_gain_ipa_2057_rev14_2g;
-+			break;
-+		case 16:
-+			if (phy->radio_rev == 9)
-+				return b43_ntab_tx_gain_ipa_2057_rev9_2g;
-+			break;
-+		case 8:
-+			if (phy->radio_rev == 5)
-+				return b43_ntab_tx_gain_ipa_2057_rev5_2g;
-+			break;
-+		case 6:
-+			if (dev->dev->chip_id == BCMA_CHIP_ID_BCM47162)
-+				return b43_ntab_tx_gain_ipa_rev5_2g;
-+			return b43_ntab_tx_gain_ipa_rev6_2g;
-+		case 5:
-+			return b43_ntab_tx_gain_ipa_rev5_2g;
-+		case 4:
-+		case 3:
-+			return b43_ntab_tx_gain_ipa_rev3_2g;
- 		}
-+
-+		b43err(dev->wl,
-+		       "No 2GHz IPA gain table available for this device\n");
-+		return NULL;
- 	} else {
--		return txpwrctrl_tx_gain_ipa_5g;
-+		switch (phy->rev) {
-+		case 16:
-+			if (phy->radio_rev == 9)
-+				return b43_ntab_tx_gain_ipa_2057_rev9_5g;
-+			break;
-+		case 3 ... 6:
-+			return b43_ntab_tx_gain_ipa_rev3_5g;
-+		}
-+
-+		b43err(dev->wl,
-+		       "No 5GHz IPA gain table available for this device\n");
-+		return NULL;
- 	}
- }
- 
- const u32 *b43_nphy_get_tx_gain_table(struct b43_wldev *dev)
- {
-+	struct b43_phy *phy = &dev->phy;
- 	enum ieee80211_band band = b43_current_band(dev->wl);
- 	struct ssb_sprom *sprom = dev->dev->bus_sprom;
- 
-@@ -3148,19 +3675,36 @@ const u32 *b43_nphy_get_tx_gain_table(st
- 	    (dev->phy.n->ipa5g_on && band == IEEE80211_BAND_5GHZ)) {
- 		return b43_nphy_get_ipa_gain_table(dev);
- 	} else if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) {
--		if (dev->phy.rev == 3)
--			return b43_ntab_tx_gain_rev3_5ghz;
--		if (dev->phy.rev == 4)
-+		switch (phy->rev) {
-+		case 6:
-+		case 5:
-+			return b43_ntab_tx_gain_epa_rev5_5g;
-+		case 4:
- 			return sprom->fem.ghz5.extpa_gain == 3 ?
--				b43_ntab_tx_gain_rev4_5ghz :
--				b43_ntab_tx_gain_rev4_5ghz; /* FIXME */
--		else
--			return b43_ntab_tx_gain_rev5plus_5ghz;
-+				b43_ntab_tx_gain_epa_rev4_5g :
-+				b43_ntab_tx_gain_epa_rev4_hi_pwr_5g;
-+		case 3:
-+			return b43_ntab_tx_gain_epa_rev3_5g;
-+		default:
-+			b43err(dev->wl,
-+			       "No 5GHz EPA gain table available for this device\n");
-+			return NULL;
-+		}
- 	} else {
--		if (dev->phy.rev >= 5 && sprom->fem.ghz5.extpa_gain == 3)
--			return b43_ntab_tx_gain_rev3plus_2ghz; /* FIXME */
--		else
--			return b43_ntab_tx_gain_rev3plus_2ghz;
-+		switch (phy->rev) {
-+		case 6:
-+		case 5:
-+			if (sprom->fem.ghz5.extpa_gain == 3)
-+				return b43_ntab_tx_gain_epa_rev3_hi_pwr_2g;
-+			/* fall through */
-+		case 4:
-+		case 3:
-+			return b43_ntab_tx_gain_epa_rev3_2g;
-+		default:
-+			b43err(dev->wl,
-+			       "No 2GHz EPA gain table available for this device\n");
-+			return NULL;
-+		}
- 	}
- }
- 
-@@ -3187,7 +3731,7 @@ struct nphy_gain_ctl_workaround_entry *b
- 	/* Some workarounds to the workarounds... */
- 	if (ghz5 && dev->phy.rev >= 6) {
- 		if (dev->phy.radio_rev == 11 &&
--		    !b43_channel_type_is_40mhz(dev->phy.channel_type))
-+		    !b43_is_40mhz(dev))
- 			e->cliplo_gain = 0x2d;
- 	} else if (!ghz5 && dev->phy.rev >= 5) {
- 		static const int gain_data[] = {0x0062, 0x0064, 0x006a, 0x106a,
---- a/drivers/net/wireless/b43/Kconfig
-+++ b/drivers/net/wireless/b43/Kconfig
-@@ -37,7 +37,7 @@ config B43_SSB
- choice
- 	prompt "Supported bus types"
- 	depends on B43
--	default B43_BCMA_AND_SSB
-+	default B43_BUSES_BCMA_AND_SSB
- 
- config B43_BUSES_BCMA_AND_SSB
- 	bool "BCMA and SSB"
-@@ -123,6 +123,15 @@ config B43_PIO
- 	select SSB_BLOCKIO
- 	default y
- 
-+config B43_PHY_G
-+	bool "Support for G-PHY (802.11g) devices"
-+	depends on B43 && B43_SSB
-+	default y
-+	---help---
-+	  This PHY type can be found in the following chipsets:
-+	  PCI: BCM4306, BCM4311, BCM4318
-+	  SoC: BCM4712, BCM5352E
-+
- config B43_PHY_N
- 	bool "Support for 802.11n (N-PHY) devices"
- 	depends on B43
---- a/drivers/net/wireless/b43/phy_ht.c
-+++ b/drivers/net/wireless/b43/phy_ht.c
-@@ -596,7 +596,7 @@ static void b43_phy_ht_tx_power_ctl_setu
- 	u8 target[3];
- 	s16 a1[3], b0[3], b1[3];
- 
--	u16 freq = dev->phy.channel_freq;
-+	u16 freq = dev->phy.chandef->chan->center_freq;
- 	int i, c;
- 
- 	if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
---- a/drivers/net/wireless/b43/phy_a.h
-+++ b/drivers/net/wireless/b43/phy_a.h
-@@ -123,8 +123,4 @@ struct b43_phy_a {
-  */
- void b43_phy_inita(struct b43_wldev *dev);
- 
--
--struct b43_phy_operations;
--extern const struct b43_phy_operations b43_phyops_a;
--
- #endif /* LINUX_B43_PHY_A_H_ */
---- a/drivers/net/wireless/b43/Makefile
-+++ b/drivers/net/wireless/b43/Makefile
-@@ -1,13 +1,11 @@
- b43-y				+= main.o
- b43-y				+= bus.o
--b43-y				+= tables.o
-+b43-$(CPTCFG_B43_PHY_G)		+= phy_a.o phy_g.o tables.o lo.o wa.o
- b43-$(CPTCFG_B43_PHY_N)		+= tables_nphy.o
- b43-$(CPTCFG_B43_PHY_N)		+= radio_2055.o
- b43-$(CPTCFG_B43_PHY_N)		+= radio_2056.o
- b43-$(CPTCFG_B43_PHY_N)		+= radio_2057.o
- b43-y				+= phy_common.o
--b43-y				+= phy_g.o
--b43-y				+= phy_a.o
- b43-$(CPTCFG_B43_PHY_N)		+= phy_n.o
- b43-$(CPTCFG_B43_PHY_LP)	+= phy_lp.o
- b43-$(CPTCFG_B43_PHY_LP)	+= tables_lpphy.o
-@@ -17,8 +15,6 @@ b43-$(CPTCFG_B43_PHY_HT)	+= radio_2059.o
- b43-$(CPTCFG_B43_PHY_LCN)	+= phy_lcn.o tables_phy_lcn.o
- b43-y				+= sysfs.o
- b43-y				+= xmit.o
--b43-y				+= lo.o
--b43-y				+= wa.o
- b43-y				+= dma.o
- b43-y				+= pio.o
- b43-y				+= rfkill.o
---- a/drivers/net/wireless/b43/phy_a.c
-+++ b/drivers/net/wireless/b43/phy_a.c
-@@ -573,7 +573,7 @@ static void b43_aphy_op_pwork_60sec(stru
- {//TODO
- }
- 
--const struct b43_phy_operations b43_phyops_a = {
-+static const struct b43_phy_operations b43_phyops_a = {
- 	.allocate		= b43_aphy_op_allocate,
- 	.free			= b43_aphy_op_free,
- 	.prepare_structs	= b43_aphy_op_prepare_structs,
---- a/drivers/net/wireless/b43/radio_2057.c
-+++ b/drivers/net/wireless/b43/radio_2057.c
-@@ -26,7 +26,7 @@
- #include "radio_2057.h"
- #include "phy_common.h"
- 
--static u16 r2057_rev4_init[42][2] = {
-+static u16 r2057_rev4_init[][2] = {
- 	{ 0x0E, 0x20 }, { 0x31, 0x00 }, { 0x32, 0x00 }, { 0x33, 0x00 },
- 	{ 0x35, 0x26 }, { 0x3C, 0xff }, { 0x3D, 0xff }, { 0x3E, 0xff },
- 	{ 0x3F, 0xff }, { 0x62, 0x33 }, { 0x8A, 0xf0 }, { 0x8B, 0x10 },
-@@ -40,7 +40,7 @@ static u16 r2057_rev4_init[42][2] = {
- 	{ 0x1AB, 0x00 }, { 0x1AC, 0x00 },
- };
- 
--static u16 r2057_rev5_init[44][2] = {
-+static u16 r2057_rev5_init[][2] = {
- 	{ 0x00, 0x00 }, { 0x01, 0x57 }, { 0x02, 0x20 }, { 0x23, 0x6 },
- 	{ 0x31, 0x00 }, { 0x32, 0x00 }, { 0x33, 0x00 }, { 0x51, 0x70 },
- 	{ 0x59, 0x88 }, { 0x5C, 0x20 }, { 0x62, 0x33 }, { 0x63, 0x0f },
-@@ -54,7 +54,7 @@ static u16 r2057_rev5_init[44][2] = {
- 	{ 0x1AC, 0x00 }, { 0x1B7, 0x0c }, { 0x1C1, 0x01 }, { 0x1C2, 0x80 },
- };
- 
--static u16 r2057_rev5a_init[45][2] = {
-+static u16 r2057_rev5a_init[][2] = {
- 	{ 0x00, 0x15 }, { 0x01, 0x57 }, { 0x02, 0x20 }, { 0x23, 0x6 },
- 	{ 0x31, 0x00 }, { 0x32, 0x00 }, { 0x33, 0x00 }, { 0x51, 0x70 },
- 	{ 0x59, 0x88 }, { 0x5C, 0x20 }, { 0x62, 0x33 }, { 0x63, 0x0f },
-@@ -69,7 +69,7 @@ static u16 r2057_rev5a_init[45][2] = {
- 	{ 0x1C2, 0x80 },
- };
- 
--static u16 r2057_rev7_init[54][2] = {
-+static u16 r2057_rev7_init[][2] = {
- 	{ 0x00, 0x00 }, { 0x01, 0x57 }, { 0x02, 0x20 }, { 0x31, 0x00 },
- 	{ 0x32, 0x00 }, { 0x33, 0x00 }, { 0x51, 0x70 }, { 0x59, 0x88 },
- 	{ 0x5C, 0x20 }, { 0x62, 0x33 }, { 0x63, 0x0f }, { 0x64, 0x13 },
-@@ -86,7 +86,8 @@ static u16 r2057_rev7_init[54][2] = {
- 	{ 0x1B7, 0x05 }, { 0x1C2, 0xa0 },
- };
- 
--static u16 r2057_rev8_init[54][2] = {
-+/* TODO: Which devices should use it?
-+static u16 r2057_rev8_init[][2] = {
- 	{ 0x00, 0x08 }, { 0x01, 0x57 }, { 0x02, 0x20 }, { 0x31, 0x00 },
- 	{ 0x32, 0x00 }, { 0x33, 0x00 }, { 0x51, 0x70 }, { 0x59, 0x88 },
- 	{ 0x5C, 0x20 }, { 0x62, 0x33 }, { 0x63, 0x0f }, { 0x64, 0x0f },
-@@ -102,6 +103,436 @@ static u16 r2057_rev8_init[54][2] = {
- 	{ 0x1A6, 0x00 }, { 0x1AA, 0x00 }, { 0x1AB, 0x00 }, { 0x1AC, 0x00 },
- 	{ 0x1B7, 0x05 }, { 0x1C2, 0xa0 },
- };
-+*/
-+
-+/* Extracted from MMIO dump of 6.30.223.141 */
-+static u16 r2057_rev9_init[][2] = {
-+	{ 0x27, 0x1f }, { 0x28, 0x0a }, { 0x29, 0x2f }, { 0x42, 0x1f },
-+	{ 0x48, 0x3f }, { 0x5c, 0x41 }, { 0x63, 0x14 }, { 0x64, 0x12 },
-+	{ 0x66, 0xff }, { 0x74, 0xa3 }, { 0x7b, 0x14 }, { 0x7c, 0x14 },
-+	{ 0x7d, 0xee }, { 0x86, 0xc0 }, { 0xc4, 0x10 }, { 0xc9, 0x01 },
-+	{ 0xe1, 0x41 }, { 0xe8, 0x14 }, { 0xe9, 0x12 }, { 0xeb, 0xff },
-+	{ 0xf5, 0x0a }, { 0xf8, 0x09 }, { 0xf9, 0xa3 }, { 0x100, 0x14 },
-+	{ 0x101, 0x10 }, { 0x102, 0xee }, { 0x10b, 0xc0 }, { 0x149, 0x10 },
-+	{ 0x14e, 0x01 }, { 0x1b7, 0x05 }, { 0x1c2, 0xa0 },
-+};
-+
-+/* Extracted from MMIO dump of 6.30.223.248 */
-+static u16 r2057_rev14_init[][2] = {
-+	{ 0x011, 0xfc }, { 0x030, 0x24 }, { 0x040, 0x1c }, { 0x082, 0x08 },
-+	{ 0x0b4, 0x44 }, { 0x0c8, 0x01 }, { 0x0c9, 0x01 }, { 0x107, 0x08 },
-+	{ 0x14d, 0x01 }, { 0x14e, 0x01 }, { 0x1af, 0x40 }, { 0x1b0, 0x40 },
-+	{ 0x1cc, 0x01 }, { 0x1cf, 0x10 }, { 0x1d0, 0x0f }, { 0x1d3, 0x10 },
-+	{ 0x1d4, 0x0f },
-+};
-+
-+#define RADIOREGS7(r00, r01, r02, r03, r04, r05, r06, r07, r08, r09, \
-+		   r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, \
-+		   r20, r21, r22, r23, r24, r25, r26, r27) \
-+	.radio_vcocal_countval0			= r00,	\
-+	.radio_vcocal_countval1			= r01,	\
-+	.radio_rfpll_refmaster_sparextalsize	= r02,	\
-+	.radio_rfpll_loopfilter_r1		= r03,	\
-+	.radio_rfpll_loopfilter_c2		= r04,	\
-+	.radio_rfpll_loopfilter_c1		= r05,	\
-+	.radio_cp_kpd_idac			= r06,	\
-+	.radio_rfpll_mmd0			= r07,	\
-+	.radio_rfpll_mmd1			= r08,	\
-+	.radio_vcobuf_tune			= r09,	\
-+	.radio_logen_mx2g_tune			= r10,	\
-+	.radio_logen_mx5g_tune			= r11,	\
-+	.radio_logen_indbuf2g_tune		= r12,	\
-+	.radio_logen_indbuf5g_tune		= r13,	\
-+	.radio_txmix2g_tune_boost_pu_core0	= r14,	\
-+	.radio_pad2g_tune_pus_core0		= r15,	\
-+	.radio_pga_boost_tune_core0		= r16,	\
-+	.radio_txmix5g_boost_tune_core0		= r17,	\
-+	.radio_pad5g_tune_misc_pus_core0	= r18,	\
-+	.radio_lna2g_tune_core0			= r19,	\
-+	.radio_lna5g_tune_core0			= r20,	\
-+	.radio_txmix2g_tune_boost_pu_core1	= r21,	\
-+	.radio_pad2g_tune_pus_core1		= r22,	\
-+	.radio_pga_boost_tune_core1		= r23,	\
-+	.radio_txmix5g_boost_tune_core1		= r24,	\
-+	.radio_pad5g_tune_misc_pus_core1	= r25,	\
-+	.radio_lna2g_tune_core1			= r26,	\
-+	.radio_lna5g_tune_core1			= r27
-+
-+#define RADIOREGS7_2G(r00, r01, r02, r03, r04, r05, r06, r07, r08, r09, \
-+		      r10, r11, r12, r13, r14, r15, r16, r17) \
-+	.radio_vcocal_countval0			= r00,	\
-+	.radio_vcocal_countval1			= r01,	\
-+	.radio_rfpll_refmaster_sparextalsize	= r02,	\
-+	.radio_rfpll_loopfilter_r1		= r03,	\
-+	.radio_rfpll_loopfilter_c2		= r04,	\
-+	.radio_rfpll_loopfilter_c1		= r05,	\
-+	.radio_cp_kpd_idac			= r06,	\
-+	.radio_rfpll_mmd0			= r07,	\
-+	.radio_rfpll_mmd1			= r08,	\
-+	.radio_vcobuf_tune			= r09,	\
-+	.radio_logen_mx2g_tune			= r10,	\
-+	.radio_logen_indbuf2g_tune		= r11,	\
-+	.radio_txmix2g_tune_boost_pu_core0	= r12,	\
-+	.radio_pad2g_tune_pus_core0		= r13,	\
-+	.radio_lna2g_tune_core0			= r14,	\
-+	.radio_txmix2g_tune_boost_pu_core1	= r15,	\
-+	.radio_pad2g_tune_pus_core1		= r16,	\
-+	.radio_lna2g_tune_core1			= r17
-+
-+#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
-+
-+/* Copied from brcmsmac (5.75.11): chan_info_nphyrev8_2057_rev5 */
-+static const struct b43_nphy_chantabent_rev7_2g b43_nphy_chantab_phy_rev8_radio_rev5[] = {
-+	{
-+		.freq			= 2412,
-+		RADIOREGS7_2G(0x48, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x6c,
-+			      0x09, 0x0d, 0x08, 0x0e, 0x61, 0x03, 0xff, 0x61,
-+			      0x03, 0xff),
-+		PHYREGS(0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443),
-+	},
-+	{
-+		.freq			= 2417,
-+		RADIOREGS7_2G(0x4b, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x71,
-+			      0x09, 0x0d, 0x08, 0x0e, 0x61, 0x03, 0xff, 0x61,
-+			      0x03, 0xff),
-+		PHYREGS(0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441),
-+	},
-+	{
-+		.freq			= 2422,
-+		RADIOREGS7_2G(0x4e, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x76,
-+			      0x09, 0x0d, 0x08, 0x0e, 0x61, 0x03, 0xef, 0x61,
-+			      0x03, 0xef),
-+		PHYREGS(0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f),
-+	},
-+	{
-+		.freq			= 2427,
-+		RADIOREGS7_2G(0x52, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x7b,
-+			      0x09, 0x0c, 0x08, 0x0e, 0x61, 0x03, 0xdf, 0x61,
-+			      0x03, 0xdf),
-+		PHYREGS(0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d),
-+	},
-+	{
-+		.freq			= 2432,
-+		RADIOREGS7_2G(0x55, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x80,
-+			      0x09, 0x0c, 0x07, 0x0d, 0x61, 0x03, 0xcf, 0x61,
-+			      0x03, 0xcf),
-+		PHYREGS(0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a),
-+	},
-+	{
-+		.freq			= 2437,
-+		RADIOREGS7_2G(0x58, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x85,
-+			      0x09, 0x0c, 0x07, 0x0d, 0x61, 0x03, 0xbf, 0x61,
-+			      0x03, 0xbf),
-+		PHYREGS(0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438),
-+	},
-+	{
-+		.freq			= 2442,
-+		RADIOREGS7_2G(0x5c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8a,
-+			      0x09, 0x0b, 0x07, 0x0d, 0x61, 0x03, 0xaf, 0x61,
-+			      0x03, 0xaf),
-+		PHYREGS(0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436),
-+	},
-+	{
-+		.freq			= 2447,
-+		RADIOREGS7_2G(0x5f, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8f,
-+			      0x09, 0x0b, 0x07, 0x0d, 0x61, 0x03, 0x9f, 0x61,
-+			      0x03, 0x9f),
-+		PHYREGS(0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434),
-+	},
-+	{
-+		.freq			= 2452,
-+		RADIOREGS7_2G(0x62, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x94,
-+			      0x09, 0x0b, 0x07, 0x0d, 0x61, 0x03, 0x8f, 0x61,
-+			      0x03, 0x8f),
-+		PHYREGS(0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431),
-+	},
-+	{
-+		.freq			= 2457,
-+		RADIOREGS7_2G(0x66, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x99,
-+			      0x09, 0x0b, 0x07, 0x0c, 0x61, 0x03, 0x7f, 0x61,
-+			      0x03, 0x7f),
-+		PHYREGS(0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f),
-+	},
-+	{
-+		.freq			= 2462,
-+		RADIOREGS7_2G(0x69, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x9e,
-+			      0x09, 0x0b, 0x07, 0x0c, 0x61, 0x03, 0x6f, 0x61,
-+			      0x03, 0x6f),
-+		PHYREGS(0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d),
-+	},
-+	{
-+		.freq			= 2467,
-+		RADIOREGS7_2G(0x6c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa3,
-+			      0x09, 0x0b, 0x06, 0x0c, 0x61, 0x03, 0x5f, 0x61,
-+			      0x03, 0x5f),
-+		PHYREGS(0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b),
-+	},
-+	{
-+		.freq			= 2472,
-+		RADIOREGS7_2G(0x70, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa8,
-+			      0x09, 0x0a, 0x06, 0x0b, 0x61, 0x03, 0x4f, 0x61,
-+			      0x03, 0x4f),
-+		PHYREGS(0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429),
-+	},
-+	{
-+		.freq			= 2484,
-+		RADIOREGS7_2G(0x78, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xb4,
-+			      0x09, 0x0a, 0x06, 0x0b, 0x61, 0x03, 0x3f, 0x61,
-+			      0x03, 0x3f),
-+		PHYREGS(0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424),
-+	}
-+};
-+
-+/* Extracted from MMIO dump of 6.30.223.248 */
-+static const struct b43_nphy_chantabent_rev7_2g b43_nphy_chantab_phy_rev17_radio_rev14[] = {
-+	{
-+		.freq			= 2412,
-+		RADIOREGS7_2G(0x48, 0x16, 0x30, 0x2b, 0x1f, 0x1f, 0x30, 0x6c,
-+			      0x09, 0x0d, 0x09, 0x03, 0x21, 0x53, 0xff, 0x21,
-+			      0x53, 0xff),
-+		PHYREGS(0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443),
-+	},
-+	{
-+		.freq			= 2417,
-+		RADIOREGS7_2G(0x4b, 0x16, 0x30, 0x2b, 0x1f, 0x1f, 0x30, 0x71,
-+			      0x09, 0x0d, 0x08, 0x03, 0x21, 0x53, 0xff, 0x21,
-+			      0x53, 0xff),
-+		PHYREGS(0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441),
-+	},
-+	{
-+		.freq			= 2422,
-+		RADIOREGS7_2G(0x4e, 0x16, 0x30, 0x2b, 0x1f, 0x1f, 0x30, 0x76,
-+			      0x09, 0x0d, 0x08, 0x03, 0x21, 0x53, 0xff, 0x21,
-+			      0x53, 0xff),
-+		PHYREGS(0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f),
-+	},
-+	{
-+		.freq			= 2427,
-+		RADIOREGS7_2G(0x52, 0x16, 0x30, 0x2b, 0x1f, 0x1f, 0x30, 0x7b,
-+			      0x09, 0x0c, 0x08, 0x03, 0x21, 0x53, 0xff, 0x21,
-+			      0x53, 0xff),
-+		PHYREGS(0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d),
-+	},
-+	{
-+		.freq			= 2432,
-+		RADIOREGS7_2G(0x55, 0x16, 0x30, 0x2b, 0x1f, 0x1f, 0x30, 0x80,
-+			      0x09, 0x0c, 0x08, 0x03, 0x21, 0x53, 0xff, 0x21,
-+			      0x53, 0xff),
-+		PHYREGS(0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a),
-+	},
-+	{
-+		.freq			= 2437,
-+		RADIOREGS7_2G(0x58, 0x16, 0x30, 0x2b, 0x1f, 0x1f, 0x30, 0x85,
-+			      0x09, 0x0c, 0x08, 0x03, 0x21, 0x53, 0xff, 0x21,
-+			      0x53, 0xff),
-+		PHYREGS(0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438),
-+	},
-+	{
-+		.freq			= 2442,
-+		RADIOREGS7_2G(0x5c, 0x16, 0x30, 0x2b, 0x1f, 0x1f, 0x30, 0x8a,
-+			      0x09, 0x0c, 0x08, 0x03, 0x21, 0x43, 0xff, 0x21,
-+			      0x43, 0xff),
-+		PHYREGS(0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436),
-+	},
-+	{
-+		.freq			= 2447,
-+		RADIOREGS7_2G(0x5f, 0x16, 0x30, 0x2b, 0x1f, 0x1f, 0x30, 0x8f,
-+			      0x09, 0x0c, 0x08, 0x03, 0x21, 0x43, 0xff, 0x21,
-+			      0x43, 0xff),
-+		PHYREGS(0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434),
-+	},
-+	{
-+		.freq			= 2452,
-+		RADIOREGS7_2G(0x62, 0x16, 0x30, 0x2b, 0x1f, 0x1f, 0x30, 0x94,
-+			      0x09, 0x0c, 0x08, 0x03, 0x21, 0x43, 0xff, 0x21,
-+			      0x43, 0xff),
-+		PHYREGS(0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431),
-+	},
-+	{
-+		.freq			= 2457,
-+		RADIOREGS7_2G(0x66, 0x16, 0x30, 0x2b, 0x1f, 0x1f, 0x30, 0x99,
-+			      0x09, 0x0b, 0x07, 0x03, 0x21, 0x43, 0xff, 0x21,
-+			      0x43, 0xff),
-+		PHYREGS(0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f),
-+	},
-+	{
-+		.freq			= 2462,
-+		RADIOREGS7_2G(0x69, 0x16, 0x30, 0x2b, 0x1f, 0x1f, 0x30, 0x9e,
-+			      0x09, 0x0b, 0x07, 0x03, 0x01, 0x43, 0xff, 0x01,
-+			      0x43, 0xff),
-+		PHYREGS(0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d),
-+	},
-+};
-+
-+/* Extracted from MMIO dump of 6.30.223.141 */
-+static const struct b43_nphy_chantabent_rev7 b43_nphy_chantab_phy_rev16_radio_rev9[] = {
-+	{
-+		.freq			= 2412,
-+		RADIOREGS7(0x48, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x6c,
-+			   0x09, 0x0f, 0x0a, 0x00, 0x0a, 0x00, 0x41, 0x63,
-+			   0x00, 0x00, 0x00, 0xf0, 0x00, 0x41, 0x63, 0x00,
-+			   0x00, 0x00, 0xf0, 0x00),
-+		PHYREGS(0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443),
-+	},
-+	{
-+		.freq			= 2417,
-+		RADIOREGS7(0x4b, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x71,
-+			   0x09, 0x0f, 0x0a, 0x00, 0x0a, 0x00, 0x41, 0x63,
-+			   0x00, 0x00, 0x00, 0xf0, 0x00, 0x41, 0x63, 0x00,
-+			   0x00, 0x00, 0xf0, 0x00),
-+		PHYREGS(0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441),
-+	},
-+	{
-+		.freq			= 2422,
-+		RADIOREGS7(0x4e, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x76,
-+			   0x09, 0x0f, 0x09, 0x00, 0x09, 0x00, 0x41, 0x63,
-+			   0x00, 0x00, 0x00, 0xf0, 0x00, 0x41, 0x63, 0x00,
-+			   0x00, 0x00, 0xf0, 0x00),
-+		PHYREGS(0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f),
-+	},
-+	{
-+		.freq			= 2427,
-+		RADIOREGS7(0x52, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x7b,
-+			   0x09, 0x0f, 0x09, 0x00, 0x09, 0x00, 0x41, 0x63,
-+			   0x00, 0x00, 0x00, 0xf0, 0x00, 0x41, 0x63, 0x00,
-+			   0x00, 0x00, 0xf0, 0x00),
-+		PHYREGS(0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d),
-+	},
-+	{
-+		.freq			= 2432,
-+		RADIOREGS7(0x55, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x80,
-+			   0x09, 0x0f, 0x08, 0x00, 0x08, 0x00, 0x41, 0x63,
-+			   0x00, 0x00, 0x00, 0xf0, 0x00, 0x41, 0x63, 0x00,
-+			   0x00, 0x00, 0xf0, 0x00),
-+		PHYREGS(0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a),
-+	},
-+	{
-+		.freq			= 2437,
-+		RADIOREGS7(0x58, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x85,
-+			   0x09, 0x0f, 0x08, 0x00, 0x08, 0x00, 0x41, 0x63,
-+			   0x00, 0x00, 0x00, 0xf0, 0x00, 0x41, 0x63, 0x00,
-+			   0x00, 0x00, 0xf0, 0x00),
-+		PHYREGS(0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438),
-+	},
-+	{
-+		.freq			= 2442,
-+		RADIOREGS7(0x5c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8a,
-+			   0x09, 0x0f, 0x07, 0x00, 0x07, 0x00, 0x41, 0x63,
-+			   0x00, 0x00, 0x00, 0xf0, 0x00, 0x41, 0x63, 0x00,
-+			   0x00, 0x00, 0xf0, 0x00),
-+		PHYREGS(0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436),
-+	},
-+	{
-+		.freq			= 2447,
-+		RADIOREGS7(0x5f, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8f,
-+			   0x09, 0x0f, 0x07, 0x00, 0x07, 0x00, 0x41, 0x63,
-+			   0x00, 0x00, 0x00, 0xf0, 0x00, 0x41, 0x63, 0x00,
-+			   0x00, 0x00, 0xf0, 0x00),
-+		PHYREGS(0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434),
-+	},
-+	{
-+		.freq			= 2452,
-+		RADIOREGS7(0x62, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x94,
-+			   0x09, 0x0f, 0x07, 0x00, 0x07, 0x00, 0x41, 0x63,
-+			   0x00, 0x00, 0x00, 0xf0, 0x00, 0x41, 0x63, 0x00,
-+			   0x00, 0x00, 0xf0, 0x00),
-+		PHYREGS(0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431),
-+	},
-+	{
-+		.freq			= 2457,
-+		RADIOREGS7(0x66, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x99,
-+			   0x09, 0x0f, 0x06, 0x00, 0x06, 0x00, 0x41, 0x63,
-+			   0x00, 0x00, 0x00, 0xf0, 0x00, 0x41, 0x63, 0x00,
-+			   0x00, 0x00, 0xf0, 0x00),
-+		PHYREGS(0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f),
-+	},
-+	{
-+		.freq			= 2462,
-+		RADIOREGS7(0x69, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x9e,
-+			   0x09, 0x0f, 0x06, 0x00, 0x06, 0x00, 0x41, 0x63,
-+			   0x00, 0x00, 0x00, 0xf0, 0x00, 0x41, 0x63, 0x00,
-+			   0x00, 0x00, 0xf0, 0x00),
-+		PHYREGS(0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d),
-+	},
-+	{
-+		.freq			= 5180,
-+		RADIOREGS7(0xbe, 0x16, 0x10, 0x1f, 0x08, 0x08, 0x3f, 0x06,
-+			   0x02, 0x0e, 0x00, 0x0e, 0x00, 0x9e, 0x00, 0x00,
-+			   0x9f, 0x2f, 0xa3, 0x00, 0xfc, 0x00, 0x00, 0x4f,
-+			   0x3a, 0x83, 0x00, 0xfc),
-+		PHYREGS(0x081c, 0x0818, 0x0814, 0x01f9, 0x01fa, 0x01fb),
-+	},
-+	{
-+		.freq			= 5200,
-+		RADIOREGS7(0xc5, 0x16, 0x10, 0x1f, 0x08, 0x08, 0x3f, 0x08,
-+			   0x02, 0x0e, 0x00, 0x0e, 0x00, 0x9e, 0x00, 0x00,
-+			   0x7f, 0x2f, 0x83, 0x00, 0xf8, 0x00, 0x00, 0x4c,
-+			   0x4a, 0x83, 0x00, 0xf8),
-+		PHYREGS(0x0824, 0x0820, 0x081c, 0x01f7, 0x01f8, 0x01f9),
-+	},
-+	{
-+		.freq			= 5220,
-+		RADIOREGS7(0xcc, 0x16, 0x10, 0x1f, 0x08, 0x08, 0x3f, 0x0a,
-+			   0x02, 0x0e, 0x00, 0x0e, 0x00, 0x9e, 0x00, 0x00,
-+			   0x6d, 0x3d, 0x83, 0x00, 0xf8, 0x00, 0x00, 0x2d,
-+			   0x2a, 0x73, 0x00, 0xf8),
-+		PHYREGS(0x082c, 0x0828, 0x0824, 0x01f5, 0x01f6, 0x01f7),
-+	},
-+	{
-+		.freq			= 5240,
-+		RADIOREGS7(0xd2, 0x16, 0x10, 0x1f, 0x08, 0x08, 0x3f, 0x0c,
-+			   0x02, 0x0d, 0x00, 0x0d, 0x00, 0x8d, 0x00, 0x00,
-+			   0x4d, 0x1c, 0x73, 0x00, 0xf8, 0x00, 0x00, 0x4d,
-+			   0x2b, 0x73, 0x00, 0xf8),
-+		PHYREGS(0x0834, 0x0830, 0x082c, 0x01f3, 0x01f4, 0x01f5),
-+	},
-+	{
-+		.freq			= 5745,
-+		RADIOREGS7(0x7b, 0x17, 0x20, 0x1f, 0x08, 0x08, 0x3f, 0x7d,
-+			   0x04, 0x08, 0x00, 0x06, 0x00, 0x15, 0x00, 0x00,
-+			   0x08, 0x03, 0x03, 0x00, 0x30, 0x00, 0x00, 0x06,
-+			   0x02, 0x03, 0x00, 0x30),
-+		PHYREGS(0x08fe, 0x08fa, 0x08f6, 0x01c8, 0x01c8, 0x01c9),
-+	},
-+	{
-+		.freq			= 5765,
-+		RADIOREGS7(0x81, 0x17, 0x20, 0x1f, 0x08, 0x08, 0x3f, 0x81,
-+			   0x04, 0x08, 0x00, 0x06, 0x00, 0x15, 0x00, 0x00,
-+			   0x06, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x05,
-+			   0x02, 0x03, 0x00, 0x00),
-+		PHYREGS(0x0906, 0x0902, 0x08fe, 0x01c6, 0x01c7, 0x01c8),
-+	},
-+	{
-+		.freq			= 5785,
-+		RADIOREGS7(0x88, 0x17, 0x20, 0x1f, 0x08, 0x08, 0x3f, 0x85,
-+			   0x04, 0x08, 0x00, 0x06, 0x00, 0x15, 0x00, 0x00,
-+			   0x08, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x05,
-+			   0x21, 0x03, 0x00, 0x00),
-+		PHYREGS(0x090e, 0x090a, 0x0906, 0x01c4, 0x01c5, 0x01c6),
-+	},
-+	{
-+		.freq			= 5805,
-+		RADIOREGS7(0x8f, 0x17, 0x20, 0x1f, 0x08, 0x08, 0x3f, 0x89,
-+			   0x04, 0x07, 0x00, 0x06, 0x00, 0x04, 0x00, 0x00,
-+			   0x06, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x03,
-+			   0x00, 0x03, 0x00, 0x00),
-+		PHYREGS(0x0916, 0x0912, 0x090e, 0x01c3, 0x01c4, 0x01c4),
-+	},
-+	{
-+		.freq			= 5825,
-+		RADIOREGS7(0x95, 0x17, 0x20, 0x1f, 0x08, 0x08, 0x3f, 0x8d,
-+			   0x04, 0x07, 0x00, 0x05, 0x00, 0x03, 0x00, 0x00,
-+			   0x05, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x03,
-+			   0x00, 0x03, 0x00, 0x00),
-+		PHYREGS(0x091e, 0x091a, 0x0916, 0x01c1, 0x01c2, 0x01c3),
-+	},
-+};
- 
- void r2057_upload_inittabs(struct b43_wldev *dev)
- {
-@@ -109,33 +540,98 @@ void r2057_upload_inittabs(struct b43_wl
- 	u16 *table = NULL;
- 	u16 size, i;
- 
--	if (phy->rev == 7) {
-+	switch (phy->rev) {
-+	case 7:
- 		table = r2057_rev4_init[0];
- 		size = ARRAY_SIZE(r2057_rev4_init);
--	} else if (phy->rev == 8 || phy->rev == 9) {
-+		break;
-+	case 8:
- 		if (phy->radio_rev == 5) {
--			if (phy->radio_rev == 8) {
--				table = r2057_rev5_init[0];
--				size = ARRAY_SIZE(r2057_rev5_init);
--			} else {
--				table = r2057_rev5a_init[0];
--				size = ARRAY_SIZE(r2057_rev5a_init);
--			}
-+			table = r2057_rev5_init[0];
-+			size = ARRAY_SIZE(r2057_rev5_init);
- 		} else if (phy->radio_rev == 7) {
- 			table = r2057_rev7_init[0];
- 			size = ARRAY_SIZE(r2057_rev7_init);
--		} else if (phy->radio_rev == 9) {
--			table = r2057_rev8_init[0];
--			size = ARRAY_SIZE(r2057_rev8_init);
- 		}
-+		break;
-+	case 9:
-+		if (phy->radio_rev == 5) {
-+			table = r2057_rev5a_init[0];
-+			size = ARRAY_SIZE(r2057_rev5a_init);
-+		}
-+		break;
-+	case 16:
-+		if (phy->radio_rev == 9) {
-+			table = r2057_rev9_init[0];
-+			size = ARRAY_SIZE(r2057_rev9_init);
-+		}
-+		break;
-+	case 17:
-+		if (phy->radio_rev == 14) {
-+			table = r2057_rev14_init[0];
-+			size = ARRAY_SIZE(r2057_rev14_init);
-+		}
-+		break;
- 	}
- 
-+	B43_WARN_ON(!table);
-+
- 	if (table) {
--		for (i = 0; i < 10; i++) {
--			pr_info("radio_write 0x%X ", *table);
--			table++;
--			pr_info("0x%X\n", *table);
--			table++;
-+		for (i = 0; i < size; i++, table += 2)
-+			b43_radio_write(dev, table[0], table[1]);
-+	}
-+}
-+
-+void r2057_get_chantabent_rev7(struct b43_wldev *dev, u16 freq,
-+			       const struct b43_nphy_chantabent_rev7 **tabent_r7,
-+			       const struct b43_nphy_chantabent_rev7_2g **tabent_r7_2g)
-+{
-+	struct b43_phy *phy = &dev->phy;
-+	const struct b43_nphy_chantabent_rev7 *e_r7 = NULL;
-+	const struct b43_nphy_chantabent_rev7_2g *e_r7_2g = NULL;
-+	unsigned int len, i;
-+
-+	*tabent_r7 = NULL;
-+	*tabent_r7_2g = NULL;
-+
-+	switch (phy->rev) {
-+	case 8:
-+		if (phy->radio_rev == 5) {
-+			e_r7_2g = b43_nphy_chantab_phy_rev8_radio_rev5;
-+			len = ARRAY_SIZE(b43_nphy_chantab_phy_rev8_radio_rev5);
-+		}
-+		break;
-+	case 16:
-+		if (phy->radio_rev == 9) {
-+			e_r7 = b43_nphy_chantab_phy_rev16_radio_rev9;
-+			len = ARRAY_SIZE(b43_nphy_chantab_phy_rev16_radio_rev9);
-+		}
-+		break;
-+	case 17:
-+		if (phy->radio_rev == 14) {
-+			e_r7_2g = b43_nphy_chantab_phy_rev17_radio_rev14;
-+			len = ARRAY_SIZE(b43_nphy_chantab_phy_rev17_radio_rev14);
-+		}
-+		break;
-+	default:
-+		break;
-+	}
-+
-+	if (e_r7) {
-+		for (i = 0; i < len; i++, e_r7++) {
-+			if (e_r7->freq == freq) {
-+				*tabent_r7 = e_r7;
-+				return;
-+			}
-+		}
-+	} else if (e_r7_2g) {
-+		for (i = 0; i < len; i++, e_r7_2g++) {
-+			if (e_r7_2g->freq == freq) {
-+				*tabent_r7_2g = e_r7_2g;
-+				return;
-+			}
- 		}
-+	} else {
-+		B43_WARN_ON(1);
- 	}
- }
---- a/drivers/net/wireless/b43/radio_2057.h
-+++ b/drivers/net/wireless/b43/radio_2057.h
-@@ -84,6 +84,8 @@
- #define R2057_CMOSBUF_RX_RCCR			0x04c
- #define R2057_LOGEN_SEL_PKDET			0x04d
- #define R2057_CMOSBUF_SHAREIQ_PTAT		0x04e
-+
-+/* MISC core 0 */
- #define R2057_RXTXBIAS_CONFIG_CORE0		0x04f
- #define R2057_TXGM_TXRF_PUS_CORE0		0x050
- #define R2057_TXGM_IDAC_BLEED_CORE0		0x051
-@@ -204,6 +206,8 @@
- #define R2057_RXBB_GPAIOSEL_RXLPF_RCCAL_CORE0	0x0d1
- #define R2057_LPF_GAIN_CORE0			0x0d2
- #define R2057_DACBUF_IDACS_BW_CORE0		0x0d3
-+
-+/* MISC core 1 */
- #define R2057_RXTXBIAS_CONFIG_CORE1		0x0d4
- #define R2057_TXGM_TXRF_PUS_CORE1		0x0d5
- #define R2057_TXGM_IDAC_BLEED_CORE1		0x0d6
-@@ -324,6 +328,7 @@
- #define R2057_RXBB_GPAIOSEL_RXLPF_RCCAL_CORE1	0x156
- #define R2057_LPF_GAIN_CORE1			0x157
- #define R2057_DACBUF_IDACS_BW_CORE1		0x158
-+
- #define R2057_DACBUF_VINCM_CORE1		0x159
- #define R2057_RCCAL_START_R1_Q1_P1		0x15a
- #define R2057_RCCAL_X1				0x15b
-@@ -345,6 +350,8 @@
- #define R2057_RCCAL_BCAP_VAL			0x16b
- #define R2057_RCCAL_HPC_VAL			0x16c
- #define R2057_RCCAL_OVERRIDES			0x16d
-+
-+/* TX core 0 */
- #define R2057_TX0_IQCAL_GAIN_BW			0x170
- #define R2057_TX0_LOFT_FINE_I			0x171
- #define R2057_TX0_LOFT_FINE_Q			0x172
-@@ -362,6 +369,8 @@
- #define R2057_TX0_TXRXCOUPLE_2G_PWRUP		0x17e
- #define R2057_TX0_TXRXCOUPLE_5G_ATTEN		0x17f
- #define R2057_TX0_TXRXCOUPLE_5G_PWRUP		0x180
-+
-+/* TX core 1 */
- #define R2057_TX1_IQCAL_GAIN_BW			0x190
- #define R2057_TX1_LOFT_FINE_I			0x191
- #define R2057_TX1_LOFT_FINE_Q			0x192
-@@ -379,6 +388,7 @@
- #define R2057_TX1_TXRXCOUPLE_2G_PWRUP		0x19e
- #define R2057_TX1_TXRXCOUPLE_5G_ATTEN		0x19f
- #define R2057_TX1_TXRXCOUPLE_5G_PWRUP		0x1a0
-+
- #define R2057_AFE_VCM_CAL_MASTER_CORE0		0x1a1
- #define R2057_AFE_SET_VCM_I_CORE0		0x1a2
- #define R2057_AFE_SET_VCM_Q_CORE0		0x1a3
-@@ -425,6 +435,72 @@
- 
- #define R2057_VCM_MASK				0x7
- 
-+struct b43_nphy_chantabent_rev7 {
-+	/* The channel frequency in MHz */
-+	u16 freq;
-+	/* Radio regs values on channelswitch */
-+	u8 radio_vcocal_countval0;
-+	u8 radio_vcocal_countval1;
-+	u8 radio_rfpll_refmaster_sparextalsize;
-+	u8 radio_rfpll_loopfilter_r1;
-+	u8 radio_rfpll_loopfilter_c2;
-+	u8 radio_rfpll_loopfilter_c1;
-+	u8 radio_cp_kpd_idac;
-+	u8 radio_rfpll_mmd0;
-+	u8 radio_rfpll_mmd1;
-+	u8 radio_vcobuf_tune;
-+	u8 radio_logen_mx2g_tune;
-+	u8 radio_logen_mx5g_tune;
-+	u8 radio_logen_indbuf2g_tune;
-+	u8 radio_logen_indbuf5g_tune;
-+	u8 radio_txmix2g_tune_boost_pu_core0;
-+	u8 radio_pad2g_tune_pus_core0;
-+	u8 radio_pga_boost_tune_core0;
-+	u8 radio_txmix5g_boost_tune_core0;
-+	u8 radio_pad5g_tune_misc_pus_core0;
-+	u8 radio_lna2g_tune_core0;
-+	u8 radio_lna5g_tune_core0;
-+	u8 radio_txmix2g_tune_boost_pu_core1;
-+	u8 radio_pad2g_tune_pus_core1;
-+	u8 radio_pga_boost_tune_core1;
-+	u8 radio_txmix5g_boost_tune_core1;
-+	u8 radio_pad5g_tune_misc_pus_core1;
-+	u8 radio_lna2g_tune_core1;
-+	u8 radio_lna5g_tune_core1;
-+	/* PHY res values on channelswitch */
-+	struct b43_phy_n_sfo_cfg phy_regs;
-+};
-+
-+struct b43_nphy_chantabent_rev7_2g {
-+	/* The channel frequency in MHz */
-+	u16 freq;
-+	/* Radio regs values on channelswitch */
-+	u8 radio_vcocal_countval0;
-+	u8 radio_vcocal_countval1;
-+	u8 radio_rfpll_refmaster_sparextalsize;
-+	u8 radio_rfpll_loopfilter_r1;
-+	u8 radio_rfpll_loopfilter_c2;
-+	u8 radio_rfpll_loopfilter_c1;
-+	u8 radio_cp_kpd_idac;
-+	u8 radio_rfpll_mmd0;
-+	u8 radio_rfpll_mmd1;
-+	u8 radio_vcobuf_tune;
-+	u8 radio_logen_mx2g_tune;
-+	u8 radio_logen_indbuf2g_tune;
-+	u8 radio_txmix2g_tune_boost_pu_core0;
-+	u8 radio_pad2g_tune_pus_core0;
-+	u8 radio_lna2g_tune_core0;
-+	u8 radio_txmix2g_tune_boost_pu_core1;
-+	u8 radio_pad2g_tune_pus_core1;
-+	u8 radio_lna2g_tune_core1;
-+	/* PHY regs values on channelswitch */
-+	struct b43_phy_n_sfo_cfg phy_regs;
-+};
-+
- void r2057_upload_inittabs(struct b43_wldev *dev);
- 
-+void r2057_get_chantabent_rev7(struct b43_wldev *dev, u16 freq,
-+			       const struct b43_nphy_chantabent_rev7 **tabent_r7,
-+			       const struct b43_nphy_chantabent_rev7_2g **tabent_r7_2g);
-+
- #endif /* B43_RADIO_2057_H_ */
---- a/drivers/net/wireless/b43/tables_nphy.h
-+++ b/drivers/net/wireless/b43/tables_nphy.h
-@@ -165,6 +165,10 @@ struct nphy_gain_ctl_workaround_entry *b
- #define B43_NTAB_C1_LOFEEDTH_R3		B43_NTAB16(27, 448) /* Local Oscillator Feed Through lookup 1 */
- #define B43_NTAB_C1_PAPD_COMP_R3	B43_NTAB16(27, 576)
- 
-+/* Static N-PHY tables, PHY revision >= 7 */
-+#define B43_NTAB_TMAP_R7		B43_NTAB32(12,   0) /* TM AP */
-+#define B43_NTAB_NOISEVAR_R7		B43_NTAB32(16,   0) /* noise variance */
-+
- #define B43_NTAB_TX_IQLO_CAL_LOFT_LADDER_40_SIZE	18
- #define B43_NTAB_TX_IQLO_CAL_LOFT_LADDER_20_SIZE	18
- #define B43_NTAB_TX_IQLO_CAL_IQIMB_LADDER_40_SIZE	18
---- a/drivers/net/wireless/b43/xmit.c
-+++ b/drivers/net/wireless/b43/xmit.c
-@@ -80,9 +80,10 @@ static int b43_plcp_get_bitrate_idx_cck(
- }
- 
- /* Extract the bitrate index out of an OFDM PLCP header. */
--static int b43_plcp_get_bitrate_idx_ofdm(struct b43_plcp_hdr6 *plcp, bool aphy)
-+static int b43_plcp_get_bitrate_idx_ofdm(struct b43_plcp_hdr6 *plcp, bool ghz5)
- {
--	int base = aphy ? 0 : 4;
-+	/* For 2 GHz band first OFDM rate is at index 4, see main.c */
-+	int base = ghz5 ? 0 : 4;
- 
- 	switch (plcp->raw[0] & 0xF) {
- 	case 0xB:
-@@ -767,7 +768,7 @@ void b43_rx(struct b43_wldev *dev, struc
- 
- 	if (phystat0 & B43_RX_PHYST0_OFDM)
- 		rate_idx = b43_plcp_get_bitrate_idx_ofdm(plcp,
--						phytype == B43_PHYTYPE_A);
-+					!!(chanstat & B43_RX_CHAN_5GHZ));
- 	else
- 		rate_idx = b43_plcp_get_bitrate_idx_cck(plcp);
- 	if (unlikely(rate_idx == -1)) {
---- a/.local-symbols
-+++ b/.local-symbols
-@@ -176,6 +176,7 @@ B43_PCMCIA=
- B43_SDIO=
- B43_BCMA_PIO=
- B43_PIO=
-+B43_PHY_G=
- B43_PHY_N=
- B43_PHY_LP=
- B43_PHY_HT=

+ 0 - 12
package/kernel/mac80211/patches/801-fix-5ghz.patch

@@ -1,12 +0,0 @@
---- a/drivers/net/wireless/b43/phy_n.c
-+++ b/drivers/net/wireless/b43/phy_n.c
-@@ -6217,6 +6217,9 @@ static void b43_nphy_channel_setup(struc
- 	u16 tmp16;
- 
- 	if (new_channel->band == IEEE80211_BAND_5GHZ) {
-+		/* Switch to 2 GHz for a moment to access B43_PHY_B_BBCFG */
-+		b43_phy_mask(dev, B43_NPHY_BANDCTL, ~B43_NPHY_BANDCTL_5GHZ);
-+
- 		tmp16 = b43_read16(dev, B43_MMIO_PSM_PHY_HDR);
- 		b43_write16(dev, B43_MMIO_PSM_PHY_HDR, tmp16 | 4);
- 		/* Put BPHY in the reset */

+ 2 - 2
package/kernel/mac80211/patches/805-b43-gpio-mask-module-option.patch

@@ -1,6 +1,6 @@
 --- a/drivers/net/wireless/b43/b43.h
 +++ b/drivers/net/wireless/b43/b43.h
-@@ -820,6 +820,7 @@ struct b43_wldev {
+@@ -837,6 +837,7 @@ struct b43_wldev {
  	bool qos_enabled;		/* TRUE, if QoS is used. */
  	bool hwcrypto_enabled;		/* TRUE, if HW crypto acceleration is enabled. */
  	bool use_pio;			/* TRUE if next init should use PIO */
@@ -22,7 +22,7 @@
  static int modparam_bad_frames_preempt;
  module_param_named(bad_frames_preempt, modparam_bad_frames_preempt, int, 0444);
  MODULE_PARM_DESC(bad_frames_preempt,
-@@ -2814,10 +2819,10 @@ static int b43_gpio_init(struct b43_wlde
+@@ -2844,10 +2849,10 @@ static int b43_gpio_init(struct b43_wlde
  	u32 mask, set;
  
  	b43_maskset32(dev, B43_MMIO_MACCTL, ~B43_MACCTL_GPOUTSMSK, 0);

+ 2 - 2
package/kernel/mac80211/patches/810-b43_no_pio.patch

@@ -7,11 +7,11 @@
 -b43-y				+= pio.o
 +b43-$(CPTCFG_B43_PIO)		+= pio.o
  b43-y				+= rfkill.o
+ b43-y				+= ppr.o
  b43-$(CPTCFG_B43_LEDS)		+= leds.o
- b43-$(CPTCFG_B43_PCMCIA)	+= pcmcia.o
 --- a/drivers/net/wireless/b43/main.c
 +++ b/drivers/net/wireless/b43/main.c
-@@ -1940,10 +1940,12 @@ static void b43_do_interrupt_thread(stru
+@@ -1970,10 +1970,12 @@ static void b43_do_interrupt_thread(stru
  			dma_reason[0], dma_reason[1],
  			dma_reason[2], dma_reason[3],
  			dma_reason[4], dma_reason[5]);

+ 9 - 9
package/kernel/mac80211/patches/820-b43-add-antenna-control.patch

@@ -1,6 +1,6 @@
 --- a/drivers/net/wireless/b43/main.c
 +++ b/drivers/net/wireless/b43/main.c
-@@ -1587,7 +1587,7 @@ static void b43_write_beacon_template(st
+@@ -1617,7 +1617,7 @@ static void b43_write_beacon_template(st
  				  len, ram_offset, shm_size_offset, rate);
  
  	/* Write the PHY TX control parameters. */
@@ -9,7 +9,7 @@
  	antenna = b43_antenna_to_phyctl(antenna);
  	ctl = b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_BEACPHYCTL);
  	/* We can't send beacons with short preamble. Would get PHY errors. */
-@@ -3218,8 +3218,8 @@ static int b43_chip_init(struct b43_wlde
+@@ -3264,8 +3264,8 @@ static int b43_chip_init(struct b43_wlde
  
  	/* Select the antennae */
  	if (phy->ops->set_rx_antenna)
@@ -20,7 +20,7 @@
  
  	if (phy->type == B43_PHYTYPE_B) {
  		value16 = b43_read16(dev, 0x005E);
-@@ -3913,7 +3913,6 @@ static int b43_op_config(struct ieee8021
+@@ -3965,7 +3965,6 @@ static int b43_op_config(struct ieee8021
  	struct b43_wldev *dev = wl->current_dev;
  	struct b43_phy *phy = &dev->phy;
  	struct ieee80211_conf *conf = &hw->conf;
@@ -28,7 +28,7 @@
  	int err = 0;
  
  	mutex_lock(&wl->mutex);
-@@ -3953,11 +3952,9 @@ static int b43_op_config(struct ieee8021
+@@ -4008,11 +4007,9 @@ static int b43_op_config(struct ieee8021
  	}
  
  	/* Antennas for RX and management frame TX. */
@@ -42,7 +42,7 @@
  
  	if (wl->radio_enabled != phy->radio_on) {
  		if (wl->radio_enabled) {
-@@ -5094,6 +5091,47 @@ static int b43_op_get_survey(struct ieee
+@@ -5162,6 +5159,47 @@ static int b43_op_get_survey(struct ieee
  	return 0;
  }
  
@@ -90,7 +90,7 @@
  static const struct ieee80211_ops b43_hw_ops = {
  	.tx			= b43_op_tx,
  	.conf_tx		= b43_op_conf_tx,
-@@ -5115,6 +5153,8 @@ static const struct ieee80211_ops b43_hw
+@@ -5183,6 +5221,8 @@ static const struct ieee80211_ops b43_hw
  	.sw_scan_complete	= b43_op_sw_scan_complete_notifier,
  	.get_survey		= b43_op_get_survey,
  	.rfkill_poll		= b43_rfkill_poll,
@@ -99,7 +99,7 @@
  };
  
  /* Hard-reset the chip. Do not call this directly.
-@@ -5418,6 +5458,8 @@ static int b43_one_core_attach(struct b4
+@@ -5486,6 +5526,8 @@ static int b43_one_core_attach(struct b4
  	if (!wldev)
  		goto out;
  
@@ -108,7 +108,7 @@
  	wldev->use_pio = b43_modparam_pio;
  	wldev->dev = dev;
  	wldev->wl = wl;
-@@ -5508,6 +5550,9 @@ static struct b43_wl *b43_wireless_init(
+@@ -5576,6 +5618,9 @@ static struct b43_wl *b43_wireless_init(
  
  	hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
  
@@ -120,7 +120,7 @@
  	SET_IEEE80211_DEV(hw, dev->dev);
 --- a/drivers/net/wireless/b43/b43.h
 +++ b/drivers/net/wireless/b43/b43.h
-@@ -821,6 +821,8 @@ struct b43_wldev {
+@@ -838,6 +838,8 @@ struct b43_wldev {
  	bool hwcrypto_enabled;		/* TRUE, if HW crypto acceleration is enabled. */
  	bool use_pio;			/* TRUE if next init should use PIO */
  	int gpiomask;			/* GPIO LED mask as a module parameter */

+ 0 - 256
package/kernel/mac80211/patches/830-b43-workaround-pcie-bcm4716.patch

@@ -1,256 +0,0 @@
-From 4f214b1ead0af7439921637645cb63f378516175 Mon Sep 17 00:00:00 2001
-From: Hauke Mehrtens <[email protected]>
-Date: Sat, 21 Jan 2012 18:48:38 +0100
-Subject: [PATCH 33/34] b43: add workaround for b43 on pcie bus of bcm4716.
-
-bcm4716 (which includes 4717 & 4718), plus 4706 on PCIe can reorder
-transactions. As a fix, a read after write is performed on certain
-places in the code. Older chips and the newer 5357 family don't require
-this fix.
-This code is based on the brcmsmac driver.
-
-Signed-off-by: Hauke Mehrtens <[email protected]>
----
- drivers/net/wireless/b43/b43.h        |   26 ++++++++++++++++++++++++++
- drivers/net/wireless/b43/bus.h        |   10 ++++++++++
- drivers/net/wireless/b43/phy_common.c |    6 ++++++
- drivers/net/wireless/b43/phy_n.c      |   10 +++++-----
- 4 files changed, 47 insertions(+), 5 deletions(-)
-
---- a/drivers/net/wireless/b43/b43.h
-+++ b/drivers/net/wireless/b43/b43.h
-@@ -1054,6 +1054,15 @@ static inline bool b43_using_pio_transfe
- 	return dev->__using_pio_transfers;
- }
- 
-+#ifdef CONFIG_BCM47XX_BCMA
-+void b43_wflush16(struct b43_wldev *dev, u16 offset, u16 value);
-+#else
-+static inline void b43_wflush16(struct b43_wldev *dev, u16 offset, u16 value)
-+{
-+	b43_write16(dev, offset, value);
-+}
-+#endif
-+
- /* Message printing */
- __printf(2, 3) void b43info(struct b43_wl *wl, const char *fmt, ...);
- __printf(2, 3) void b43err(struct b43_wl *wl, const char *fmt, ...);
---- a/drivers/net/wireless/b43/bus.h
-+++ b/drivers/net/wireless/b43/bus.h
-@@ -70,6 +70,18 @@ static inline bool b43_bus_host_is_sdio(
- 	return false;
- #endif
- }
-+static inline bool b43_bus_host_is_pci(struct b43_bus_dev *dev)
-+{
-+#ifdef CPTCFG_B43_BCMA
-+	if (dev->bus_type == B43_BUS_BCMA)
-+		return (dev->bdev->bus->hosttype == BCMA_HOSTTYPE_PCI);
-+#endif
-+#ifdef CPTCFG_B43_SSB
-+	if (dev->bus_type == B43_BUS_SSB)
-+		return (dev->sdev->bus->bustype == SSB_BUSTYPE_PCI);
-+#endif
-+	return false;
-+}
- 
- struct b43_bus_dev *b43_bus_dev_bcma_init(struct bcma_device *core);
- struct b43_bus_dev *b43_bus_dev_ssb_init(struct ssb_device *sdev);
---- a/drivers/net/wireless/b43/main.c
-+++ b/drivers/net/wireless/b43/main.c
-@@ -4481,7 +4481,7 @@ static int b43_phy_versioning(struct b43
- 		u16 radio24[3];
- 
- 		for (tmp = 0; tmp < 3; tmp++) {
--			b43_write16(dev, B43_MMIO_RADIO24_CONTROL, tmp);
-+			b43_wflush16(dev, B43_MMIO_RADIO24_CONTROL, tmp);
- 			radio24[tmp] = b43_read16(dev, B43_MMIO_RADIO24_DATA);
- 		}
- 
-@@ -4498,10 +4498,10 @@ static int b43_phy_versioning(struct b43
- 			else
- 				tmp = 0x5205017F;
- 		} else {
--			b43_write16(dev, B43_MMIO_RADIO_CONTROL,
-+			b43_wflush16(dev, B43_MMIO_RADIO_CONTROL,
- 				    B43_RADIOCTL_ID);
- 			tmp = b43_read16(dev, B43_MMIO_RADIO_DATA_LOW);
--			b43_write16(dev, B43_MMIO_RADIO_CONTROL,
-+			b43_wflush16(dev, B43_MMIO_RADIO_CONTROL,
- 				    B43_RADIOCTL_ID);
- 			tmp |= (u32)b43_read16(dev, B43_MMIO_RADIO_DATA_HIGH)
- 				<< 16;
-@@ -4576,6 +4576,26 @@ static int b43_phy_versioning(struct b43
- 	return 0;
- }
- 
-+/*
-+ * bcm4716 (which includes 4717 & 4718), plus 4706 on PCIe can reorder
-+ * transactions. As a fix, a read after write is performed on certain places
-+ * in the code. Older chips and the newer 5357 family don't require this fix.
-+ */
-+#ifdef CONFIG_BCM47XX_BCMA
-+#include <asm/mach-bcm47xx/bcm47xx.h>
-+void b43_wflush16(struct b43_wldev *dev, u16 offset, u16 value)
-+{
-+	if (b43_bus_host_is_pci(dev->dev) &&
-+	    bcm47xx_bus_type == BCM47XX_BUS_TYPE_BCMA &&
-+	    bcm47xx_bus.bcma.bus.chipinfo.id == BCMA_CHIP_ID_BCM4716) {
-+		b43_write16(dev, offset, value);
-+		b43_read16(dev, offset);
-+	} else {
-+		b43_write16(dev, offset, value);
-+	}
-+}
-+#endif
-+
- static void setup_struct_phy_for_init(struct b43_wldev *dev,
- 				      struct b43_phy *phy)
- {
---- a/drivers/net/wireless/b43/phy_common.c
-+++ b/drivers/net/wireless/b43/phy_common.c
-@@ -275,6 +275,12 @@ void b43_phy_write(struct b43_wldev *dev
- {
- 	assert_mac_suspended(dev);
- 	dev->phy.ops->phy_write(dev, reg, value);
-+#ifdef CONFIG_BCM47XX
-+	if (b43_bus_host_is_pci(dev->dev) && reg == 0x72) {
-+		b43_read16(dev, B43_MMIO_PHY_VER);
-+		return;
-+	}
-+#endif
- 	if (++dev->phy.writes_counter == B43_MAX_WRITES_IN_ROW) {
- 		b43_read16(dev, B43_MMIO_PHY_VER);
- 		dev->phy.writes_counter = 0;
---- a/drivers/net/wireless/b43/phy_ht.c
-+++ b/drivers/net/wireless/b43/phy_ht.c
-@@ -1073,20 +1073,20 @@ static unsigned int b43_phy_ht_op_get_de
- 
- static u16 b43_phy_ht_op_read(struct b43_wldev *dev, u16 reg)
- {
--	b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
-+	b43_wflush16(dev, B43_MMIO_PHY_CONTROL, reg);
- 	return b43_read16(dev, B43_MMIO_PHY_DATA);
- }
- 
- static void b43_phy_ht_op_write(struct b43_wldev *dev, u16 reg, u16 value)
- {
--	b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
-+	b43_wflush16(dev, B43_MMIO_PHY_CONTROL, reg);
- 	b43_write16(dev, B43_MMIO_PHY_DATA, value);
- }
- 
- static void b43_phy_ht_op_maskset(struct b43_wldev *dev, u16 reg, u16 mask,
- 				 u16 set)
- {
--	b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
-+	b43_wflush16(dev, B43_MMIO_PHY_CONTROL, reg);
- 	b43_write16(dev, B43_MMIO_PHY_DATA,
- 		    (b43_read16(dev, B43_MMIO_PHY_DATA) & mask) | set);
- }
-@@ -1096,14 +1096,14 @@ static u16 b43_phy_ht_op_radio_read(stru
- 	/* HT-PHY needs 0x200 for read access */
- 	reg |= 0x200;
- 
--	b43_write16(dev, B43_MMIO_RADIO24_CONTROL, reg);
-+	b43_wflush16(dev, B43_MMIO_RADIO24_CONTROL, reg);
- 	return b43_read16(dev, B43_MMIO_RADIO24_DATA);
- }
- 
- static void b43_phy_ht_op_radio_write(struct b43_wldev *dev, u16 reg,
- 				      u16 value)
- {
--	b43_write16(dev, B43_MMIO_RADIO24_CONTROL, reg);
-+	b43_wflush16(dev, B43_MMIO_RADIO24_CONTROL, reg);
- 	b43_write16(dev, B43_MMIO_RADIO24_DATA, value);
- }
- 
---- a/drivers/net/wireless/b43/phy_lcn.c
-+++ b/drivers/net/wireless/b43/phy_lcn.c
-@@ -812,20 +812,20 @@ static void b43_phy_lcn_op_adjust_txpowe
- 
- static u16 b43_phy_lcn_op_read(struct b43_wldev *dev, u16 reg)
- {
--	b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
-+	b43_wflush16(dev, B43_MMIO_PHY_CONTROL, reg);
- 	return b43_read16(dev, B43_MMIO_PHY_DATA);
- }
- 
- static void b43_phy_lcn_op_write(struct b43_wldev *dev, u16 reg, u16 value)
- {
--	b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
-+	b43_wflush16(dev, B43_MMIO_PHY_CONTROL, reg);
- 	b43_write16(dev, B43_MMIO_PHY_DATA, value);
- }
- 
- static void b43_phy_lcn_op_maskset(struct b43_wldev *dev, u16 reg, u16 mask,
- 				   u16 set)
- {
--	b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
-+	b43_wflush16(dev, B43_MMIO_PHY_CONTROL, reg);
- 	b43_write16(dev, B43_MMIO_PHY_DATA,
- 		    (b43_read16(dev, B43_MMIO_PHY_DATA) & mask) | set);
- }
-@@ -835,14 +835,14 @@ static u16 b43_phy_lcn_op_radio_read(str
- 	/* LCN-PHY needs 0x200 for read access */
- 	reg |= 0x200;
- 
--	b43_write16(dev, B43_MMIO_RADIO24_CONTROL, reg);
-+	b43_wflush16(dev, B43_MMIO_RADIO24_CONTROL, reg);
- 	return b43_read16(dev, B43_MMIO_RADIO24_DATA);
- }
- 
- static void b43_phy_lcn_op_radio_write(struct b43_wldev *dev, u16 reg,
- 				       u16 value)
- {
--	b43_write16(dev, B43_MMIO_RADIO24_CONTROL, reg);
-+	b43_wflush16(dev, B43_MMIO_RADIO24_CONTROL, reg);
- 	b43_write16(dev, B43_MMIO_RADIO24_DATA, value);
- }
- 
---- a/drivers/net/wireless/b43/phy_n.c
-+++ b/drivers/net/wireless/b43/phy_n.c
-@@ -6500,14 +6500,14 @@ static inline void check_phyreg(struct b
- static u16 b43_nphy_op_read(struct b43_wldev *dev, u16 reg)
- {
- 	check_phyreg(dev, reg);
--	b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
-+	b43_wflush16(dev, B43_MMIO_PHY_CONTROL, reg);
- 	return b43_read16(dev, B43_MMIO_PHY_DATA);
- }
- 
- static void b43_nphy_op_write(struct b43_wldev *dev, u16 reg, u16 value)
- {
- 	check_phyreg(dev, reg);
--	b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
-+	b43_wflush16(dev, B43_MMIO_PHY_CONTROL, reg);
- 	b43_write16(dev, B43_MMIO_PHY_DATA, value);
- }
- 
-@@ -6515,7 +6515,7 @@ static void b43_nphy_op_maskset(struct b
- 				 u16 set)
- {
- 	check_phyreg(dev, reg);
--	b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
-+	b43_wflush16(dev, B43_MMIO_PHY_CONTROL, reg);
- 	b43_maskset16(dev, B43_MMIO_PHY_DATA, mask, set);
- }
- 
-@@ -6529,7 +6529,7 @@ static u16 b43_nphy_op_radio_read(struct
- 	else
- 		reg |= 0x100;
- 
--	b43_write16(dev, B43_MMIO_RADIO_CONTROL, reg);
-+	b43_wflush16(dev, B43_MMIO_RADIO_CONTROL, reg);
- 	return b43_read16(dev, B43_MMIO_RADIO_DATA_LOW);
- }
- 
-@@ -6538,7 +6538,7 @@ static void b43_nphy_op_radio_write(stru
- 	/* Register 1 is a 32-bit register. */
- 	B43_WARN_ON(dev->phy.rev < 7 && reg == 1);
- 
--	b43_write16(dev, B43_MMIO_RADIO_CONTROL, reg);
-+	b43_wflush16(dev, B43_MMIO_RADIO_CONTROL, reg);
- 	b43_write16(dev, B43_MMIO_RADIO_DATA_LOW, value);
- }
- 

+ 1 - 1
package/kernel/mac80211/patches/845-b43-only-use-gpio-0-1-for-led.patch

@@ -1,6 +1,6 @@
 --- a/drivers/net/wireless/b43/main.c
 +++ b/drivers/net/wireless/b43/main.c
-@@ -2831,6 +2831,14 @@ static int b43_gpio_init(struct b43_wlde
+@@ -2861,6 +2861,14 @@ static int b43_gpio_init(struct b43_wlde
  	} else if (dev->dev->chip_id == 0x5354) {
  		/* Don't allow overtaking buttons GPIOs */
  		set &= 0x2; /* 0x2 is LED GPIO on BCM5354 */

+ 0 - 36
package/kernel/mac80211/patches/901-wlcore-don-t-switch-channels-on-disconnected-STA-vif.patch

@@ -1,36 +0,0 @@
-From 4101e8dc540d19f1f6c24930629149191786e4cd Mon Sep 17 00:00:00 2001
-From: Arik Nemtsov <[email protected]>
-Date: Mon, 9 Sep 2013 16:48:59 +0300
-Subject: [PATCH 27/75] wlcore: don't switch channels on disconnected STA vifs
-
-Sending the FW a channel switch command on a disconnected vif may result
-in a beacon loss event. Avoid this edge case.
-
-Signed-off-by: Arik Nemtsov <[email protected]>
----
- drivers/net/wireless/ti/wlcore/main.c | 7 +++++++
- 1 file changed, 7 insertions(+)
-
---- a/drivers/net/wireless/ti/wlcore/main.c
-+++ b/drivers/net/wireless/ti/wlcore/main.c
-@@ -5148,6 +5148,10 @@ static void wl12xx_op_channel_switch(str
- 	if (unlikely(wl->state == WLCORE_STATE_OFF)) {
- 		wl12xx_for_each_wlvif_sta(wl, wlvif) {
- 			struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif);
-+
-+			if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags))
-+				continue;
-+
- 			ieee80211_chswitch_done(vif, false);
- 		}
- 		goto out;
-@@ -5163,6 +5167,9 @@ static void wl12xx_op_channel_switch(str
- 	wl12xx_for_each_wlvif_sta(wl, wlvif) {
- 		unsigned long delay_usec;
- 
-+		if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags))
-+			continue;
-+
- 		ret = wl->ops->channel_switch(wl, wlvif, ch_switch);
- 		if (ret)
- 			goto out_sleep;

+ 22 - 22
package/kernel/mac80211/patches/910-01-add-support-for-mt7620.patch

@@ -1,6 +1,6 @@
---- a/drivers/net/wireless/rt2x00/rt2800.h	2014-06-30 01:05:26.000000000 +0300
-+++ b/drivers/net/wireless/rt2x00/rt2800.h	2014-06-30 01:23:42.000000000 +0300
-@@ -79,6 +79,7 @@
+--- a/drivers/net/wireless/rt2x00/rt2800.h
++++ b/drivers/net/wireless/rt2x00/rt2800.h
+@@ -81,6 +81,7 @@
  #define RF5372				0x5372
  #define RF5390				0x5390
  #define RF5392				0x5392
@@ -8,7 +8,7 @@
  
  /*
   * Chipset revisions.
-@@ -654,6 +655,14 @@
+@@ -656,6 +657,14 @@
  #define RF_CSR_CFG_BUSY			FIELD32(0x00020000)
  
  /*
@@ -23,7 +23,7 @@
   * EFUSE_CSR: RT30x0 EEPROM
   */
  #define EFUSE_CTRL			0x0580
-@@ -1037,6 +1046,11 @@
+@@ -1039,6 +1048,11 @@
  #define AUTOWAKEUP_CFG_AUTOWAKE		FIELD32(0x00008000)
  
  /*
@@ -35,7 +35,7 @@
   * EDCA_AC0_CFG:
   */
  #define EDCA_AC0_CFG			0x1300
-@@ -1216,6 +1230,8 @@
+@@ -1218,6 +1232,8 @@
  #define TX_PIN_CFG_RFTR_POL		FIELD32(0x00020000)
  #define TX_PIN_CFG_TRSW_EN		FIELD32(0x00040000)
  #define TX_PIN_CFG_TRSW_POL		FIELD32(0x00080000)
@@ -44,7 +44,7 @@
  #define TX_PIN_CFG_PA_PE_A2_EN		FIELD32(0x01000000)
  #define TX_PIN_CFG_PA_PE_G2_EN		FIELD32(0x02000000)
  #define TX_PIN_CFG_PA_PE_A2_POL		FIELD32(0x04000000)
-@@ -1562,6 +1578,17 @@
+@@ -1564,6 +1580,17 @@
  #define TX_PWR_CFG_4_EXT_STBC4_CH2	FIELD32(0x0000000f)
  #define TX_PWR_CFG_4_EXT_STBC6_CH2	FIELD32(0x00000f00)
  
@@ -62,8 +62,8 @@
  /* TX_PWR_CFG_7 */
  #define TX_PWR_CFG_7			0x13d4
  #define TX_PWR_CFG_7_OFDM54_CH0		FIELD32(0x0000000f)
---- a/drivers/net/wireless/rt2x00/rt2800lib.c	2014-06-30 01:05:26.000000000 +0300
-+++ b/drivers/net/wireless/rt2x00/rt2800lib.c	2014-06-30 17:31:35.000000000 +0300
+--- a/drivers/net/wireless/rt2x00/rt2800lib.c
++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
 @@ -61,6 +61,8 @@
  	rt2800_regbusy_read((__dev), BBP_CSR_CFG, BBP_CSR_CFG_BUSY, (__reg))
  #define WAIT_FOR_RFCSR(__dev, __reg) \
@@ -529,7 +529,7 @@
  	u8 bbp, rfcsr;
  
  	info->default_power1 = rt2800_txpower_to_dev(rt2x00dev, rf->channel,
-@@ -3535,6 +3911,9 @@ static void rt2800_config_channel(struct
+@@ -3536,6 +3912,9 @@ static void rt2800_config_channel(struct
  	case RF5592:
  		rt2800_config_channel_rf55xx(rt2x00dev, conf, rf, info);
  		break;
@@ -539,7 +539,7 @@
  	default:
  		rt2800_config_channel_rf2xxx(rt2x00dev, conf, rf, info);
  	}
-@@ -3631,7 +4010,7 @@ static void rt2800_config_channel(struct
+@@ -3638,7 +4017,7 @@ static void rt2800_config_channel(struct
  		else if (rt2x00_rt(rt2x00dev, RT3593) ||
  			 rt2x00_rt(rt2x00dev, RT3883))
  			rt2800_bbp_write(rt2x00dev, 82, 0x82);
@@ -548,7 +548,7 @@
  			rt2800_bbp_write(rt2x00dev, 82, 0xf2);
  
  		if (rt2x00_rt(rt2x00dev, RT3593) ||
-@@ -3653,7 +4032,7 @@ static void rt2800_config_channel(struct
+@@ -3660,7 +4039,7 @@ static void rt2800_config_channel(struct
  	if (rt2x00_rt(rt2x00dev, RT3572))
  		rt2800_rfcsr_write(rt2x00dev, 8, 0);
  
@@ -557,7 +557,7 @@
  
  	switch (rt2x00dev->default_ant.tx_chain_num) {
  	case 3:
-@@ -3702,6 +4081,7 @@ static void rt2800_config_channel(struct
+@@ -3709,6 +4088,7 @@ static void rt2800_config_channel(struct
  
  	rt2x00_set_field32(&tx_pin, TX_PIN_CFG_RFTR_EN, 1);
  	rt2x00_set_field32(&tx_pin, TX_PIN_CFG_TRSW_EN, 1);
@@ -565,7 +565,7 @@
  
  	rt2800_register_write(rt2x00dev, TX_PIN_CFG, tx_pin);
  
-@@ -4710,6 +5090,14 @@ void rt2800_vco_calibration(struct rt2x0
+@@ -4718,6 +5098,14 @@ void rt2800_vco_calibration(struct rt2x0
  		rt2x00_set_field8(&rfcsr, RFCSR3_VCOCAL_EN, 1);
  		rt2800_rfcsr_write(rt2x00dev, 3, rfcsr);
  		break;
@@ -580,7 +580,7 @@
  	default:
  		return;
  	}
-@@ -5110,9 +5498,42 @@ static int rt2800_init_registers(struct
+@@ -5118,9 +5506,42 @@ static int rt2800_init_registers(struct 
  	} else if (rt2x00_rt(rt2x00dev, RT5390) ||
  		   rt2x00_rt(rt2x00dev, RT5392) ||
  		   rt2x00_rt(rt2x00dev, RT5592)) {
@@ -626,7 +626,7 @@
  	} else if (rt2x00_rt(rt2x00dev, RT5350)) {
  		rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000404);
  	} else {
-@@ -6144,6 +6565,225 @@ static void rt2800_init_bbp_5592(struct
+@@ -6152,6 +6573,225 @@ static void rt2800_init_bbp_5592(struct 
  		rt2800_bbp_write(rt2x00dev, 103, 0xc0);
  }
  
@@ -852,7 +852,7 @@
  static void rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
  {
  	unsigned int i;
-@@ -6186,7 +6826,10 @@ static void rt2800_init_bbp(struct rt2x0
+@@ -6194,7 +6834,10 @@ static void rt2800_init_bbp(struct rt2x0
  		return;
  	case RT5390:
  	case RT5392:
@@ -864,7 +864,7 @@
  		break;
  	case RT5592:
  		rt2800_init_bbp_5592(rt2x00dev);
-@@ -7400,6 +8043,295 @@ static void rt2800_init_rfcsr_5592(struc
+@@ -7408,6 +8051,295 @@ static void rt2800_init_rfcsr_5592(struc
  	rt2800_led_open_drain_enable(rt2x00dev);
  }
  
@@ -1160,7 +1160,7 @@
  static void rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
  {
  	if (rt2800_is_305x_soc(rt2x00dev)) {
-@@ -7435,7 +8367,10 @@ static void rt2800_init_rfcsr(struct rt2
+@@ -7443,7 +8375,10 @@ static void rt2800_init_rfcsr(struct rt2
  		rt2800_init_rfcsr_5350(rt2x00dev);
  		break;
  	case RT5390:
@@ -1172,7 +1172,7 @@
  		break;
  	case RT5392:
  		rt2800_init_rfcsr_5392(rt2x00dev);
-@@ -7866,6 +8801,7 @@ static int rt2800_init_eeprom(struct rt2
+@@ -7875,6 +8810,7 @@ static int rt2800_init_eeprom(struct rt2
  	case RF5390:
  	case RF5392:
  	case RF5592:
@@ -1180,7 +1180,7 @@
  		break;
  	default:
  		rt2x00_err(rt2x00dev, "Invalid RF chipset 0x%04x detected\n",
-@@ -8431,6 +9367,7 @@ static int rt2800_probe_hw_mode(struct r
+@@ -8441,6 +9377,7 @@ static int rt2800_probe_hw_mode(struct r
  	case RF5372:
  	case RF5390:
  	case RF5392:
@@ -1188,7 +1188,7 @@
  		spec->num_channels = 14;
  		if (spec->clk_is_20mhz)
  			spec->channels = rf_vals_xtal20mhz_3x;
-@@ -8570,6 +9507,7 @@ static int rt2800_probe_hw_mode(struct r
+@@ -8581,6 +9518,7 @@ static int rt2800_probe_hw_mode(struct r
  	case RF5372:
  	case RF5390:
  	case RF5392:

+ 4 - 4
package/kernel/mac80211/patches/920-ath10k_allow_fallback_to_board_bin_on_empty_otp_stream.patch

@@ -1,14 +1,14 @@
 --- a/drivers/net/wireless/ath/ath10k/core.c
 +++ b/drivers/net/wireless/ath/ath10k/core.c
-@@ -277,7 +277,10 @@ static int ath10k_download_and_run_otp(s
+@@ -250,7 +250,10 @@ static int ath10k_download_and_run_otp(s
  
- 	ath10k_dbg(ATH10K_DBG_BOOT, "boot otp execute result %d\n", result);
+ 	ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot otp execute result %d\n", result);
  
 -	if (result != 0) {
 +	if (result == 2) {
-+		ath10k_warn("otp stream is empty, using board.bin contents");
++		ath10k_warn(ar, "otp stream is empty, using board.bin contents");
 +		return 0;
 +	} else if (result != 0) {
- 		ath10k_err("otp calibration failed: %d", result);
+ 		ath10k_err(ar, "otp calibration failed: %d", result);
  		return -EINVAL;
  	}