aboutsummaryrefslogtreecommitdiffstats
path: root/package/mac80211/patches
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@openwrt.org>2013-04-28 12:37:09 +0000
committerFelix Fietkau <nbd@openwrt.org>2013-04-28 12:37:09 +0000
commitd520c048d8eda9083b3fffb4e4e0a82a8a8b0c6b (patch)
tree55111555c00d21d4857262bd9ca3ee0bc2bcf222 /package/mac80211/patches
parentacd03cf8d8c3a047108b7983944b0c8d0228f812 (diff)
downloadupstream-d520c048d8eda9083b3fffb4e4e0a82a8a8b0c6b.tar.gz
upstream-d520c048d8eda9083b3fffb4e4e0a82a8a8b0c6b.tar.bz2
upstream-d520c048d8eda9083b3fffb4e4e0a82a8a8b0c6b.zip
mac80211: update to 2013-02-22 from trunk + backports
Signed-off-by: Felix Fietkau <nbd@openwrt.org> git-svn-id: svn://svn.openwrt.org/openwrt/branches/attitude_adjustment@36470 3c298f89-4303-0410-b956-a3cf2f4a3e73
Diffstat (limited to 'package/mac80211/patches')
-rw-r--r--package/mac80211/patches/000-disable_ethernet.patch12
-rw-r--r--package/mac80211/patches/001-disable_b44.patch13
-rw-r--r--package/mac80211/patches/001-disable_rfkill.patch13
-rw-r--r--package/mac80211/patches/002-disable_rfkill.patch38
-rw-r--r--package/mac80211/patches/002-disable_ssb_build.patch21
-rw-r--r--package/mac80211/patches/003-disable_bt.patch15
-rw-r--r--package/mac80211/patches/003-disable_codel.patch (renamed from package/mac80211/patches/070-disable_codel.patch)0
-rw-r--r--package/mac80211/patches/004-use_env_for_bash.patch8
-rw-r--r--package/mac80211/patches/005-disable_ssb_build.patch49
-rw-r--r--package/mac80211/patches/006-disable_bcma_build.patch30
-rw-r--r--package/mac80211/patches/007-remove_misc_drivers.patch61
-rw-r--r--package/mac80211/patches/008-disable_mesh.patch11
-rw-r--r--package/mac80211/patches/009-remove_mac80211_module_dependence.patch11
-rw-r--r--package/mac80211/patches/010-add_include_for_bcma.patch (renamed from package/mac80211/patches/021-add_include_for_bcma.patch)0
-rw-r--r--package/mac80211/patches/010-no_pcmcia.patch20
-rw-r--r--package/mac80211/patches/011-no_sdio.patch11
-rw-r--r--package/mac80211/patches/013-disable_b43_nphy.patch13
-rw-r--r--package/mac80211/patches/015-remove-rt2x00-options.patch20
-rw-r--r--package/mac80211/patches/016-remove_pid_algo.patch11
-rw-r--r--package/mac80211/patches/017-remove_ath9k_rc.patch11
-rw-r--r--package/mac80211/patches/018-revert_printk_va_format.patch188
-rw-r--r--package/mac80211/patches/019-remove_ath5k_pci_option.patch11
-rw-r--r--package/mac80211/patches/020-disable_tty_set_termios.patch (renamed from package/mac80211/patches/030-disable_tty_set_termios.patch)0
-rw-r--r--package/mac80211/patches/022-remove_crc8_and_cordic.patch166
-rw-r--r--package/mac80211/patches/023-ath9k_disable_btcoex.patch11
-rw-r--r--package/mac80211/patches/030-wext.patch18
-rw-r--r--package/mac80211/patches/040-linux_3_9_compat.patch153
-rw-r--r--package/mac80211/patches/050-compat_firmware.patch78
-rw-r--r--package/mac80211/patches/060-compat_add_module_pci_driver.patch22
-rw-r--r--package/mac80211/patches/071-add_codel_ifdef.patch19
-rw-r--r--package/mac80211/patches/100-disable_pcmcia_compat.patch65
-rw-r--r--package/mac80211/patches/110-disable_usb_compat.patch44
-rw-r--r--package/mac80211/patches/130-mesh_pathtbl_backport.patch208
-rw-r--r--package/mac80211/patches/150-disable_addr_notifier.patch67
-rw-r--r--package/mac80211/patches/300-pending_work.patch3175
-rw-r--r--package/mac80211/patches/310-ap_scan.patch16
-rw-r--r--package/mac80211/patches/320-ath9k_no_eeprom_name.patch24
-rw-r--r--package/mac80211/patches/321-bcma_backport.patch42
-rw-r--r--package/mac80211/patches/400-ath_move_debug_code.patch4
-rw-r--r--package/mac80211/patches/401-ath9k_blink_default.patch2
-rw-r--r--package/mac80211/patches/402-ath9k-fix-invalid-mac-address-handling.patch2
-rw-r--r--package/mac80211/patches/403-ath_regd_optional.patch16
-rw-r--r--package/mac80211/patches/405-regd_no_assoc_hints.patch13
-rw-r--r--package/mac80211/patches/410-ath9k_allow_adhoc_and_ap.patch8
-rw-r--r--package/mac80211/patches/411-ath5k_allow_adhoc_and_ap.patch10
-rw-r--r--package/mac80211/patches/412-mac80211_allow_adhoc_and_ap.patch20
-rw-r--r--package/mac80211/patches/420-ath5k_disable_fast_cc.patch4
-rw-r--r--package/mac80211/patches/500-ath9k_eeprom_debugfs.patch18
-rw-r--r--package/mac80211/patches/501-ath9k-eeprom_endianess.patch30
-rw-r--r--package/mac80211/patches/502-ath9k_ahb_init.patch2
-rw-r--r--package/mac80211/patches/510-ath9k_intr_mitigation_tweak.patch2
-rw-r--r--package/mac80211/patches/511-ath9k_reduce_rxbuf.patch2
-rw-r--r--package/mac80211/patches/512-ath9k_channelbw_debugfs.patch28
-rw-r--r--package/mac80211/patches/513-mac80211_reduce_txqueuelen.patch10
-rw-r--r--package/mac80211/patches/520-mac80211_cur_txpower.patch22
-rw-r--r--package/mac80211/patches/521-ath9k_cur_txpower.patch4
-rw-r--r--package/mac80211/patches/522-ath9k_per_chain_signal_strength.patch99
-rw-r--r--package/mac80211/patches/523-cfg80211_fix_antenna_gain.patch12
-rw-r--r--package/mac80211/patches/523-mac80211_configure_antenna_gain.patch (renamed from package/mac80211/patches/524-mac80211_configure_antenna_gain.patch)149
-rw-r--r--package/mac80211/patches/524-ath9k_use_configured_antenna_gain.patch (renamed from package/mac80211/patches/525-ath9k_use_configured_antenna_gain.patch)4
-rw-r--r--package/mac80211/patches/526-cfg80211_fix_max_reg_power.patch21
-rw-r--r--package/mac80211/patches/530-ath9k_extra_leds.patch (renamed from package/mac80211/patches/540-ath9k_extra_leds.patch)42
-rw-r--r--package/mac80211/patches/530-ath9k_fix_initvals.patch208
-rw-r--r--package/mac80211/patches/531-ath9k_extra_platform_leds.patch (renamed from package/mac80211/patches/541-ath9k_extra_platform_leds.patch)4
-rw-r--r--package/mac80211/patches/540-mac80211_optimize_mcs_rate_mask.patch (renamed from package/mac80211/patches/550-mac80211_optimize_mcs_rate_mask.patch)14
-rw-r--r--package/mac80211/patches/541-ath9k_optimize_interrupt_mitigation.patch (renamed from package/mac80211/patches/551-ath9k_optimize_interrupt_mitigation.patch)2
-rw-r--r--package/mac80211/patches/550-ath9k_reduce_ani_interval.patch (renamed from package/mac80211/patches/560-ath9k_reduce_ani_interval.patch)0
-rw-r--r--package/mac80211/patches/551-ath9k_revert_initval_change.patch (renamed from package/mac80211/patches/561-ath9k_revert_initval_change.patch)0
-rw-r--r--package/mac80211/patches/552-ath9k_rx_dma_stop_check.patch (renamed from package/mac80211/patches/563-ath9k_rx_dma_stop_check.patch)0
-rw-r--r--package/mac80211/patches/553-ath9k_debugfs_diag.patch (renamed from package/mac80211/patches/564-ath9k_debugfs_diag.patch)34
-rw-r--r--package/mac80211/patches/554-ath9k_ani_mrc_fix.patch (renamed from package/mac80211/patches/567-ath9k_ani_mrc_fix.patch)2
-rw-r--r--package/mac80211/patches/555-ath9k-allow-to-disable-bands-via-platform-data.patch (renamed from package/mac80211/patches/b01-ath9k-allow-to-disable-bands-via-platform-data.patch)14
-rw-r--r--package/mac80211/patches/562-ath9k_add_idle_hack.patch20
-rw-r--r--package/mac80211/patches/565-ath9k_disable_paprd.patch72
-rw-r--r--package/mac80211/patches/566-ath9k_use_ieee80211_free_txskb.patch149
-rw-r--r--package/mac80211/patches/568-ath9k_fix_stale_pointer.patch18
-rw-r--r--package/mac80211/patches/603-rt2x00-introduce-rt2x00eeprom.patch25
-rw-r--r--package/mac80211/patches/604-rt2x00-add-CONFIG_RT2X00_LIB_EEPROM-option.patch2
-rw-r--r--package/mac80211/patches/605-rt2x00-pci-eeprom.patch18
-rw-r--r--package/mac80211/patches/606-rt2x00_no_realign.patch2
-rw-r--r--package/mac80211/patches/607-rt2x00-allow_disabling_bands_through_platform_data.patch4
-rw-r--r--package/mac80211/patches/608-add_platform_data_mac_addr.patch4
-rw-r--r--package/mac80211/patches/610-rt2x00-fix-rt3352-ext-pa.patch214
-rw-r--r--package/mac80211/patches/611-rt2x00-rf_vals-rt3352-xtal20.patch (renamed from package/mac80211/patches/623-rt2x00-rf_vals-rt3352-xtal20.patch)14
-rw-r--r--package/mac80211/patches/612-rt2x00-make-wmac-loadable-via-OF-on-rt288x-305x-SoC.patch34
-rw-r--r--package/mac80211/patches/613-rt2x00-fixup-symbols.patch47
-rw-r--r--package/mac80211/patches/614-rt2x00-of_load_eeprom_filename.patch20
-rw-r--r--package/mac80211/patches/615-rt2x00-fix_20mhz_clk.patch29
-rw-r--r--package/mac80211/patches/616-rt2x00-support-rt5350.patch407
-rw-r--r--package/mac80211/patches/617-rt2x00-load-eeprom-on-SoC-from-a-mtd-device-defines-.patch102
-rw-r--r--package/mac80211/patches/620-rt2x00-support-rt3352.patch455
-rw-r--r--package/mac80211/patches/621-rt2x00-fix-rt3352-lnagain.patch25
-rw-r--r--package/mac80211/patches/622-rt2x00-fix-rt3352-ext-pa.patch212
-rw-r--r--package/mac80211/patches/700-mwl8k-missing-pci-id-for-WNR854T.patch2
-rw-r--r--package/mac80211/patches/701-mwl8k-don-t-overwrite-regulatory-settings.patch70
-rw-r--r--package/mac80211/patches/702-mwl8k-always-apply-configuration-even-when-device-is.patch44
-rw-r--r--package/mac80211/patches/800-b43-gpio-mask-module-option.patch4
-rw-r--r--package/mac80211/patches/810-b43_no_pio.patch2
-rw-r--r--package/mac80211/patches/820-b43-add-antenna-control.patch18
-rw-r--r--package/mac80211/patches/830-b43-workaround-pcie-bcm4716.patch2
-rw-r--r--package/mac80211/patches/849-brcmsmac-add-device-found-on-some-SoCs-like-the-bcm4.patch39
-rw-r--r--package/mac80211/patches/850-brcmsmac-add-support-for-BCM43224.patch29
-rw-r--r--package/mac80211/patches/850-brcmsmac-start-adding-support-for-core-rev-28.patch (renamed from package/mac80211/patches/851-brcmsmac-start-adding-support-for-core-rev-28.patch)12
-rw-r--r--package/mac80211/patches/860-brcmsmac-implement-ieee80211_ops-get_tsf-and-set_tsf.patch121
-rw-r--r--package/mac80211/patches/861-brcmsmac-add-interface-type-to-brcms_bss_cfg.patch66
-rw-r--r--package/mac80211/patches/862-brcmsmac-remove-brcms_bss_cfg-BSS.patch79
-rw-r--r--package/mac80211/patches/863-brcmsmac-remove-brcms_bss_cfg-associated.patch74
-rw-r--r--package/mac80211/patches/864-brcmsmac-remove-brcms_bss_cfg-enable.patch32
-rw-r--r--package/mac80211/patches/865-brcmsmac-remove-brcms_bss_cfg-up.patch51
-rw-r--r--package/mac80211/patches/866-brcmsmac-remove-brcms_bss_cfg-cur_etheraddr.patch30
-rw-r--r--package/mac80211/patches/867-brcmsmac-remove-brcms_pub-bcmerr.patch21
-rw-r--r--package/mac80211/patches/868-brcmsmac-write-beacon-period-to-hardware.patch23
-rw-r--r--package/mac80211/patches/869-brcmsmac-add-beacon-template-support.patch266
-rw-r--r--package/mac80211/patches/870-brcmsmac-react-on-changing-SSID.patch43
-rw-r--r--package/mac80211/patches/871-brcmsmac-add-support-for-probe-response-template.patch216
-rw-r--r--package/mac80211/patches/872-brcmsmac-deactivate-ucode-sending-probe-responses.patch59
-rw-r--r--package/mac80211/patches/873-brcmsmac-activate-AP-support.patch79
-rw-r--r--package/mac80211/patches/874-brcmsmac-add-support-for-adhoc-mode.patch74
-rw-r--r--package/mac80211/patches/875-brcmsmac-remove-extra-regulation-restriction.patch31
-rw-r--r--package/mac80211/patches/b02-rt2x00-add-multiple-ap.patch94
120 files changed, 4521 insertions, 4410 deletions
diff --git a/package/mac80211/patches/000-disable_ethernet.patch b/package/mac80211/patches/000-disable_ethernet.patch
deleted file mode 100644
index 08f908b10f..0000000000
--- a/package/mac80211/patches/000-disable_ethernet.patch
+++ /dev/null
@@ -1,12 +0,0 @@
---- a/Makefile
-+++ b/Makefile
-@@ -45,9 +45,6 @@ obj-$(CONFIG_COMPAT_WIRELESS_MODULES) +=
-
- obj-$(CONFIG_COMPAT_NET_USB_MODULES) += drivers/net/usb/
-
--obj-$(CONFIG_COMPAT_NETWORK_MODULES) += drivers/net/ethernet/atheros/
--obj-$(CONFIG_COMPAT_NETWORK_MODULES) += drivers/net/ethernet/broadcom/
--
- obj-$(CONFIG_COMPAT_VAR_MODULES) += drivers/ssb/
- obj-$(CONFIG_COMPAT_VAR_MODULES) += drivers/bcma/
- obj-$(CONFIG_COMPAT_VAR_MODULES) += drivers/misc/eeprom/
diff --git a/package/mac80211/patches/001-disable_b44.patch b/package/mac80211/patches/001-disable_b44.patch
deleted file mode 100644
index 389dac1aed..0000000000
--- a/package/mac80211/patches/001-disable_b44.patch
+++ /dev/null
@@ -1,13 +0,0 @@
---- a/config.mk
-+++ b/config.mk
-@@ -377,8 +377,8 @@ export CONFIG_B43_BCMA_EXTRA=y
-
- export CONFIG_P54_PCI=m
-
--export CONFIG_B44=m
--export CONFIG_B44_PCI=y
-+# export CONFIG_B44=m
-+# export CONFIG_B44_PCI=y
-
- export CONFIG_RTL8180=m
-
diff --git a/package/mac80211/patches/001-disable_rfkill.patch b/package/mac80211/patches/001-disable_rfkill.patch
new file mode 100644
index 0000000000..7af485f5bf
--- /dev/null
+++ b/package/mac80211/patches/001-disable_rfkill.patch
@@ -0,0 +1,13 @@
+--- a/include/linux/rfkill.h
++++ b/include/linux/rfkill.h
+@@ -3,6 +3,10 @@
+
+ #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,31))
+
++#undef CONFIG_RFKILL
++#undef CONFIG_RFKILL_LEDS
++#undef CONFIG_RFKILL_MODULE
++
+ #include_next <linux/rfkill.h>
+
+ #else
diff --git a/package/mac80211/patches/002-disable_rfkill.patch b/package/mac80211/patches/002-disable_rfkill.patch
deleted file mode 100644
index 685006bd58..0000000000
--- a/package/mac80211/patches/002-disable_rfkill.patch
+++ /dev/null
@@ -1,38 +0,0 @@
---- a/config.mk
-+++ b/config.mk
-@@ -78,7 +78,7 @@ endif # build check
- endif # kernel Makefile check
-
- # These both are needed by 802.11 and bluetooth so enable
-- export CONFIG_COMPAT_RFKILL=y
-+# export CONFIG_COMPAT_RFKILL=y
-
- ifeq ($(CONFIG_MAC80211),y)
- $(error "ERROR: you have MAC80211 compiled into the kernel, CONFIG_MAC80211=y, as such you cannot replace its mac80211 driver. You need this set to CONFIG_MAC80211=m. If you are using Fedora upgrade your kernel as later version should this set as modular. For further information on Fedora see https://bugzilla.redhat.com/show_bug.cgi?id=470143. If you are using your own kernel recompile it and make mac80211 modular")
-@@ -690,10 +690,10 @@ endif #CONFIG_COMPAT_KERNEL_2_6_27
- # We need the backported rfkill module on kernel < 2.6.31.
- # In more recent kernel versions use the in kernel rfkill module.
- ifdef CONFIG_COMPAT_KERNEL_2_6_31
--export CONFIG_RFKILL_BACKPORT=m
-+#export CONFIG_RFKILL_BACKPORT=m
- ifdef CONFIG_LEDS_TRIGGERS
--export CONFIG_RFKILL_BACKPORT_LEDS=y
-+#export CONFIG_RFKILL_BACKPORT_LEDS=y
- endif #CONFIG_LEDS_TRIGGERS
--export CONFIG_RFKILL_BACKPORT_INPUT=y
-+#export CONFIG_RFKILL_BACKPORT_INPUT=y
- endif #CONFIG_COMPAT_KERNEL_2_6_31
-
---- a/include/linux/rfkill.h
-+++ b/include/linux/rfkill.h
-@@ -3,6 +3,10 @@
-
- #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,31))
-
-+#undef CONFIG_RFKILL
-+#undef CONFIG_RFKILL_LEDS
-+#undef CONFIG_RFKILL_MODULE
-+
- #include_next <linux/rfkill.h>
-
- #else
diff --git a/package/mac80211/patches/002-disable_ssb_build.patch b/package/mac80211/patches/002-disable_ssb_build.patch
new file mode 100644
index 0000000000..ef184c416a
--- /dev/null
+++ b/package/mac80211/patches/002-disable_ssb_build.patch
@@ -0,0 +1,21 @@
+--- a/config.mk
++++ b/config.mk
+@@ -364,7 +364,8 @@ export CONFIG_IPW2200_QOS=y
+ # % echo 1 > /sys/bus/pci/drivers/ipw2200/*/rtap_iface
+ endif #CONFIG_WIRELESS_EXT
+
+-ifdef CONFIG_SSB
++# disabled
++ifdef __CONFIG_SSB
+ # Sonics Silicon Backplane
+ export CONFIG_SSB_SPROM=y
+
+@@ -377,7 +378,7 @@ endif #CONFIG_PCMCIA
+ # export CONFIG_SSB_DEBUG=y
+ export CONFIG_SSB_DRIVER_PCICORE=y
+ export CONFIG_B43_SSB=y
+-endif #CONFIG_SSB
++endif #__CONFIG_SSB
+
+ # export CONFIG_BCMA=m
+ # export CONFIG_BCMA_BLOCKIO=y
diff --git a/package/mac80211/patches/003-disable_bt.patch b/package/mac80211/patches/003-disable_bt.patch
deleted file mode 100644
index b56ccbdc6a..0000000000
--- a/package/mac80211/patches/003-disable_bt.patch
+++ /dev/null
@@ -1,15 +0,0 @@
---- a/config.mk
-+++ b/config.mk
-@@ -100,9 +100,9 @@ ifndef CONFIG_COMPAT_KERNEL_2_6_27
- ifeq ($(CONFIG_BT),y)
- # we'll ignore compiling bluetooth
- else
-- export CONFIG_COMPAT_BLUETOOTH=y
-- export CONFIG_COMPAT_BLUETOOTH_MODULES=m
-- export CONFIG_HID_GENERIC=m
-+# export CONFIG_COMPAT_BLUETOOTH=y
-+# export CONFIG_COMPAT_BLUETOOTH_MODULES=m
-+# export CONFIG_HID_GENERIC=m
- endif
- endif #CONFIG_COMPAT_KERNEL_2_6_27
-
diff --git a/package/mac80211/patches/070-disable_codel.patch b/package/mac80211/patches/003-disable_codel.patch
index 0d6d749110..0d6d749110 100644
--- a/package/mac80211/patches/070-disable_codel.patch
+++ b/package/mac80211/patches/003-disable_codel.patch
diff --git a/package/mac80211/patches/004-use_env_for_bash.patch b/package/mac80211/patches/004-use_env_for_bash.patch
new file mode 100644
index 0000000000..0ae382055a
--- /dev/null
+++ b/package/mac80211/patches/004-use_env_for_bash.patch
@@ -0,0 +1,8 @@
+--- a/compat/scripts/gen-compat-config.sh
++++ b/compat/scripts/gen-compat-config.sh
+@@ -1,4 +1,4 @@
+-#!/bin/bash
++#!/usr/bin/env bash
+ # Copyright 2012 Luis R. Rodriguez <mcgrof@frijolero.org>
+ # Copyright 2012 Hauke Mehrtens <hauke@hauke-m.de>
+ #
diff --git a/package/mac80211/patches/005-disable_ssb_build.patch b/package/mac80211/patches/005-disable_ssb_build.patch
deleted file mode 100644
index d42a6121d1..0000000000
--- a/package/mac80211/patches/005-disable_ssb_build.patch
+++ /dev/null
@@ -1,49 +0,0 @@
---- a/Makefile
-+++ b/Makefile
-@@ -45,7 +45,6 @@ obj-$(CONFIG_COMPAT_WIRELESS_MODULES) +=
-
- obj-$(CONFIG_COMPAT_NET_USB_MODULES) += drivers/net/usb/
-
--obj-$(CONFIG_COMPAT_VAR_MODULES) += drivers/ssb/
- obj-$(CONFIG_COMPAT_VAR_MODULES) += drivers/bcma/
- obj-$(CONFIG_COMPAT_VAR_MODULES) += drivers/misc/eeprom/
-
---- a/config.mk
-+++ b/config.mk
-@@ -3,7 +3,7 @@ ifeq ($(wildcard $(KLIB_BUILD)/.config),
- export CONFIG_PCI=y
- export CONFIG_USB=y
- export CONFIG_PCMCIA=y
-- export CONFIG_SSB=m
-+# export CONFIG_SSB=m
- else
- include $(KLIB_BUILD)/.config
- endif
-@@ -353,7 +353,8 @@ export CONFIG_IPW2200_QOS=y
- # % echo 1 > /sys/bus/pci/drivers/ipw2200/*/rtap_iface
- endif #CONFIG_WIRELESS_EXT
-
--ifdef CONFIG_SSB
-+# disabled
-+ifdef __CONFIG_SSB
- # Sonics Silicon Backplane
- export CONFIG_SSB_SPROM=y
-
-@@ -366,7 +367,7 @@ endif #CONFIG_PCMCIA
- # export CONFIG_SSB_DEBUG=y
- export CONFIG_SSB_DRIVER_PCICORE=y
- export CONFIG_B43_SSB=y
--endif #CONFIG_SSB
-+endif #__CONFIG_SSB
-
- export CONFIG_BCMA=m
- export CONFIG_BCMA_BLOCKIO=y
-@@ -580,7 +581,7 @@ endif #CONFIG_SPI_MASTER end of SPI driv
-
- ifdef CONFIG_MMC
-
--export CONFIG_SSB_SDIOHOST=y
-+# export CONFIG_SSB_SDIOHOST=y
- export CONFIG_B43_SDIO=y
-
- ifdef CONFIG_CRC7
diff --git a/package/mac80211/patches/006-disable_bcma_build.patch b/package/mac80211/patches/006-disable_bcma_build.patch
deleted file mode 100644
index da11ad4556..0000000000
--- a/package/mac80211/patches/006-disable_bcma_build.patch
+++ /dev/null
@@ -1,30 +0,0 @@
---- a/Makefile
-+++ b/Makefile
-@@ -45,7 +45,6 @@ obj-$(CONFIG_COMPAT_WIRELESS_MODULES) +=
-
- obj-$(CONFIG_COMPAT_NET_USB_MODULES) += drivers/net/usb/
-
--obj-$(CONFIG_COMPAT_VAR_MODULES) += drivers/bcma/
- obj-$(CONFIG_COMPAT_VAR_MODULES) += drivers/misc/eeprom/
-
- ifeq ($(CONFIG_STAGING_EXCLUDE_BUILD),)
---- a/config.mk
-+++ b/config.mk
-@@ -369,12 +369,12 @@ export CONFIG_SSB_DRIVER_PCICORE=y
- export CONFIG_B43_SSB=y
- endif #__CONFIG_SSB
-
--export CONFIG_BCMA=m
--export CONFIG_BCMA_BLOCKIO=y
--export CONFIG_BCMA_HOST_PCI=y
-+# export CONFIG_BCMA=m
-+# export CONFIG_BCMA_BLOCKIO=y
-+# export CONFIG_BCMA_HOST_PCI=y
- # export CONFIG_BCMA_DEBUG=y
--export CONFIG_B43_BCMA=y
--export CONFIG_B43_BCMA_EXTRA=y
-+# export CONFIG_B43_BCMA=y
-+# export CONFIG_B43_BCMA_EXTRA=y
-
- export CONFIG_P54_PCI=m
-
diff --git a/package/mac80211/patches/007-remove_misc_drivers.patch b/package/mac80211/patches/007-remove_misc_drivers.patch
deleted file mode 100644
index 9e7f651665..0000000000
--- a/package/mac80211/patches/007-remove_misc_drivers.patch
+++ /dev/null
@@ -1,61 +0,0 @@
---- a/config.mk
-+++ b/config.mk
-@@ -241,7 +241,7 @@ $(warning "WARNING: CONFIG_CFG80211_WEXT
- endif #CONFIG_WIRELESS_EXT
-
- ifdef CONFIG_STAGING
--export CONFIG_COMPAT_STAGING=m
-+# export CONFIG_COMPAT_STAGING=m
- endif #CONFIG_STAGING
-
- # mac80211 test driver
-@@ -406,12 +406,12 @@ endif #CONFIG_CRC_ITU_T
- export CONFIG_MWL8K=m
-
- # Ethernet drivers go here
--export CONFIG_ATL1=m
--export CONFIG_ATL2=m
--export CONFIG_ATL1E=m
-+# export CONFIG_ATL1=m
-+# export CONFIG_ATL2=m
-+# export CONFIG_ATL1E=m
- ifndef CONFIG_COMPAT_KERNEL_2_6_28
--export CONFIG_ATL1C=m
--export CONFIG_ALX=m
-+# export CONFIG_ATL1C=m
-+# export CONFIG_ALX=m
- endif #CONFIG_COMPAT_KERNEL_2_6_28
-
- ifdef CONFIG_WIRELESS_EXT
-@@ -472,21 +472,21 @@ endif #CONFIG_COMPAT_KERNEL_2_6_29
- # Note: this depends on CONFIG_USB_NET_RNDIS_HOST and CONFIG_USB_NET_CDCETHER
- # it also requires new RNDIS_HOST and CDC_ETHER modules which we add
- ifdef CONFIG_COMPAT_KERNEL_2_6_29
--export CONFIG_USB_COMPAT_USBNET=n
--export CONFIG_USB_NET_COMPAT_RNDIS_HOST=n
--export CONFIG_USB_NET_COMPAT_RNDIS_WLAN=n
--export CONFIG_USB_NET_COMPAT_CDCETHER=n
-+# export CONFIG_USB_COMPAT_USBNET=n
-+# export CONFIG_USB_NET_COMPAT_RNDIS_HOST=n
-+# export CONFIG_USB_NET_COMPAT_RNDIS_WLAN=n
-+# export CONFIG_USB_NET_COMPAT_CDCETHER=n
- else #CONFIG_COMPAT_KERNEL_2_6_29
--export CONFIG_USB_COMPAT_USBNET=m
-+# export CONFIG_USB_COMPAT_USBNET=m
- ifdef CONFIG_USB_NET_CDCETHER
--export CONFIG_USB_NET_COMPAT_RNDIS_HOST=m
--export CONFIG_USB_NET_COMPAT_RNDIS_WLAN=m
-+# export CONFIG_USB_NET_COMPAT_RNDIS_HOST=m
-+# export CONFIG_USB_NET_COMPAT_RNDIS_WLAN=m
- endif #CONFIG_USB_NET_CDCETHER
- ifdef CONFIG_USB_NET_CDCETHER_MODULE
--export CONFIG_USB_NET_COMPAT_RNDIS_HOST=m
--export CONFIG_USB_NET_COMPAT_RNDIS_WLAN=m
-+# export CONFIG_USB_NET_COMPAT_RNDIS_HOST=m
-+# export CONFIG_USB_NET_COMPAT_RNDIS_WLAN=m
- endif #CONFIG_USB_NET_CDCETHER
--export CONFIG_USB_NET_COMPAT_CDCETHER=m
-+# export CONFIG_USB_NET_COMPAT_CDCETHER=m
- endif #CONFIG_COMPAT_KERNEL_2_6_29
-
-
diff --git a/package/mac80211/patches/008-disable_mesh.patch b/package/mac80211/patches/008-disable_mesh.patch
deleted file mode 100644
index d5a0ac8e6e..0000000000
--- a/package/mac80211/patches/008-disable_mesh.patch
+++ /dev/null
@@ -1,11 +0,0 @@
---- a/config.mk
-+++ b/config.mk
-@@ -177,7 +177,7 @@ export CONFIG_MAC80211_LEDS=y
- endif #CONFIG_LEDS_TRIGGERS
-
- # enable mesh networking too
--export CONFIG_MAC80211_MESH=y
-+# export CONFIG_MAC80211_MESH=y
-
- export CONFIG_CFG80211=m
- export CONFIG_CFG80211_DEFAULT_PS=y
diff --git a/package/mac80211/patches/009-remove_mac80211_module_dependence.patch b/package/mac80211/patches/009-remove_mac80211_module_dependence.patch
deleted file mode 100644
index 2bc46c4ed6..0000000000
--- a/package/mac80211/patches/009-remove_mac80211_module_dependence.patch
+++ /dev/null
@@ -1,11 +0,0 @@
---- a/config.mk
-+++ b/config.mk
-@@ -54,7 +54,7 @@ endif
- ifeq ($(KERNEL_VERSION),2)
- ifeq ($(shell test $(KERNEL_VERSION) -eq 2 -a $(KERNEL_26SUBLEVEL) -ge 27 -a $(KERNEL_26SUBLEVEL) -le 31 && echo yes),yes)
- ifeq ($(CONFIG_MAC80211),)
--$(error "ERROR: Your >=2.6.27 and <= 2.6.31 kernel has CONFIG_MAC80211 disabled, you should have it CONFIG_MAC80211=m if you want to use this thing.")
-+# $(error "ERROR: Your >=2.6.27 and <= 2.6.31 kernel has CONFIG_MAC80211 disabled, you should have it CONFIG_MAC80211=m if you want to use this thing.")
- endif
- endif
- endif
diff --git a/package/mac80211/patches/021-add_include_for_bcma.patch b/package/mac80211/patches/010-add_include_for_bcma.patch
index e2e856eb05..e2e856eb05 100644
--- a/package/mac80211/patches/021-add_include_for_bcma.patch
+++ b/package/mac80211/patches/010-add_include_for_bcma.patch
diff --git a/package/mac80211/patches/010-no_pcmcia.patch b/package/mac80211/patches/010-no_pcmcia.patch
deleted file mode 100644
index af6a7545be..0000000000
--- a/package/mac80211/patches/010-no_pcmcia.patch
+++ /dev/null
@@ -1,20 +0,0 @@
---- a/config.mk
-+++ b/config.mk
-@@ -2,7 +2,7 @@ ifeq ($(wildcard $(KLIB_BUILD)/.config),
- # These will be ignored by compat autoconf
- export CONFIG_PCI=y
- export CONFIG_USB=y
-- export CONFIG_PCMCIA=y
-+# export CONFIG_PCMCIA=y
- # export CONFIG_SSB=m
- else
- include $(KLIB_BUILD)/.config
-@@ -304,7 +304,7 @@ export CONFIG_B43=m
- export CONFIG_B43_HWRNG=y
- export CONFIG_B43_PCI_AUTOSELECT=y
- ifdef CONFIG_PCMCIA
--export CONFIG_B43_PCMCIA=y
-+# export CONFIG_B43_PCMCIA=y
- endif #CONFIG_PCMCIA
- ifdef CONFIG_MAC80211_LEDS
- export CONFIG_B43_LEDS=y
diff --git a/package/mac80211/patches/011-no_sdio.patch b/package/mac80211/patches/011-no_sdio.patch
deleted file mode 100644
index 4d364e0454..0000000000
--- a/package/mac80211/patches/011-no_sdio.patch
+++ /dev/null
@@ -1,11 +0,0 @@
---- a/config.mk
-+++ b/config.mk
-@@ -582,7 +582,7 @@ endif #CONFIG_SPI_MASTER end of SPI driv
- ifdef CONFIG_MMC
-
- # export CONFIG_SSB_SDIOHOST=y
--export CONFIG_B43_SDIO=y
-+# export CONFIG_B43_SDIO=y
-
- ifdef CONFIG_CRC7
- ifdef CONFIG_WL12XX_PLATFORM_DATA
diff --git a/package/mac80211/patches/013-disable_b43_nphy.patch b/package/mac80211/patches/013-disable_b43_nphy.patch
deleted file mode 100644
index ba37bad951..0000000000
--- a/package/mac80211/patches/013-disable_b43_nphy.patch
+++ /dev/null
@@ -1,13 +0,0 @@
---- a/config.mk
-+++ b/config.mk
-@@ -310,8 +310,8 @@ ifdef CONFIG_MAC80211_LEDS
- export CONFIG_B43_LEDS=y
- endif #CONFIG_MAC80211_LEDS
- export CONFIG_B43_PHY_LP=y
--export CONFIG_B43_PHY_N=y
--export CONFIG_B43_PHY_HT=y
-+# export CONFIG_B43_PHY_N=y
-+# export CONFIG_B43_PHY_HT=y
- # export CONFIG_B43_PHY_LCN=y
- # export CONFIG_B43_DEBUG=y
-
diff --git a/package/mac80211/patches/015-remove-rt2x00-options.patch b/package/mac80211/patches/015-remove-rt2x00-options.patch
deleted file mode 100644
index 66c0d67a5f..0000000000
--- a/package/mac80211/patches/015-remove-rt2x00-options.patch
+++ /dev/null
@@ -1,20 +0,0 @@
---- a/config.mk
-+++ b/config.mk
-@@ -385,7 +385,7 @@ export CONFIG_RTL8180=m
-
- export CONFIG_ADM8211=m
-
--export CONFIG_RT2X00_LIB_PCI=m
-+# export CONFIG_RT2X00_LIB_PCI=m
- export CONFIG_RT2400PCI=m
- export CONFIG_RT2500PCI=m
- ifdef CONFIG_CRC_CCITT
-@@ -528,7 +528,7 @@ export CONFIG_RT2800USB_RT35XX=y
- export CONFIG_RT2800USB_RT53XX=y
- export CONFIG_RT2800USB_UNKNOWN=y
- endif #CONFIG_CRC_CCITT
--export CONFIG_RT2X00_LIB_USB=m
-+# export CONFIG_RT2X00_LIB_USB=m
- NEED_RT2X00=y
- # RT73USB requires firmware
- ifdef CONFIG_CRC_ITU_T
diff --git a/package/mac80211/patches/016-remove_pid_algo.patch b/package/mac80211/patches/016-remove_pid_algo.patch
deleted file mode 100644
index 7180a63cef..0000000000
--- a/package/mac80211/patches/016-remove_pid_algo.patch
+++ /dev/null
@@ -1,11 +0,0 @@
---- a/config.mk
-+++ b/config.mk
-@@ -169,7 +169,7 @@ export CONFIG_MAC80211_RC_DEFAULT_MINSTR
- # This is the one used by our compat-drivers net/mac80211/rate.c
- # in case you have and old kernel which is overriding this to pid.
- export CONFIG_COMPAT_MAC80211_RC_DEFAULT=minstrel_ht
--export CONFIG_MAC80211_RC_PID=y
-+# export CONFIG_MAC80211_RC_PID=y
- export CONFIG_MAC80211_RC_MINSTREL=y
- export CONFIG_MAC80211_RC_MINSTREL_HT=y
- ifdef CONFIG_LEDS_TRIGGERS
diff --git a/package/mac80211/patches/017-remove_ath9k_rc.patch b/package/mac80211/patches/017-remove_ath9k_rc.patch
deleted file mode 100644
index 99b520911b..0000000000
--- a/package/mac80211/patches/017-remove_ath9k_rc.patch
+++ /dev/null
@@ -1,11 +0,0 @@
---- a/config.mk
-+++ b/config.mk
-@@ -265,7 +265,7 @@ export CONFIG_ATH9K_COMMON=m
- # as default once we get minstrel properly tested and blessed by
- # our systems engineering team. CCK rates also need to be used
- # for long range considerations.
--export CONFIG_COMPAT_ATH9K_RATE_CONTROL=y
-+# export CONFIG_COMPAT_ATH9K_RATE_CONTROL=y
-
- export CONFIG_ATH9K_BTCOEX_SUPPORT=y
-
diff --git a/package/mac80211/patches/018-revert_printk_va_format.patch b/package/mac80211/patches/018-revert_printk_va_format.patch
deleted file mode 100644
index fa2237c950..0000000000
--- a/package/mac80211/patches/018-revert_printk_va_format.patch
+++ /dev/null
@@ -1,188 +0,0 @@
---- a/drivers/net/wireless/b43/main.c
-+++ b/drivers/net/wireless/b43/main.c
-@@ -341,83 +341,59 @@ static int b43_ratelimit(struct b43_wl *
-
- void b43info(struct b43_wl *wl, const char *fmt, ...)
- {
-- struct va_format vaf;
- va_list args;
-
- if (b43_modparam_verbose < B43_VERBOSITY_INFO)
- return;
- if (!b43_ratelimit(wl))
- return;
--
- va_start(args, fmt);
--
-- vaf.fmt = fmt;
-- vaf.va = &args;
--
-- printk(KERN_INFO "b43-%s: %pV",
-- (wl && wl->hw) ? wiphy_name(wl->hw->wiphy) : "wlan", &vaf);
--
-+ printk(KERN_INFO "b43-%s: ",
-+ (wl && wl->hw) ? wiphy_name(wl->hw->wiphy) : "wlan");
-+ vprintk(fmt, args);
- va_end(args);
- }
-
- void b43err(struct b43_wl *wl, const char *fmt, ...)
- {
-- struct va_format vaf;
- va_list args;
-
- if (b43_modparam_verbose < B43_VERBOSITY_ERROR)
- return;
- if (!b43_ratelimit(wl))
- return;
--
- va_start(args, fmt);
--
-- vaf.fmt = fmt;
-- vaf.va = &args;
--
-- printk(KERN_ERR "b43-%s ERROR: %pV",
-- (wl && wl->hw) ? wiphy_name(wl->hw->wiphy) : "wlan", &vaf);
--
-+ printk(KERN_ERR "b43-%s ERROR: ",
-+ (wl && wl->hw) ? wiphy_name(wl->hw->wiphy) : "wlan");
-+ vprintk(fmt, args);
- va_end(args);
- }
-
- void b43warn(struct b43_wl *wl, const char *fmt, ...)
- {
-- struct va_format vaf;
- va_list args;
-
- if (b43_modparam_verbose < B43_VERBOSITY_WARN)
- return;
- if (!b43_ratelimit(wl))
- return;
--
- va_start(args, fmt);
--
-- vaf.fmt = fmt;
-- vaf.va = &args;
--
-- printk(KERN_WARNING "b43-%s warning: %pV",
-- (wl && wl->hw) ? wiphy_name(wl->hw->wiphy) : "wlan", &vaf);
--
-+ printk(KERN_WARNING "b43-%s warning: ",
-+ (wl && wl->hw) ? wiphy_name(wl->hw->wiphy) : "wlan");
-+ vprintk(fmt, args);
- va_end(args);
- }
-
- void b43dbg(struct b43_wl *wl, const char *fmt, ...)
- {
-- struct va_format vaf;
- va_list args;
-
- if (b43_modparam_verbose < B43_VERBOSITY_DEBUG)
- return;
--
- va_start(args, fmt);
--
-- vaf.fmt = fmt;
-- vaf.va = &args;
--
-- printk(KERN_DEBUG "b43-%s debug: %pV",
-- (wl && wl->hw) ? wiphy_name(wl->hw->wiphy) : "wlan", &vaf);
--
-+ printk(KERN_DEBUG "b43-%s debug: ",
-+ (wl && wl->hw) ? wiphy_name(wl->hw->wiphy) : "wlan");
-+ vprintk(fmt, args);
- va_end(args);
- }
-
---- a/drivers/net/wireless/b43legacy/main.c
-+++ b/drivers/net/wireless/b43legacy/main.c
-@@ -179,75 +179,52 @@ static int b43legacy_ratelimit(struct b4
-
- void b43legacyinfo(struct b43legacy_wl *wl, const char *fmt, ...)
- {
-- struct va_format vaf;
- va_list args;
-
- if (!b43legacy_ratelimit(wl))
- return;
--
- va_start(args, fmt);
--
-- vaf.fmt = fmt;
-- vaf.va = &args;
--
-- printk(KERN_INFO "b43legacy-%s: %pV",
-- (wl && wl->hw) ? wiphy_name(wl->hw->wiphy) : "wlan", &vaf);
--
-+ printk(KERN_INFO "b43legacy-%s: ",
-+ (wl && wl->hw) ? wiphy_name(wl->hw->wiphy) : "wlan");
-+ vprintk(fmt, args);
- va_end(args);
- }
-
- void b43legacyerr(struct b43legacy_wl *wl, const char *fmt, ...)
- {
-- struct va_format vaf;
- va_list args;
-
- if (!b43legacy_ratelimit(wl))
- return;
--
- va_start(args, fmt);
--
-- vaf.fmt = fmt;
-- vaf.va = &args;
--
-- printk(KERN_ERR "b43legacy-%s ERROR: %pV",
-- (wl && wl->hw) ? wiphy_name(wl->hw->wiphy) : "wlan", &vaf);
--
-+ printk(KERN_ERR "b43legacy-%s ERROR: ",
-+ (wl && wl->hw) ? wiphy_name(wl->hw->wiphy) : "wlan");
-+ vprintk(fmt, args);
- va_end(args);
- }
-
- void b43legacywarn(struct b43legacy_wl *wl, const char *fmt, ...)
- {
-- struct va_format vaf;
- va_list args;
-
- if (!b43legacy_ratelimit(wl))
- return;
--
- va_start(args, fmt);
--
-- vaf.fmt = fmt;
-- vaf.va = &args;
--
-- printk(KERN_WARNING "b43legacy-%s warning: %pV",
-- (wl && wl->hw) ? wiphy_name(wl->hw->wiphy) : "wlan", &vaf);
--
-+ printk(KERN_WARNING "b43legacy-%s warning: ",
-+ (wl && wl->hw) ? wiphy_name(wl->hw->wiphy) : "wlan");
-+ vprintk(fmt, args);
- va_end(args);
- }
-
- #if B43legacy_DEBUG
- void b43legacydbg(struct b43legacy_wl *wl, const char *fmt, ...)
- {
-- struct va_format vaf;
- va_list args;
-
- va_start(args, fmt);
--
-- vaf.fmt = fmt;
-- vaf.va = &args;
--
-- printk(KERN_DEBUG "b43legacy-%s debug: %pV",
-- (wl && wl->hw) ? wiphy_name(wl->hw->wiphy) : "wlan", &vaf);
--
-+ printk(KERN_DEBUG "b43legacy-%s debug: ",
-+ (wl && wl->hw) ? wiphy_name(wl->hw->wiphy) : "wlan");
-+ vprintk(fmt, args);
- va_end(args);
- }
- #endif /* DEBUG */
diff --git a/package/mac80211/patches/019-remove_ath5k_pci_option.patch b/package/mac80211/patches/019-remove_ath5k_pci_option.patch
deleted file mode 100644
index d0149d39c1..0000000000
--- a/package/mac80211/patches/019-remove_ath5k_pci_option.patch
+++ /dev/null
@@ -1,11 +0,0 @@
---- a/config.mk
-+++ b/config.mk
-@@ -282,7 +282,7 @@ endif #CONFIG_COMPAT_KERNEL_2_6_27
- # PCI Drivers
- ifdef CONFIG_PCI
-
--export CONFIG_ATH5K_PCI=y
-+# export CONFIG_ATH5K_PCI=y
- export CONFIG_ATH9K_PCI=y
-
- export CONFIG_IWLWIFI=m
diff --git a/package/mac80211/patches/030-disable_tty_set_termios.patch b/package/mac80211/patches/020-disable_tty_set_termios.patch
index fc5d4d63fb..fc5d4d63fb 100644
--- a/package/mac80211/patches/030-disable_tty_set_termios.patch
+++ b/package/mac80211/patches/020-disable_tty_set_termios.patch
diff --git a/package/mac80211/patches/022-remove_crc8_and_cordic.patch b/package/mac80211/patches/022-remove_crc8_and_cordic.patch
deleted file mode 100644
index 13ad2c895c..0000000000
--- a/package/mac80211/patches/022-remove_crc8_and_cordic.patch
+++ /dev/null
@@ -1,166 +0,0 @@
---- a/compat/Makefile
-+++ b/compat/Makefile
-@@ -47,8 +47,6 @@ compat-$(CONFIG_COMPAT_KERNEL_3_3) += \
- compat-$(CONFIG_COMPAT_KERNEL_3_4) += compat-3.4.o
- compat-$(CONFIG_COMPAT_KERNEL_3_7) += compat-3.7.o
-
--compat-$(CONFIG_COMPAT_CORDIC) += cordic.o
--compat-$(CONFIG_COMPAT_CRC8) += crc8.o
-
- ifndef CONFIG_64BIT
- ifndef CONFIG_GENERIC_ATOMIC64
---- a/include/linux/cordic.h
-+++ /dev/null
-@@ -1,48 +0,0 @@
--/*
-- * Copyright (c) 2011 Broadcom Corporation
-- *
-- * Permission to use, copy, modify, and/or distribute this software for any
-- * purpose with or without fee is hereby granted, provided that the above
-- * copyright notice and this permission notice appear in all copies.
-- *
-- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
-- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
-- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
-- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-- */
--#ifndef __CORDIC_H_
--#define __CORDIC_H_
--
--#include <linux/types.h>
--
--/**
-- * struct cordic_iq - i/q coordinate.
-- *
-- * @i: real part of coordinate (in phase).
-- * @q: imaginary part of coordinate (quadrature).
-- */
--struct cordic_iq {
-- s32 i;
-- s32 q;
--};
--
--/**
-- * cordic_calc_iq() - calculates the i/q coordinate for given angle.
-- *
-- * @theta: angle in degrees for which i/q coordinate is to be calculated.
-- * @coord: function output parameter holding the i/q coordinate.
-- *
-- * The function calculates the i/q coordinate for a given angle using
-- * cordic algorithm. The coordinate consists of a real (i) and an
-- * imaginary (q) part. The real part is essentially the cosine of the
-- * angle and the imaginary part is the sine of the angle. The returned
-- * values are scaled by 2^16 for precision. The range for theta is
-- * for -180 degrees to +180 degrees. Passed values outside this range are
-- * converted before doing the actual calculation.
-- */
--struct cordic_iq cordic_calc_iq(s32 theta);
--
--#endif /* __CORDIC_H_ */
---- a/include/linux/crc8.h
-+++ /dev/null
-@@ -1,101 +0,0 @@
--/*
-- * Copyright (c) 2011 Broadcom Corporation
-- *
-- * Permission to use, copy, modify, and/or distribute this software for any
-- * purpose with or without fee is hereby granted, provided that the above
-- * copyright notice and this permission notice appear in all copies.
-- *
-- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
-- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
-- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
-- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-- */
--#ifndef __CRC8_H_
--#define __CRC8_H_
--
--#include <linux/types.h>
--
--/* see usage of this value in crc8() description */
--#define CRC8_INIT_VALUE 0xFF
--
--/*
-- * Return value of crc8() indicating valid message+crc. This is true
-- * if a CRC is inverted before transmission. The CRC computed over the
-- * whole received bitstream is _table[x], where x is the bit pattern
-- * of the modification (almost always 0xff).
-- */
--#define CRC8_GOOD_VALUE(_table) (_table[0xFF])
--
--/* required table size for crc8 algorithm */
--#define CRC8_TABLE_SIZE 256
--
--/* helper macro assuring right table size is used */
--#define DECLARE_CRC8_TABLE(_table) \
-- static u8 _table[CRC8_TABLE_SIZE]
--
--/**
-- * crc8_populate_lsb - fill crc table for given polynomial in regular bit order.
-- *
-- * @table: table to be filled.
-- * @polynomial: polynomial for which table is to be filled.
-- *
-- * This function fills the provided table according the polynomial provided for
-- * regular bit order (lsb first). Polynomials in CRC algorithms are typically
-- * represented as shown below.
-- *
-- * poly = x^8 + x^7 + x^6 + x^4 + x^2 + 1
-- *
-- * For lsb first direction x^7 maps to the lsb. So the polynomial is as below.
-- *
-- * - lsb first: poly = 10101011(1) = 0xAB
-- */
--void crc8_populate_lsb(u8 table[CRC8_TABLE_SIZE], u8 polynomial);
--
--/**
-- * crc8_populate_msb - fill crc table for given polynomial in reverse bit order.
-- *
-- * @table: table to be filled.
-- * @polynomial: polynomial for which table is to be filled.
-- *
-- * This function fills the provided table according the polynomial provided for
-- * reverse bit order (msb first). Polynomials in CRC algorithms are typically
-- * represented as shown below.
-- *
-- * poly = x^8 + x^7 + x^6 + x^4 + x^2 + 1
-- *
-- * For msb first direction x^7 maps to the msb. So the polynomial is as below.
-- *
-- * - msb first: poly = (1)11010101 = 0xD5
-- */
--void crc8_populate_msb(u8 table[CRC8_TABLE_SIZE], u8 polynomial);
--
--/**
-- * crc8() - calculate a crc8 over the given input data.
-- *
-- * @table: crc table used for calculation.
-- * @pdata: pointer to data buffer.
-- * @nbytes: number of bytes in data buffer.
-- * @crc: previous returned crc8 value.
-- *
-- * The CRC8 is calculated using the polynomial given in crc8_populate_msb()
-- * or crc8_populate_lsb().
-- *
-- * The caller provides the initial value (either %CRC8_INIT_VALUE
-- * or the previous returned value) to allow for processing of
-- * discontiguous blocks of data. When generating the CRC the
-- * caller is responsible for complementing the final return value
-- * and inserting it into the byte stream. When validating a byte
-- * stream (including CRC8), a final return value of %CRC8_GOOD_VALUE
-- * indicates the byte stream data can be considered valid.
-- *
-- * Reference:
-- * "A Painless Guide to CRC Error Detection Algorithms", ver 3, Aug 1993
-- * Williams, Ross N., ross<at>ross.net
-- * (see URL http://www.ross.net/crc/download/crc_v3.txt).
-- */
--u8 crc8(const u8 table[CRC8_TABLE_SIZE], u8 *pdata, size_t nbytes, u8 crc);
--
--#endif /* __CRC8_H_ */
diff --git a/package/mac80211/patches/023-ath9k_disable_btcoex.patch b/package/mac80211/patches/023-ath9k_disable_btcoex.patch
deleted file mode 100644
index 37ae2d5d74..0000000000
--- a/package/mac80211/patches/023-ath9k_disable_btcoex.patch
+++ /dev/null
@@ -1,11 +0,0 @@
---- a/config.mk
-+++ b/config.mk
-@@ -267,7 +267,7 @@ export CONFIG_ATH9K_COMMON=m
- # for long range considerations.
- # export CONFIG_COMPAT_ATH9K_RATE_CONTROL=y
-
--export CONFIG_ATH9K_BTCOEX_SUPPORT=y
-+# export CONFIG_ATH9K_BTCOEX_SUPPORT=y
-
- # WIL6210 requires MSI only available >= 2.6.30
- ifndef CONFIG_COMPAT_KERNEL_2_6_30
diff --git a/package/mac80211/patches/030-wext.patch b/package/mac80211/patches/030-wext.patch
new file mode 100644
index 0000000000..cb52e7ccb3
--- /dev/null
+++ b/package/mac80211/patches/030-wext.patch
@@ -0,0 +1,18 @@
+--- a/net/wireless/core.c
++++ b/net/wireless/core.c
+@@ -884,6 +884,15 @@ static int cfg80211_netdev_notifier_call
+ wdev->sme_state = CFG80211_SME_IDLE;
+ mutex_unlock(&rdev->devlist_mtx);
+ #ifdef CONFIG_CFG80211_WEXT
++#ifdef CONFIG_WIRELESS_EXT
++ if (!dev->wireless_handlers)
++ dev->wireless_handlers = &cfg80211_wext_handler;
++#else
++ printk_once(KERN_WARNING "cfg80211: wext will not work because "
++ "kernel was compiled with CONFIG_WIRELESS_EXT=n. "
++ "Tools using wext interface, like iwconfig will "
++ "not work.\n");
++#endif
+ wdev->wext.default_key = -1;
+ wdev->wext.default_mgmt_key = -1;
+ wdev->wext.connect.auth_type = NL80211_AUTHTYPE_AUTOMATIC;
diff --git a/package/mac80211/patches/040-linux_3_9_compat.patch b/package/mac80211/patches/040-linux_3_9_compat.patch
new file mode 100644
index 0000000000..d83c39c06f
--- /dev/null
+++ b/package/mac80211/patches/040-linux_3_9_compat.patch
@@ -0,0 +1,153 @@
+--- a/include/linux/compat-2.6.h
++++ b/include/linux/compat-2.6.h
+@@ -69,6 +69,7 @@ void compat_dependency_symbol(void);
+ #include <linux/compat-3.6.h>
+ #include <linux/compat-3.7.h>
+ #include <linux/compat-3.8.h>
++#include <linux/compat-3.9.h>
+
+ #endif /* __ASSEMBLY__ */
+
+--- /dev/null
++++ b/include/linux/compat-3.9.h
+@@ -0,0 +1,140 @@
++#ifndef LINUX_3_9_COMPAT_H
++#define LINUX_3_9_COMPAT_H
++
++#include <linux/version.h>
++
++#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,9,0))
++
++#include <linux/idr.h>
++#include <linux/list.h>
++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,25))
++#include <linux/rculist.h>
++#endif
++#include <net/sock.h>
++#include <linux/tty.h>
++#include <linux/tty_flip.h>
++
++/* include this before changing hlist_for_each_* to use the old versions. */
++#include <net/sch_generic.h>
++
++
++/**
++ * backport of idr idr_alloc() usage
++ *
++ * This backports a patch series send by Tejun Heo:
++ * https://lkml.org/lkml/2013/2/2/159
++ */
++static inline void compat_idr_destroy(struct idr *idp)
++{
++ idr_remove_all(idp);
++ idr_destroy(idp);
++}
++#define idr_destroy(idp) compat_idr_destroy(idp)
++
++static inline int idr_alloc(struct idr *idr, void *ptr, int start, int end,
++ gfp_t gfp_mask)
++{
++ int id, ret;
++
++ do {
++ if (!idr_pre_get(idr, gfp_mask))
++ return -ENOMEM;
++ ret = idr_get_new_above(idr, ptr, start, &id);
++ if (!ret && id > end) {
++ idr_remove(idr, id);
++ ret = -ENOSPC;
++ }
++ } while (ret == -EAGAIN);
++
++ return ret ? ret : id;
++}
++
++static inline void idr_preload(gfp_t gfp_mask)
++{
++}
++
++static inline void idr_preload_end(void)
++{
++}
++
++
++/**
++ * backport:
++ *
++ * commit 0bbacca7c3911451cea923b0ad6389d58e3d9ce9
++ * Author: Sasha Levin <sasha.levin@oracle.com>
++ * Date: Thu Feb 7 12:32:18 2013 +1100
++ *
++ * hlist: drop the node parameter from iterators
++ */
++
++#define hlist_entry_safe(ptr, type, member) \
++ (ptr) ? hlist_entry(ptr, type, member) : NULL
++
++#undef hlist_for_each_entry
++/**
++ * hlist_for_each_entry - iterate over list of given type
++ * @pos: the type * to use as a loop cursor.
++ * @head: the head for your list.
++ * @member: the name of the hlist_node within the struct.
++ */
++#define hlist_for_each_entry(pos, head, member) \
++ for (pos = hlist_entry_safe((head)->first, typeof(*(pos)), member); \
++ pos; \
++ pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member))
++
++#undef hlist_for_each_entry_safe
++/**
++ * hlist_for_each_entry_safe - iterate over list of given type safe against removal of list entry
++ * @pos: the type * to use as a loop cursor.
++ * @n: another &struct hlist_node to use as temporary storage
++ * @head: the head for your list.
++ * @member: the name of the hlist_node within the struct.
++ */
++#define hlist_for_each_entry_safe(pos, n, head, member) \
++ for (pos = hlist_entry_safe((head)->first, typeof(*pos), member); \
++ pos && ({ n = pos->member.next; 1; }); \
++ pos = hlist_entry_safe(n, typeof(*pos), member))
++
++#undef hlist_for_each_entry_rcu
++/**
++ * hlist_for_each_entry_rcu - iterate over rcu list of given type
++ * @pos: the type * to use as a loop cursor.
++ * @head: the head for your list.
++ * @member: the name of the hlist_node within the struct.
++ *
++ * This list-traversal primitive may safely run concurrently with
++ * the _rcu list-mutation primitives such as hlist_add_head_rcu()
++ * as long as the traversal is guarded by rcu_read_lock().
++ */
++#define hlist_for_each_entry_rcu(pos, head, member) \
++ for (pos = hlist_entry_safe (rcu_dereference_raw(hlist_first_rcu(head)),\
++ typeof(*(pos)), member); \
++ pos; \
++ pos = hlist_entry_safe(rcu_dereference_raw(hlist_next_rcu( \
++ &(pos)->member)), typeof(*(pos)), member))
++
++#undef sk_for_each
++#define sk_for_each(__sk, list) \
++ hlist_for_each_entry(__sk, list, sk_node)
++
++#define tty_flip_buffer_push(port) tty_flip_buffer_push((port)->tty)
++#define tty_insert_flip_string(port, chars, size) tty_insert_flip_string((port)->tty, chars, size)
++
++/**
++ * backport of:
++ *
++ * commit 496ad9aa8ef448058e36ca7a787c61f2e63f0f54
++ * Author: Al Viro <viro@zeniv.linux.org.uk>
++ * Date: Wed Jan 23 17:07:38 2013 -0500
++ *
++ * new helper: file_inode(file)
++ */
++static inline struct inode *file_inode(struct file *f)
++{
++ return f->f_path.dentry->d_inode;
++}
++
++#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(3,9,0)) */
++
++#endif /* LINUX_3_9_COMPAT_H */
diff --git a/package/mac80211/patches/050-compat_firmware.patch b/package/mac80211/patches/050-compat_firmware.patch
deleted file mode 100644
index e4b91a3167..0000000000
--- a/package/mac80211/patches/050-compat_firmware.patch
+++ /dev/null
@@ -1,78 +0,0 @@
---- a/compat/Makefile
-+++ b/compat/Makefile
-@@ -1,7 +1,10 @@
- obj-m += compat.o
- #compat-objs :=
-
--obj-$(CONFIG_COMPAT_FIRMWARE_CLASS) += compat_firmware_class.o
-+ifdef CONFIG_COMPAT_FIRMWARE_CLASS
-+ compat-y += compat_firmware_class.o
-+endif
-+
- obj-$(CONFIG_COMPAT_NET_SCH_CODEL) += sch_codel.o
-
- sch_fq_codel-y = sch_fq_codel_core.o flow_dissector.o
---- a/compat/compat_firmware_class.c
-+++ b/compat/compat_firmware_class.c
-@@ -741,19 +741,16 @@ compat_request_firmware_nowait(
- return 0;
- }
-
--static int __init firmware_class_init(void)
-+int __init firmware_class_init(void)
- {
- return class_register(&firmware_class);
- }
-
--static void __exit firmware_class_exit(void)
-+void __exit firmware_class_exit(void)
- {
- class_unregister(&firmware_class);
- }
-
--fs_initcall(firmware_class_init);
--module_exit(firmware_class_exit);
--
- EXPORT_SYMBOL_GPL(release_firmware);
- EXPORT_SYMBOL_GPL(request_firmware);
- EXPORT_SYMBOL_GPL(request_firmware_nowait);
---- a/compat/main.c
-+++ b/compat/main.c
-@@ -47,6 +47,17 @@ void compat_dependency_symbol(void)
- EXPORT_SYMBOL_GPL(compat_dependency_symbol);
-
-
-+#if defined(CONFIG_FW_LOADER) && (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33))
-+int __init firmware_class_init(void);
-+void __exit firmware_class_exit(void);
-+#else
-+static inline int firmware_class_init(void)
-+{
-+ return 0;
-+}
-+static inline void firmware_class_exit(void) {}
-+#endif
-+
- static int __init compat_init(void)
- {
- compat_pm_qos_power_init();
-@@ -63,7 +74,8 @@ static int __init compat_init(void)
- printk(KERN_INFO "compat.git: "
- COMPAT_BASE_TREE "\n");
-
-- return 0;
-+ firmware_class_init();
-+ return 0;
- }
- module_init(compat_init);
-
-@@ -72,7 +84,8 @@ static void __exit compat_exit(void)
- compat_pm_qos_power_deinit();
- compat_system_workqueue_destroy();
-
-- return;
-+ firmware_class_exit();
-+ return;
- }
- module_exit(compat_exit);
-
diff --git a/package/mac80211/patches/060-compat_add_module_pci_driver.patch b/package/mac80211/patches/060-compat_add_module_pci_driver.patch
deleted file mode 100644
index 277ca3d379..0000000000
--- a/package/mac80211/patches/060-compat_add_module_pci_driver.patch
+++ /dev/null
@@ -1,22 +0,0 @@
---- a/include/linux/compat-3.4.h
-+++ b/include/linux/compat-3.4.h
-@@ -112,6 +112,19 @@ static inline void eth_hw_addr_random(st
- module_driver(__pci_driver, pci_register_driver, \
- pci_unregister_driver)
-
-+/* source include/linux/pci.h */
-+/**
-+ * module_pci_driver() - Helper macro for registering a PCI driver
-+ * @__pci_driver: pci_driver struct
-+ *
-+ * Helper macro for PCI drivers which do not do anything special in module
-+ * init/exit. This eliminates a lot of boilerplate. Each module may only
-+ * use this macro once, and calling it replaces module_init() and module_exit()
-+ */
-+#define module_pci_driver(__pci_driver) \
-+ module_driver(__pci_driver, pci_register_driver, \
-+ pci_unregister_driver)
-+
- #endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0)) */
-
- #endif /* LINUX_5_4_COMPAT_H */
diff --git a/package/mac80211/patches/071-add_codel_ifdef.patch b/package/mac80211/patches/071-add_codel_ifdef.patch
deleted file mode 100644
index 86b415170b..0000000000
--- a/package/mac80211/patches/071-add_codel_ifdef.patch
+++ /dev/null
@@ -1,19 +0,0 @@
---- a/include/linux/compat-3.5.h
-+++ b/include/linux/compat-3.5.h
-@@ -8,6 +8,8 @@
-
- #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0))
-
-+#ifndef TCA_CODEL_MAX
-+
- /*
- * This backports:
- *
-@@ -135,6 +137,7 @@ static inline int compat_vga_switcheroo_
-
- #define SIZE_MAX (~(size_t)0)
-
-+#endif /* TCA_CODEL_MAX */
-
- #include <linux/pkt_sched.h>
-
diff --git a/package/mac80211/patches/100-disable_pcmcia_compat.patch b/package/mac80211/patches/100-disable_pcmcia_compat.patch
deleted file mode 100644
index 60927555bb..0000000000
--- a/package/mac80211/patches/100-disable_pcmcia_compat.patch
+++ /dev/null
@@ -1,65 +0,0 @@
---- a/compat/compat-2.6.28.c
-+++ b/compat/compat-2.6.28.c
-@@ -86,7 +86,7 @@ EXPORT_SYMBOL_GPL(usb_poison_urb);
- #endif
- #endif /* CONFIG_USB */
-
--#if defined(CONFIG_PCMCIA) || defined(CONFIG_PCMCIA_MODULE)
-+#if 0
-
- #include <pcmcia/ds.h>
- struct pcmcia_cfg_mem {
---- a/compat/compat-2.6.33.c
-+++ b/compat/compat-2.6.33.c
-@@ -10,7 +10,7 @@
-
- #include <linux/compat.h>
-
--#if defined(CONFIG_PCCARD) || defined(CONFIG_PCCARD_MODULE)
-+#if 0
-
- /**
- * pccard_loop_tuple() - loop over tuples in the CIS
-@@ -72,7 +72,7 @@ next_entry:
- EXPORT_SYMBOL_GPL(pccard_loop_tuple);
- /* Source: drivers/pcmcia/cistpl.c */
-
--#if defined(CONFIG_PCMCIA) || defined(CONFIG_PCMCIA_MODULE)
-+#if 0
-
- struct pcmcia_loop_mem {
- struct pcmcia_device *p_dev;
---- a/include/linux/compat-2.6.28.h
-+++ b/include/linux/compat-2.6.28.h
-@@ -49,7 +49,7 @@ typedef u32 phys_addr_t;
- })
- #endif /* From include/asm-generic/bug.h */
-
--#if defined(CONFIG_PCMCIA) || defined(CONFIG_PCMCIA_MODULE)
-+#if 0
-
- #include <pcmcia/cs_types.h>
- #include <pcmcia/cs.h>
---- a/include/linux/compat-2.6.33.h
-+++ b/include/linux/compat-2.6.33.h
-@@ -7,7 +7,7 @@
-
- #include <linux/skbuff.h>
- #include <linux/pci.h>
--#if defined(CONFIG_PCCARD) || defined(CONFIG_PCCARD_MODULE)
-+#if 0
- #include <pcmcia/cs_types.h>
- #include <pcmcia/cistpl.h>
- #include <pcmcia/ds.h>
-@@ -82,9 +82,9 @@ static inline struct sk_buff *netdev_all
- return skb;
- }
-
--#if defined(CONFIG_PCCARD) || defined(CONFIG_PCCARD_MODULE)
-+#if 0
-
--#if defined(CONFIG_PCMCIA) || defined(CONFIG_PCMCIA_MODULE)
-+#if 0
-
- #define pcmcia_request_window(a, b, c) pcmcia_request_window(&a, b, c)
-
diff --git a/package/mac80211/patches/110-disable_usb_compat.patch b/package/mac80211/patches/110-disable_usb_compat.patch
deleted file mode 100644
index d6287fd045..0000000000
--- a/package/mac80211/patches/110-disable_usb_compat.patch
+++ /dev/null
@@ -1,44 +0,0 @@
---- a/compat/compat-2.6.28.c
-+++ b/compat/compat-2.6.28.c
-@@ -165,7 +165,7 @@ EXPORT_SYMBOL_GPL(pcmcia_loop_config);
-
- #endif /* CONFIG_PCMCIA */
-
--#if defined(CONFIG_USB) || defined(CONFIG_USB_MODULE)
-+#if 0
-
- void usb_unpoison_urb(struct urb *urb)
- {
---- a/compat/compat-2.6.29.c
-+++ b/compat/compat-2.6.29.c
-@@ -49,7 +49,7 @@ void netdev_attach_ops(struct net_device
- EXPORT_SYMBOL_GPL(netdev_attach_ops);
-
- #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23))
--#if defined(CONFIG_USB) || defined(CONFIG_USB_MODULE)
-+#if 0
- /**
- * usb_unpoison_anchored_urbs - let an anchor be used successfully again
- * @anchor: anchor the requests are bound to
---- a/include/linux/compat-2.6.28.h
-+++ b/include/linux/compat-2.6.28.h
-@@ -74,7 +74,7 @@ int pcmcia_loop_config(struct pcmcia_dev
- /* USB anchors were added as of 2.6.23 */
- #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23))
-
--#if defined(CONFIG_USB) || defined(CONFIG_USB_MODULE)
-+#if 0
- #if 0
- extern void usb_poison_urb(struct urb *urb);
- #endif
---- a/config.mk
-+++ b/config.mk
-@@ -510,7 +510,7 @@ endif #CONFIG_COMPAT_KERNEL_2_6_29
- # This activates a threading fix for usb urb.
- # this is mainline commit: b3e670443b7fb8a2d29831b62b44a039c283e351
- # This fix will be included in some stable releases.
--export CONFIG_COMPAT_USB_URB_THREAD_FIX=y
-+# export CONFIG_COMPAT_USB_URB_THREAD_FIX=y
-
- export CONFIG_ATH9K_HTC=m
- # export CONFIG_ATH9K_HTC_DEBUGFS=y
diff --git a/package/mac80211/patches/130-mesh_pathtbl_backport.patch b/package/mac80211/patches/130-mesh_pathtbl_backport.patch
index fbe3e3ae45..13220997f2 100644
--- a/package/mac80211/patches/130-mesh_pathtbl_backport.patch
+++ b/package/mac80211/patches/130-mesh_pathtbl_backport.patch
@@ -1,10 +1,212 @@
--- a/net/mac80211/mesh_pathtbl.c
+++ b/net/mac80211/mesh_pathtbl.c
-@@ -813,7 +813,6 @@ static void table_flush_by_iface(struct
- struct hlist_node *p;
+@@ -72,9 +72,9 @@ static inline struct mesh_table *resize_
+ * it's used twice. So it is illegal to do
+ * for_each_mesh_entry(rcu_dereference(...), ...)
+ */
+-#define for_each_mesh_entry(tbl, p, node, i) \
++#define for_each_mesh_entry(tbl, node, i) \
+ for (i = 0; i <= tbl->hash_mask; i++) \
+- hlist_for_each_entry_rcu(node, p, &tbl->hash_buckets[i], list)
++ hlist_for_each_entry_rcu(node, &tbl->hash_buckets[i], list)
+
+
+ static struct mesh_table *mesh_table_alloc(int size_order)
+@@ -139,7 +139,7 @@ static void mesh_table_free(struct mesh_
+ }
+ if (free_leafs) {
+ spin_lock_bh(&tbl->gates_lock);
+- hlist_for_each_entry_safe(gate, p, q,
++ hlist_for_each_entry_safe(gate, q,
+ tbl->known_gates, list) {
+ hlist_del(&gate->list);
+ kfree(gate);
+@@ -333,12 +333,11 @@ static struct mesh_path *mpath_lookup(st
+ struct ieee80211_sub_if_data *sdata)
+ {
+ struct mesh_path *mpath;
+- struct hlist_node *n;
+ struct hlist_head *bucket;
+ struct mpath_node *node;
+
+ bucket = &tbl->hash_buckets[mesh_table_hash(dst, sdata, tbl)];
+- hlist_for_each_entry_rcu(node, n, bucket, list) {
++ hlist_for_each_entry_rcu(node, bucket, list) {
+ mpath = node->mpath;
+ if (mpath->sdata == sdata &&
+ ether_addr_equal(dst, mpath->dst)) {
+@@ -389,11 +388,10 @@ mesh_path_lookup_by_idx(struct ieee80211
+ {
+ struct mesh_table *tbl = rcu_dereference(mesh_paths);
+ struct mpath_node *node;
+- struct hlist_node *p;
+ int i;
+ int j = 0;
+
+- for_each_mesh_entry(tbl, p, node, i) {
++ for_each_mesh_entry(tbl, node, i) {
+ if (sdata && node->mpath->sdata != sdata)
+ continue;
+ if (j++ == idx) {
+@@ -417,13 +415,12 @@ int mesh_path_add_gate(struct mesh_path
+ {
+ struct mesh_table *tbl;
+ struct mpath_node *gate, *new_gate;
+- struct hlist_node *n;
+ int err;
+
+ rcu_read_lock();
+ tbl = rcu_dereference(mesh_paths);
+
+- hlist_for_each_entry_rcu(gate, n, tbl->known_gates, list)
++ hlist_for_each_entry_rcu(gate, tbl->known_gates, list)
+ if (gate->mpath == mpath) {
+ err = -EEXIST;
+ goto err_rcu;
+@@ -460,9 +457,9 @@ err_rcu:
+ static void mesh_gate_del(struct mesh_table *tbl, struct mesh_path *mpath)
+ {
+ struct mpath_node *gate;
+- struct hlist_node *p, *q;
++ struct hlist_node *q;
+
+- hlist_for_each_entry_safe(gate, p, q, tbl->known_gates, list) {
++ hlist_for_each_entry_safe(gate, q, tbl->known_gates, list) {
+ if (gate->mpath != mpath)
+ continue;
+ spin_lock_bh(&tbl->gates_lock);
+@@ -504,7 +501,6 @@ int mesh_path_add(struct ieee80211_sub_i
+ struct mesh_path *mpath, *new_mpath;
+ struct mpath_node *node, *new_node;
+ struct hlist_head *bucket;
+- struct hlist_node *n;
+ int grow = 0;
+ int err = 0;
+ u32 hash_idx;
+@@ -550,7 +546,7 @@ int mesh_path_add(struct ieee80211_sub_i
+ spin_lock(&tbl->hashwlock[hash_idx]);
+
+ err = -EEXIST;
+- hlist_for_each_entry(node, n, bucket, list) {
++ hlist_for_each_entry(node, bucket, list) {
+ mpath = node->mpath;
+ if (mpath->sdata == sdata &&
+ ether_addr_equal(dst, mpath->dst))
+@@ -640,7 +636,6 @@ int mpp_path_add(struct ieee80211_sub_if
+ struct mesh_path *mpath, *new_mpath;
+ struct mpath_node *node, *new_node;
+ struct hlist_head *bucket;
+- struct hlist_node *n;
+ int grow = 0;
+ int err = 0;
+ u32 hash_idx;
+@@ -680,7 +675,7 @@ int mpp_path_add(struct ieee80211_sub_if
+ spin_lock(&tbl->hashwlock[hash_idx]);
+
+ err = -EEXIST;
+- hlist_for_each_entry(node, n, bucket, list) {
++ hlist_for_each_entry(node, bucket, list) {
+ mpath = node->mpath;
+ if (mpath->sdata == sdata &&
+ ether_addr_equal(dst, mpath->dst))
+@@ -725,14 +720,13 @@ void mesh_plink_broken(struct sta_info *
+ static const u8 bcast[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+ struct mesh_path *mpath;
+ struct mpath_node *node;
+- struct hlist_node *p;
+ struct ieee80211_sub_if_data *sdata = sta->sdata;
+ int i;
+ __le16 reason = cpu_to_le16(WLAN_REASON_MESH_PATH_DEST_UNREACHABLE);
+
+ rcu_read_lock();
+ tbl = rcu_dereference(mesh_paths);
+- for_each_mesh_entry(tbl, p, node, i) {
++ for_each_mesh_entry(tbl, node, i) {
+ mpath = node->mpath;
+ if (rcu_dereference(mpath->next_hop) == sta &&
+ mpath->flags & MESH_PATH_ACTIVE &&
+@@ -792,13 +786,12 @@ void mesh_path_flush_by_nexthop(struct s
+ struct mesh_table *tbl;
+ struct mesh_path *mpath;
+ struct mpath_node *node;
+- struct hlist_node *p;
+ int i;
+
+ rcu_read_lock();
+ read_lock_bh(&pathtbl_resize_lock);
+ tbl = resize_dereference_mesh_paths();
+- for_each_mesh_entry(tbl, p, node, i) {
++ for_each_mesh_entry(tbl, node, i) {
+ mpath = node->mpath;
+ if (rcu_dereference(mpath->next_hop) == sta) {
+ spin_lock(&tbl->hashwlock[i]);
+@@ -815,11 +808,9 @@ static void table_flush_by_iface(struct
+ {
+ struct mesh_path *mpath;
+ struct mpath_node *node;
+- struct hlist_node *p;
int i;
- WARN_ON(!rcu_read_lock_held());
- for_each_mesh_entry(tbl, p, node, i) {
+- for_each_mesh_entry(tbl, p, node, i) {
++ for_each_mesh_entry(tbl, node, i) {
mpath = node->mpath;
if (mpath->sdata != sdata)
+ continue;
+@@ -865,7 +856,6 @@ int mesh_path_del(struct ieee80211_sub_i
+ struct mesh_path *mpath;
+ struct mpath_node *node;
+ struct hlist_head *bucket;
+- struct hlist_node *n;
+ int hash_idx;
+ int err = 0;
+
+@@ -875,7 +865,7 @@ int mesh_path_del(struct ieee80211_sub_i
+ bucket = &tbl->hash_buckets[hash_idx];
+
+ spin_lock(&tbl->hashwlock[hash_idx]);
+- hlist_for_each_entry(node, n, bucket, list) {
++ hlist_for_each_entry(node, bucket, list) {
+ mpath = node->mpath;
+ if (mpath->sdata == sdata &&
+ ether_addr_equal(addr, mpath->dst)) {
+@@ -920,7 +910,6 @@ void mesh_path_tx_pending(struct mesh_pa
+ int mesh_path_send_to_gates(struct mesh_path *mpath)
+ {
+ struct ieee80211_sub_if_data *sdata = mpath->sdata;
+- struct hlist_node *n;
+ struct mesh_table *tbl;
+ struct mesh_path *from_mpath = mpath;
+ struct mpath_node *gate = NULL;
+@@ -935,7 +924,7 @@ int mesh_path_send_to_gates(struct mesh_
+ if (!known_gates)
+ return -EHOSTUNREACH;
+
+- hlist_for_each_entry_rcu(gate, n, known_gates, list) {
++ hlist_for_each_entry_rcu(gate, known_gates, list) {
+ if (gate->mpath->sdata != sdata)
+ continue;
+
+@@ -951,7 +940,7 @@ int mesh_path_send_to_gates(struct mesh_
+ }
+ }
+
+- hlist_for_each_entry_rcu(gate, n, known_gates, list)
++ hlist_for_each_entry_rcu(gate, known_gates, list)
+ if (gate->mpath->sdata == sdata) {
+ mpath_dbg(sdata, "Sending to %pM\n", gate->mpath->dst);
+ mesh_path_tx_pending(gate->mpath);
+@@ -1096,12 +1085,11 @@ void mesh_path_expire(struct ieee80211_s
+ struct mesh_table *tbl;
+ struct mesh_path *mpath;
+ struct mpath_node *node;
+- struct hlist_node *p;
+ int i;
+
+ rcu_read_lock();
+ tbl = rcu_dereference(mesh_paths);
+- for_each_mesh_entry(tbl, p, node, i) {
++ for_each_mesh_entry(tbl, node, i) {
+ if (node->mpath->sdata != sdata)
+ continue;
+ mpath = node->mpath;
diff --git a/package/mac80211/patches/150-disable_addr_notifier.patch b/package/mac80211/patches/150-disable_addr_notifier.patch
new file mode 100644
index 0000000000..9714696ecc
--- /dev/null
+++ b/package/mac80211/patches/150-disable_addr_notifier.patch
@@ -0,0 +1,67 @@
+--- a/net/mac80211/main.c
++++ b/net/mac80211/main.c
+@@ -313,7 +313,7 @@ void ieee80211_restart_hw(struct ieee802
+ }
+ EXPORT_SYMBOL(ieee80211_restart_hw);
+
+-#ifdef CONFIG_INET
++#ifdef __disabled__CONFIG_INET
+ static int ieee80211_ifa_changed(struct notifier_block *nb,
+ unsigned long data, void *arg)
+ {
+@@ -372,7 +372,7 @@ static int ieee80211_ifa_changed(struct
+ }
+ #endif
+
+-#if IS_ENABLED(CONFIG_IPV6)
++#if IS_ENABLED(__disabled__CONFIG_IPV6)
+ static int ieee80211_ifa6_changed(struct notifier_block *nb,
+ unsigned long data, void *arg)
+ {
+@@ -1015,14 +1015,14 @@ int ieee80211_register_hw(struct ieee802
+ goto fail_pm_qos;
+ }
+
+-#ifdef CONFIG_INET
++#ifdef __disabled__CONFIG_INET
+ local->ifa_notifier.notifier_call = ieee80211_ifa_changed;
+ result = register_inetaddr_notifier(&local->ifa_notifier);
+ if (result)
+ goto fail_ifa;
+ #endif
+
+-#if IS_ENABLED(CONFIG_IPV6)
++#if IS_ENABLED(__disabled__CONFIG_IPV6)
+ local->ifa6_notifier.notifier_call = ieee80211_ifa6_changed;
+ result = register_inet6addr_notifier(&local->ifa6_notifier);
+ if (result)
+@@ -1034,13 +1034,13 @@ int ieee80211_register_hw(struct ieee802
+
+ return 0;
+
+-#if IS_ENABLED(CONFIG_IPV6)
++#if IS_ENABLED(__disabled__CONFIG_IPV6)
+ fail_ifa6:
+-#ifdef CONFIG_INET
++#ifdef __disabled__CONFIG_INET
+ unregister_inetaddr_notifier(&local->ifa_notifier);
+ #endif
+ #endif
+-#if defined(CONFIG_INET) || defined(CONFIG_IPV6)
++#if defined(__disabled__CONFIG_INET) || defined(__disabled__CONFIG_IPV6)
+ fail_ifa:
+ pm_qos_remove_notifier(PM_QOS_NETWORK_LATENCY,
+ &local->network_latency_notifier);
+@@ -1073,10 +1073,10 @@ void ieee80211_unregister_hw(struct ieee
+
+ pm_qos_remove_notifier(PM_QOS_NETWORK_LATENCY,
+ &local->network_latency_notifier);
+-#ifdef CONFIG_INET
++#ifdef __disabled__CONFIG_INET
+ unregister_inetaddr_notifier(&local->ifa_notifier);
+ #endif
+-#if IS_ENABLED(CONFIG_IPV6)
++#if IS_ENABLED(__disabled__CONFIG_IPV6)
+ unregister_inet6addr_notifier(&local->ifa6_notifier);
+ #endif
+
diff --git a/package/mac80211/patches/300-pending_work.patch b/package/mac80211/patches/300-pending_work.patch
index ad9c5004a8..d3867c409b 100644
--- a/package/mac80211/patches/300-pending_work.patch
+++ b/package/mac80211/patches/300-pending_work.patch
@@ -1,35 +1,117 @@
---- a/drivers/net/wireless/ath/ath5k/base.c
-+++ b/drivers/net/wireless/ath/ath5k/base.c
-@@ -325,6 +325,8 @@ ath5k_setup_channels(struct ath5k_hw *ah
- if (!ath5k_is_standard_channel(ch, band))
- continue;
+--- a/drivers/net/wireless/ath/ath9k/common.h
++++ b/drivers/net/wireless/ath/ath9k/common.h
+@@ -27,7 +27,7 @@
+ #define WME_MAX_BA WME_BA_BMP_SIZE
+ #define ATH_TID_MAX_BUFS (2 * WME_MAX_BA)
+
+-#define ATH_RSSI_DUMMY_MARKER 0x127
++#define ATH_RSSI_DUMMY_MARKER 127
+ #define ATH_RSSI_LPF_LEN 10
+ #define RSSI_LPF_THRESHOLD -20
+ #define ATH_RSSI_EP_MULTIPLIER (1<<7)
+--- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
++++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
+@@ -1067,15 +1067,19 @@ static bool ath9k_rx_prepare(struct ath9
+
+ last_rssi = priv->rx.last_rssi;
+
+- if (likely(last_rssi != ATH_RSSI_DUMMY_MARKER))
+- rxbuf->rxstatus.rs_rssi = ATH_EP_RND(last_rssi,
+- ATH_RSSI_EP_MULTIPLIER);
++ if (ieee80211_is_beacon(hdr->frame_control) &&
++ !is_zero_ether_addr(common->curbssid) &&
++ ether_addr_equal(hdr->addr3, common->curbssid)) {
++ s8 rssi = rxbuf->rxstatus.rs_rssi;
-+ channels[count].max_power = AR5K_TUNE_MAX_TXPOWER/2;
+- if (rxbuf->rxstatus.rs_rssi < 0)
+- rxbuf->rxstatus.rs_rssi = 0;
++ if (likely(last_rssi != ATH_RSSI_DUMMY_MARKER))
++ rssi = ATH_EP_RND(last_rssi, ATH_RSSI_EP_MULTIPLIER);
+
+- if (ieee80211_is_beacon(fc))
+- priv->ah->stats.avgbrssi = rxbuf->rxstatus.rs_rssi;
++ if (rssi < 0)
++ rssi = 0;
+
- count++;
- }
++ priv->ah->stats.avgbrssi = rssi;
++ }
-@@ -850,7 +852,7 @@ ath5k_txbuf_free_skb(struct ath5k_hw *ah
- return;
- dma_unmap_single(ah->dev, bf->skbaddr, bf->skb->len,
- DMA_TO_DEVICE);
-- dev_kfree_skb_any(bf->skb);
-+ ieee80211_free_txskb(ah->hw, bf->skb);
- bf->skb = NULL;
- bf->skbaddr = 0;
- bf->desc->ds_data = 0;
-@@ -1577,7 +1579,7 @@ ath5k_tx_queue(struct ieee80211_hw *hw,
- return;
-
- drop_packet:
-- dev_kfree_skb_any(skb);
-+ ieee80211_free_txskb(hw, skb);
- }
+ rx_status->mactime = be64_to_cpu(rxbuf->rxstatus.rs_tstamp);
+ rx_status->band = hw->conf.channel->band;
+--- a/include/linux/ieee80211.h
++++ b/include/linux/ieee80211.h
+@@ -185,7 +185,7 @@ struct ieee80211_hdr {
+ u8 addr3[6];
+ __le16 seq_ctrl;
+ u8 addr4[6];
+-} __packed;
++} __packed __aligned(2);
+
+ struct ieee80211_hdr_3addr {
+ __le16 frame_control;
+@@ -194,7 +194,7 @@ struct ieee80211_hdr_3addr {
+ u8 addr2[6];
+ u8 addr3[6];
+ __le16 seq_ctrl;
+-} __packed;
++} __packed __aligned(2);
+
+ struct ieee80211_qos_hdr {
+ __le16 frame_control;
+@@ -204,7 +204,7 @@ struct ieee80211_qos_hdr {
+ u8 addr3[6];
+ __le16 seq_ctrl;
+ __le16 qos_ctrl;
+-} __packed;
++} __packed __aligned(2);
+
+ /**
+ * ieee80211_has_tods - check if IEEE80211_FCTL_TODS is set
+@@ -581,7 +581,7 @@ struct ieee80211s_hdr {
+ __le32 seqnum;
+ u8 eaddr1[6];
+ u8 eaddr2[6];
+-} __packed;
++} __packed __aligned(2);
+
+ /* Mesh flags */
+ #define MESH_FLAGS_AE_A4 0x1
+@@ -875,7 +875,7 @@ struct ieee80211_mgmt {
+ } u;
+ } __packed action;
+ } u;
+-} __packed;
++} __packed __aligned(2);
+
+ /* Supported Rates value encodings in 802.11n-2009 7.3.2.2 */
+ #define BSS_MEMBERSHIP_SELECTOR_HT_PHY 127
+@@ -906,20 +906,20 @@ struct ieee80211_rts {
+ __le16 duration;
+ u8 ra[6];
+ u8 ta[6];
+-} __packed;
++} __packed __aligned(2);
+
+ struct ieee80211_cts {
+ __le16 frame_control;
+ __le16 duration;
+ u8 ra[6];
+-} __packed;
++} __packed __aligned(2);
+
+ struct ieee80211_pspoll {
+ __le16 frame_control;
+ __le16 aid;
+ u8 bssid[6];
+ u8 ta[6];
+-} __packed;
++} __packed __aligned(2);
+
+ /* TDLS */
- static void
--- a/net/mac80211/agg-rx.c
+++ b/net/mac80211/agg-rx.c
-@@ -203,6 +203,8 @@ static void ieee80211_send_addba_resp(st
+@@ -204,6 +204,8 @@ static void ieee80211_send_addba_resp(st
memcpy(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN);
else if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
memcpy(mgmt->bssid, sdata->u.ibss.bssid, ETH_ALEN);
@@ -50,7 +132,7 @@
memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN);
else if (sdata->vif.type == NL80211_IFTYPE_STATION)
memcpy(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN);
-@@ -460,6 +461,7 @@ int ieee80211_start_tx_ba_session(struct
+@@ -527,6 +528,7 @@ int ieee80211_start_tx_ba_session(struct
sdata->vif.type != NL80211_IFTYPE_MESH_POINT &&
sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
sdata->vif.type != NL80211_IFTYPE_AP &&
@@ -58,23 +140,14 @@
sdata->vif.type != NL80211_IFTYPE_ADHOC)
return -EINVAL;
-@@ -869,7 +871,7 @@ void ieee80211_process_addba_resp(struct
-
- } else {
- ___ieee80211_stop_tx_ba_session(sta, tid, WLAN_BACK_INITIATOR,
-- true);
-+ false);
- }
-
- out:
--- a/net/mac80211/debugfs_sta.c
+++ b/net/mac80211/debugfs_sta.c
-@@ -63,11 +63,11 @@ static ssize_t sta_flags_read(struct fil
+@@ -65,11 +65,11 @@ static ssize_t sta_flags_read(struct fil
test_sta_flag(sta, WLAN_STA_##flg) ? #flg "\n" : ""
int res = scnprintf(buf, sizeof(buf),
-- "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
-+ "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
+- "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
++ "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
TEST(AUTH), TEST(ASSOC), TEST(PS_STA),
TEST(PS_DRIVER), TEST(AUTHORIZED),
TEST(SHORT_PREAMBLE),
@@ -85,7 +158,25 @@
TEST(TDLS_PEER_AUTH), TEST(4ADDR_EVENT),
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
-@@ -420,7 +420,6 @@ int ieee80211_do_open(struct wireless_de
+@@ -78,7 +78,7 @@ void ieee80211_recalc_txpower(struct iee
+ ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_TXPOWER);
+ }
+
+-static u32 ieee80211_idle_off(struct ieee80211_local *local)
++u32 ieee80211_idle_off(struct ieee80211_local *local)
+ {
+ if (!(local->hw.conf.flags & IEEE80211_CONF_IDLE))
+ return 0;
+@@ -107,7 +107,7 @@ void ieee80211_recalc_idle(struct ieee80
+
+ lockdep_assert_held(&local->mtx);
+
+- active = !list_empty(&local->chanctx_list);
++ active = !list_empty(&local->chanctx_list) || local->monitors;
+
+ if (!local->ops->remain_on_channel) {
+ list_for_each_entry(roc, &local->roc_list, list) {
+@@ -436,7 +436,6 @@ int ieee80211_do_open(struct wireless_de
struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
struct net_device *dev = wdev->netdev;
struct ieee80211_local *local = sdata->local;
@@ -93,7 +184,17 @@
u32 changed = 0;
int res;
u32 hw_reconf_flags = 0;
-@@ -575,30 +574,8 @@ int ieee80211_do_open(struct wireless_de
+@@ -541,6 +540,9 @@ int ieee80211_do_open(struct wireless_de
+
+ ieee80211_adjust_monitor_flags(sdata, 1);
+ ieee80211_configure_filter(local);
++ mutex_lock(&local->mtx);
++ ieee80211_recalc_idle(local);
++ mutex_unlock(&local->mtx);
+
+ netif_carrier_on(dev);
+ break;
+@@ -595,30 +597,8 @@ int ieee80211_do_open(struct wireless_de
set_bit(SDATA_STATE_RUNNING, &sdata->state);
@@ -125,16 +226,17 @@
/*
* set_multicast_list will be invoked by the networking core
-@@ -849,7 +826,7 @@ static void ieee80211_do_stop(struct iee
- struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
- if (info->control.vif == &sdata->vif) {
- __skb_unlink(skb, &local->pending[i]);
-- dev_kfree_skb_irq(skb);
-+ ieee80211_free_txskb(&local->hw, skb);
- }
- }
- }
-@@ -997,6 +974,72 @@ static void ieee80211_if_setup(struct ne
+@@ -817,6 +797,9 @@ static void ieee80211_do_stop(struct iee
+
+ ieee80211_adjust_monitor_flags(sdata, -1);
+ ieee80211_configure_filter(local);
++ mutex_lock(&local->mtx);
++ ieee80211_recalc_idle(local);
++ mutex_unlock(&local->mtx);
+ break;
+ case NL80211_IFTYPE_P2P_DEVICE:
+ /* relies on synchronize_rcu() below */
+@@ -1022,6 +1005,72 @@ static void ieee80211_if_setup(struct ne
dev->destructor = free_netdev;
}
@@ -188,7 +290,7 @@
+
+ if (elems.ht_cap_elem)
+ ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband,
-+ elems.ht_cap_elem, &sta->sta.ht_cap);
++ elems.ht_cap_elem, sta);
+
+ if (elems.wmm_param)
+ set_sta_flag(sta, WLAN_STA_WME);
@@ -207,7 +309,7 @@
static void ieee80211_iface_work(struct work_struct *work)
{
struct ieee80211_sub_if_data *sdata =
-@@ -1101,6 +1144,9 @@ static void ieee80211_iface_work(struct
+@@ -1126,6 +1175,9 @@ static void ieee80211_iface_work(struct
break;
ieee80211_mesh_rx_queued_mgmt(sdata, skb);
break;
@@ -219,7 +321,7 @@
break;
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
-@@ -2279,6 +2279,7 @@ ieee80211_rx_h_action(struct ieee80211_r
+@@ -2365,6 +2365,7 @@ ieee80211_rx_h_action(struct ieee80211_r
sdata->vif.type != NL80211_IFTYPE_MESH_POINT &&
sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
sdata->vif.type != NL80211_IFTYPE_AP &&
@@ -227,7 +329,7 @@
sdata->vif.type != NL80211_IFTYPE_ADHOC)
break;
-@@ -2496,14 +2497,15 @@ ieee80211_rx_h_mgmt(struct ieee80211_rx_
+@@ -2692,14 +2693,15 @@ ieee80211_rx_h_mgmt(struct ieee80211_rx_
if (!ieee80211_vif_is_mesh(&sdata->vif) &&
sdata->vif.type != NL80211_IFTYPE_ADHOC &&
@@ -245,7 +347,7 @@
break;
case cpu_to_le16(IEEE80211_STYPE_ASSOC_RESP):
case cpu_to_le16(IEEE80211_STYPE_REASSOC_RESP):
-@@ -2827,10 +2829,16 @@ static int prepare_for_handlers(struct i
+@@ -3028,10 +3030,16 @@ static int prepare_for_handlers(struct i
}
break;
case NL80211_IFTYPE_WDS:
@@ -274,7 +376,7 @@
* @WLAN_STA_CLEAR_PS_FILT: Clear PS filter in hardware (using the
* IEEE80211_TX_CTL_CLEAR_PS_FILT control flag) when the next
* frame to this station is transmitted.
-@@ -64,7 +63,6 @@ enum ieee80211_sta_info_flags {
+@@ -66,7 +65,6 @@ enum ieee80211_sta_info_flags {
WLAN_STA_AUTHORIZED,
WLAN_STA_SHORT_PREAMBLE,
WLAN_STA_WME,
@@ -282,1829 +384,1384 @@
WLAN_STA_CLEAR_PS_FILT,
WLAN_STA_MFP,
WLAN_STA_BLOCK_BA,
---- a/net/mac80211/status.c
-+++ b/net/mac80211/status.c
-@@ -34,7 +34,7 @@ void ieee80211_tx_status_irqsafe(struct
- skb_queue_len(&local->skb_queue_unreliable);
- while (tmp > IEEE80211_IRQSAFE_QUEUE_LIMIT &&
- (skb = skb_dequeue(&local->skb_queue_unreliable))) {
-- dev_kfree_skb_irq(skb);
-+ ieee80211_free_txskb(hw, skb);
- tmp--;
- I802_DEBUG_INC(local->tx_status_drop);
- }
-@@ -159,7 +159,7 @@ static void ieee80211_handle_filtered_fr
- "dropped TX filtered frame, queue_len=%d PS=%d @%lu\n",
- skb_queue_len(&sta->tx_filtered[ac]),
- !!test_sta_flag(sta, WLAN_STA_PS_STA), jiffies);
-- dev_kfree_skb(skb);
-+ ieee80211_free_txskb(&local->hw, skb);
- }
-
- static void ieee80211_check_pending_bar(struct sta_info *sta, u8 *addr, u8 tid)
-@@ -324,6 +324,75 @@ static void ieee80211_add_tx_radiotap_he
-
- }
-
-+static void ieee80211_report_used_skb(struct ieee80211_local *local,
-+ struct sk_buff *skb, bool dropped)
-+{
-+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
-+ struct ieee80211_hdr *hdr = (void *)skb->data;
-+ bool acked = info->flags & IEEE80211_TX_STAT_ACK;
-+
-+ if (dropped)
-+ acked = false;
-+
-+ if (info->flags & IEEE80211_TX_INTFL_NL80211_FRAME_TX) {
-+ struct ieee80211_sub_if_data *sdata = NULL;
-+ struct ieee80211_sub_if_data *iter_sdata;
-+ u64 cookie = (unsigned long)skb;
-+
-+ rcu_read_lock();
-+
-+ if (skb->dev) {
-+ list_for_each_entry_rcu(iter_sdata, &local->interfaces,
-+ list) {
-+ if (!iter_sdata->dev)
-+ continue;
-+
-+ if (skb->dev == iter_sdata->dev) {
-+ sdata = iter_sdata;
-+ break;
+--- a/net/mac80211/tx.c
++++ b/net/mac80211/tx.c
+@@ -1231,34 +1231,40 @@ static bool ieee80211_tx_frags(struct ie
+ if (local->queue_stop_reasons[q] ||
+ (!txpending && !skb_queue_empty(&local->pending[q]))) {
+ if (unlikely(info->flags &
+- IEEE80211_TX_INTFL_OFFCHAN_TX_OK &&
+- local->queue_stop_reasons[q] &
+- ~BIT(IEEE80211_QUEUE_STOP_REASON_OFFCHANNEL))) {
++ IEEE80211_TX_INTFL_OFFCHAN_TX_OK)) {
++ if (local->queue_stop_reasons[q] &
++ ~BIT(IEEE80211_QUEUE_STOP_REASON_OFFCHANNEL)) {
++ /*
++ * Drop off-channel frames if queues
++ * are stopped for any reason other
++ * than off-channel operation. Never
++ * queue them.
++ */
++ spin_unlock_irqrestore(
++ &local->queue_stop_reason_lock,
++ flags);
++ ieee80211_purge_tx_queue(&local->hw,
++ skbs);
++ return true;
+ }
-+ }
-+ } else {
-+ sdata = rcu_dereference(local->p2p_sdata);
-+ }
-+
-+ if (!sdata)
-+ skb->dev = NULL;
-+ else if (ieee80211_is_nullfunc(hdr->frame_control) ||
-+ ieee80211_is_qos_nullfunc(hdr->frame_control)) {
-+ cfg80211_probe_status(sdata->dev, hdr->addr1,
-+ cookie, acked, GFP_ATOMIC);
-+ } else {
-+ cfg80211_mgmt_tx_status(&sdata->wdev, cookie, skb->data,
-+ skb->len, acked, GFP_ATOMIC);
-+ }
-+
-+ rcu_read_unlock();
-+ }
++ } else {
+
-+ if (unlikely(info->ack_frame_id)) {
-+ struct sk_buff *ack_skb;
-+ unsigned long flags;
+ /*
+- * Drop off-channel frames if queues are stopped
+- * for any reason other than off-channel
+- * operation. Never queue them.
++ * Since queue is stopped, queue up frames for
++ * later transmission from the tx-pending
++ * tasklet when the queue is woken again.
+ */
+- spin_unlock_irqrestore(
+- &local->queue_stop_reason_lock, flags);
+- ieee80211_purge_tx_queue(&local->hw, skbs);
+- return true;
++ if (txpending)
++ skb_queue_splice_init(skbs,
++ &local->pending[q]);
++ else
++ skb_queue_splice_tail_init(skbs,
++ &local->pending[q]);
+
-+ spin_lock_irqsave(&local->ack_status_lock, flags);
-+ ack_skb = idr_find(&local->ack_status_frames,
-+ info->ack_frame_id);
-+ if (ack_skb)
-+ idr_remove(&local->ack_status_frames,
-+ info->ack_frame_id);
-+ spin_unlock_irqrestore(&local->ack_status_lock, flags);
++ spin_unlock_irqrestore(&local->queue_stop_reason_lock,
++ flags);
++ return false;
+ }
+-
+- /*
+- * Since queue is stopped, queue up frames for later
+- * transmission from the tx-pending tasklet when the
+- * queue is woken again.
+- */
+- if (txpending)
+- skb_queue_splice_init(skbs, &local->pending[q]);
+- else
+- skb_queue_splice_tail_init(skbs,
+- &local->pending[q]);
+-
+- spin_unlock_irqrestore(&local->queue_stop_reason_lock,
+- flags);
+- return false;
+ }
+ spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
+
+@@ -1848,9 +1854,24 @@ netdev_tx_t ieee80211_subif_start_xmit(s
+ }
+
+ if (!is_multicast_ether_addr(skb->data)) {
++ struct sta_info *next_hop;
++ bool mpp_lookup = true;
+
-+ if (ack_skb) {
-+ if (!dropped) {
-+ /* consumes ack_skb */
-+ skb_complete_wifi_ack(ack_skb, acked);
-+ } else {
-+ dev_kfree_skb_any(ack_skb);
+ mpath = mesh_path_lookup(sdata, skb->data);
+- if (!mpath)
++ if (mpath) {
++ mpp_lookup = false;
++ next_hop = rcu_dereference(mpath->next_hop);
++ if (!next_hop ||
++ !(mpath->flags & (MESH_PATH_ACTIVE |
++ MESH_PATH_RESOLVING)))
++ mpp_lookup = true;
+ }
-+ }
-+ }
-+}
+
- /*
- * Use a static threshold for now, best value to be determined
- * by testing ...
-@@ -515,50 +584,7 @@ void ieee80211_tx_status(struct ieee8021
- msecs_to_jiffies(10));
++ if (mpp_lookup)
+ mppath = mpp_path_lookup(sdata, skb->data);
++
++ if (mppath && mpath)
++ mesh_path_del(mpath->sdata, mpath->dst);
+ }
+
+ /*
+--- a/net/wireless/nl80211.c
++++ b/net/wireless/nl80211.c
+@@ -554,16 +554,9 @@ static int nl80211_msg_put_channel(struc
+ if ((chan->flags & IEEE80211_CHAN_NO_IBSS) &&
+ nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_IBSS))
+ goto nla_put_failure;
+- if (chan->flags & IEEE80211_CHAN_RADAR) {
+- u32 time = elapsed_jiffies_msecs(chan->dfs_state_entered);
+- if (nla_put_flag(msg, NL80211_FREQUENCY_ATTR_RADAR))
+- goto nla_put_failure;
+- if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_DFS_STATE,
+- chan->dfs_state))
+- goto nla_put_failure;
+- if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_DFS_TIME, time))
+- goto nla_put_failure;
+- }
++ if ((chan->flags & IEEE80211_CHAN_RADAR) &&
++ nla_put_flag(msg, NL80211_FREQUENCY_ATTR_RADAR))
++ goto nla_put_failure;
+ if ((chan->flags & IEEE80211_CHAN_NO_HT40MINUS) &&
+ nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_HT40_MINUS))
+ goto nla_put_failure;
+@@ -900,9 +893,6 @@ static int nl80211_put_iface_combination
+ nla_put_u32(msg, NL80211_IFACE_COMB_MAXNUM,
+ c->max_interfaces))
+ goto nla_put_failure;
+- if (nla_put_u32(msg, NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS,
+- c->radar_detect_widths))
+- goto nla_put_failure;
+
+ nla_nest_end(msg, nl_combi);
}
+@@ -914,48 +904,6 @@ nla_put_failure:
+ return -ENOBUFS;
+ }
-- if (info->flags & IEEE80211_TX_INTFL_NL80211_FRAME_TX) {
-- u64 cookie = (unsigned long)skb;
-- acked = info->flags & IEEE80211_TX_STAT_ACK;
+-#ifdef CONFIG_PM
+-static int nl80211_send_wowlan_tcp_caps(struct cfg80211_registered_device *rdev,
+- struct sk_buff *msg)
+-{
+- const struct wiphy_wowlan_tcp_support *tcp = rdev->wiphy.wowlan.tcp;
+- struct nlattr *nl_tcp;
-
-- if (ieee80211_is_nullfunc(hdr->frame_control) ||
-- ieee80211_is_qos_nullfunc(hdr->frame_control)) {
-- cfg80211_probe_status(skb->dev, hdr->addr1,
-- cookie, acked, GFP_ATOMIC);
-- } else if (skb->dev) {
-- cfg80211_mgmt_tx_status(
-- skb->dev->ieee80211_ptr, cookie, skb->data,
-- skb->len, acked, GFP_ATOMIC);
-- } else {
-- struct ieee80211_sub_if_data *p2p_sdata;
+- if (!tcp)
+- return 0;
-
-- rcu_read_lock();
+- nl_tcp = nla_nest_start(msg, NL80211_WOWLAN_TRIG_TCP_CONNECTION);
+- if (!nl_tcp)
+- return -ENOBUFS;
-
-- p2p_sdata = rcu_dereference(local->p2p_sdata);
-- if (p2p_sdata) {
-- cfg80211_mgmt_tx_status(
-- &p2p_sdata->wdev, cookie, skb->data,
-- skb->len, acked, GFP_ATOMIC);
-- }
-- rcu_read_unlock();
-- }
-- }
+- if (nla_put_u32(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD,
+- tcp->data_payload_max))
+- return -ENOBUFS;
-
-- if (unlikely(info->ack_frame_id)) {
-- struct sk_buff *ack_skb;
-- unsigned long flags;
+- if (nla_put_u32(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD,
+- tcp->data_payload_max))
+- return -ENOBUFS;
-
-- spin_lock_irqsave(&local->ack_status_lock, flags);
-- ack_skb = idr_find(&local->ack_status_frames,
-- info->ack_frame_id);
-- if (ack_skb)
-- idr_remove(&local->ack_status_frames,
-- info->ack_frame_id);
-- spin_unlock_irqrestore(&local->ack_status_lock, flags);
+- if (tcp->seq && nla_put_flag(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ))
+- return -ENOBUFS;
-
-- /* consumes ack_skb */
-- if (ack_skb)
-- skb_complete_wifi_ack(ack_skb,
-- info->flags & IEEE80211_TX_STAT_ACK);
-- }
-+ ieee80211_report_used_skb(local, skb, false);
-
- /* this was a transmitted frame, but now we want to reuse it */
- skb_orphan(skb);
-@@ -634,25 +660,17 @@ EXPORT_SYMBOL(ieee80211_report_low_ack);
- void ieee80211_free_txskb(struct ieee80211_hw *hw, struct sk_buff *skb)
- {
- struct ieee80211_local *local = hw_to_local(hw);
-- struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+- if (tcp->tok && nla_put(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN,
+- sizeof(*tcp->tok), tcp->tok))
+- return -ENOBUFS;
-
-- if (unlikely(info->ack_frame_id)) {
-- struct sk_buff *ack_skb;
-- unsigned long flags;
+- if (nla_put_u32(msg, NL80211_WOWLAN_TCP_DATA_INTERVAL,
+- tcp->data_interval_max))
+- return -ENOBUFS;
-
-- spin_lock_irqsave(&local->ack_status_lock, flags);
-- ack_skb = idr_find(&local->ack_status_frames,
-- info->ack_frame_id);
-- if (ack_skb)
-- idr_remove(&local->ack_status_frames,
-- info->ack_frame_id);
-- spin_unlock_irqrestore(&local->ack_status_lock, flags);
+- if (nla_put_u32(msg, NL80211_WOWLAN_TCP_WAKE_PAYLOAD,
+- tcp->wake_payload_max))
+- return -ENOBUFS;
-
-- /* consumes ack_skb */
-- if (ack_skb)
-- dev_kfree_skb_any(ack_skb);
-- }
-
-+ ieee80211_report_used_skb(local, skb, true);
- dev_kfree_skb_any(skb);
- }
- EXPORT_SYMBOL(ieee80211_free_txskb);
-+
-+void ieee80211_purge_tx_queue(struct ieee80211_hw *hw,
-+ struct sk_buff_head *skbs)
-+{
-+ struct sk_buff *skb;
-+
-+ while ((skb = __skb_dequeue(skbs)))
-+ ieee80211_free_txskb(hw, skb);
-+}
---- a/drivers/net/wireless/p54/main.c
-+++ b/drivers/net/wireless/p54/main.c
-@@ -139,6 +139,7 @@ static int p54_beacon_format_ie_tim(stru
- static int p54_beacon_update(struct p54_common *priv,
- struct ieee80211_vif *vif)
+- nla_nest_end(msg, nl_tcp);
+- return 0;
+-}
+-#endif
+-
+ static int nl80211_send_wiphy(struct sk_buff *msg, u32 portid, u32 seq, int flags,
+ struct cfg80211_registered_device *dev)
{
-+ struct ieee80211_tx_control control = { };
- struct sk_buff *beacon;
- int ret;
-
-@@ -158,7 +159,7 @@ static int p54_beacon_update(struct p54_
- * to cancel the old beacon template by hand, instead the firmware
- * will release the previous one through the feedback mechanism.
- */
-- p54_tx_80211(priv->hw, NULL, beacon);
-+ p54_tx_80211(priv->hw, &control, beacon);
- priv->tsf_high32 = 0;
- priv->tsf_low32 = 0;
-
---- a/net/wireless/reg.c
-+++ b/net/wireless/reg.c
-@@ -352,6 +352,9 @@ static void reg_regdb_search(struct work
- struct reg_regdb_search_request *request;
- const struct ieee80211_regdomain *curdom, *regdom;
- int i, r;
-+ bool set_reg = false;
-+
-+ mutex_lock(&cfg80211_mutex);
-
- mutex_lock(&reg_regdb_search_mutex);
- while (!list_empty(&reg_regdb_search_list)) {
-@@ -367,9 +370,7 @@ static void reg_regdb_search(struct work
- r = reg_copy_regd(&regdom, curdom);
- if (r)
- break;
-- mutex_lock(&cfg80211_mutex);
-- set_regdom(regdom);
-- mutex_unlock(&cfg80211_mutex);
-+ set_reg = true;
- break;
- }
+@@ -1330,9 +1278,6 @@ static int nl80211_send_wiphy(struct sk_
+ goto nla_put_failure;
}
-@@ -377,6 +378,11 @@ static void reg_regdb_search(struct work
- kfree(request);
- }
- mutex_unlock(&reg_regdb_search_mutex);
-+
-+ if (set_reg)
-+ set_regdom(regdom);
-+
-+ mutex_unlock(&cfg80211_mutex);
- }
-
- static DECLARE_WORK(reg_regdb_work, reg_regdb_search);
---- a/drivers/net/wireless/ath/ath9k/recv.c
-+++ b/drivers/net/wireless/ath/ath9k/recv.c
-@@ -254,8 +254,6 @@ rx_init_fail:
-
- static void ath_edma_start_recv(struct ath_softc *sc)
- {
-- spin_lock_bh(&sc->rx.rxbuflock);
--
- ath9k_hw_rxena(sc->sc_ah);
- ath_rx_addbuffer_edma(sc, ATH9K_RX_QUEUE_HP,
-@@ -267,8 +265,6 @@ static void ath_edma_start_recv(struct a
- ath_opmode_init(sc);
-
- ath9k_hw_startpcureceive(sc->sc_ah, !!(sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL));
+- if (nl80211_send_wowlan_tcp_caps(dev, msg))
+- goto nla_put_failure;
-
-- spin_unlock_bh(&sc->rx.rxbuflock);
- }
-
- static void ath_edma_stop_recv(struct ath_softc *sc)
-@@ -285,8 +281,6 @@ int ath_rx_init(struct ath_softc *sc, in
- int error = 0;
-
- spin_lock_init(&sc->sc_pcu_lock);
-- spin_lock_init(&sc->rx.rxbuflock);
-- clear_bit(SC_OP_RXFLUSH, &sc->sc_flags);
-
- common->rx_bufsize = IEEE80211_MAX_MPDU_LEN / 2 +
- sc->sc_ah->caps.rx_status_len;
-@@ -424,8 +418,8 @@ u32 ath_calcrxfilter(struct ath_softc *s
- rfilt |= ATH9K_RX_FILTER_COMP_BAR;
-
- if (sc->nvifs > 1 || (sc->rx.rxfilter & FIF_OTHER_BSS)) {
-- /* The following may also be needed for other older chips */
-- if (sc->sc_ah->hw_version.macVersion == AR_SREV_VERSION_9160)
-+ /* This is needed for older chips */
-+ if (sc->sc_ah->hw_version.macVersion <= AR_SREV_VERSION_9160)
- rfilt |= ATH9K_RX_FILTER_PROM;
- rfilt |= ATH9K_RX_FILTER_MCAST_BCAST_ALL;
+ nla_nest_end(msg, nl_wowlan);
}
-@@ -447,7 +441,6 @@ int ath_startrecv(struct ath_softc *sc)
- return 0;
+ #endif
+--- a/net/mac80211/cfg.c
++++ b/net/mac80211/cfg.c
+@@ -3285,13 +3285,19 @@ static int ieee80211_cfg_get_channel(str
+ struct cfg80211_chan_def *chandef)
+ {
+ struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
++ struct ieee80211_local *local = wiphy_priv(wiphy);
+ struct ieee80211_chanctx_conf *chanctx_conf;
+ int ret = -ENODATA;
+
+ rcu_read_lock();
+- chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
+- if (chanctx_conf) {
+- *chandef = chanctx_conf->def;
++ if (local->use_chanctx) {
++ chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
++ if (chanctx_conf) {
++ *chandef = chanctx_conf->def;
++ ret = 0;
++ }
++ } else if (local->open_count == local->monitors) {
++ *chandef = local->monitor_chandef;
+ ret = 0;
}
+ rcu_read_unlock();
+--- a/drivers/net/wireless/ath/ath9k/hw.c
++++ b/drivers/net/wireless/ath/ath9k/hw.c
+@@ -1463,7 +1463,9 @@ static bool ath9k_hw_chip_reset(struct a
+ reset_type = ATH9K_RESET_POWER_ON;
+ else
+ reset_type = ATH9K_RESET_COLD;
+- }
++ } else if (ah->chip_fullsleep || REG_READ(ah, AR_Q_TXE) ||
++ (REG_READ(ah, AR_CR) & AR_CR_RXE))
++ reset_type = ATH9K_RESET_COLD;
-- spin_lock_bh(&sc->rx.rxbuflock);
- if (list_empty(&sc->rx.rxbuf))
- goto start_recv;
-
-@@ -468,26 +461,31 @@ start_recv:
- ath_opmode_init(sc);
- ath9k_hw_startpcureceive(ah, !!(sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL));
+ if (!ath9k_hw_set_reset_reg(ah, reset_type))
+ return false;
+@@ -1876,13 +1878,12 @@ int ath9k_hw_reset(struct ath_hw *ah, st
+
+ ENABLE_REGWRITE_BUFFER(ah);
+
+- REG_WRITE(ah, AR_STA_ID0, get_unaligned_le32(common->macaddr));
+- REG_WRITE(ah, AR_STA_ID1, get_unaligned_le16(common->macaddr + 4)
+- | macStaId1
++ REG_RMW(ah, AR_STA_ID1, macStaId1
+ | AR_STA_ID1_RTS_USE_DEF
+ | (ah->config.
+ ack_6mb ? AR_STA_ID1_ACKCTS_6MB : 0)
+- | ah->sta_id1_defaults);
++ | ah->sta_id1_defaults,
++ ~AR_STA_ID1_SADH_MASK);
+ ath_hw_setbssidmask(common);
+ REG_WRITE(ah, AR_DEF_ANTENNA, saveDefAntenna);
+ ath9k_hw_write_associd(ah);
+--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
++++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
+@@ -1236,8 +1236,10 @@ static inline void rt2x00lib_set_if_comb
+ */
+ if_limit = &rt2x00dev->if_limits_ap;
+ if_limit->max = rt2x00dev->ops->max_ap_intf;
+- if_limit->types = BIT(NL80211_IFTYPE_AP) |
+- BIT(NL80211_IFTYPE_MESH_POINT);
++ if_limit->types = BIT(NL80211_IFTYPE_AP);
++#ifdef CONFIG_MAC80211_MESH
++ if_limit->types |= BIT(NL80211_IFTYPE_MESH_POINT);
++#endif
-- spin_unlock_bh(&sc->rx.rxbuflock);
--
- return 0;
+ /*
+ * Build up AP interface combinations structure.
+@@ -1309,7 +1311,9 @@ int rt2x00lib_probe_dev(struct rt2x00_de
+ rt2x00dev->hw->wiphy->interface_modes |=
+ BIT(NL80211_IFTYPE_ADHOC) |
+ BIT(NL80211_IFTYPE_AP) |
++#ifdef CONFIG_MAC80211_MESH
+ BIT(NL80211_IFTYPE_MESH_POINT) |
++#endif
+ BIT(NL80211_IFTYPE_WDS);
+
+ rt2x00dev->hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
+--- a/net/mac80211/rc80211_minstrel_ht.c
++++ b/net/mac80211/rc80211_minstrel_ht.c
+@@ -17,8 +17,6 @@
+ #include "rc80211_minstrel_ht.h"
+
+ #define AVG_PKT_SIZE 1200
+-#define SAMPLE_COLUMNS 10
+-#define EWMA_LEVEL 75
+
+ /* Number of bits for an average sized packet */
+ #define MCS_NBITS (AVG_PKT_SIZE << 3)
+@@ -26,11 +24,11 @@
+ /* Number of symbols for a packet with (bps) bits per symbol */
+ #define MCS_NSYMS(bps) ((MCS_NBITS + (bps) - 1) / (bps))
+
+-/* Transmission time for a packet containing (syms) symbols */
++/* Transmission time (nanoseconds) for a packet containing (syms) symbols */
+ #define MCS_SYMBOL_TIME(sgi, syms) \
+ (sgi ? \
+- ((syms) * 18 + 4) / 5 : /* syms * 3.6 us */ \
+- (syms) << 2 /* syms * 4 us */ \
++ ((syms) * 18000 + 4000) / 5 : /* syms * 3.6 us */ \
++ ((syms) * 1000) << 2 /* syms * 4 us */ \
+ )
+
+ /* Transmit duration for the raw data part of an average sized packet */
+@@ -64,9 +62,9 @@
}
-+static void ath_flushrecv(struct ath_softc *sc)
-+{
-+ if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
-+ ath_rx_tasklet(sc, 1, true);
-+ ath_rx_tasklet(sc, 1, false);
-+}
-+
- bool ath_stoprecv(struct ath_softc *sc)
- {
- struct ath_hw *ah = sc->sc_ah;
- bool stopped, reset = false;
-
-- spin_lock_bh(&sc->rx.rxbuflock);
- ath9k_hw_abortpcurecv(ah);
- ath9k_hw_setrxfilter(ah, 0);
- stopped = ath9k_hw_stopdmarecv(ah, &reset);
-
-+ ath_flushrecv(sc);
-+
- if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
- ath_edma_stop_recv(sc);
- else
- sc->rx.rxlink = NULL;
-- spin_unlock_bh(&sc->rx.rxbuflock);
+ #define CCK_DURATION(_bitrate, _short, _len) \
+- (10 /* SIFS */ + \
++ (1000 * (10 /* SIFS */ + \
+ (_short ? 72 + 24 : 144 + 48 ) + \
+- (8 * (_len + 4) * 10) / (_bitrate))
++ (8 * (_len + 4) * 10) / (_bitrate)))
- if (!(ah->ah_flags & AH_UNPLUGGED) &&
- unlikely(!stopped)) {
-@@ -499,15 +497,6 @@ bool ath_stoprecv(struct ath_softc *sc)
- return stopped && !reset;
- }
+ #define CCK_ACK_DURATION(_bitrate, _short) \
+ (CCK_DURATION((_bitrate > 10 ? 20 : 10), false, 60) + \
+@@ -129,15 +127,6 @@ const struct mcs_group minstrel_mcs_grou
+ static u8 sample_table[SAMPLE_COLUMNS][MCS_GROUP_RATES];
--void ath_flushrecv(struct ath_softc *sc)
+ /*
+- * Perform EWMA (Exponentially Weighted Moving Average) calculation
+- */
+-static int
+-minstrel_ewma(int old, int new, int weight)
-{
-- set_bit(SC_OP_RXFLUSH, &sc->sc_flags);
-- if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
-- ath_rx_tasklet(sc, 1, true);
-- ath_rx_tasklet(sc, 1, false);
-- clear_bit(SC_OP_RXFLUSH, &sc->sc_flags);
+- return (new * (100 - weight) + old * weight) / 100;
-}
-
- static bool ath_beacon_dtim_pending_cab(struct sk_buff *skb)
+-/*
+ * Look up an MCS group index based on mac80211 rate information
+ */
+ static int
+@@ -211,20 +200,32 @@ static void
+ minstrel_ht_calc_tp(struct minstrel_ht_sta *mi, int group, int rate)
{
- /* Check whether the Beacon frame has DTIM indicating buffered bc/mc */
-@@ -744,6 +733,7 @@ static struct ath_buf *ath_get_next_rx_b
- return NULL;
+ struct minstrel_rate_stats *mr;
+- unsigned int usecs = 0;
++ unsigned int nsecs = 0;
++ unsigned int tp;
++ unsigned int prob;
+
+ mr = &mi->groups[group].rates[rate];
++ prob = mr->probability;
+
+- if (mr->probability < MINSTREL_FRAC(1, 10)) {
++ if (prob < MINSTREL_FRAC(1, 10)) {
+ mr->cur_tp = 0;
+ return;
}
-+ list_del(&bf->list);
- if (!bf->bf_mpdu)
- return bf;
-
-@@ -1059,16 +1049,12 @@ int ath_rx_tasklet(struct ath_softc *sc,
- dma_type = DMA_FROM_DEVICE;
-
- qtype = hp ? ATH9K_RX_QUEUE_HP : ATH9K_RX_QUEUE_LP;
-- spin_lock_bh(&sc->rx.rxbuflock);
-
- tsf = ath9k_hw_gettsf64(ah);
- tsf_lower = tsf & 0xffffffff;
-
- do {
- bool decrypt_error = false;
-- /* If handling rx interrupt and flush is in progress => exit */
-- if (test_bit(SC_OP_RXFLUSH, &sc->sc_flags) && (flush == 0))
-- break;
-
- memset(&rs, 0, sizeof(rs));
- if (edma)
-@@ -1108,15 +1094,6 @@ int ath_rx_tasklet(struct ath_softc *sc,
- sc->rx.num_pkts++;
- ath_debug_stat_rx(sc, &rs);
-
-- /*
-- * If we're asked to flush receive queue, directly
-- * chain it back at the queue without processing it.
-- */
-- if (test_bit(SC_OP_RXFLUSH, &sc->sc_flags)) {
-- RX_STAT_INC(rx_drop_rxflush);
-- goto requeue_drop_frag;
-- }
--
- memset(rxs, 0, sizeof(struct ieee80211_rx_status));
-
- rxs->mactime = (tsf & ~0xffffffffULL) | rs.rs_tstamp;
-@@ -1251,19 +1228,18 @@ requeue_drop_frag:
- sc->rx.frag = NULL;
- }
- requeue:
-+ list_add_tail(&bf->list, &sc->rx.rxbuf);
-+ if (flush)
-+ continue;
++ /*
++ * For the throughput calculation, limit the probability value to 90% to
++ * account for collision related packet error rate fluctuation
++ */
++ if (prob > MINSTREL_FRAC(9, 10))
++ prob = MINSTREL_FRAC(9, 10);
+
- if (edma) {
-- list_add_tail(&bf->list, &sc->rx.rxbuf);
- ath_rx_edma_buf_link(sc, qtype);
- } else {
-- list_move_tail(&bf->list, &sc->rx.rxbuf);
- ath_rx_buf_link(sc, bf);
-- if (!flush)
-- ath9k_hw_rxena(ah);
-+ ath9k_hw_rxena(ah);
- }
- } while (1);
+ if (group != MINSTREL_CCK_GROUP)
+- usecs = mi->overhead / MINSTREL_TRUNC(mi->avg_ampdu_len);
++ nsecs = 1000 * mi->overhead / MINSTREL_TRUNC(mi->avg_ampdu_len);
++
++ nsecs += minstrel_mcs_groups[group].duration[rate];
++ tp = 1000000 * ((mr->probability * 1000) / nsecs);
-- spin_unlock_bh(&sc->rx.rxbuflock);
--
- if (!(ah->imask & ATH9K_INT_RXEOL)) {
- ah->imask |= (ATH9K_INT_RXEOL | ATH9K_INT_RXORN);
- ath9k_hw_set_interrupts(ah);
---- a/net/mac80211/mlme.c
-+++ b/net/mac80211/mlme.c
-@@ -818,23 +818,71 @@ void ieee80211_sta_process_chanswitch(st
+- usecs += minstrel_mcs_groups[group].duration[rate];
+- mr->cur_tp = MINSTREL_TRUNC((1000000 / usecs) * mr->probability);
++ mr->cur_tp = MINSTREL_TRUNC(tp);
}
- static void ieee80211_handle_pwr_constr(struct ieee80211_sub_if_data *sdata,
-- u16 capab_info, u8 *pwr_constr_elem,
-- u8 pwr_constr_elem_len)
-+ struct ieee80211_channel *channel,
-+ const u8 *country_ie, u8 country_ie_len,
-+ const u8 *pwr_constr_elem)
- {
-- struct ieee80211_conf *conf = &sdata->local->hw.conf;
-+ struct ieee80211_country_ie_triplet *triplet;
-+ int chan = ieee80211_frequency_to_channel(channel->center_freq);
-+ int i, chan_pwr, chan_increment, new_ap_level;
-+ bool have_chan_pwr = false;
-
-- if (!(capab_info & WLAN_CAPABILITY_SPECTRUM_MGMT))
-+ /* Invalid IE */
-+ if (country_ie_len % 2 || country_ie_len < IEEE80211_COUNTRY_IE_MIN_LEN)
- return;
+ /*
+@@ -308,8 +309,8 @@ minstrel_ht_update_stats(struct minstrel
+ }
+ }
+
+- /* try to sample up to half of the available rates during each interval */
+- mi->sample_count *= 4;
++ /* try to sample all available rates during each interval */
++ mi->sample_count *= 8;
+
+ cur_prob = 0;
+ cur_prob_tp = 0;
+@@ -320,20 +321,13 @@ minstrel_ht_update_stats(struct minstrel
+ if (!mg->supported)
+ continue;
+
+- mr = minstrel_get_ratestats(mi, mg->max_prob_rate);
+- if (cur_prob_tp < mr->cur_tp &&
+- minstrel_mcs_groups[group].streams == 1) {
+- mi->max_prob_rate = mg->max_prob_rate;
+- cur_prob = mr->cur_prob;
+- cur_prob_tp = mr->cur_tp;
+- }
+-
+ mr = minstrel_get_ratestats(mi, mg->max_tp_rate);
+ if (cur_tp < mr->cur_tp) {
+ mi->max_tp_rate2 = mi->max_tp_rate;
+ cur_tp2 = cur_tp;
+ mi->max_tp_rate = mg->max_tp_rate;
+ cur_tp = mr->cur_tp;
++ mi->max_prob_streams = minstrel_mcs_groups[group].streams - 1;
+ }
-- /* Power constraint IE length should be 1 octet */
-- if (pwr_constr_elem_len != 1)
-- return;
-+ triplet = (void *)(country_ie + 3);
-+ country_ie_len -= 3;
-
-- if ((*pwr_constr_elem <= conf->channel->max_reg_power) &&
-- (*pwr_constr_elem != sdata->local->power_constr_level)) {
-- sdata->local->power_constr_level = *pwr_constr_elem;
-- ieee80211_hw_config(sdata->local, 0);
-+ switch (channel->band) {
-+ default:
-+ WARN_ON_ONCE(1);
-+ /* fall through */
-+ case IEEE80211_BAND_2GHZ:
-+ case IEEE80211_BAND_60GHZ:
-+ chan_increment = 1;
-+ break;
-+ case IEEE80211_BAND_5GHZ:
-+ chan_increment = 4;
-+ break;
+ mr = minstrel_get_ratestats(mi, mg->max_tp_rate2);
+@@ -343,6 +337,23 @@ minstrel_ht_update_stats(struct minstrel
+ }
}
+
++ if (mi->max_prob_streams < 1)
++ mi->max_prob_streams = 1;
+
-+ /* find channel */
-+ while (country_ie_len >= 3) {
-+ u8 first_channel = triplet->chans.first_channel;
-+
-+ if (first_channel >= IEEE80211_COUNTRY_EXTENSION_ID)
-+ goto next;
-+
-+ for (i = 0; i < triplet->chans.num_channels; i++) {
-+ if (first_channel + i * chan_increment == chan) {
-+ have_chan_pwr = true;
-+ chan_pwr = triplet->chans.max_power;
-+ break;
-+ }
++ for (group = 0; group < ARRAY_SIZE(minstrel_mcs_groups); group++) {
++ mg = &mi->groups[group];
++ if (!mg->supported)
++ continue;
++ mr = minstrel_get_ratestats(mi, mg->max_prob_rate);
++ if (cur_prob_tp < mr->cur_tp &&
++ minstrel_mcs_groups[group].streams <= mi->max_prob_streams) {
++ mi->max_prob_rate = mg->max_prob_rate;
++ cur_prob = mr->cur_prob;
++ cur_prob_tp = mr->cur_tp;
+ }
-+ if (have_chan_pwr)
-+ break;
-+
-+ next:
-+ triplet++;
-+ country_ie_len -= 3;
+ }
+
-+ if (!have_chan_pwr)
-+ return;
-+
-+ new_ap_level = max_t(int, 0, chan_pwr - *pwr_constr_elem);
-+
-+ if (sdata->local->ap_power_level == new_ap_level)
-+ return;
+
-+ sdata_info(sdata,
-+ "Limiting TX power to %d (%d - %d) dBm as advertised by %pM\n",
-+ new_ap_level, chan_pwr, *pwr_constr_elem,
-+ sdata->u.mgd.bssid);
-+ sdata->local->ap_power_level = new_ap_level;
-+ ieee80211_hw_config(sdata->local, 0);
+ mi->stats_update = jiffies;
}
- void ieee80211_enable_dyn_ps(struct ieee80211_vif *vif)
-@@ -1390,7 +1438,7 @@ static void ieee80211_set_disassoc(struc
- sta = sta_info_get(sdata, ifmgd->bssid);
- if (sta) {
- set_sta_flag(sta, WLAN_STA_BLOCK_BA);
-- ieee80211_sta_tear_down_BA_sessions(sta, tx);
-+ ieee80211_sta_tear_down_BA_sessions(sta, false);
- }
- mutex_unlock(&local->sta_mtx);
+@@ -467,7 +478,7 @@ minstrel_ht_tx_status(void *priv, struct
-@@ -1438,7 +1486,7 @@ static void ieee80211_set_disassoc(struc
- memset(&ifmgd->ht_capa, 0, sizeof(ifmgd->ht_capa));
- memset(&ifmgd->ht_capa_mask, 0, sizeof(ifmgd->ht_capa_mask));
+ if (!mi->sample_wait && !mi->sample_tries && mi->sample_count > 0) {
+ mi->sample_wait = 16 + 2 * MINSTREL_TRUNC(mi->avg_ampdu_len);
+- mi->sample_tries = 2;
++ mi->sample_tries = 1;
+ mi->sample_count--;
+ }
-- local->power_constr_level = 0;
-+ local->ap_power_level = 0;
+@@ -536,7 +547,7 @@ minstrel_calc_retransmit(struct minstrel
+ mr->retry_updated = true;
- del_timer_sync(&local->dynamic_ps_timer);
- cancel_work_sync(&local->dynamic_ps_enable_work);
-@@ -2530,15 +2578,13 @@ static void ieee80211_rx_mgmt_beacon(str
- bssid, true);
- }
+ group = &minstrel_mcs_groups[index / MCS_GROUP_RATES];
+- tx_time_data = group->duration[index % MCS_GROUP_RATES] * ampdu_len;
++ tx_time_data = group->duration[index % MCS_GROUP_RATES] * ampdu_len / 1000;
-- /* Note: country IE parsing is done for us by cfg80211 */
-- if (elems.country_elem) {
-- /* TODO: IBSS also needs this */
-- if (elems.pwr_constr_elem)
-- ieee80211_handle_pwr_constr(sdata,
-- le16_to_cpu(mgmt->u.probe_resp.capab_info),
-- elems.pwr_constr_elem,
-- elems.pwr_constr_elem_len);
-- }
-+ if (elems.country_elem && elems.pwr_constr_elem &&
-+ mgmt->u.probe_resp.capab_info &
-+ cpu_to_le16(WLAN_CAPABILITY_SPECTRUM_MGMT))
-+ ieee80211_handle_pwr_constr(sdata, local->oper_channel,
-+ elems.country_elem,
-+ elems.country_elem_len,
-+ elems.pwr_constr_elem);
-
- ieee80211_bss_info_change_notify(sdata, changed);
- }
-@@ -3526,6 +3572,7 @@ int ieee80211_mgd_deauth(struct ieee8021
+ /* Contention time for first 2 tries */
+ ctime = (t_slot * cw) >> 1;
+@@ -616,6 +627,7 @@ minstrel_get_sample_rate(struct minstrel
{
- struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
- u8 frame_buf[DEAUTH_DISASSOC_LEN];
-+ bool tx = !req->local_state_change;
-
- mutex_lock(&ifmgd->mtx);
+ struct minstrel_rate_stats *mr;
+ struct minstrel_mcs_group_data *mg;
++ unsigned int sample_dur, sample_group;
+ int sample_idx = 0;
+
+ if (mi->sample_wait > 0) {
+@@ -626,39 +638,46 @@ minstrel_get_sample_rate(struct minstrel
+ if (!mi->sample_tries)
+ return -1;
-@@ -3542,12 +3589,12 @@ int ieee80211_mgd_deauth(struct ieee8021
- if (ifmgd->associated &&
- ether_addr_equal(ifmgd->associated->bssid, req->bssid)) {
- ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH,
-- req->reason_code, true, frame_buf);
-+ req->reason_code, tx, frame_buf);
- } else {
- drv_mgd_prepare_tx(sdata->local, sdata);
- ieee80211_send_deauth_disassoc(sdata, req->bssid,
- IEEE80211_STYPE_DEAUTH,
-- req->reason_code, true,
-+ req->reason_code, tx,
- frame_buf);
- }
-
---- a/net/mac80211/sta_info.c
-+++ b/net/mac80211/sta_info.c
-@@ -585,7 +585,7 @@ static bool sta_info_cleanup_expire_buff
- */
- if (!skb)
- break;
-- dev_kfree_skb(skb);
-+ ieee80211_free_txskb(&local->hw, skb);
- }
+- mi->sample_tries--;
+ mg = &mi->groups[mi->sample_group];
+ sample_idx = sample_table[mg->column][mg->index];
+ mr = &mg->rates[sample_idx];
+- sample_idx += mi->sample_group * MCS_GROUP_RATES;
++ sample_group = mi->sample_group;
++ sample_idx += sample_group * MCS_GROUP_RATES;
+ minstrel_next_sample_idx(mi);
/*
-@@ -614,7 +614,7 @@ static bool sta_info_cleanup_expire_buff
- local->total_ps_buffered--;
- ps_dbg(sta->sdata, "Buffered frame expired (STA %pM)\n",
- sta->sta.addr);
-- dev_kfree_skb(skb);
-+ ieee80211_free_txskb(&local->hw, skb);
- }
-
+ * Sampling might add some overhead (RTS, no aggregation)
+ * to the frame. Hence, don't use sampling for the currently
+- * used max TP rate.
++ * used rates.
+ */
+- if (sample_idx == mi->max_tp_rate)
++ if (sample_idx == mi->max_tp_rate ||
++ sample_idx == mi->max_tp_rate2 ||
++ sample_idx == mi->max_prob_rate)
+ return -1;
++
/*
-@@ -674,7 +674,7 @@ int __must_check __sta_info_destroy(stru
- * will be sufficient.
+- * When not using MRR, do not sample if the probability is already
+- * higher than 95% to avoid wasting airtime
++ * Do not sample if the probability is already higher than 95%
++ * to avoid wasting airtime.
*/
- set_sta_flag(sta, WLAN_STA_BLOCK_BA);
-- ieee80211_sta_tear_down_BA_sessions(sta, true);
-+ ieee80211_sta_tear_down_BA_sessions(sta, false);
-
- ret = sta_info_hash_del(local, sta);
- if (ret)
-@@ -730,8 +730,8 @@ int __must_check __sta_info_destroy(stru
-
- for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
- local->total_ps_buffered -= skb_queue_len(&sta->ps_tx_buf[ac]);
-- __skb_queue_purge(&sta->ps_tx_buf[ac]);
-- __skb_queue_purge(&sta->tx_filtered[ac]);
-+ ieee80211_purge_tx_queue(&local->hw, &sta->ps_tx_buf[ac]);
-+ ieee80211_purge_tx_queue(&local->hw, &sta->tx_filtered[ac]);
- }
-
- #ifdef CONFIG_MAC80211_MESH
-@@ -765,7 +765,7 @@ int __must_check __sta_info_destroy(stru
- tid_tx = rcu_dereference_raw(sta->ampdu_mlme.tid_tx[i]);
- if (!tid_tx)
- continue;
-- __skb_queue_purge(&tid_tx->pending);
-+ ieee80211_purge_tx_queue(&local->hw, &tid_tx->pending);
- kfree(tid_tx);
- }
+- if (!mp->has_mrr && (mr->probability > MINSTREL_FRAC(95, 100)))
++ if (mr->probability > MINSTREL_FRAC(95, 100))
+ return -1;
---- a/drivers/net/wireless/ath/ath5k/phy.c
-+++ b/drivers/net/wireless/ath/ath5k/phy.c
-@@ -1977,11 +1977,13 @@ ath5k_hw_set_spur_mitigation_filter(stru
- spur_delta_phase = (spur_offset << 18) / 25;
- spur_freq_sigma_delta = (spur_delta_phase >> 10);
- symbol_width = AR5K_SPUR_SYMBOL_WIDTH_BASE_100Hz / 2;
-+ break;
- case AR5K_BWMODE_5MHZ:
- /* Both sample_freq and chip_freq are 10MHz (?) */
- spur_delta_phase = (spur_offset << 19) / 25;
- spur_freq_sigma_delta = (spur_delta_phase >> 10);
- symbol_width = AR5K_SPUR_SYMBOL_WIDTH_BASE_100Hz / 4;
-+ break;
- default:
- if (channel->band == IEEE80211_BAND_5GHZ) {
- /* Both sample_freq and chip_freq are 40MHz */
---- a/net/mac80211/ieee80211_i.h
-+++ b/net/mac80211/ieee80211_i.h
-@@ -1062,7 +1062,7 @@ struct ieee80211_local {
- bool disable_dynamic_ps;
-
- int user_power_level; /* in dBm */
-- int power_constr_level; /* in dBm */
-+ int ap_power_level; /* in dBm */
-
- enum ieee80211_smps_mode smps_mode;
-
-@@ -1170,7 +1170,6 @@ struct ieee802_11_elems {
- u8 prep_len;
- u8 perr_len;
- u8 country_elem_len;
-- u8 pwr_constr_elem_len;
- u8 quiet_elem_len;
- u8 num_of_quiet_elem; /* can be more the one */
- u8 timeout_int_len;
-@@ -1318,6 +1317,8 @@ netdev_tx_t ieee80211_monitor_start_xmit
- struct net_device *dev);
- netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
- struct net_device *dev);
-+void ieee80211_purge_tx_queue(struct ieee80211_hw *hw,
-+ struct sk_buff_head *skbs);
-
- /* HT */
- void ieee80211_apply_htcap_overrides(struct ieee80211_sub_if_data *sdata,
---- a/net/mac80211/util.c
-+++ b/net/mac80211/util.c
-@@ -406,7 +406,7 @@ void ieee80211_add_pending_skb(struct ie
- int queue = info->hw_queue;
-
- if (WARN_ON(!info->control.vif)) {
-- kfree_skb(skb);
-+ ieee80211_free_txskb(&local->hw, skb);
- return;
+ /*
+ * Make sure that lower rates get sampled only occasionally,
+ * if the link is working perfectly.
+ */
+- if (minstrel_get_duration(sample_idx) >
+- minstrel_get_duration(mi->max_tp_rate)) {
++ sample_dur = minstrel_get_duration(sample_idx);
++ if (sample_dur >= minstrel_get_duration(mi->max_tp_rate2) &&
++ (mi->max_prob_streams <
++ minstrel_mcs_groups[sample_group].streams ||
++ sample_dur >= minstrel_get_duration(mi->max_prob_rate))) {
+ if (mr->sample_skipped < 20)
+ return -1;
+
+ if (mi->sample_slow++ > 2)
+ return -1;
}
++ mi->sample_tries--;
-@@ -431,7 +431,7 @@ void ieee80211_add_pending_skbs_fn(struc
- struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+ return sample_idx;
+ }
+--- a/net/mac80211/rc80211_minstrel_ht.h
++++ b/net/mac80211/rc80211_minstrel_ht.h
+@@ -16,11 +16,6 @@
+ #define MINSTREL_MAX_STREAMS 3
+ #define MINSTREL_STREAM_GROUPS 4
+
+-/* scaled fraction values */
+-#define MINSTREL_SCALE 16
+-#define MINSTREL_FRAC(val, div) (((val) << MINSTREL_SCALE) / div)
+-#define MINSTREL_TRUNC(val) ((val) >> MINSTREL_SCALE)
+-
+ #define MCS_GROUP_RATES 8
- if (WARN_ON(!info->control.vif)) {
-- kfree_skb(skb);
-+ ieee80211_free_txskb(&local->hw, skb);
- continue;
- }
+ struct mcs_group {
+@@ -85,6 +80,7 @@ struct minstrel_ht_sta {
-@@ -792,8 +792,11 @@ u32 ieee802_11_parse_elems_crc(u8 *start
- elems->country_elem_len = elen;
- break;
- case WLAN_EID_PWR_CONSTRAINT:
-+ if (elen != 1) {
-+ elem_parse_failed = true;
-+ break;
-+ }
- elems->pwr_constr_elem = pos;
-- elems->pwr_constr_elem_len = elen;
- break;
- case WLAN_EID_TIMEOUT_INTERVAL:
- elems->timeout_int = pos;
---- a/net/mac80211/main.c
-+++ b/net/mac80211/main.c
-@@ -154,13 +154,11 @@ int ieee80211_hw_config(struct ieee80211
-
- if (test_bit(SCAN_SW_SCANNING, &local->scanning) ||
- test_bit(SCAN_ONCHANNEL_SCANNING, &local->scanning) ||
-- test_bit(SCAN_HW_SCANNING, &local->scanning))
-+ test_bit(SCAN_HW_SCANNING, &local->scanning) ||
-+ !local->ap_power_level)
- power = chan->max_power;
- else
-- power = local->power_constr_level ?
-- min(chan->max_power,
-- (chan->max_reg_power - local->power_constr_level)) :
-- chan->max_power;
-+ power = min(chan->max_power, local->ap_power_level);
-
- if (local->user_power_level >= 0)
- power = min(power, local->user_power_level);
---- a/include/net/cfg80211.h
-+++ b/include/net/cfg80211.h
-@@ -1218,6 +1218,7 @@ struct cfg80211_deauth_request {
- const u8 *ie;
- size_t ie_len;
- u16 reason_code;
-+ bool local_state_change;
- };
+ /* best probability rate */
+ unsigned int max_prob_rate;
++ unsigned int max_prob_streams;
- /**
---- a/net/wireless/mlme.c
-+++ b/net/wireless/mlme.c
-@@ -457,20 +457,14 @@ int __cfg80211_mlme_deauth(struct cfg802
- .reason_code = reason,
- .ie = ie,
- .ie_len = ie_len,
-+ .local_state_change = local_state_change,
- };
-
- ASSERT_WDEV_LOCK(wdev);
-
-- if (local_state_change) {
-- if (wdev->current_bss &&
-- ether_addr_equal(wdev->current_bss->pub.bssid, bssid)) {
-- cfg80211_unhold_bss(wdev->current_bss);
-- cfg80211_put_bss(&wdev->current_bss->pub);
-- wdev->current_bss = NULL;
-- }
--
-+ if (local_state_change && (!wdev->current_bss ||
-+ !ether_addr_equal(wdev->current_bss->pub.bssid, bssid)))
- return 0;
-- }
+ /* time of last status update */
+ unsigned long stats_update;
+--- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c
++++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c
+@@ -1023,6 +1023,7 @@ static bool ar9003_hw_init_cal(struct at
+ AR_PHY_AGC_CONTROL_FLTR_CAL |
+ AR_PHY_AGC_CONTROL_PKDET_CAL;
- return rdev->ops->deauth(&rdev->wiphy, dev, &req);
- }
---- a/drivers/net/wireless/ath/ath9k/xmit.c
-+++ b/drivers/net/wireless/ath/ath9k/xmit.c
-@@ -386,7 +386,7 @@ static void ath_tx_complete_aggr(struct
- u16 seq_st = 0, acked_cnt = 0, txfail_cnt = 0, seq_first;
- u32 ba[WME_BA_BMP_SIZE >> 5];
- int isaggr, txfail, txpending, sendbar = 0, needreset = 0, nbad = 0;
-- bool rc_update = true;
-+ bool rc_update = true, isba;
- struct ieee80211_tx_rate rates[4];
- struct ath_frame_info *fi;
- int nframes;
-@@ -430,13 +430,17 @@ static void ath_tx_complete_aggr(struct
- tidno = ieee80211_get_qos_ctl(hdr)[0] & IEEE80211_QOS_CTL_TID_MASK;
- tid = ATH_AN_2_TID(an, tidno);
- seq_first = tid->seq_start;
-+ isba = ts->ts_flags & ATH9K_TX_BA;
++ /* Use chip chainmask only for calibration */
+ ar9003_hw_set_chain_masks(ah, ah->caps.rx_chainmask, ah->caps.tx_chainmask);
- /*
- * The hardware occasionally sends a tx status for the wrong TID.
- * In this case, the BA status cannot be considered valid and all
- * subframes need to be retransmitted
-+ *
-+ * Only BlockAcks have a TID and therefore normal Acks cannot be
-+ * checked
- */
-- if (tidno != ts->tid)
-+ if (isba && tidno != ts->tid)
- txok = false;
+ if (rtt) {
+@@ -1150,6 +1151,9 @@ skip_tx_iqcal:
+ ar9003_hw_rtt_disable(ah);
+ }
- isaggr = bf_isaggr(bf);
---- a/net/mac80211/cfg.c
-+++ b/net/mac80211/cfg.c
-@@ -2563,6 +2563,9 @@ static void ieee80211_mgmt_frame_registe
- else
- local->probe_req_reg--;
++ /* Revert chainmask to runtime parameters */
++ ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask);
++
+ /* Initialize list pointers */
+ ah->cal_list = ah->cal_list_last = ah->cal_list_curr = NULL;
+
+--- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
++++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
+@@ -3606,6 +3606,12 @@ static void ar9003_hw_ant_ctrl_apply(str
+ value = ar9003_hw_ant_ctrl_common_2_get(ah, is2ghz);
+ REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM_2, AR_SWITCH_TABLE_COM2_ALL, value);
+
++ if ((AR_SREV_9462(ah)) && (ah->rxchainmask == 0x2)) {
++ value = ar9003_hw_ant_ctrl_chain_get(ah, 1, is2ghz);
++ REG_RMW_FIELD(ah, switch_chain_reg[0],
++ AR_SWITCH_TABLE_ALL, value);
++ }
++
+ for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) {
+ if ((ah->rxchainmask & BIT(chain)) ||
+ (ah->txchainmask & BIT(chain))) {
+@@ -3772,6 +3778,17 @@ static void ar9003_hw_atten_apply(struct
+ AR_PHY_EXT_ATTEN_CTL_2,
+ };
+
++ if ((AR_SREV_9462(ah)) && (ah->rxchainmask == 0x2)) {
++ value = ar9003_hw_atten_chain_get(ah, 1, chan);
++ REG_RMW_FIELD(ah, ext_atten_reg[0],
++ AR_PHY_EXT_ATTEN_CTL_XATTEN1_DB, value);
++
++ value = ar9003_hw_atten_chain_get_margin(ah, 1, chan);
++ REG_RMW_FIELD(ah, ext_atten_reg[0],
++ AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN,
++ value);
++ }
++
+ /* Test value. if 0 then attenuation is unused. Don't load anything. */
+ for (i = 0; i < 3; i++) {
+ if (ah->txchainmask & BIT(i)) {
+--- a/drivers/net/wireless/ath/ath9k/link.c
++++ b/drivers/net/wireless/ath/ath9k/link.c
+@@ -28,21 +28,21 @@ void ath_tx_complete_poll_work(struct wo
+ int i;
+ bool needreset = false;
-+ if (!local->open_count)
-+ break;
+- for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
+- if (ATH_TXQ_SETUP(sc, i)) {
+- txq = &sc->tx.txq[i];
+- ath_txq_lock(sc, txq);
+- if (txq->axq_depth) {
+- if (txq->axq_tx_inprogress) {
+- needreset = true;
+- ath_txq_unlock(sc, txq);
+- break;
+- } else {
+- txq->axq_tx_inprogress = true;
+- }
++ for (i = 0; i < IEEE80211_NUM_ACS; i++) {
++ txq = sc->tx.txq_map[i];
+
- ieee80211_queue_work(&local->hw, &local->reconfig_filter);
- break;
- default:
---- a/net/mac80211/tx.c
-+++ b/net/mac80211/tx.c
-@@ -354,7 +354,7 @@ static void purge_old_ps_buffers(struct
- total += skb_queue_len(&sta->ps_tx_buf[ac]);
- if (skb) {
- purged++;
-- dev_kfree_skb(skb);
-+ ieee80211_free_txskb(&local->hw, skb);
- break;
++ ath_txq_lock(sc, txq);
++ if (txq->axq_depth) {
++ if (txq->axq_tx_inprogress) {
++ needreset = true;
++ ath_txq_unlock(sc, txq);
++ break;
++ } else {
++ txq->axq_tx_inprogress = true;
}
+- ath_txq_unlock_complete(sc, txq);
}
-@@ -466,7 +466,7 @@ ieee80211_tx_h_unicast_ps_buf(struct iee
- ps_dbg(tx->sdata,
- "STA %pM TX buffer for AC %d full - dropping oldest frame\n",
- sta->sta.addr, ac);
-- dev_kfree_skb(old);
-+ ieee80211_free_txskb(&local->hw, old);
- } else
- tx->local->total_ps_buffered++;
-
-@@ -1103,7 +1103,7 @@ static bool ieee80211_tx_prep_agg(struct
- spin_unlock(&tx->sta->lock);
-
- if (purge_skb)
-- dev_kfree_skb(purge_skb);
-+ ieee80211_free_txskb(&tx->local->hw, purge_skb);
- }
++ ath_txq_unlock_complete(sc, txq);
++ }
- /* reset session timer */
-@@ -1214,7 +1214,7 @@ static bool ieee80211_tx_frags(struct ie
- #ifdef CONFIG_MAC80211_VERBOSE_DEBUG
- if (WARN_ON_ONCE(q >= local->hw.queues)) {
- __skb_unlink(skb, skbs);
-- dev_kfree_skb(skb);
-+ ieee80211_free_txskb(&local->hw, skb);
- continue;
+ if (needreset) {
+ ath_dbg(ath9k_hw_common(sc->sc_ah), RESET,
+--- a/net/mac80211/sta_info.c
++++ b/net/mac80211/sta_info.c
+@@ -766,6 +766,7 @@ int __must_check __sta_info_destroy(stru
+ struct ieee80211_local *local;
+ struct ieee80211_sub_if_data *sdata;
+ int ret, i;
++ bool have_key = false;
+
+ might_sleep();
+
+@@ -793,12 +794,19 @@ int __must_check __sta_info_destroy(stru
+ list_del_rcu(&sta->list);
+
+ mutex_lock(&local->key_mtx);
+- for (i = 0; i < NUM_DEFAULT_KEYS; i++)
++ for (i = 0; i < NUM_DEFAULT_KEYS; i++) {
+ __ieee80211_key_free(key_mtx_dereference(local, sta->gtk[i]));
+- if (sta->ptk)
++ have_key = true;
++ }
++ if (sta->ptk) {
+ __ieee80211_key_free(key_mtx_dereference(local, sta->ptk));
++ have_key = true;
++ }
+ mutex_unlock(&local->key_mtx);
+
++ if (!have_key)
++ synchronize_net();
++
+ sta->dead = true;
+
+ local->num_sta--;
+--- a/net/mac80211/chan.c
++++ b/net/mac80211/chan.c
+@@ -63,6 +63,7 @@ ieee80211_new_chanctx(struct ieee80211_l
+ enum ieee80211_chanctx_mode mode)
+ {
+ struct ieee80211_chanctx *ctx;
++ u32 changed;
+ int err;
+
+ lockdep_assert_held(&local->chanctx_mtx);
+@@ -76,6 +77,13 @@ ieee80211_new_chanctx(struct ieee80211_l
+ ctx->conf.rx_chains_dynamic = 1;
+ ctx->mode = mode;
+
++ /* acquire mutex to prevent idle from changing */
++ mutex_lock(&local->mtx);
++ /* turn idle off *before* setting channel -- some drivers need that */
++ changed = ieee80211_idle_off(local);
++ if (changed)
++ ieee80211_hw_config(local, changed);
++
+ if (!local->use_chanctx) {
+ local->_oper_channel_type =
+ cfg80211_get_chandef_type(chandef);
+@@ -85,14 +93,17 @@ ieee80211_new_chanctx(struct ieee80211_l
+ err = drv_add_chanctx(local, ctx);
+ if (err) {
+ kfree(ctx);
+- return ERR_PTR(err);
++ ctx = ERR_PTR(err);
++
++ ieee80211_recalc_idle(local);
++ goto out;
}
- #endif
-@@ -1356,9 +1356,9 @@ static int invoke_tx_handlers(struct iee
- if (unlikely(res == TX_DROP)) {
- I802_DEBUG_INC(tx->local->tx_handlers_drop);
- if (tx->skb)
-- dev_kfree_skb(tx->skb);
-+ ieee80211_free_txskb(&tx->local->hw, tx->skb);
- else
-- __skb_queue_purge(&tx->skbs);
-+ ieee80211_purge_tx_queue(&tx->local->hw, &tx->skbs);
- return -1;
- } else if (unlikely(res == TX_QUEUED)) {
- I802_DEBUG_INC(tx->local->tx_handlers_queued);
-@@ -1393,7 +1393,7 @@ static bool ieee80211_tx(struct ieee8021
- res_prepare = ieee80211_tx_prepare(sdata, &tx, skb);
-
- if (unlikely(res_prepare == TX_DROP)) {
-- dev_kfree_skb(skb);
-+ ieee80211_free_txskb(&local->hw, skb);
- goto out;
- } else if (unlikely(res_prepare == TX_QUEUED)) {
- goto out;
-@@ -1465,7 +1465,7 @@ void ieee80211_xmit(struct ieee80211_sub
- headroom = max_t(int, 0, headroom);
-
- if (ieee80211_skb_resize(sdata, skb, headroom, may_encrypt)) {
-- dev_kfree_skb(skb);
-+ ieee80211_free_txskb(&local->hw, skb);
- rcu_read_unlock();
- return;
- }
-@@ -2056,8 +2056,10 @@ netdev_tx_t ieee80211_subif_start_xmit(s
- head_need += IEEE80211_ENCRYPT_HEADROOM;
- head_need += local->tx_headroom;
- head_need = max_t(int, 0, head_need);
-- if (ieee80211_skb_resize(sdata, skb, head_need, true))
-- goto fail;
-+ if (ieee80211_skb_resize(sdata, skb, head_need, true)) {
-+ ieee80211_free_txskb(&local->hw, skb);
-+ return NETDEV_TX_OK;
-+ }
}
- if (encaps_data) {
-@@ -2124,10 +2126,13 @@ netdev_tx_t ieee80211_subif_start_xmit(s
- */
- void ieee80211_clear_tx_pending(struct ieee80211_local *local)
- {
-+ struct sk_buff *skb;
- int i;
++ /* and keep the mutex held until the new chanctx is on the list */
+ list_add_rcu(&ctx->list, &local->chanctx_list);
-- for (i = 0; i < local->hw.queues; i++)
-- skb_queue_purge(&local->pending[i]);
-+ for (i = 0; i < local->hw.queues; i++) {
-+ while ((skb = skb_dequeue(&local->pending[i])) != NULL)
-+ ieee80211_free_txskb(&local->hw, skb);
-+ }
- }
+- mutex_lock(&local->mtx);
+- ieee80211_recalc_idle(local);
++ out:
+ mutex_unlock(&local->mtx);
- /*
-@@ -2190,7 +2195,7 @@ void ieee80211_tx_pending(unsigned long
- struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+ return ctx;
+--- a/net/mac80211/ieee80211_i.h
++++ b/net/mac80211/ieee80211_i.h
+@@ -1366,6 +1366,7 @@ int ieee80211_if_change_type(struct ieee
+ enum nl80211_iftype type);
+ void ieee80211_if_remove(struct ieee80211_sub_if_data *sdata);
+ void ieee80211_remove_interfaces(struct ieee80211_local *local);
++u32 ieee80211_idle_off(struct ieee80211_local *local);
+ void ieee80211_recalc_idle(struct ieee80211_local *local);
+ void ieee80211_adjust_monitor_flags(struct ieee80211_sub_if_data *sdata,
+ const int offset);
+--- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c
++++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
+@@ -799,7 +799,7 @@ static int ath9k_init_firmware_version(s
+ * required version.
+ */
+ if (priv->fw_version_major != MAJOR_VERSION_REQ ||
+- priv->fw_version_minor != MINOR_VERSION_REQ) {
++ priv->fw_version_minor < MINOR_VERSION_REQ) {
+ dev_err(priv->dev, "ath9k_htc: Please upgrade to FW version %d.%d\n",
+ MAJOR_VERSION_REQ, MINOR_VERSION_REQ);
+ return -EINVAL;
+--- a/drivers/net/wireless/ath/ath9k/xmit.c
++++ b/drivers/net/wireless/ath/ath9k/xmit.c
+@@ -516,8 +516,7 @@ static void ath_tx_complete_aggr(struct
+ * not a holding desc.
+ */
+ INIT_LIST_HEAD(&bf_head);
+- if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) ||
+- bf_next != NULL || !bf_last->bf_stale)
++ if (bf_next != NULL || !bf_last->bf_stale)
+ list_move_tail(&bf->list, &bf_head);
+
+ if (!txpending || (tid->state & AGGR_CLEANUP)) {
+@@ -537,8 +536,7 @@ static void ath_tx_complete_aggr(struct
+ !txfail);
+ } else {
+ /* retry the un-acked ones */
+- if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) &&
+- bf->bf_next == NULL && bf_last->bf_stale) {
++ if (bf->bf_next == NULL && bf_last->bf_stale) {
+ struct ath_buf *tbf;
+
+ tbf = ath_clone_txbuf(sc, bf_last);
+@@ -2264,6 +2262,7 @@ void ath_tx_edma_tasklet(struct ath_soft
+ struct ath_txq *txq;
+ struct ath_buf *bf, *lastbf;
+ struct list_head bf_head;
++ struct list_head *fifo_list;
+ int status;
+
+ for (;;) {
+@@ -2291,20 +2290,24 @@ void ath_tx_edma_tasklet(struct ath_soft
+
+ TX_STAT_INC(txq->axq_qnum, txprocdesc);
+
+- if (list_empty(&txq->txq_fifo[txq->txq_tailidx])) {
++ fifo_list = &txq->txq_fifo[txq->txq_tailidx];
++ if (list_empty(fifo_list)) {
+ ath_txq_unlock(sc, txq);
+ return;
+ }
+
+- bf = list_first_entry(&txq->txq_fifo[txq->txq_tailidx],
+- struct ath_buf, list);
++ bf = list_first_entry(fifo_list, struct ath_buf, list);
++ if (bf->bf_stale) {
++ list_del(&bf->list);
++ ath_tx_return_buffer(sc, bf);
++ bf = list_first_entry(fifo_list, struct ath_buf, list);
++ }
++
+ lastbf = bf->bf_lastbf;
- if (WARN_ON(!info->control.vif)) {
-- kfree_skb(skb);
-+ ieee80211_free_txskb(&local->hw, skb);
- continue;
+ INIT_LIST_HEAD(&bf_head);
+- list_cut_position(&bf_head, &txq->txq_fifo[txq->txq_tailidx],
+- &lastbf->list);
+-
+- if (list_empty(&txq->txq_fifo[txq->txq_tailidx])) {
++ if (list_is_last(&lastbf->list, fifo_list)) {
++ list_splice_tail_init(fifo_list, &bf_head);
+ INCR(txq->txq_tailidx, ATH_TXFIFO_DEPTH);
+
+ if (!list_empty(&txq->axq_q)) {
+@@ -2315,6 +2318,11 @@ void ath_tx_edma_tasklet(struct ath_soft
+ list_splice_tail_init(&txq->axq_q, &bf_q);
+ ath_tx_txqaddbuf(sc, txq, &bf_q, true);
}
++ } else {
++ lastbf->bf_stale = true;
++ if (bf != lastbf)
++ list_cut_position(&bf_head, fifo_list,
++ lastbf->list.prev);
+ }
---- a/drivers/net/wireless/ath/ath5k/mac80211-ops.c
-+++ b/drivers/net/wireless/ath/ath5k/mac80211-ops.c
-@@ -65,7 +65,7 @@ ath5k_tx(struct ieee80211_hw *hw, struct
- u16 qnum = skb_get_queue_mapping(skb);
+ ath_tx_process_buffer(sc, txq, &ts, bf, &bf_head);
+--- a/drivers/net/wireless/ath/ath9k/ar9580_1p0_initvals.h
++++ b/drivers/net/wireless/ath/ath9k/ar9580_1p0_initvals.h
+@@ -519,7 +519,7 @@ static const u32 ar9580_1p0_mac_core[][2
+ {0x00008258, 0x00000000},
+ {0x0000825c, 0x40000000},
+ {0x00008260, 0x00080922},
+- {0x00008264, 0x9bc00010},
++ {0x00008264, 0x9d400010},
+ {0x00008268, 0xffffffff},
+ {0x0000826c, 0x0000ffff},
+ {0x00008270, 0x00000000},
+--- a/net/mac80211/mlme.c
++++ b/net/mac80211/mlme.c
+@@ -3955,8 +3955,16 @@ int ieee80211_mgd_auth(struct ieee80211_
+ /* prep auth_data so we don't go into idle on disassoc */
+ ifmgd->auth_data = auth_data;
+
+- if (ifmgd->associated)
+- ieee80211_set_disassoc(sdata, 0, 0, false, NULL);
++ if (ifmgd->associated) {
++ u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN];
++
++ ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH,
++ WLAN_REASON_UNSPECIFIED,
++ false, frame_buf);
++
++ __cfg80211_send_deauth(sdata->dev, frame_buf,
++ sizeof(frame_buf));
++ }
- if (WARN_ON(qnum >= ah->ah_capabilities.cap_queues.q_tx_num)) {
-- dev_kfree_skb_any(skb);
-+ ieee80211_free_txskb(hw, skb);
- return;
- }
+ sdata_info(sdata, "authenticate with %pM\n", req->bss->bssid);
---- a/drivers/net/wireless/ath/ath9k/hw.c
-+++ b/drivers/net/wireless/ath/ath9k/hw.c
-@@ -1467,7 +1467,9 @@ static bool ath9k_hw_chip_reset(struct a
- reset_type = ATH9K_RESET_POWER_ON;
- else
- reset_type = ATH9K_RESET_COLD;
-- }
-+ } else if (ah->chip_fullsleep || REG_READ(ah, AR_Q_TXE) ||
-+ (REG_READ(ah, AR_CR) & AR_CR_RXE))
-+ reset_type = ATH9K_RESET_COLD;
+@@ -4016,8 +4024,16 @@ int ieee80211_mgd_assoc(struct ieee80211
- if (!ath9k_hw_set_reset_reg(ah, reset_type))
- return false;
-@@ -2568,7 +2570,7 @@ int ath9k_hw_fill_cap_info(struct ath_hw
+ mutex_lock(&ifmgd->mtx);
- if (AR_SREV_9300_20_OR_LATER(ah)) {
- ah->enabled_cals |= TX_IQ_CAL;
-- if (AR_SREV_9485_OR_LATER(ah))
-+ if (AR_SREV_9485_OR_LATER(ah) && !AR_SREV_9340(ah))
- ah->enabled_cals |= TX_IQ_ON_AGC_CAL;
- }
+- if (ifmgd->associated)
+- ieee80211_set_disassoc(sdata, 0, 0, false, NULL);
++ if (ifmgd->associated) {
++ u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN];
++
++ ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH,
++ WLAN_REASON_UNSPECIFIED,
++ false, frame_buf);
++
++ __cfg80211_send_deauth(sdata->dev, frame_buf,
++ sizeof(frame_buf));
++ }
---- a/drivers/net/wireless/ath/ath9k/ath9k.h
-+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
-@@ -313,7 +313,6 @@ struct ath_rx {
- u32 *rxlink;
- u32 num_pkts;
- unsigned int rxfilter;
-- spinlock_t rxbuflock;
- struct list_head rxbuf;
- struct ath_descdma rxdma;
- struct ath_buf *rx_bufptr;
-@@ -324,7 +323,6 @@ struct ath_rx {
-
- int ath_startrecv(struct ath_softc *sc);
- bool ath_stoprecv(struct ath_softc *sc);
--void ath_flushrecv(struct ath_softc *sc);
- u32 ath_calcrxfilter(struct ath_softc *sc);
- int ath_rx_init(struct ath_softc *sc, int nbufs);
- void ath_rx_cleanup(struct ath_softc *sc);
-@@ -627,7 +625,6 @@ void ath_ant_comb_update(struct ath_soft
- enum sc_op_flags {
- SC_OP_INVALID,
- SC_OP_BEACONS,
-- SC_OP_RXFLUSH,
- SC_OP_ANI_RUN,
- SC_OP_PRIM_STA_VIF,
- SC_OP_HW_RESET,
---- a/drivers/net/wireless/ath/ath9k/beacon.c
-+++ b/drivers/net/wireless/ath/ath9k/beacon.c
-@@ -147,6 +147,7 @@ static struct ath_buf *ath9k_beacon_gene
- skb->len, DMA_TO_DEVICE);
- dev_kfree_skb_any(skb);
- bf->bf_buf_addr = 0;
-+ bf->bf_mpdu = NULL;
- }
+ if (ifmgd->auth_data && !ifmgd->auth_data->done) {
+ err = -EBUSY;
+--- a/net/mac80211/rc80211_minstrel.c
++++ b/net/mac80211/rc80211_minstrel.c
+@@ -55,7 +55,6 @@
+ #include "rate.h"
+ #include "rc80211_minstrel.h"
- skb = ieee80211_beacon_get(hw, vif);
-@@ -359,7 +360,6 @@ void ath9k_beacon_tasklet(unsigned long
- return;
+-#define SAMPLE_COLUMNS 10
+ #define SAMPLE_TBL(_mi, _idx, _col) \
+ _mi->sample_table[(_idx * SAMPLE_COLUMNS) + _col]
- bf = ath9k_beacon_generate(sc->hw, vif);
-- WARN_ON(!bf);
-
- if (sc->beacon.bmisscnt != 0) {
- ath_dbg(common, BSTUCK, "resume beacon xmit after %u misses\n",
---- a/drivers/net/wireless/ath/ath9k/debug.c
-+++ b/drivers/net/wireless/ath/ath9k/debug.c
-@@ -919,7 +919,6 @@ static ssize_t read_file_recv(struct fil
- RXS_ERR("RX-LENGTH-ERR", rx_len_err);
- RXS_ERR("RX-OOM-ERR", rx_oom_err);
- RXS_ERR("RX-RATE-ERR", rx_rate_err);
-- RXS_ERR("RX-DROP-RXFLUSH", rx_drop_rxflush);
- RXS_ERR("RX-TOO-MANY-FRAGS", rx_too_many_frags_err);
-
- PHY_ERR("UNDERRUN ERR", ATH9K_PHYERR_UNDERRUN);
---- a/drivers/net/wireless/ath/ath9k/debug.h
-+++ b/drivers/net/wireless/ath/ath9k/debug.h
-@@ -198,7 +198,6 @@ struct ath_tx_stats {
- * @rx_oom_err: No. of frames dropped due to OOM issues.
- * @rx_rate_err: No. of frames dropped due to rate errors.
- * @rx_too_many_frags_err: Frames dropped due to too-many-frags received.
-- * @rx_drop_rxflush: No. of frames dropped due to RX-FLUSH.
- * @rx_beacons: No. of beacons received.
- * @rx_frags: No. of rx-fragements received.
- */
-@@ -217,7 +216,6 @@ struct ath_rx_stats {
- u32 rx_oom_err;
- u32 rx_rate_err;
- u32 rx_too_many_frags_err;
-- u32 rx_drop_rxflush;
- u32 rx_beacons;
- u32 rx_frags;
- };
---- a/drivers/net/wireless/ath/ath9k/main.c
-+++ b/drivers/net/wireless/ath/ath9k/main.c
-@@ -181,7 +181,7 @@ static void ath_restart_work(struct ath_
- ath_start_ani(sc);
+@@ -70,16 +69,31 @@ rix_to_ndx(struct minstrel_sta_info *mi,
+ return i;
}
--static bool ath_prepare_reset(struct ath_softc *sc, bool retry_tx, bool flush)
-+static bool ath_prepare_reset(struct ath_softc *sc, bool retry_tx)
++/* find & sort topmost throughput rates */
++static inline void
++minstrel_sort_best_tp_rates(struct minstrel_sta_info *mi, int i, u8 *tp_list)
++{
++ int j = MAX_THR_RATES;
++
++ while (j > 0 && mi->r[i].cur_tp > mi->r[tp_list[j - 1]].cur_tp)
++ j--;
++ if (j < MAX_THR_RATES - 1)
++ memmove(&tp_list[j + 1], &tp_list[j], MAX_THR_RATES - (j + 1));
++ if (j < MAX_THR_RATES)
++ tp_list[j] = i;
++}
++
+ static void
+ minstrel_update_stats(struct minstrel_priv *mp, struct minstrel_sta_info *mi)
{
- struct ath_hw *ah = sc->sc_ah;
- bool ret = true;
-@@ -201,14 +201,6 @@ static bool ath_prepare_reset(struct ath
- if (!ath_drain_all_txq(sc, retry_tx))
- ret = false;
-
-- if (!flush) {
-- if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
-- ath_rx_tasklet(sc, 1, true);
-- ath_rx_tasklet(sc, 1, false);
-- } else {
-- ath_flushrecv(sc);
-- }
--
- return ret;
- }
-
-@@ -261,11 +253,11 @@ static int ath_reset_internal(struct ath
- struct ath_common *common = ath9k_hw_common(ah);
- struct ath9k_hw_cal_data *caldata = NULL;
- bool fastcc = true;
-- bool flush = false;
- int r;
-
- __ath_cancel_work(sc);
-
-+ tasklet_disable(&sc->intr_tq);
- spin_lock_bh(&sc->sc_pcu_lock);
+- u32 max_tp = 0, index_max_tp = 0, index_max_tp2 = 0;
+- u32 max_prob = 0, index_max_prob = 0;
++ u8 tmp_tp_rate[MAX_THR_RATES];
++ u8 tmp_prob_rate = 0;
+ u32 usecs;
+- u32 p;
+ int i;
- if (!(sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)) {
-@@ -275,11 +267,10 @@ static int ath_reset_internal(struct ath
+- mi->stats_update = jiffies;
++ for (i=0; i < MAX_THR_RATES; i++)
++ tmp_tp_rate[i] = 0;
++
+ for (i = 0; i < mi->n_rates; i++) {
+ struct minstrel_rate *mr = &mi->r[i];
+
+@@ -87,27 +101,32 @@ minstrel_update_stats(struct minstrel_pr
+ if (!usecs)
+ usecs = 1000000;
+
+- /* To avoid rounding issues, probabilities scale from 0 (0%)
+- * to 18000 (100%) */
+- if (mr->attempts) {
+- p = (mr->success * 18000) / mr->attempts;
++ if (unlikely(mr->attempts > 0)) {
++ mr->sample_skipped = 0;
++ mr->cur_prob = MINSTREL_FRAC(mr->success, mr->attempts);
+ mr->succ_hist += mr->success;
+ mr->att_hist += mr->attempts;
+- mr->cur_prob = p;
+- p = ((p * (100 - mp->ewma_level)) + (mr->probability *
+- mp->ewma_level)) / 100;
+- mr->probability = p;
+- mr->cur_tp = p * (1000000 / usecs);
+- }
++ mr->probability = minstrel_ewma(mr->probability,
++ mr->cur_prob,
++ EWMA_LEVEL);
++ } else
++ mr->sample_skipped++;
+
+ mr->last_success = mr->success;
+ mr->last_attempts = mr->attempts;
+ mr->success = 0;
+ mr->attempts = 0;
+
++ /* Update throughput per rate, reset thr. below 10% success */
++ if (mr->probability < MINSTREL_FRAC(10, 100))
++ mr->cur_tp = 0;
++ else
++ mr->cur_tp = mr->probability * (1000000 / usecs);
++
+ /* Sample less often below the 10% chance of success.
+ * Sample less often above the 95% chance of success. */
+- if ((mr->probability > 17100) || (mr->probability < 1800)) {
++ if (mr->probability > MINSTREL_FRAC(95, 100) ||
++ mr->probability < MINSTREL_FRAC(10, 100)) {
+ mr->adjusted_retry_count = mr->retry_count >> 1;
+ if (mr->adjusted_retry_count > 2)
+ mr->adjusted_retry_count = 2;
+@@ -118,35 +137,30 @@ minstrel_update_stats(struct minstrel_pr
+ }
+ if (!mr->adjusted_retry_count)
+ mr->adjusted_retry_count = 2;
+- }
- if (!hchan) {
- fastcc = false;
-- flush = true;
- hchan = ah->curchan;
+- for (i = 0; i < mi->n_rates; i++) {
+- struct minstrel_rate *mr = &mi->r[i];
+- if (max_tp < mr->cur_tp) {
+- index_max_tp = i;
+- max_tp = mr->cur_tp;
+- }
+- if (max_prob < mr->probability) {
+- index_max_prob = i;
+- max_prob = mr->probability;
++ minstrel_sort_best_tp_rates(mi, i, tmp_tp_rate);
++
++ /* To determine the most robust rate (max_prob_rate) used at
++ * 3rd mmr stage we distinct between two cases:
++ * (1) if any success probabilitiy >= 95%, out of those rates
++ * choose the maximum throughput rate as max_prob_rate
++ * (2) if all success probabilities < 95%, the rate with
++ * highest success probability is choosen as max_prob_rate */
++ if (mr->probability >= MINSTREL_FRAC(95,100)) {
++ if (mr->cur_tp >= mi->r[tmp_prob_rate].cur_tp)
++ tmp_prob_rate = i;
++ } else {
++ if (mr->probability >= mi->r[tmp_prob_rate].probability)
++ tmp_prob_rate = i;
+ }
}
-- if (!ath_prepare_reset(sc, retry_tx, flush))
-+ if (!ath_prepare_reset(sc, retry_tx))
- fastcc = false;
+- max_tp = 0;
+- for (i = 0; i < mi->n_rates; i++) {
+- struct minstrel_rate *mr = &mi->r[i];
+-
+- if (i == index_max_tp)
+- continue;
++ /* Assign the new rate set */
++ memcpy(mi->max_tp_rate, tmp_tp_rate, sizeof(mi->max_tp_rate));
++ mi->max_prob_rate = tmp_prob_rate;
+
+- if (max_tp < mr->cur_tp) {
+- index_max_tp2 = i;
+- max_tp = mr->cur_tp;
+- }
+- }
+- mi->max_tp_rate = index_max_tp;
+- mi->max_tp_rate2 = index_max_tp2;
+- mi->max_prob_rate = index_max_prob;
++ /* Reset update timer */
++ mi->stats_update = jiffies;
+ }
- ath_dbg(common, CONFIG, "Reset to %u MHz, HT40: %d fastcc: %d\n",
-@@ -297,6 +288,8 @@ static int ath_reset_internal(struct ath
+ static void
+@@ -207,10 +221,10 @@ static int
+ minstrel_get_next_sample(struct minstrel_sta_info *mi)
+ {
+ unsigned int sample_ndx;
+- sample_ndx = SAMPLE_TBL(mi, mi->sample_idx, mi->sample_column);
+- mi->sample_idx++;
+- if ((int) mi->sample_idx > (mi->n_rates - 2)) {
+- mi->sample_idx = 0;
++ sample_ndx = SAMPLE_TBL(mi, mi->sample_row, mi->sample_column);
++ mi->sample_row++;
++ if ((int) mi->sample_row >= mi->n_rates) {
++ mi->sample_row = 0;
+ mi->sample_column++;
+ if (mi->sample_column >= SAMPLE_COLUMNS)
+ mi->sample_column = 0;
+@@ -228,31 +242,37 @@ minstrel_get_rate(void *priv, struct iee
+ struct minstrel_priv *mp = priv;
+ struct ieee80211_tx_rate *ar = info->control.rates;
+ unsigned int ndx, sample_ndx = 0;
+- bool mrr;
+- bool sample_slower = false;
+- bool sample = false;
++ bool mrr_capable;
++ bool indirect_rate_sampling = false;
++ bool rate_sampling = false;
+ int i, delta;
+ int mrr_ndx[3];
+- int sample_rate;
++ int sampling_ratio;
+
++ /* management/no-ack frames do not use rate control */
+ if (rate_control_send_low(sta, priv_sta, txrc))
+ return;
- out:
- spin_unlock_bh(&sc->sc_pcu_lock);
-+ tasklet_enable(&sc->intr_tq);
+- mrr = mp->has_mrr && !txrc->rts && !txrc->bss_conf->use_cts_prot;
+-
+- ndx = mi->max_tp_rate;
+-
+- if (mrr)
+- sample_rate = mp->lookaround_rate_mrr;
++ /* check multi-rate-retry capabilities & adjust lookaround_rate */
++ mrr_capable = mp->has_mrr &&
++ !txrc->rts &&
++ !txrc->bss_conf->use_cts_prot;
++ if (mrr_capable)
++ sampling_ratio = mp->lookaround_rate_mrr;
+ else
+- sample_rate = mp->lookaround_rate;
++ sampling_ratio = mp->lookaround_rate;
+
- return r;
- }
-
-@@ -821,7 +814,7 @@ static void ath9k_stop(struct ieee80211_
- ath9k_hw_cfg_gpio_input(ah, ah->led_pin);
- }
++ /* init rateindex [ndx] with max throughput rate */
++ ndx = mi->max_tp_rate[0];
-- ath_prepare_reset(sc, false, true);
-+ ath_prepare_reset(sc, false);
++ /* increase sum packet counter */
+ mi->packet_count++;
+- delta = (mi->packet_count * sample_rate / 100) -
++
++ delta = (mi->packet_count * sampling_ratio / 100) -
+ (mi->sample_count + mi->sample_deferred / 2);
+
+ /* delta > 0: sampling required */
+- if ((delta > 0) && (mrr || !mi->prev_sample)) {
++ if ((delta > 0) && (mrr_capable || !mi->prev_sample)) {
+ struct minstrel_rate *msr;
+ if (mi->packet_count >= 10000) {
+ mi->sample_deferred = 0;
+@@ -271,21 +291,28 @@ minstrel_get_rate(void *priv, struct iee
+ mi->sample_count += (delta - mi->n_rates * 2);
+ }
- if (sc->rx.frag) {
- dev_kfree_skb_any(sc->rx.frag);
---- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c
-+++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c
-@@ -893,7 +893,7 @@ static bool ar9003_hw_init_cal(struct at
- struct ath9k_hw_cal_data *caldata = ah->caldata;
- bool txiqcal_done = false, txclcal_done = false;
- bool is_reusable = true, status = true;
-- bool run_rtt_cal = false, run_agc_cal;
-+ bool run_rtt_cal = false, run_agc_cal, sep_iq_cal = false;
- bool rtt = !!(ah->caps.hw_caps & ATH9K_HW_CAP_RTT);
- u32 agc_ctrl = 0, agc_supp_cals = AR_PHY_AGC_CONTROL_OFFSET_CAL |
- AR_PHY_AGC_CONTROL_FLTR_CAL |
-@@ -939,7 +939,8 @@ static bool ar9003_hw_init_cal(struct at
++ /* get next random rate sample */
+ sample_ndx = minstrel_get_next_sample(mi);
+ msr = &mi->r[sample_ndx];
+- sample = true;
+- sample_slower = mrr && (msr->perfect_tx_time >
+- mi->r[ndx].perfect_tx_time);
++ rate_sampling = true;
+
+- if (!sample_slower) {
++ /* Decide if direct ( 1st mrr stage) or indirect (2nd mrr stage)
++ * rate sampling method should be used.
++ * Respect such rates that are not sampled for 20 interations.
++ */
++ if (mrr_capable &&
++ msr->perfect_tx_time > mi->r[ndx].perfect_tx_time &&
++ msr->sample_skipped < 20)
++ indirect_rate_sampling = true;
++
++ if (!indirect_rate_sampling) {
+ if (msr->sample_limit != 0) {
+ ndx = sample_ndx;
+ mi->sample_count++;
+ if (msr->sample_limit > 0)
+ msr->sample_limit--;
+- } else {
+- sample = false;
+- }
++ } else
++ rate_sampling = false;
+ } else {
+ /* Only use IEEE80211_TX_CTL_RATE_CTRL_PROBE to mark
+ * packets that have the sampling rate deferred to the
+@@ -297,34 +324,39 @@ minstrel_get_rate(void *priv, struct iee
+ mi->sample_deferred++;
}
}
+- mi->prev_sample = sample;
++ mi->prev_sample = rate_sampling;
+
+ /* If we're not using MRR and the sampling rate already
+ * has a probability of >95%, we shouldn't be attempting
+ * to use it, as this only wastes precious airtime */
+- if (!mrr && sample && (mi->r[ndx].probability > 17100))
+- ndx = mi->max_tp_rate;
++ if (!mrr_capable && rate_sampling &&
++ (mi->r[ndx].probability > MINSTREL_FRAC(95, 100)))
++ ndx = mi->max_tp_rate[0];
+
++ /* mrr setup for 1st stage */
+ ar[0].idx = mi->r[ndx].rix;
+ ar[0].count = minstrel_get_retry_count(&mi->r[ndx], info);
+
+- if (!mrr) {
+- if (!sample)
++ /* non mrr setup for 2nd stage */
++ if (!mrr_capable) {
++ if (!rate_sampling)
+ ar[0].count = mp->max_retry;
+ ar[1].idx = mi->lowest_rix;
+ ar[1].count = mp->max_retry;
+ return;
+ }
-- if (!(ah->enabled_cals & TX_IQ_CAL))
-+ if ((IS_CHAN_HALF_RATE(chan) || IS_CHAN_QUARTER_RATE(chan)) ||
-+ !(ah->enabled_cals & TX_IQ_CAL))
- goto skip_tx_iqcal;
-
- /* Do Tx IQ Calibration */
-@@ -959,21 +960,22 @@ static bool ar9003_hw_init_cal(struct at
- REG_CLR_BIT(ah, AR_PHY_TX_IQCAL_CONTROL_0,
- AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL);
- txiqcal_done = run_agc_cal = true;
-- goto skip_tx_iqcal;
-- } else if (caldata && !caldata->done_txiqcal_once)
-+ } else if (caldata && !caldata->done_txiqcal_once) {
- run_agc_cal = true;
-+ sep_iq_cal = true;
-+ }
+- /* MRR setup */
+- if (sample) {
+- if (sample_slower)
++ /* mrr setup for 2nd stage */
++ if (rate_sampling) {
++ if (indirect_rate_sampling)
+ mrr_ndx[0] = sample_ndx;
+ else
+- mrr_ndx[0] = mi->max_tp_rate;
++ mrr_ndx[0] = mi->max_tp_rate[0];
+ } else {
+- mrr_ndx[0] = mi->max_tp_rate2;
++ mrr_ndx[0] = mi->max_tp_rate[1];
+ }
++
++ /* mrr setup for 3rd & 4th stage */
+ mrr_ndx[1] = mi->max_prob_rate;
+ mrr_ndx[2] = 0;
+ for (i = 1; i < 4; i++) {
+@@ -351,26 +383,21 @@ static void
+ init_sample_table(struct minstrel_sta_info *mi)
+ {
+ unsigned int i, col, new_idx;
+- unsigned int n_srates = mi->n_rates - 1;
+ u8 rnd[8];
+
+ mi->sample_column = 0;
+- mi->sample_idx = 0;
+- memset(mi->sample_table, 0, SAMPLE_COLUMNS * mi->n_rates);
++ mi->sample_row = 0;
++ memset(mi->sample_table, 0xff, SAMPLE_COLUMNS * mi->n_rates);
+
+ for (col = 0; col < SAMPLE_COLUMNS; col++) {
+- for (i = 0; i < n_srates; i++) {
++ for (i = 0; i < mi->n_rates; i++) {
+ get_random_bytes(rnd, sizeof(rnd));
+- new_idx = (i + rnd[i & 7]) % n_srates;
++ new_idx = (i + rnd[i & 7]) % mi->n_rates;
+
+- while (SAMPLE_TBL(mi, new_idx, col) != 0)
+- new_idx = (new_idx + 1) % n_srates;
++ while (SAMPLE_TBL(mi, new_idx, col) != 0xff)
++ new_idx = (new_idx + 1) % mi->n_rates;
+
+- /* Don't sample the slowest rate (i.e. slowest base
+- * rate). We must presume that the slowest rate works
+- * fine, or else other management frames will also be
+- * failing and the link will break */
+- SAMPLE_TBL(mi, new_idx, col) = i + 1;
++ SAMPLE_TBL(mi, new_idx, col) = i;
+ }
+ }
+ }
+@@ -542,9 +569,6 @@ minstrel_alloc(struct ieee80211_hw *hw,
+ mp->lookaround_rate = 5;
+ mp->lookaround_rate_mrr = 10;
-+skip_tx_iqcal:
- if (ath9k_hw_mci_is_enabled(ah) && IS_CHAN_2GHZ(chan) && run_agc_cal)
- ar9003_mci_init_cal_req(ah, &is_reusable);
+- /* moving average weight for EWMA */
+- mp->ewma_level = 75;
+-
+ /* maximum time that the hw is allowed to stay in one MRR segment */
+ mp->segment_size = 6000;
-- if (!(IS_CHAN_HALF_RATE(chan) || IS_CHAN_QUARTER_RATE(chan))) {
-+ if (sep_iq_cal) {
- txiqcal_done = ar9003_hw_tx_iq_cal_run(ah);
- REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS);
- udelay(5);
- REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
- }
+--- a/net/mac80211/rc80211_minstrel.h
++++ b/net/mac80211/rc80211_minstrel.h
+@@ -9,6 +9,28 @@
+ #ifndef __RC_MINSTREL_H
+ #define __RC_MINSTREL_H
--skip_tx_iqcal:
- if (run_agc_cal || !(ah->ah_flags & AH_FASTCC)) {
- /* Calibrate the AGC */
- REG_WRITE(ah, AR_PHY_AGC_CONTROL,
---- a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h
-+++ b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h
-@@ -744,6 +744,186 @@ static const u32 ar9300Modes_high_ob_db_
- {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
- };
-
-+static const u32 ar9300Modes_mixed_ob_db_tx_gain_table_2p2[][5] = {
-+ /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
-+ {0x0000a2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352},
-+ {0x0000a2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584},
-+ {0x0000a2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800},
-+ {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
-+ {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9},
-+ {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
-+ {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002},
-+ {0x0000a508, 0x0a000020, 0x0a000020, 0x08000004, 0x08000004},
-+ {0x0000a50c, 0x10000023, 0x10000023, 0x0b000200, 0x0b000200},
-+ {0x0000a510, 0x16000220, 0x16000220, 0x0f000202, 0x0f000202},
-+ {0x0000a514, 0x1c000223, 0x1c000223, 0x11000400, 0x11000400},
-+ {0x0000a518, 0x21002220, 0x21002220, 0x15000402, 0x15000402},
-+ {0x0000a51c, 0x27002223, 0x27002223, 0x19000404, 0x19000404},
-+ {0x0000a520, 0x2b022220, 0x2b022220, 0x1b000603, 0x1b000603},
-+ {0x0000a524, 0x2f022222, 0x2f022222, 0x1f000a02, 0x1f000a02},
-+ {0x0000a528, 0x34022225, 0x34022225, 0x23000a04, 0x23000a04},
-+ {0x0000a52c, 0x3a02222a, 0x3a02222a, 0x26000a20, 0x26000a20},
-+ {0x0000a530, 0x3e02222c, 0x3e02222c, 0x2a000e20, 0x2a000e20},
-+ {0x0000a534, 0x4202242a, 0x4202242a, 0x2e000e22, 0x2e000e22},
-+ {0x0000a538, 0x4702244a, 0x4702244a, 0x31000e24, 0x31000e24},
-+ {0x0000a53c, 0x4b02244c, 0x4b02244c, 0x34001640, 0x34001640},
-+ {0x0000a540, 0x4e02246c, 0x4e02246c, 0x38001660, 0x38001660},
-+ {0x0000a544, 0x52022470, 0x52022470, 0x3b001861, 0x3b001861},
-+ {0x0000a548, 0x55022490, 0x55022490, 0x3e001a81, 0x3e001a81},
-+ {0x0000a54c, 0x59022492, 0x59022492, 0x42001a83, 0x42001a83},
-+ {0x0000a550, 0x5d022692, 0x5d022692, 0x44001c84, 0x44001c84},
-+ {0x0000a554, 0x61022892, 0x61022892, 0x48001ce3, 0x48001ce3},
-+ {0x0000a558, 0x65024890, 0x65024890, 0x4c001ce5, 0x4c001ce5},
-+ {0x0000a55c, 0x69024892, 0x69024892, 0x50001ce9, 0x50001ce9},
-+ {0x0000a560, 0x6e024c92, 0x6e024c92, 0x54001ceb, 0x54001ceb},
-+ {0x0000a564, 0x74026e92, 0x74026e92, 0x56001eec, 0x56001eec},
-+ {0x0000a568, 0x74026e92, 0x74026e92, 0x56001eec, 0x56001eec},
-+ {0x0000a56c, 0x74026e92, 0x74026e92, 0x56001eec, 0x56001eec},
-+ {0x0000a570, 0x74026e92, 0x74026e92, 0x56001eec, 0x56001eec},
-+ {0x0000a574, 0x74026e92, 0x74026e92, 0x56001eec, 0x56001eec},
-+ {0x0000a578, 0x74026e92, 0x74026e92, 0x56001eec, 0x56001eec},
-+ {0x0000a57c, 0x74026e92, 0x74026e92, 0x56001eec, 0x56001eec},
-+ {0x0000a580, 0x00800000, 0x00800000, 0x00800000, 0x00800000},
-+ {0x0000a584, 0x06800003, 0x06800003, 0x04800002, 0x04800002},
-+ {0x0000a588, 0x0a800020, 0x0a800020, 0x08800004, 0x08800004},
-+ {0x0000a58c, 0x10800023, 0x10800023, 0x0b800200, 0x0b800200},
-+ {0x0000a590, 0x16800220, 0x16800220, 0x0f800202, 0x0f800202},
-+ {0x0000a594, 0x1c800223, 0x1c800223, 0x11800400, 0x11800400},
-+ {0x0000a598, 0x21802220, 0x21802220, 0x15800402, 0x15800402},
-+ {0x0000a59c, 0x27802223, 0x27802223, 0x19800404, 0x19800404},
-+ {0x0000a5a0, 0x2b822220, 0x2b822220, 0x1b800603, 0x1b800603},
-+ {0x0000a5a4, 0x2f822222, 0x2f822222, 0x1f800a02, 0x1f800a02},
-+ {0x0000a5a8, 0x34822225, 0x34822225, 0x23800a04, 0x23800a04},
-+ {0x0000a5ac, 0x3a82222a, 0x3a82222a, 0x26800a20, 0x26800a20},
-+ {0x0000a5b0, 0x3e82222c, 0x3e82222c, 0x2a800e20, 0x2a800e20},
-+ {0x0000a5b4, 0x4282242a, 0x4282242a, 0x2e800e22, 0x2e800e22},
-+ {0x0000a5b8, 0x4782244a, 0x4782244a, 0x31800e24, 0x31800e24},
-+ {0x0000a5bc, 0x4b82244c, 0x4b82244c, 0x34801640, 0x34801640},
-+ {0x0000a5c0, 0x4e82246c, 0x4e82246c, 0x38801660, 0x38801660},
-+ {0x0000a5c4, 0x52822470, 0x52822470, 0x3b801861, 0x3b801861},
-+ {0x0000a5c8, 0x55822490, 0x55822490, 0x3e801a81, 0x3e801a81},
-+ {0x0000a5cc, 0x59822492, 0x59822492, 0x42801a83, 0x42801a83},
-+ {0x0000a5d0, 0x5d822692, 0x5d822692, 0x44801c84, 0x44801c84},
-+ {0x0000a5d4, 0x61822892, 0x61822892, 0x48801ce3, 0x48801ce3},
-+ {0x0000a5d8, 0x65824890, 0x65824890, 0x4c801ce5, 0x4c801ce5},
-+ {0x0000a5dc, 0x69824892, 0x69824892, 0x50801ce9, 0x50801ce9},
-+ {0x0000a5e0, 0x6e824c92, 0x6e824c92, 0x54801ceb, 0x54801ceb},
-+ {0x0000a5e4, 0x74826e92, 0x74826e92, 0x56801eec, 0x56801eec},
-+ {0x0000a5e8, 0x74826e92, 0x74826e92, 0x56801eec, 0x56801eec},
-+ {0x0000a5ec, 0x74826e92, 0x74826e92, 0x56801eec, 0x56801eec},
-+ {0x0000a5f0, 0x74826e92, 0x74826e92, 0x56801eec, 0x56801eec},
-+ {0x0000a5f4, 0x74826e92, 0x74826e92, 0x56801eec, 0x56801eec},
-+ {0x0000a5f8, 0x74826e92, 0x74826e92, 0x56801eec, 0x56801eec},
-+ {0x0000a5fc, 0x74826e92, 0x74826e92, 0x56801eec, 0x56801eec},
-+ {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
-+ {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
-+ {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
-+ {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
-+ {0x0000a610, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
-+ {0x0000a614, 0x02004000, 0x02004000, 0x01404000, 0x01404000},
-+ {0x0000a618, 0x02004801, 0x02004801, 0x01404501, 0x01404501},
-+ {0x0000a61c, 0x02808a02, 0x02808a02, 0x02008501, 0x02008501},
-+ {0x0000a620, 0x0380ce03, 0x0380ce03, 0x0280ca03, 0x0280ca03},
-+ {0x0000a624, 0x04411104, 0x04411104, 0x03010c04, 0x03010c04},
-+ {0x0000a628, 0x04411104, 0x04411104, 0x04014c04, 0x04014c04},
-+ {0x0000a62c, 0x04411104, 0x04411104, 0x04015005, 0x04015005},
-+ {0x0000a630, 0x04411104, 0x04411104, 0x04015005, 0x04015005},
-+ {0x0000a634, 0x04411104, 0x04411104, 0x04015005, 0x04015005},
-+ {0x0000a638, 0x04411104, 0x04411104, 0x04015005, 0x04015005},
-+ {0x0000a63c, 0x04411104, 0x04411104, 0x04015005, 0x04015005},
-+ {0x0000b2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352},
-+ {0x0000b2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584},
-+ {0x0000b2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800},
-+ {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
-+ {0x0000c2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352},
-+ {0x0000c2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584},
-+ {0x0000c2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800},
-+ {0x0000c2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
-+ {0x00016044, 0x012492d4, 0x012492d4, 0x056db2e4, 0x056db2e4},
-+ {0x00016048, 0x66480001, 0x66480001, 0x8e480001, 0x8e480001},
-+ {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
-+ {0x00016444, 0x012492d4, 0x012492d4, 0x056db2e4, 0x056db2e4},
-+ {0x00016448, 0x66480001, 0x66480001, 0x8e480001, 0x8e480001},
-+ {0x00016468, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
-+ {0x00016844, 0x012492d4, 0x012492d4, 0x056db2e4, 0x056db2e4},
-+ {0x00016848, 0x66480001, 0x66480001, 0x8e480001, 0x8e480001},
-+ {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
-+};
++#define EWMA_LEVEL 75 /* ewma weighting factor [%] */
++#define SAMPLE_COLUMNS 10 /* number of columns in sample table */
+
-+static const u32 ar9300Modes_type5_tx_gain_table_2p2[][5] = {
-+ /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
-+ {0x0000a2dc, 0x000cfff0, 0x000cfff0, 0x03aaa352, 0x03aaa352},
-+ {0x0000a2e0, 0x000f0000, 0x000f0000, 0x03ccc584, 0x03ccc584},
-+ {0x0000a2e4, 0x03f00000, 0x03f00000, 0x03f0f800, 0x03f0f800},
-+ {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
-+ {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9},
-+ {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
-+ {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002},
-+ {0x0000a508, 0x0a000020, 0x0a000020, 0x08000004, 0x08000004},
-+ {0x0000a50c, 0x10000023, 0x10000023, 0x0b000200, 0x0b000200},
-+ {0x0000a510, 0x15000028, 0x15000028, 0x0f000202, 0x0f000202},
-+ {0x0000a514, 0x1b00002b, 0x1b00002b, 0x12000400, 0x12000400},
-+ {0x0000a518, 0x1f020028, 0x1f020028, 0x16000402, 0x16000402},
-+ {0x0000a51c, 0x2502002b, 0x2502002b, 0x19000404, 0x19000404},
-+ {0x0000a520, 0x2a04002a, 0x2a04002a, 0x1c000603, 0x1c000603},
-+ {0x0000a524, 0x2e06002a, 0x2e06002a, 0x21000a02, 0x21000a02},
-+ {0x0000a528, 0x3302202d, 0x3302202d, 0x25000a04, 0x25000a04},
-+ {0x0000a52c, 0x3804202c, 0x3804202c, 0x28000a20, 0x28000a20},
-+ {0x0000a530, 0x3c06202c, 0x3c06202c, 0x2c000e20, 0x2c000e20},
-+ {0x0000a534, 0x4108202d, 0x4108202d, 0x30000e22, 0x30000e22},
-+ {0x0000a538, 0x4506402d, 0x4506402d, 0x34000e24, 0x34000e24},
-+ {0x0000a53c, 0x4906222d, 0x4906222d, 0x38001640, 0x38001640},
-+ {0x0000a540, 0x4d062231, 0x4d062231, 0x3c001660, 0x3c001660},
-+ {0x0000a544, 0x50082231, 0x50082231, 0x3f001861, 0x3f001861},
-+ {0x0000a548, 0x5608422e, 0x5608422e, 0x43001a81, 0x43001a81},
-+ {0x0000a54c, 0x5e08442e, 0x5e08442e, 0x47001a83, 0x47001a83},
-+ {0x0000a550, 0x620a4431, 0x620a4431, 0x4a001c84, 0x4a001c84},
-+ {0x0000a554, 0x640a4432, 0x640a4432, 0x4e001ce3, 0x4e001ce3},
-+ {0x0000a558, 0x680a4434, 0x680a4434, 0x52001ce5, 0x52001ce5},
-+ {0x0000a55c, 0x6c0a6434, 0x6c0a6434, 0x56001ce9, 0x56001ce9},
-+ {0x0000a560, 0x6f0a6633, 0x6f0a6633, 0x5a001ceb, 0x5a001ceb},
-+ {0x0000a564, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
-+ {0x0000a568, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
-+ {0x0000a56c, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
-+ {0x0000a570, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
-+ {0x0000a574, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
-+ {0x0000a578, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
-+ {0x0000a57c, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
-+ {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
-+ {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
-+ {0x0000a608, 0x01804601, 0x01804601, 0x00000000, 0x00000000},
-+ {0x0000a60c, 0x01804601, 0x01804601, 0x00000000, 0x00000000},
-+ {0x0000a610, 0x01804601, 0x01804601, 0x00000000, 0x00000000},
-+ {0x0000a614, 0x01804601, 0x01804601, 0x01404000, 0x01404000},
-+ {0x0000a618, 0x01804601, 0x01804601, 0x01404501, 0x01404501},
-+ {0x0000a61c, 0x01804601, 0x01804601, 0x02008501, 0x02008501},
-+ {0x0000a620, 0x03408d02, 0x03408d02, 0x0280ca03, 0x0280ca03},
-+ {0x0000a624, 0x0300cc03, 0x0300cc03, 0x03010c04, 0x03010c04},
-+ {0x0000a628, 0x03410d04, 0x03410d04, 0x04014c04, 0x04014c04},
-+ {0x0000a62c, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005},
-+ {0x0000a630, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005},
-+ {0x0000a634, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005},
-+ {0x0000a638, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005},
-+ {0x0000a63c, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005},
-+ {0x0000b2dc, 0x000cfff0, 0x000cfff0, 0x03aaa352, 0x03aaa352},
-+ {0x0000b2e0, 0x000f0000, 0x000f0000, 0x03ccc584, 0x03ccc584},
-+ {0x0000b2e4, 0x03f00000, 0x03f00000, 0x03f0f800, 0x03f0f800},
-+ {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
-+ {0x0000c2dc, 0x000cfff0, 0x000cfff0, 0x03aaa352, 0x03aaa352},
-+ {0x0000c2e0, 0x000f0000, 0x000f0000, 0x03ccc584, 0x03ccc584},
-+ {0x0000c2e4, 0x03f00000, 0x03f00000, 0x03f0f800, 0x03f0f800},
-+ {0x0000c2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
-+ {0x00016044, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
-+ {0x00016048, 0x65240001, 0x65240001, 0x66480001, 0x66480001},
-+ {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
-+ {0x00016444, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
-+ {0x00016448, 0x65240001, 0x65240001, 0x66480001, 0x66480001},
-+ {0x00016468, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
-+ {0x00016844, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
-+ {0x00016848, 0x65240001, 0x65240001, 0x66480001, 0x66480001},
-+ {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
-+};
+
- static const u32 ar9300Common_rx_gain_table_2p2[][2] = {
- /* Addr allmodes */
- {0x0000a000, 0x00010000},
---- a/drivers/net/wireless/ath/ath9k/ar9003_hw.c
-+++ b/drivers/net/wireless/ath/ath9k/ar9003_hw.c
-@@ -459,28 +459,59 @@ static void ar9003_tx_gain_table_mode4(s
- else if (AR_SREV_9580(ah))
- INIT_INI_ARRAY(&ah->iniModesTxGain,
- ar9580_1p0_mixed_ob_db_tx_gain_table);
-+ else
-+ INIT_INI_ARRAY(&ah->iniModesTxGain,
-+ ar9300Modes_mixed_ob_db_tx_gain_table_2p2);
-+}
++/* scaled fraction values */
++#define MINSTREL_SCALE 16
++#define MINSTREL_FRAC(val, div) (((val) << MINSTREL_SCALE) / div)
++#define MINSTREL_TRUNC(val) ((val) >> MINSTREL_SCALE)
+
-+static void ar9003_tx_gain_table_mode5(struct ath_hw *ah)
-+{
-+ if (AR_SREV_9485_11(ah))
-+ INIT_INI_ARRAY(&ah->iniModesTxGain,
-+ ar9485Modes_green_ob_db_tx_gain_1_1);
-+ else if (AR_SREV_9340(ah))
-+ INIT_INI_ARRAY(&ah->iniModesTxGain,
-+ ar9340Modes_ub124_tx_gain_table_1p0);
-+ else if (AR_SREV_9580(ah))
-+ INIT_INI_ARRAY(&ah->iniModesTxGain,
-+ ar9580_1p0_type5_tx_gain_table);
-+ else if (AR_SREV_9300_22(ah))
-+ INIT_INI_ARRAY(&ah->iniModesTxGain,
-+ ar9300Modes_type5_tx_gain_table_2p2);
-+}
++/* number of highest throughput rates to consider*/
++#define MAX_THR_RATES 4
+
-+static void ar9003_tx_gain_table_mode6(struct ath_hw *ah)
++/*
++ * Perform EWMA (Exponentially Weighted Moving Average) calculation
++ */
++static inline int
++minstrel_ewma(int old, int new, int weight)
+{
-+ if (AR_SREV_9340(ah))
-+ INIT_INI_ARRAY(&ah->iniModesTxGain,
-+ ar9340Modes_low_ob_db_and_spur_tx_gain_table_1p0);
-+ else if (AR_SREV_9485_11(ah))
-+ INIT_INI_ARRAY(&ah->iniModesTxGain,
-+ ar9485Modes_green_spur_ob_db_tx_gain_1_1);
-+ else if (AR_SREV_9580(ah))
-+ INIT_INI_ARRAY(&ah->iniModesTxGain,
-+ ar9580_1p0_type6_tx_gain_table);
- }
-
-+typedef void (*ath_txgain_tab)(struct ath_hw *ah);
-+
- static void ar9003_tx_gain_table_apply(struct ath_hw *ah)
- {
-- switch (ar9003_hw_get_tx_gain_idx(ah)) {
-- case 0:
-- default:
-- ar9003_tx_gain_table_mode0(ah);
-- break;
-- case 1:
-- ar9003_tx_gain_table_mode1(ah);
-- break;
-- case 2:
-- ar9003_tx_gain_table_mode2(ah);
-- break;
-- case 3:
-- ar9003_tx_gain_table_mode3(ah);
-- break;
-- case 4:
-- ar9003_tx_gain_table_mode4(ah);
-- break;
-- }
-+ static const ath_txgain_tab modes[] = {
-+ ar9003_tx_gain_table_mode0,
-+ ar9003_tx_gain_table_mode1,
-+ ar9003_tx_gain_table_mode2,
-+ ar9003_tx_gain_table_mode3,
-+ ar9003_tx_gain_table_mode4,
-+ ar9003_tx_gain_table_mode5,
-+ ar9003_tx_gain_table_mode6,
-+ };
-+ int idx = ar9003_hw_get_tx_gain_idx(ah);
-+
-+ if (idx >= ARRAY_SIZE(modes))
-+ idx = 0;
-+
-+ modes[idx](ah);
- }
-
- static void ar9003_rx_gain_table_mode0(struct ath_hw *ah)
---- a/drivers/net/wireless/ath/ath9k/ar9340_initvals.h
-+++ b/drivers/net/wireless/ath/ath9k/ar9340_initvals.h
-@@ -1170,6 +1170,106 @@ static const u32 ar9340Modes_mixed_ob_db
- {0x00016448, 0x24925666, 0x24925666, 0x8e481266, 0x8e481266},
- };
-
-+static const u32 ar9340Modes_low_ob_db_and_spur_tx_gain_table_1p0[][5] = {
-+ /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
-+ {0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x03eaac5a, 0x03eaac5a},
-+ {0x0000a2e0, 0x0000f800, 0x0000f800, 0x03f330ac, 0x03f330ac},
-+ {0x0000a2e4, 0x03ff0000, 0x03ff0000, 0x03fc3f00, 0x03fc3f00},
-+ {0x0000a2e8, 0x00000000, 0x00000000, 0x03ffc000, 0x03ffc000},
-+ {0x0000a394, 0x00000444, 0x00000444, 0x00000404, 0x00000404},
-+ {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9},
-+ {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
-+ {0x0000a504, 0x06000003, 0x06000003, 0x02000001, 0x02000001},
-+ {0x0000a508, 0x0a000020, 0x0a000020, 0x05000003, 0x05000003},
-+ {0x0000a50c, 0x10000023, 0x10000023, 0x0a000005, 0x0a000005},
-+ {0x0000a510, 0x16000220, 0x16000220, 0x0e000201, 0x0e000201},
-+ {0x0000a514, 0x1c000223, 0x1c000223, 0x11000203, 0x11000203},
-+ {0x0000a518, 0x21002220, 0x21002220, 0x14000401, 0x14000401},
-+ {0x0000a51c, 0x27002223, 0x27002223, 0x18000403, 0x18000403},
-+ {0x0000a520, 0x2b022220, 0x2b022220, 0x1b000602, 0x1b000602},
-+ {0x0000a524, 0x2f022222, 0x2f022222, 0x1f000802, 0x1f000802},
-+ {0x0000a528, 0x34022225, 0x34022225, 0x21000620, 0x21000620},
-+ {0x0000a52c, 0x3a02222a, 0x3a02222a, 0x25000820, 0x25000820},
-+ {0x0000a530, 0x3e02222c, 0x3e02222c, 0x29000822, 0x29000822},
-+ {0x0000a534, 0x4202242a, 0x4202242a, 0x2d000824, 0x2d000824},
-+ {0x0000a538, 0x4702244a, 0x4702244a, 0x30000828, 0x30000828},
-+ {0x0000a53c, 0x4b02244c, 0x4b02244c, 0x3400082a, 0x3400082a},
-+ {0x0000a540, 0x4e02246c, 0x4e02246c, 0x38000849, 0x38000849},
-+ {0x0000a544, 0x5302266c, 0x5302266c, 0x3b000a2c, 0x3b000a2c},
-+ {0x0000a548, 0x5702286c, 0x5702286c, 0x3e000e2b, 0x3e000e2b},
-+ {0x0000a54c, 0x5c02486b, 0x5c02486b, 0x42000e2d, 0x42000e2d},
-+ {0x0000a550, 0x61024a6c, 0x61024a6c, 0x4500124a, 0x4500124a},
-+ {0x0000a554, 0x66026a6c, 0x66026a6c, 0x4900124c, 0x4900124c},
-+ {0x0000a558, 0x6b026e6c, 0x6b026e6c, 0x4c00126c, 0x4c00126c},
-+ {0x0000a55c, 0x7002708c, 0x7002708c, 0x4f00128c, 0x4f00128c},
-+ {0x0000a560, 0x7302b08a, 0x7302b08a, 0x52001290, 0x52001290},
-+ {0x0000a564, 0x7702b08c, 0x7702b08c, 0x56001292, 0x56001292},
-+ {0x0000a568, 0x7702b08c, 0x7702b08c, 0x56001292, 0x56001292},
-+ {0x0000a56c, 0x7702b08c, 0x7702b08c, 0x56001292, 0x56001292},
-+ {0x0000a570, 0x7702b08c, 0x7702b08c, 0x56001292, 0x56001292},
-+ {0x0000a574, 0x7702b08c, 0x7702b08c, 0x56001292, 0x56001292},
-+ {0x0000a578, 0x7702b08c, 0x7702b08c, 0x56001292, 0x56001292},
-+ {0x0000a57c, 0x7702b08c, 0x7702b08c, 0x56001292, 0x56001292},
-+ {0x0000a580, 0x00800000, 0x00800000, 0x00800000, 0x00800000},
-+ {0x0000a584, 0x06800003, 0x06800003, 0x02800001, 0x02800001},
-+ {0x0000a588, 0x0a800020, 0x0a800020, 0x05800003, 0x05800003},
-+ {0x0000a58c, 0x10800023, 0x10800023, 0x0a800005, 0x0a800005},
-+ {0x0000a590, 0x16800220, 0x16800220, 0x0e800201, 0x0e800201},
-+ {0x0000a594, 0x1c800223, 0x1c800223, 0x11800203, 0x11800203},
-+ {0x0000a598, 0x21820220, 0x21820220, 0x14800401, 0x14800401},
-+ {0x0000a59c, 0x27820223, 0x27820223, 0x18800403, 0x18800403},
-+ {0x0000a5a0, 0x2b822220, 0x2b822220, 0x1b800602, 0x1b800602},
-+ {0x0000a5a4, 0x2f822222, 0x2f822222, 0x1f800802, 0x1f800802},
-+ {0x0000a5a8, 0x34822225, 0x34822225, 0x21800620, 0x21800620},
-+ {0x0000a5ac, 0x3a82222a, 0x3a82222a, 0x25800820, 0x25800820},
-+ {0x0000a5b0, 0x3e82222c, 0x3e82222c, 0x29800822, 0x29800822},
-+ {0x0000a5b4, 0x4282242a, 0x4282242a, 0x2d800824, 0x2d800824},
-+ {0x0000a5b8, 0x4782244a, 0x4782244a, 0x30800828, 0x30800828},
-+ {0x0000a5bc, 0x4b82244c, 0x4b82244c, 0x3480082a, 0x3480082a},
-+ {0x0000a5c0, 0x4e82246c, 0x4e82246c, 0x38800849, 0x38800849},
-+ {0x0000a5c4, 0x5382266c, 0x5382266c, 0x3b800a2c, 0x3b800a2c},
-+ {0x0000a5c8, 0x5782286c, 0x5782286c, 0x3e800e2b, 0x3e800e2b},
-+ {0x0000a5cc, 0x5c84286b, 0x5c84286b, 0x42800e2d, 0x42800e2d},
-+ {0x0000a5d0, 0x61842a6c, 0x61842a6c, 0x4580124a, 0x4580124a},
-+ {0x0000a5d4, 0x66862a6c, 0x66862a6c, 0x4980124c, 0x4980124c},
-+ {0x0000a5d8, 0x6b862e6c, 0x6b862e6c, 0x4c80126c, 0x4c80126c},
-+ {0x0000a5dc, 0x7086308c, 0x7086308c, 0x4f80128c, 0x4f80128c},
-+ {0x0000a5e0, 0x738a308a, 0x738a308a, 0x52801290, 0x52801290},
-+ {0x0000a5e4, 0x778a308c, 0x778a308c, 0x56801292, 0x56801292},
-+ {0x0000a5e8, 0x778a308c, 0x778a308c, 0x56801292, 0x56801292},
-+ {0x0000a5ec, 0x778a308c, 0x778a308c, 0x56801292, 0x56801292},
-+ {0x0000a5f0, 0x778a308c, 0x778a308c, 0x56801292, 0x56801292},
-+ {0x0000a5f4, 0x778a308c, 0x778a308c, 0x56801292, 0x56801292},
-+ {0x0000a5f8, 0x778a308c, 0x778a308c, 0x56801292, 0x56801292},
-+ {0x0000a5fc, 0x778a308c, 0x778a308c, 0x56801292, 0x56801292},
-+ {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
-+ {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
-+ {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
-+ {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
-+ {0x0000a610, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
-+ {0x0000a614, 0x01404000, 0x01404000, 0x01404501, 0x01404501},
-+ {0x0000a618, 0x01404501, 0x01404501, 0x01404501, 0x01404501},
-+ {0x0000a61c, 0x02008802, 0x02008802, 0x01404501, 0x01404501},
-+ {0x0000a620, 0x0300cc03, 0x0300cc03, 0x03c0cf02, 0x03c0cf02},
-+ {0x0000a624, 0x0300cc03, 0x0300cc03, 0x03c0cf03, 0x03c0cf03},
-+ {0x0000a628, 0x0300cc03, 0x0300cc03, 0x04011004, 0x04011004},
-+ {0x0000a62c, 0x03810c03, 0x03810c03, 0x05419405, 0x05419405},
-+ {0x0000a630, 0x03810e04, 0x03810e04, 0x05419506, 0x05419506},
-+ {0x0000a634, 0x03810e04, 0x03810e04, 0x05419506, 0x05419506},
-+ {0x0000a638, 0x03810e04, 0x03810e04, 0x05419506, 0x05419506},
-+ {0x0000a63c, 0x03810e04, 0x03810e04, 0x05419506, 0x05419506},
-+ {0x0000b2dc, 0x0380c7fc, 0x0380c7fc, 0x03eaac5a, 0x03eaac5a},
-+ {0x0000b2e0, 0x0000f800, 0x0000f800, 0x03f330ac, 0x03f330ac},
-+ {0x0000b2e4, 0x03ff0000, 0x03ff0000, 0x03fc3f00, 0x03fc3f00},
-+ {0x0000b2e8, 0x00000000, 0x00000000, 0x03ffc000, 0x03ffc000},
-+ {0x00016044, 0x022492db, 0x022492db, 0x022492db, 0x022492db},
-+ {0x00016048, 0x24925666, 0x24925666, 0x24925266, 0x24925266},
-+ {0x00016280, 0x01000015, 0x01000015, 0x01001015, 0x01001015},
-+ {0x00016288, 0xf0318000, 0xf0318000, 0xf0318000, 0xf0318000},
-+ {0x00016444, 0x022492db, 0x022492db, 0x022492db, 0x022492db},
-+ {0x00016448, 0x24925666, 0x24925666, 0x24925266, 0x24925266},
-+};
++ return (new * (100 - weight) + old * weight) / 100;
++}
+
- static const u32 ar9340_1p0_mac_core[][2] = {
- /* Addr allmodes */
- {0x00000008, 0x00000000},
---- a/drivers/net/wireless/ath/ath9k/ar9485_initvals.h
-+++ b/drivers/net/wireless/ath/ath9k/ar9485_initvals.h
-@@ -234,12 +234,158 @@ static const u32 ar9485Modes_high_power_
- {0x00016048, 0x6c924260, 0x6c924260, 0x6c924260, 0x6c924260},
- };
-
-+static const u32 ar9485Modes_green_ob_db_tx_gain_1_1[][5] = {
-+ /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
-+ {0x000098bc, 0x00000003, 0x00000003, 0x00000003, 0x00000003},
-+ {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d8, 0x000050d8},
-+ {0x0000a458, 0x80000000, 0x80000000, 0x80000000, 0x80000000},
-+ {0x0000a500, 0x00022200, 0x00022200, 0x00000006, 0x00000006},
-+ {0x0000a504, 0x05062002, 0x05062002, 0x03000201, 0x03000201},
-+ {0x0000a508, 0x0c002e00, 0x0c002e00, 0x06000203, 0x06000203},
-+ {0x0000a50c, 0x11062202, 0x11062202, 0x0a000401, 0x0a000401},
-+ {0x0000a510, 0x17022e00, 0x17022e00, 0x0e000403, 0x0e000403},
-+ {0x0000a514, 0x1d000ec2, 0x1d000ec2, 0x12000405, 0x12000405},
-+ {0x0000a518, 0x25020ec0, 0x25020ec0, 0x15000604, 0x15000604},
-+ {0x0000a51c, 0x2b020ec3, 0x2b020ec3, 0x18000605, 0x18000605},
-+ {0x0000a520, 0x2f001f04, 0x2f001f04, 0x1c000a04, 0x1c000a04},
-+ {0x0000a524, 0x35001fc4, 0x35001fc4, 0x21000a06, 0x21000a06},
-+ {0x0000a528, 0x3c022f04, 0x3c022f04, 0x29000a24, 0x29000a24},
-+ {0x0000a52c, 0x41023e85, 0x41023e85, 0x2f000e21, 0x2f000e21},
-+ {0x0000a530, 0x48023ec6, 0x48023ec6, 0x31000e20, 0x31000e20},
-+ {0x0000a534, 0x4d023f01, 0x4d023f01, 0x33000e20, 0x33000e20},
-+ {0x0000a538, 0x53023f4b, 0x53023f4b, 0x43000e62, 0x43000e62},
-+ {0x0000a53c, 0x5a027f09, 0x5a027f09, 0x45000e63, 0x45000e63},
-+ {0x0000a540, 0x5f027fc9, 0x5f027fc9, 0x49000e65, 0x49000e65},
-+ {0x0000a544, 0x6502feca, 0x6502feca, 0x4b000e66, 0x4b000e66},
-+ {0x0000a548, 0x6b02ff4a, 0x6b02ff4a, 0x4d001645, 0x4d001645},
-+ {0x0000a54c, 0x7203feca, 0x7203feca, 0x51001865, 0x51001865},
-+ {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x55001a86, 0x55001a86},
-+ {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x57001ce9, 0x57001ce9},
-+ {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001ceb, 0x5a001ceb},
-+ {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x5e001eeb, 0x5e001eeb},
-+ {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5e001eeb, 0x5e001eeb},
-+ {0x0000a564, 0x960fffcb, 0x960fffcb, 0x5e001eeb, 0x5e001eeb},
-+ {0x0000a568, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
-+ {0x0000a56c, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
-+ {0x0000a570, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
-+ {0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
-+ {0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
-+ {0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
-+ {0x0000b500, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a},
-+ {0x0000b504, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a},
-+ {0x0000b508, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a},
-+ {0x0000b50c, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a},
-+ {0x0000b510, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a},
-+ {0x0000b514, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a},
-+ {0x0000b518, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a},
-+ {0x0000b51c, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a},
-+ {0x0000b520, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a},
-+ {0x0000b524, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a},
-+ {0x0000b528, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a},
-+ {0x0000b52c, 0x0000002a, 0x0000002a, 0x0000002a, 0x0000002a},
-+ {0x0000b530, 0x0000003a, 0x0000003a, 0x0000003a, 0x0000003a},
-+ {0x0000b534, 0x0000004a, 0x0000004a, 0x0000004a, 0x0000004a},
-+ {0x0000b538, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
-+ {0x0000b53c, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
-+ {0x0000b540, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
-+ {0x0000b544, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
-+ {0x0000b548, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
-+ {0x0000b54c, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
-+ {0x0000b550, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
-+ {0x0000b554, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
-+ {0x0000b558, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
-+ {0x0000b55c, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
-+ {0x0000b560, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
-+ {0x0000b564, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
-+ {0x0000b568, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
-+ {0x0000b56c, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
-+ {0x0000b570, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
-+ {0x0000b574, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
-+ {0x0000b578, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
-+ {0x0000b57c, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
-+ {0x00016044, 0x05d6b2db, 0x05d6b2db, 0x05d6b2db, 0x05d6b2db},
-+ {0x00016048, 0x6c924260, 0x6c924260, 0x6c924260, 0x6c924260},
-+};
+
- #define ar9485Modes_high_ob_db_tx_gain_1_1 ar9485Modes_high_power_tx_gain_1_1
-
- #define ar9485Modes_low_ob_db_tx_gain_1_1 ar9485Modes_high_ob_db_tx_gain_1_1
-
- #define ar9485_modes_lowest_ob_db_tx_gain_1_1 ar9485Modes_low_ob_db_tx_gain_1_1
-
-+static const u32 ar9485Modes_green_spur_ob_db_tx_gain_1_1[][5] = {
-+ /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
-+ {0x000098bc, 0x00000003, 0x00000003, 0x00000003, 0x00000003},
-+ {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d8, 0x000050d8},
-+ {0x0000a458, 0x80000000, 0x80000000, 0x80000000, 0x80000000},
-+ {0x0000a500, 0x00022200, 0x00022200, 0x00000006, 0x00000006},
-+ {0x0000a504, 0x05062002, 0x05062002, 0x03000201, 0x03000201},
-+ {0x0000a508, 0x0c002e00, 0x0c002e00, 0x07000203, 0x07000203},
-+ {0x0000a50c, 0x11062202, 0x11062202, 0x0a000401, 0x0a000401},
-+ {0x0000a510, 0x17022e00, 0x17022e00, 0x0e000403, 0x0e000403},
-+ {0x0000a514, 0x1d000ec2, 0x1d000ec2, 0x12000405, 0x12000405},
-+ {0x0000a518, 0x25020ec0, 0x25020ec0, 0x14000406, 0x14000406},
-+ {0x0000a51c, 0x2b020ec3, 0x2b020ec3, 0x1800040a, 0x1800040a},
-+ {0x0000a520, 0x2f001f04, 0x2f001f04, 0x1c000460, 0x1c000460},
-+ {0x0000a524, 0x35001fc4, 0x35001fc4, 0x22000463, 0x22000463},
-+ {0x0000a528, 0x3c022f04, 0x3c022f04, 0x26000465, 0x26000465},
-+ {0x0000a52c, 0x41023e85, 0x41023e85, 0x2e0006e0, 0x2e0006e0},
-+ {0x0000a530, 0x48023ec6, 0x48023ec6, 0x310006e0, 0x310006e0},
-+ {0x0000a534, 0x4d023f01, 0x4d023f01, 0x330006e0, 0x330006e0},
-+ {0x0000a538, 0x53023f4b, 0x53023f4b, 0x3e0008e3, 0x3e0008e3},
-+ {0x0000a53c, 0x5a027f09, 0x5a027f09, 0x410008e5, 0x410008e5},
-+ {0x0000a540, 0x5f027fc9, 0x5f027fc9, 0x430008e6, 0x430008e6},
-+ {0x0000a544, 0x6502feca, 0x6502feca, 0x4a0008ec, 0x4a0008ec},
-+ {0x0000a548, 0x6b02ff4a, 0x6b02ff4a, 0x4e0008f1, 0x4e0008f1},
-+ {0x0000a54c, 0x7203feca, 0x7203feca, 0x520008f3, 0x520008f3},
-+ {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x54000eed, 0x54000eed},
-+ {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x58000ef1, 0x58000ef1},
-+ {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5c000ef3, 0x5c000ef3},
-+ {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x60000ef5, 0x60000ef5},
-+ {0x0000a560, 0x900fff0b, 0x900fff0b, 0x62000ef6, 0x62000ef6},
-+ {0x0000a564, 0x960fffcb, 0x960fffcb, 0x62000ef6, 0x62000ef6},
-+ {0x0000a568, 0x9c1fff0b, 0x9c1fff0b, 0x62000ef6, 0x62000ef6},
-+ {0x0000a56c, 0x9c1fff0b, 0x9c1fff0b, 0x62000ef6, 0x62000ef6},
-+ {0x0000a570, 0x9c1fff0b, 0x9c1fff0b, 0x62000ef6, 0x62000ef6},
-+ {0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x62000ef6, 0x62000ef6},
-+ {0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x62000ef6, 0x62000ef6},
-+ {0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x62000ef6, 0x62000ef6},
-+ {0x0000b500, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a},
-+ {0x0000b504, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a},
-+ {0x0000b508, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a},
-+ {0x0000b50c, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a},
-+ {0x0000b510, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a},
-+ {0x0000b514, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a},
-+ {0x0000b518, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a},
-+ {0x0000b51c, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a},
-+ {0x0000b520, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a},
-+ {0x0000b524, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a},
-+ {0x0000b528, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a},
-+ {0x0000b52c, 0x0000002a, 0x0000002a, 0x0000002a, 0x0000002a},
-+ {0x0000b530, 0x0000003a, 0x0000003a, 0x0000003a, 0x0000003a},
-+ {0x0000b534, 0x0000004a, 0x0000004a, 0x0000004a, 0x0000004a},
-+ {0x0000b538, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
-+ {0x0000b53c, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
-+ {0x0000b540, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
-+ {0x0000b544, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
-+ {0x0000b548, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
-+ {0x0000b54c, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
-+ {0x0000b550, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
-+ {0x0000b554, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
-+ {0x0000b558, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
-+ {0x0000b55c, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
-+ {0x0000b560, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
-+ {0x0000b564, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
-+ {0x0000b568, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
-+ {0x0000b56c, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
-+ {0x0000b570, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
-+ {0x0000b574, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
-+ {0x0000b578, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
-+ {0x0000b57c, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
-+ {0x00016044, 0x05d6b2db, 0x05d6b2db, 0x05d6b2db, 0x05d6b2db},
-+ {0x00016048, 0x6c924260, 0x6c924260, 0x6c924260, 0x6c924260},
-+};
+ struct minstrel_rate {
+ int bitrate;
+ int rix;
+@@ -26,6 +48,7 @@ struct minstrel_rate {
+ u32 attempts;
+ u32 last_attempts;
+ u32 last_success;
++ u8 sample_skipped;
+
+ /* parts per thousand */
+ u32 cur_prob;
+@@ -45,14 +68,13 @@ struct minstrel_sta_info {
+
+ unsigned int lowest_rix;
+
+- unsigned int max_tp_rate;
+- unsigned int max_tp_rate2;
+- unsigned int max_prob_rate;
++ u8 max_tp_rate[MAX_THR_RATES];
++ u8 max_prob_rate;
+ unsigned int packet_count;
+ unsigned int sample_count;
+ int sample_deferred;
+
+- unsigned int sample_idx;
++ unsigned int sample_row;
+ unsigned int sample_column;
+
+ int n_rates;
+@@ -73,7 +95,6 @@ struct minstrel_priv {
+ unsigned int cw_min;
+ unsigned int cw_max;
+ unsigned int max_retry;
+- unsigned int ewma_level;
+ unsigned int segment_size;
+ unsigned int update_interval;
+ unsigned int lookaround_rate;
+--- a/net/mac80211/rc80211_minstrel_debugfs.c
++++ b/net/mac80211/rc80211_minstrel_debugfs.c
+@@ -73,15 +73,17 @@ minstrel_stats_open(struct inode *inode,
+ for (i = 0; i < mi->n_rates; i++) {
+ struct minstrel_rate *mr = &mi->r[i];
+
+- *(p++) = (i == mi->max_tp_rate) ? 'T' : ' ';
+- *(p++) = (i == mi->max_tp_rate2) ? 't' : ' ';
++ *(p++) = (i == mi->max_tp_rate[0]) ? 'A' : ' ';
++ *(p++) = (i == mi->max_tp_rate[1]) ? 'B' : ' ';
++ *(p++) = (i == mi->max_tp_rate[2]) ? 'C' : ' ';
++ *(p++) = (i == mi->max_tp_rate[3]) ? 'D' : ' ';
+ *(p++) = (i == mi->max_prob_rate) ? 'P' : ' ';
+ p += sprintf(p, "%3u%s", mr->bitrate / 2,
+ (mr->bitrate & 1 ? ".5" : " "));
+
+- tp = mr->cur_tp / ((18000 << 10) / 96);
+- prob = mr->cur_prob / 18;
+- eprob = mr->probability / 18;
++ tp = MINSTREL_TRUNC(mr->cur_tp / 10);
++ prob = MINSTREL_TRUNC(mr->cur_prob * 1000);
++ eprob = MINSTREL_TRUNC(mr->probability * 1000);
+
+ p += sprintf(p, " %6u.%1u %6u.%1u %6u.%1u "
+ "%3u(%3u) %8llu %8llu\n",
+--- a/drivers/net/wireless/ath/ath9k/ath9k.h
++++ b/drivers/net/wireless/ath/ath9k/ath9k.h
+@@ -657,11 +657,10 @@ enum sc_op_flags {
+ struct ath_rate_table;
+
+ struct ath9k_vif_iter_data {
+- const u8 *hw_macaddr; /* phy's hardware address, set
+- * before starting iteration for
+- * valid bssid mask.
+- */
++ u8 hw_macaddr[ETH_ALEN]; /* address of the first vif */
+ u8 mask[ETH_ALEN]; /* bssid mask */
++ bool has_hw_macaddr;
+
- static const u32 ar9485_1_1[][2] = {
- /* Addr allmodes */
- {0x0000a580, 0x00000000},
---- a/drivers/net/wireless/ath/ath9k/ar9580_1p0_initvals.h
-+++ b/drivers/net/wireless/ath/ath9k/ar9580_1p0_initvals.h
-@@ -685,6 +685,82 @@ static const u32 ar9580_1p0_mixed_ob_db_
+ int naps; /* number of AP vifs */
+ int nmeshes; /* number of mesh vifs */
+ int nstations; /* number of station vifs */
+--- a/drivers/net/wireless/ath/ath9k/main.c
++++ b/drivers/net/wireless/ath/ath9k/main.c
+@@ -835,10 +835,14 @@ static void ath9k_vif_iter(void *data, u
+ struct ath9k_vif_iter_data *iter_data = data;
+ int i;
- #define ar9580_1p0_high_ob_db_tx_gain_table ar9300Modes_high_ob_db_tx_gain_table_2p2
+- if (iter_data->hw_macaddr)
++ if (iter_data->has_hw_macaddr) {
+ for (i = 0; i < ETH_ALEN; i++)
+ iter_data->mask[i] &=
+ ~(iter_data->hw_macaddr[i] ^ mac[i]);
++ } else {
++ memcpy(iter_data->hw_macaddr, mac, ETH_ALEN);
++ iter_data->has_hw_macaddr = true;
++ }
-+#define ar9580_1p0_type5_tx_gain_table ar9300Modes_type5_tx_gain_table_2p2
-+
-+static const u32 ar9580_1p0_type6_tx_gain_table[][5] = {
-+ /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
-+ {0x0000a2dc, 0x000cfff0, 0x000cfff0, 0x03aaa352, 0x03aaa352},
-+ {0x0000a2e0, 0x000f0000, 0x000f0000, 0x03ccc584, 0x03ccc584},
-+ {0x0000a2e4, 0x03f00000, 0x03f00000, 0x03f0f800, 0x03f0f800},
-+ {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
-+ {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9},
-+ {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
-+ {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002},
-+ {0x0000a508, 0x0a000020, 0x0a000020, 0x08000004, 0x08000004},
-+ {0x0000a50c, 0x10000023, 0x10000023, 0x0b000200, 0x0b000200},
-+ {0x0000a510, 0x15000028, 0x15000028, 0x0f000202, 0x0f000202},
-+ {0x0000a514, 0x1b00002b, 0x1b00002b, 0x12000400, 0x12000400},
-+ {0x0000a518, 0x1f020028, 0x1f020028, 0x16000402, 0x16000402},
-+ {0x0000a51c, 0x2502002b, 0x2502002b, 0x19000404, 0x19000404},
-+ {0x0000a520, 0x2a04002a, 0x2a04002a, 0x1c000603, 0x1c000603},
-+ {0x0000a524, 0x2e06002a, 0x2e06002a, 0x21000a02, 0x21000a02},
-+ {0x0000a528, 0x3302202d, 0x3302202d, 0x25000a04, 0x25000a04},
-+ {0x0000a52c, 0x3804202c, 0x3804202c, 0x28000a20, 0x28000a20},
-+ {0x0000a530, 0x3c06202c, 0x3c06202c, 0x2c000e20, 0x2c000e20},
-+ {0x0000a534, 0x4108202d, 0x4108202d, 0x30000e22, 0x30000e22},
-+ {0x0000a538, 0x4506402d, 0x4506402d, 0x34000e24, 0x34000e24},
-+ {0x0000a53c, 0x4906222d, 0x4906222d, 0x38001640, 0x38001640},
-+ {0x0000a540, 0x4d062231, 0x4d062231, 0x3c001660, 0x3c001660},
-+ {0x0000a544, 0x50082231, 0x50082231, 0x3f001861, 0x3f001861},
-+ {0x0000a548, 0x5608422e, 0x5608422e, 0x43001a81, 0x43001a81},
-+ {0x0000a54c, 0x5e08442e, 0x5e08442e, 0x47001a83, 0x47001a83},
-+ {0x0000a550, 0x620a4431, 0x620a4431, 0x4a001c84, 0x4a001c84},
-+ {0x0000a554, 0x640a4432, 0x640a4432, 0x4e001ce3, 0x4e001ce3},
-+ {0x0000a558, 0x680a4434, 0x680a4434, 0x52001ce5, 0x52001ce5},
-+ {0x0000a55c, 0x6c0a6434, 0x6c0a6434, 0x56001ce9, 0x56001ce9},
-+ {0x0000a560, 0x6f0a6633, 0x6f0a6633, 0x5a001ceb, 0x5a001ceb},
-+ {0x0000a564, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
-+ {0x0000a568, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
-+ {0x0000a56c, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
-+ {0x0000a570, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
-+ {0x0000a574, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
-+ {0x0000a578, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
-+ {0x0000a57c, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
-+ {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
-+ {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
-+ {0x0000a608, 0x01804601, 0x01804601, 0x00000000, 0x00000000},
-+ {0x0000a60c, 0x01804601, 0x01804601, 0x00000000, 0x00000000},
-+ {0x0000a610, 0x01804601, 0x01804601, 0x00000000, 0x00000000},
-+ {0x0000a614, 0x01804601, 0x01804601, 0x01404000, 0x01404000},
-+ {0x0000a618, 0x01804601, 0x01804601, 0x01404501, 0x01404501},
-+ {0x0000a61c, 0x01804601, 0x01804601, 0x02008501, 0x02008501},
-+ {0x0000a620, 0x03408d02, 0x03408d02, 0x0280ca03, 0x0280ca03},
-+ {0x0000a624, 0x0300cc03, 0x0300cc03, 0x03010c04, 0x03010c04},
-+ {0x0000a628, 0x03410d04, 0x03410d04, 0x04014c04, 0x04014c04},
-+ {0x0000a62c, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005},
-+ {0x0000a630, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005},
-+ {0x0000a634, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005},
-+ {0x0000a638, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005},
-+ {0x0000a63c, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005},
-+ {0x0000b2dc, 0x000cfff0, 0x000cfff0, 0x03aaa352, 0x03aaa352},
-+ {0x0000b2e0, 0x000f0000, 0x000f0000, 0x03ccc584, 0x03ccc584},
-+ {0x0000b2e4, 0x03f00000, 0x03f00000, 0x03f0f800, 0x03f0f800},
-+ {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
-+ {0x0000c2dc, 0x000cfff0, 0x000cfff0, 0x03aaa352, 0x03aaa352},
-+ {0x0000c2e0, 0x000f0000, 0x000f0000, 0x03ccc584, 0x03ccc584},
-+ {0x0000c2e4, 0x03f00000, 0x03f00000, 0x03f0f800, 0x03f0f800},
-+ {0x0000c2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
-+ {0x00016044, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
-+ {0x00016048, 0x61200001, 0x61200001, 0x66480001, 0x66480001},
-+ {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
-+ {0x00016444, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
-+ {0x00016448, 0x61200001, 0x61200001, 0x66480001, 0x66480001},
-+ {0x00016468, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
-+ {0x00016844, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
-+ {0x00016848, 0x61200001, 0x61200001, 0x66480001, 0x66480001},
-+ {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
-+};
+ switch (vif->type) {
+ case NL80211_IFTYPE_AP:
+@@ -887,7 +891,6 @@ void ath9k_calculate_iter_data(struct ie
+ * together with the BSSID mask when matching addresses.
+ */
+ memset(iter_data, 0, sizeof(*iter_data));
+- iter_data->hw_macaddr = common->macaddr;
+ memset(&iter_data->mask, 0xff, ETH_ALEN);
+
+ if (vif)
+@@ -897,6 +900,8 @@ void ath9k_calculate_iter_data(struct ie
+ ieee80211_iterate_active_interfaces_atomic(
+ sc->hw, IEEE80211_IFACE_ITER_RESUME_ALL,
+ ath9k_vif_iter, iter_data);
+
- static const u32 ar9580_1p0_soc_preamble[][2] = {
- /* Addr allmodes */
- {0x000040a4, 0x00a0c1c9},
---- a/drivers/net/wireless/ath/ath9k/reg.h
-+++ b/drivers/net/wireless/ath/ath9k/reg.h
-@@ -789,6 +789,7 @@
- #define AR_SREV_REVISION_9271_11 1
- #define AR_SREV_VERSION_9300 0x1c0
- #define AR_SREV_REVISION_9300_20 2 /* 2.0 and 2.1 */
-+#define AR_SREV_REVISION_9300_22 3
- #define AR_SREV_VERSION_9330 0x200
- #define AR_SREV_REVISION_9330_10 0
- #define AR_SREV_REVISION_9330_11 1
-@@ -867,6 +868,9 @@
- (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9300))
- #define AR_SREV_9300_20_OR_LATER(_ah) \
- ((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9300)
-+#define AR_SREV_9300_22(_ah) \
-+ (AR_SREV_9300(ah) && \
-+ ((_ah)->hw_version.macRev == AR_SREV_REVISION_9300_22))
-
- #define AR_SREV_9330(_ah) \
- (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9330))
---- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
-+++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
-@@ -1067,15 +1067,19 @@ static bool ath9k_rx_prepare(struct ath9
++ memcpy(common->macaddr, iter_data->hw_macaddr, ETH_ALEN);
+ }
- last_rssi = priv->rx.last_rssi;
+ /* Called with sc->mutex held. */
+@@ -1304,6 +1309,7 @@ static int ath9k_sta_add(struct ieee8021
+ struct ath_common *common = ath9k_hw_common(sc->sc_ah);
+ struct ath_node *an = (struct ath_node *) sta->drv_priv;
+ struct ieee80211_key_conf ps_key = { };
++ int key;
-- if (likely(last_rssi != ATH_RSSI_DUMMY_MARKER))
-- rxbuf->rxstatus.rs_rssi = ATH_EP_RND(last_rssi,
-- ATH_RSSI_EP_MULTIPLIER);
-+ if (ieee80211_is_beacon(hdr->frame_control) &&
-+ !is_zero_ether_addr(common->curbssid) &&
-+ ether_addr_equal(hdr->addr3, common->curbssid)) {
-+ s8 rssi = rxbuf->rxstatus.rs_rssi;
+ ath_node_attach(sc, sta, vif);
-- if (rxbuf->rxstatus.rs_rssi < 0)
-- rxbuf->rxstatus.rs_rssi = 0;
-+ if (likely(last_rssi != ATH_RSSI_DUMMY_MARKER))
-+ rssi = ATH_EP_RND(last_rssi, ATH_RSSI_EP_MULTIPLIER);
+@@ -1311,7 +1317,9 @@ static int ath9k_sta_add(struct ieee8021
+ vif->type != NL80211_IFTYPE_AP_VLAN)
+ return 0;
-- if (ieee80211_is_beacon(fc))
-- priv->ah->stats.avgbrssi = rxbuf->rxstatus.rs_rssi;
-+ if (rssi < 0)
-+ rssi = 0;
-+
-+ priv->ah->stats.avgbrssi = rssi;
-+ }
+- an->ps_key = ath_key_config(common, vif, sta, &ps_key);
++ key = ath_key_config(common, vif, sta, &ps_key);
++ if (key > 0)
++ an->ps_key = key;
- rx_status->mactime = be64_to_cpu(rxbuf->rxstatus.rs_tstamp);
- rx_status->band = hw->conf.channel->band;
---- a/drivers/net/wireless/ath/ath9k/common.h
-+++ b/drivers/net/wireless/ath/ath9k/common.h
-@@ -35,7 +35,7 @@
- #define WME_AC_BK 3
- #define WME_NUM_AC 4
+ return 0;
+ }
+@@ -1328,6 +1336,7 @@ static void ath9k_del_ps_key(struct ath_
+ return;
--#define ATH_RSSI_DUMMY_MARKER 0x127
-+#define ATH_RSSI_DUMMY_MARKER 127
- #define ATH_RSSI_LPF_LEN 10
- #define RSSI_LPF_THRESHOLD -20
- #define ATH_RSSI_EP_MULTIPLIER (1<<7)
---- a/drivers/net/wireless/ath/ath9k/link.c
-+++ b/drivers/net/wireless/ath/ath9k/link.c
-@@ -31,21 +31,21 @@ void ath_tx_complete_poll_work(struct wo
- sc->tx_complete_poll_work_seen++;
- #endif
+ ath_key_delete(common, &ps_key);
++ an->ps_key = 0;
+ }
-- for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
-- if (ATH_TXQ_SETUP(sc, i)) {
-- txq = &sc->tx.txq[i];
-- ath_txq_lock(sc, txq);
-- if (txq->axq_depth) {
-- if (txq->axq_tx_inprogress) {
-- needreset = true;
-- ath_txq_unlock(sc, txq);
-- break;
-- } else {
-- txq->axq_tx_inprogress = true;
-- }
-+ for (i = 0; i < IEEE80211_NUM_ACS; i++) {
-+ txq = sc->tx.txq_map[i];
+ static int ath9k_sta_remove(struct ieee80211_hw *hw,
+--- a/drivers/net/wireless/ath/ath9k/reg.h
++++ b/drivers/net/wireless/ath/ath9k/reg.h
+@@ -1493,9 +1493,6 @@ enum {
+ #define AR9271_RADIO_RF_RST 0x20
+ #define AR9271_GATE_MAC_CTL 0x4000
+
+-#define AR_STA_ID0 0x8000
+-#define AR_STA_ID1 0x8004
+-#define AR_STA_ID1_SADH_MASK 0x0000FFFF
+ #define AR_STA_ID1_STA_AP 0x00010000
+ #define AR_STA_ID1_ADHOC 0x00020000
+ #define AR_STA_ID1_PWR_SAV 0x00040000
+--- a/drivers/net/wireless/ath/hw.c
++++ b/drivers/net/wireless/ath/hw.c
+@@ -118,6 +118,12 @@
+ void ath_hw_setbssidmask(struct ath_common *common)
+ {
+ void *ah = common->ah;
++ u32 id1;
+
-+ ath_txq_lock(sc, txq);
-+ if (txq->axq_depth) {
-+ if (txq->axq_tx_inprogress) {
-+ needreset = true;
-+ ath_txq_unlock(sc, txq);
-+ break;
-+ } else {
-+ txq->axq_tx_inprogress = true;
- }
-- ath_txq_unlock_complete(sc, txq);
- }
-+ ath_txq_unlock_complete(sc, txq);
-+ }
-
- if (needreset) {
- ath_dbg(ath9k_hw_common(sc->sc_ah), RESET,
++ REG_WRITE(ah, AR_STA_ID0, get_unaligned_le32(common->macaddr));
++ id1 = REG_READ(ah, AR_STA_ID1) & ~AR_STA_ID1_SADH_MASK;
++ id1 |= get_unaligned_le16(common->macaddr + 4);
++ REG_WRITE(ah, AR_STA_ID1, id1);
+
+ REG_WRITE(ah, AR_BSSMSKL, get_unaligned_le32(common->bssidmask));
+ REG_WRITE(ah, AR_BSSMSKU, get_unaligned_le16(common->bssidmask + 4));
+--- a/drivers/net/wireless/ath/reg.h
++++ b/drivers/net/wireless/ath/reg.h
+@@ -23,6 +23,10 @@
+ #define AR_MIBC_CMC 0x00000004
+ #define AR_MIBC_MCS 0x00000008
+
++#define AR_STA_ID0 0x8000
++#define AR_STA_ID1 0x8004
++#define AR_STA_ID1_SADH_MASK 0x0000ffff
++
+ /*
+ * BSSID mask registers. See ath_hw_set_bssid_mask()
+ * for detailed documentation about these registers.
diff --git a/package/mac80211/patches/310-ap_scan.patch b/package/mac80211/patches/310-ap_scan.patch
index 67a9dcaba8..b8f2671150 100644
--- a/package/mac80211/patches/310-ap_scan.patch
+++ b/package/mac80211/patches/310-ap_scan.patch
@@ -1,11 +1,11 @@
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
-@@ -1796,8 +1796,6 @@ static int ieee80211_scan(struct wiphy *
- * beaconing hasn't been configured yet
+@@ -2009,7 +2009,7 @@ static int ieee80211_scan(struct wiphy *
+ * the frames sent while scanning on other channel will be
+ * lost)
*/
- case NL80211_IFTYPE_AP:
-- if (sdata->u.ap.beacon)
-- return -EOPNOTSUPP;
- break;
- default:
- return -EOPNOTSUPP;
+- if (sdata->u.ap.beacon &&
++ if (0 && sdata->u.ap.beacon &&
+ (!(wiphy->features & NL80211_FEATURE_AP_SCAN) ||
+ !(req->flags & NL80211_SCAN_FLAG_AP)))
+ return -EOPNOTSUPP;
diff --git a/package/mac80211/patches/320-ath9k_no_eeprom_name.patch b/package/mac80211/patches/320-ath9k_no_eeprom_name.patch
new file mode 100644
index 0000000000..438094bad9
--- /dev/null
+++ b/package/mac80211/patches/320-ath9k_no_eeprom_name.patch
@@ -0,0 +1,24 @@
+--- a/drivers/net/wireless/ath/ath9k/init.c
++++ b/drivers/net/wireless/ath/ath9k/init.c
+@@ -631,8 +631,8 @@ static int ath9k_init_softc(u16 devid, s
+ ath_read_cachesize(common, &csz);
+ common->cachelsz = csz << 2; /* convert to bytes */
+
+- if (pdata && pdata->eeprom_name) {
+- ret = ath9k_eeprom_request(sc, pdata->eeprom_name);
++ if (0) {
++ ret = ath9k_eeprom_request(sc, NULL);
+ if (ret)
+ return ret;
+ }
+--- a/include/linux/ath9k_platform.h
++++ b/include/linux/ath9k_platform.h
+@@ -22,8 +22,6 @@
+ #define ATH9K_PLAT_EEP_MAX_WORDS 2048
+
+ struct ath9k_platform_data {
+- const char *eeprom_name;
+-
+ u16 eeprom_data[ATH9K_PLAT_EEP_MAX_WORDS];
+ u8 *macaddr;
+
diff --git a/package/mac80211/patches/321-bcma_backport.patch b/package/mac80211/patches/321-bcma_backport.patch
new file mode 100644
index 0000000000..cf9f412641
--- /dev/null
+++ b/package/mac80211/patches/321-bcma_backport.patch
@@ -0,0 +1,42 @@
+--- a/drivers/net/wireless/b43/main.c
++++ b/drivers/net/wireless/b43/main.c
+@@ -4697,7 +4697,7 @@ static int b43_wireless_core_init(struct
+ switch (dev->dev->bus_type) {
+ #ifdef CONFIG_B43_BCMA
+ case B43_BUS_BCMA:
+- bcma_core_pci_irq_ctl(&dev->dev->bdev->bus->drv_pci[0],
++ bcma_core_pci_irq_ctl(&dev->dev->bdev->bus->drv_pci,
+ dev->dev->bdev, true);
+ break;
+ #endif
+--- a/drivers/net/wireless/brcm80211/brcmsmac/aiutils.c
++++ b/drivers/net/wireless/brcm80211/brcmsmac/aiutils.c
+@@ -694,7 +694,7 @@ void ai_pci_up(struct si_pub *sih)
+ sii = container_of(sih, struct si_info, pub);
+
+ if (sii->icbus->hosttype == BCMA_HOSTTYPE_PCI)
+- bcma_core_pci_extend_L1timer(&sii->icbus->drv_pci[0], true);
++ bcma_core_pci_extend_L1timer(&sii->icbus->drv_pci, true);
+ }
+
+ /* Unconfigure and/or apply various WARs when going down */
+@@ -705,7 +705,7 @@ void ai_pci_down(struct si_pub *sih)
+ sii = container_of(sih, struct si_info, pub);
+
+ if (sii->icbus->hosttype == BCMA_HOSTTYPE_PCI)
+- bcma_core_pci_extend_L1timer(&sii->icbus->drv_pci[0], false);
++ bcma_core_pci_extend_L1timer(&sii->icbus->drv_pci, false);
+ }
+
+ /* Enable BT-COEX & Ex-PA for 4313 */
+--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
++++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
+@@ -4979,7 +4979,7 @@ static int brcms_b_up_prep(struct brcms_
+ * Configure pci/pcmcia here instead of in brcms_c_attach()
+ * to allow mfg hotswap: down, hotswap (chip power cycle), up.
+ */
+- bcma_core_pci_irq_ctl(&wlc_hw->d11core->bus->drv_pci[0], wlc_hw->d11core,
++ bcma_core_pci_irq_ctl(&wlc_hw->d11core->bus->drv_pci, wlc_hw->d11core,
+ true);
+
+ /*
diff --git a/package/mac80211/patches/400-ath_move_debug_code.patch b/package/mac80211/patches/400-ath_move_debug_code.patch
index 256da42ded..c91128db61 100644
--- a/package/mac80211/patches/400-ath_move_debug_code.patch
+++ b/package/mac80211/patches/400-ath_move_debug_code.patch
@@ -1,6 +1,6 @@
--- a/drivers/net/wireless/ath/Makefile
+++ b/drivers/net/wireless/ath/Makefile
-@@ -8,7 +8,7 @@ obj-$(CONFIG_ATH_COMMON) += ath.o
+@@ -10,7 +10,7 @@ obj-$(CONFIG_ATH_COMMON) += ath.o
ath-objs := main.o \
regd.o \
hw.o \
@@ -12,7 +12,7 @@
ccflags-y += -D__CHECK_ENDIAN__
--- a/drivers/net/wireless/ath/ath.h
+++ b/drivers/net/wireless/ath/ath.h
-@@ -280,13 +280,6 @@ void _ath_dbg(struct ath_common *common,
+@@ -281,13 +281,6 @@ void _ath_dbg(struct ath_common *common,
#endif /* CONFIG_ATH_DEBUG */
/** Returns string describing opmode, or NULL if unknown mode. */
diff --git a/package/mac80211/patches/401-ath9k_blink_default.patch b/package/mac80211/patches/401-ath9k_blink_default.patch
index 10c7636963..421e78571d 100644
--- a/package/mac80211/patches/401-ath9k_blink_default.patch
+++ b/package/mac80211/patches/401-ath9k_blink_default.patch
@@ -1,6 +1,6 @@
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
-@@ -40,7 +40,7 @@ int ath9k_modparam_nohwcrypt;
+@@ -46,7 +46,7 @@ int ath9k_modparam_nohwcrypt;
module_param_named(nohwcrypt, ath9k_modparam_nohwcrypt, int, 0444);
MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption");
diff --git a/package/mac80211/patches/402-ath9k-fix-invalid-mac-address-handling.patch b/package/mac80211/patches/402-ath9k-fix-invalid-mac-address-handling.patch
index 7c59e1f109..40c4cb755c 100644
--- a/package/mac80211/patches/402-ath9k-fix-invalid-mac-address-handling.patch
+++ b/package/mac80211/patches/402-ath9k-fix-invalid-mac-address-handling.patch
@@ -8,7 +8,7 @@
#include <asm/unaligned.h>
#include "hw.h"
-@@ -523,8 +524,16 @@ static int ath9k_hw_init_macaddr(struct
+@@ -519,8 +520,16 @@ static int ath9k_hw_init_macaddr(struct
common->macaddr[2 * i] = eeval >> 8;
common->macaddr[2 * i + 1] = eeval & 0xff;
}
diff --git a/package/mac80211/patches/403-ath_regd_optional.patch b/package/mac80211/patches/403-ath_regd_optional.patch
index 1854c271e5..683417b776 100644
--- a/package/mac80211/patches/403-ath_regd_optional.patch
+++ b/package/mac80211/patches/403-ath_regd_optional.patch
@@ -1,8 +1,8 @@
--- a/drivers/net/wireless/ath/regd.c
+++ b/drivers/net/wireless/ath/regd.c
-@@ -200,6 +200,10 @@ ath_reg_apply_beaconing_flags(struct wip
- u32 bandwidth = 0;
- int r;
+@@ -198,6 +198,10 @@ ath_reg_apply_beaconing_flags(struct wip
+ struct ieee80211_channel *ch;
+ unsigned int i;
+#ifdef ATH_USER_REGD
+ return;
@@ -11,9 +11,9 @@
for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
if (!wiphy->bands[band])
-@@ -259,6 +263,10 @@ ath_reg_apply_active_scan_flags(struct w
- u32 bandwidth = 0;
- int r;
+@@ -252,6 +256,10 @@ ath_reg_apply_active_scan_flags(struct w
+ struct ieee80211_channel *ch;
+ const struct ieee80211_reg_rule *reg_rule;
+#ifdef ATH_USER_REGD
+ return;
@@ -22,7 +22,7 @@
sband = wiphy->bands[IEEE80211_BAND_2GHZ];
if (!sband)
return;
-@@ -308,6 +316,10 @@ static void ath_reg_apply_radar_flags(st
+@@ -301,6 +309,10 @@ static void ath_reg_apply_radar_flags(st
struct ieee80211_channel *ch;
unsigned int i;
@@ -33,7 +33,7 @@
if (!wiphy->bands[IEEE80211_BAND_5GHZ])
return;
-@@ -514,6 +526,10 @@ ath_regd_init_wiphy(struct ath_regulator
+@@ -505,6 +517,10 @@ ath_regd_init_wiphy(struct ath_regulator
{
const struct ieee80211_regdomain *regd;
diff --git a/package/mac80211/patches/405-regd_no_assoc_hints.patch b/package/mac80211/patches/405-regd_no_assoc_hints.patch
index 8a5c2a2e33..938ac42165 100644
--- a/package/mac80211/patches/405-regd_no_assoc_hints.patch
+++ b/package/mac80211/patches/405-regd_no_assoc_hints.patch
@@ -1,20 +1,19 @@
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
-@@ -1796,6 +1796,8 @@ void regulatory_hint_11d(struct wiphy *w
+@@ -1730,6 +1730,8 @@ void regulatory_hint_11d(struct wiphy *w
enum environment_cap env = ENVIRON_ANY;
- struct regulatory_request *request;
+ struct regulatory_request *request, *lr;
+ return;
+
mutex_lock(&reg_mutex);
+ lr = get_last_request();
- if (unlikely(!last_request))
-@@ -2030,6 +2032,8 @@ static void restore_regulatory_settings(
+@@ -1926,6 +1928,7 @@ static void restore_regulatory_settings(
void regulatory_hint_disconnect(void)
{
+ return;
-+
- REG_DBG_PRINT("All devices are disconnected, going to "
- "restore regulatory settings\n");
+ REG_DBG_PRINT("All devices are disconnected, going to restore regulatory settings\n");
restore_regulatory_settings(false);
+ }
diff --git a/package/mac80211/patches/410-ath9k_allow_adhoc_and_ap.patch b/package/mac80211/patches/410-ath9k_allow_adhoc_and_ap.patch
index aabf3c3f49..7a07eb6e97 100644
--- a/package/mac80211/patches/410-ath9k_allow_adhoc_and_ap.patch
+++ b/package/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
-@@ -667,6 +667,7 @@ static const struct ieee80211_iface_limi
- #ifdef CONFIG_MAC80211_MESH
- BIT(NL80211_IFTYPE_MESH_POINT) |
+@@ -727,6 +727,7 @@ static const struct ieee80211_iface_limi
#endif
-+ BIT(NL80211_IFTYPE_ADHOC) |
BIT(NL80211_IFTYPE_AP) |
BIT(NL80211_IFTYPE_P2P_GO) },
++ { .max = 1, .types = BIT(NL80211_IFTYPE_ADHOC) },
};
+
+ static const struct ieee80211_iface_combination if_comb = {
diff --git a/package/mac80211/patches/411-ath5k_allow_adhoc_and_ap.patch b/package/mac80211/patches/411-ath5k_allow_adhoc_and_ap.patch
index 8e02950e4a..22d911370f 100644
--- a/package/mac80211/patches/411-ath5k_allow_adhoc_and_ap.patch
+++ b/package/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
-@@ -1878,7 +1878,7 @@ ath5k_beacon_send(struct ath5k_hw *ah)
+@@ -1868,7 +1868,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);
-@@ -1964,7 +1964,7 @@ ath5k_beacon_update_timers(struct ath5k_
+@@ -1954,7 +1954,7 @@ ath5k_beacon_update_timers(struct ath5k_
intval = ah->bintval & AR5K_BEACON_PERIOD;
if (ah->opmode == NL80211_IFTYPE_AP && ah->num_ap_vifs
@@ -36,11 +36,11 @@
intval /= ATH_BCBUF; /* staggered multi-bss beacons */
if (intval < 15)
ATH5K_WARN(ah, "intval %u is too low, min 15\n",
-@@ -2427,6 +2427,7 @@ static const struct ieee80211_iface_limi
- #ifdef CONFIG_MAC80211_MESH
+@@ -2418,6 +2418,7 @@ static const struct ieee80211_iface_limi
BIT(NL80211_IFTYPE_MESH_POINT) |
#endif
-+ BIT(NL80211_IFTYPE_ADHOC) |
BIT(NL80211_IFTYPE_AP) },
++ { .max = 1, .types = BIT(NL80211_IFTYPE_ADHOC) },
};
+ static const struct ieee80211_iface_combination if_comb = {
diff --git a/package/mac80211/patches/412-mac80211_allow_adhoc_and_ap.patch b/package/mac80211/patches/412-mac80211_allow_adhoc_and_ap.patch
deleted file mode 100644
index 93f35567eb..0000000000
--- a/package/mac80211/patches/412-mac80211_allow_adhoc_and_ap.patch
+++ /dev/null
@@ -1,20 +0,0 @@
---- a/net/mac80211/main.c
-+++ b/net/mac80211/main.c
-@@ -792,17 +792,11 @@ int ieee80211_register_hw(struct ieee802
- */
- for (i = 0; i < hw->wiphy->n_iface_combinations; i++) {
- const struct ieee80211_iface_combination *c;
-- int j;
-
- c = &hw->wiphy->iface_combinations[i];
-
- if (c->num_different_channels > 1)
- return -EINVAL;
--
-- for (j = 0; j < c->n_limits; j++)
-- if ((c->limits[j].types & BIT(NL80211_IFTYPE_ADHOC)) &&
-- c->limits[j].max > 1)
-- return -EINVAL;
- }
-
- #ifndef CONFIG_MAC80211_MESH
diff --git a/package/mac80211/patches/420-ath5k_disable_fast_cc.patch b/package/mac80211/patches/420-ath5k_disable_fast_cc.patch
index bd661c6fbf..48b8467144 100644
--- a/package/mac80211/patches/420-ath5k_disable_fast_cc.patch
+++ b/package/mac80211/patches/420-ath5k_disable_fast_cc.patch
@@ -1,6 +1,6 @@
--- a/drivers/net/wireless/ath/ath5k/reset.c
+++ b/drivers/net/wireless/ath/ath5k/reset.c
-@@ -1156,6 +1156,7 @@ ath5k_hw_reset(struct ath5k_hw *ah, enum
+@@ -1158,6 +1158,7 @@ ath5k_hw_reset(struct ath5k_hw *ah, enum
tsf_lo = 0;
mode = 0;
@@ -8,7 +8,7 @@
/*
* Sanity check for fast flag
* Fast channel change only available
-@@ -1163,6 +1164,7 @@ ath5k_hw_reset(struct ath5k_hw *ah, enum
+@@ -1165,6 +1166,7 @@ ath5k_hw_reset(struct ath5k_hw *ah, enum
*/
if (fast && (ah->ah_radio != AR5K_RF2413) &&
(ah->ah_radio != AR5K_RF5413))
diff --git a/package/mac80211/patches/500-ath9k_eeprom_debugfs.patch b/package/mac80211/patches/500-ath9k_eeprom_debugfs.patch
index 0fa054aa1b..285fce2e36 100644
--- a/package/mac80211/patches/500-ath9k_eeprom_debugfs.patch
+++ b/package/mac80211/patches/500-ath9k_eeprom_debugfs.patch
@@ -1,8 +1,8 @@
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
-@@ -1531,6 +1531,53 @@ static const struct file_operations fops
-
- #endif
+@@ -2003,6 +2003,53 @@ void ath9k_get_et_stats(struct ieee80211
+ WARN_ON(i != ATH9K_SSTATS_LEN);
+ }
+static ssize_t read_file_eeprom(struct file *file, char __user *user_buf,
+ size_t count, loff_t *ppos)
@@ -54,12 +54,12 @@
int ath9k_init_debug(struct ath_hw *ah)
{
struct ath_common *common = ath9k_hw_common(ah);
-@@ -1602,5 +1649,8 @@ int ath9k_init_debug(struct ath_hw *ah)
- debugfs_create_u32("gpio_val", S_IRUSR | S_IWUSR,
- sc->debug.debugfs_phy, &sc->sc_ah->gpio_val);
+@@ -2020,6 +2067,8 @@ int ath9k_init_debug(struct ath_hw *ah)
+
+ ath9k_dfs_init_debug(sc);
+ debugfs_create_file("eeprom", S_IRUSR, sc->debug.debugfs_phy, sc,
+ &fops_eeprom);
-+
- return 0;
- }
+ debugfs_create_file("dma", S_IRUSR, sc->debug.debugfs_phy, sc,
+ &fops_dma);
+ debugfs_create_file("interrupt", S_IRUSR, sc->debug.debugfs_phy, sc,
diff --git a/package/mac80211/patches/501-ath9k-eeprom_endianess.patch b/package/mac80211/patches/501-ath9k-eeprom_endianess.patch
index 52ae70fc63..06c34b75de 100644
--- a/package/mac80211/patches/501-ath9k-eeprom_endianess.patch
+++ b/package/mac80211/patches/501-ath9k-eeprom_endianess.patch
@@ -1,6 +1,6 @@
--- a/drivers/net/wireless/ath/ath9k/eeprom_def.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom_def.c
-@@ -266,7 +266,7 @@ static int ath9k_hw_def_check_eeprom(str
+@@ -262,7 +262,7 @@ static int ath9k_hw_def_check_eeprom(str
{
struct ar5416_eeprom_def *eep = &ah->eeprom.def;
struct ath_common *common = ath9k_hw_common(ah);
@@ -9,7 +9,7 @@
u32 sum = 0, el;
bool need_swap = false;
int i, addr, size;
-@@ -276,27 +276,16 @@ static int ath9k_hw_def_check_eeprom(str
+@@ -272,27 +272,16 @@ static int ath9k_hw_def_check_eeprom(str
return false;
}
@@ -49,29 +49,29 @@
--- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
-@@ -195,7 +195,7 @@ static int ath9k_hw_4k_check_eeprom(stru
- int i, addr;
-
+@@ -57,7 +57,7 @@ static bool ath9k_hw_4k_fill_eeprom(stru
+ {
+ struct ath_common *common = ath9k_hw_common(ah);
- if (!ath9k_hw_use_flash(ah)) {
+ if (!(ah->ah_flags & AH_NO_EEP_SWAP)) {
- if (!ath9k_hw_nvram_read(common, AR5416_EEPROM_MAGIC_OFFSET,
- &magic)) {
- ath_err(common, "Reading Magic # failed\n");
+ ath_dbg(common, EEPROM, "Reading from EEPROM, not flash\n");
+ }
+
--- a/drivers/net/wireless/ath/ath9k/eeprom_9287.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom_9287.c
-@@ -189,7 +189,7 @@ static int ath9k_hw_ar9287_check_eeprom(
- struct ar9287_eeprom *eep = &ah->eeprom.map9287;
+@@ -60,7 +60,7 @@ static bool ath9k_hw_ar9287_fill_eeprom(
+ {
struct ath_common *common = ath9k_hw_common(ah);
- if (!ath9k_hw_use_flash(ah)) {
+ if (!(ah->ah_flags & AH_NO_EEP_SWAP)) {
- if (!ath9k_hw_nvram_read(common, AR5416_EEPROM_MAGIC_OFFSET,
- &magic)) {
- ath_err(common, "Reading Magic # failed\n");
+ ath_dbg(common, EEPROM, "Reading from EEPROM, not flash\n");
+ }
+
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
-@@ -705,6 +705,7 @@ enum ath_cal_list {
+@@ -740,6 +740,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
-@@ -537,6 +537,8 @@ static int ath9k_init_softc(u16 devid, s
+@@ -587,6 +587,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;
diff --git a/package/mac80211/patches/502-ath9k_ahb_init.patch b/package/mac80211/patches/502-ath9k_ahb_init.patch
index 7d3df6b204..88841632d9 100644
--- a/package/mac80211/patches/502-ath9k_ahb_init.patch
+++ b/package/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
-@@ -926,23 +926,23 @@ static int __init ath9k_init(void)
+@@ -965,23 +965,23 @@ static int __init ath9k_init(void)
goto err_out;
}
diff --git a/package/mac80211/patches/510-ath9k_intr_mitigation_tweak.patch b/package/mac80211/patches/510-ath9k_intr_mitigation_tweak.patch
index b6591b06e9..855b3364cd 100644
--- a/package/mac80211/patches/510-ath9k_intr_mitigation_tweak.patch
+++ b/package/mac80211/patches/510-ath9k_intr_mitigation_tweak.patch
@@ -1,6 +1,6 @@
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
-@@ -1951,8 +1951,8 @@ int ath9k_hw_reset(struct ath_hw *ah, st
+@@ -1946,8 +1946,8 @@ int ath9k_hw_reset(struct ath_hw *ah, st
REG_WRITE(ah, AR_OBS, 8);
if (ah->config.rx_intr_mitigation) {
diff --git a/package/mac80211/patches/511-ath9k_reduce_rxbuf.patch b/package/mac80211/patches/511-ath9k_reduce_rxbuf.patch
index db13fea1bc..8d8c5fd7fe 100644
--- a/package/mac80211/patches/511-ath9k_reduce_rxbuf.patch
+++ b/package/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
-@@ -122,7 +122,7 @@ void ath_descdma_cleanup(struct ath_soft
+@@ -119,7 +119,7 @@ int ath_descdma_setup(struct ath_softc *
/* RX / TX */
/***********/
diff --git a/package/mac80211/patches/512-ath9k_channelbw_debugfs.patch b/package/mac80211/patches/512-ath9k_channelbw_debugfs.patch
index 15111e9b82..4156773228 100644
--- a/package/mac80211/patches/512-ath9k_channelbw_debugfs.patch
+++ b/package/mac80211/patches/512-ath9k_channelbw_debugfs.patch
@@ -1,6 +1,6 @@
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
-@@ -656,6 +656,7 @@ struct ath_softc {
+@@ -689,6 +689,7 @@ struct ath_softc {
struct ieee80211_hw *hw;
struct device *dev;
@@ -8,9 +8,9 @@
struct survey_info *cur_survey;
struct survey_info survey[ATH9K_NUM_CHANNELS];
-@@ -731,6 +732,7 @@ struct ath_softc {
- #endif
- };
+@@ -893,6 +894,7 @@ struct fft_sample_ht20 {
+ u8 data[SPECTRAL_HT20_NUM_BINS];
+ } __packed;
+int ath9k_config(struct ieee80211_hw *hw, u32 changed);
void ath9k_tasklet(unsigned long data);
@@ -18,7 +18,7 @@
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
-@@ -1578,6 +1578,50 @@ static const struct file_operations fops
+@@ -2050,6 +2050,50 @@ static const struct file_operations fops
.owner = THIS_MODULE
};
@@ -69,19 +69,19 @@
int ath9k_init_debug(struct ath_hw *ah)
{
struct ath_common *common = ath9k_hw_common(ah);
-@@ -1652,5 +1696,8 @@ int ath9k_init_debug(struct ath_hw *ah)
+@@ -2069,6 +2113,8 @@ int ath9k_init_debug(struct ath_hw *ah)
+
debugfs_create_file("eeprom", S_IRUSR, sc->debug.debugfs_phy, sc,
&fops_eeprom);
-
+ debugfs_create_file("chanbw", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
+ sc, &fops_chanbw);
-+
- return 0;
- }
+ debugfs_create_file("dma", S_IRUSR, sc->debug.debugfs_phy, sc,
+ &fops_dma);
+ debugfs_create_file("interrupt", S_IRUSR, sc->debug.debugfs_phy, sc,
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
-@@ -1120,7 +1120,7 @@ static void ath9k_disable_ps(struct ath_
- ath_dbg(common, PS, "PowerSave disabled\n");
+@@ -1136,7 +1136,7 @@ int ath9k_spectral_scan_config(struct ie
+ return 0;
}
-static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
@@ -89,7 +89,7 @@
{
struct ath_softc *sc = hw->priv;
struct ath_hw *ah = sc->sc_ah;
-@@ -1174,9 +1174,11 @@ static int ath9k_config(struct ieee80211
+@@ -1190,9 +1190,11 @@ static int ath9k_config(struct ieee80211
if ((changed & IEEE80211_CONF_CHANGE_CHANNEL) || reset_channel) {
struct ieee80211_channel *curchan = hw->conf.channel;
@@ -101,7 +101,7 @@
if (ah->curchan)
old_pos = ah->curchan - &ah->channels[0];
-@@ -1219,7 +1221,23 @@ static int ath9k_config(struct ieee80211
+@@ -1235,7 +1237,23 @@ static int ath9k_config(struct ieee80211
memset(&sc->survey[pos], 0, sizeof(struct survey_info));
}
diff --git a/package/mac80211/patches/513-mac80211_reduce_txqueuelen.patch b/package/mac80211/patches/513-mac80211_reduce_txqueuelen.patch
deleted file mode 100644
index 25f4fdd401..0000000000
--- a/package/mac80211/patches/513-mac80211_reduce_txqueuelen.patch
+++ /dev/null
@@ -1,10 +0,0 @@
---- a/net/mac80211/iface.c
-+++ b/net/mac80211/iface.c
-@@ -964,6 +964,7 @@ static const struct net_device_ops ieee8
- static void ieee80211_if_setup(struct net_device *dev)
- {
- ether_setup(dev);
-+ dev->tx_queue_len = 32;
- dev->priv_flags &= ~IFF_TX_SKB_SHARING;
- netdev_attach_ops(dev, &ieee80211_dataif_ops);
- #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29))
diff --git a/package/mac80211/patches/520-mac80211_cur_txpower.patch b/package/mac80211/patches/520-mac80211_cur_txpower.patch
index 54f2e5040b..f0ed3d944d 100644
--- a/package/mac80211/patches/520-mac80211_cur_txpower.patch
+++ b/package/mac80211/patches/520-mac80211_cur_txpower.patch
@@ -1,27 +1,29 @@
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
-@@ -1372,6 +1372,7 @@ struct ieee80211_hw {
+@@ -1554,6 +1554,7 @@ struct ieee80211_hw {
u8 max_tx_aggregation_subframes;
u8 offchannel_tx_hw_queue;
u8 radiotap_mcs_details;
+ s8 cur_power_level;
+ u16 radiotap_vht_details;
netdev_features_t netdev_features;
};
-
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
-@@ -1967,7 +1967,7 @@ static int ieee80211_get_tx_power(struct
- {
+@@ -2190,7 +2190,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);
-- *dbm = local->hw.conf.power_level;
-+ *dbm = local->hw.cur_power_level;
-
- return 0;
- }
+- if (!local->use_chanctx)
++ if (local->hw.cur_power_level)
++ *dbm = local->hw.cur_power_level;
++ else if (!local->use_chanctx)
+ *dbm = local->hw.conf.power_level;
+ else
+ *dbm = sdata->vif.bss_conf.txpower;
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
-@@ -165,6 +165,7 @@ int ieee80211_hw_config(struct ieee80211
+@@ -166,6 +166,7 @@ static u32 ieee80211_hw_conf_chan(struct
if (local->hw.conf.power_level != power) {
changed |= IEEE80211_CONF_CHANGE_POWER;
diff --git a/package/mac80211/patches/521-ath9k_cur_txpower.patch b/package/mac80211/patches/521-ath9k_cur_txpower.patch
index 14b59e58e7..f4c1f5d54f 100644
--- a/package/mac80211/patches/521-ath9k_cur_txpower.patch
+++ b/package/mac80211/patches/521-ath9k_cur_txpower.patch
@@ -1,6 +1,6 @@
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
-@@ -1244,6 +1244,8 @@ int ath9k_config(struct ieee80211_hw *hw
+@@ -1260,6 +1260,8 @@ int ath9k_config(struct ieee80211_hw *hw
return -EINVAL;
}
@@ -9,7 +9,7 @@
/*
* The most recent snapshot of channel->noisefloor for the old
* channel is only available after the hardware reset. Copy it to
-@@ -1258,6 +1260,7 @@ int ath9k_config(struct ieee80211_hw *hw
+@@ -1279,6 +1281,7 @@ int ath9k_config(struct ieee80211_hw *hw
sc->config.txpowlimit = 2 * conf->power_level;
ath9k_cmn_update_txpow(ah, sc->curtxpow,
sc->config.txpowlimit, &sc->curtxpow);
diff --git a/package/mac80211/patches/522-ath9k_per_chain_signal_strength.patch b/package/mac80211/patches/522-ath9k_per_chain_signal_strength.patch
index 9df453c2f5..6808cc4df7 100644
--- a/package/mac80211/patches/522-ath9k_per_chain_signal_strength.patch
+++ b/package/mac80211/patches/522-ath9k_per_chain_signal_strength.patch
@@ -1,6 +1,6 @@
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
-@@ -729,6 +729,9 @@ enum mac80211_rx_flags {
+@@ -839,6 +839,9 @@ enum mac80211_rx_flags {
* @signal: signal strength when receiving this frame, either in dBm, in dB or
* unspecified depending on the hardware capabilities flags
* @IEEE80211_HW_SIGNAL_*
@@ -9,33 +9,33 @@
+ * @chain_signal: per-chain signal strength, same format as @signal
* @antenna: antenna used
* @rate_idx: index of data rate into band's supported rates or MCS index if
- * HT rates are use (RX_FLAG_HT)
-@@ -749,6 +752,8 @@ struct ieee80211_rx_status {
+ * HT or VHT is used (%RX_FLAG_HT/%RX_FLAG_VHT)
+@@ -870,6 +873,8 @@ struct ieee80211_rx_status {
u8 band;
u8 antenna;
s8 signal;
+ u8 chains;
+ s8 chain_signal[4];
u8 ampdu_delimiter_crc;
- };
-
+ u8 vendor_radiotap_align;
+ u8 vendor_radiotap_oui[3];
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
-@@ -325,6 +325,11 @@ struct sta_info {
- unsigned long rx_dropped;
+@@ -342,6 +342,11 @@ struct sta_info {
int last_signal;
struct ewma avg_signal;
+ int last_ack_signal;
+
+ u8 chains;
+ s8 chain_signal_last[4];
+ struct ewma chain_signal_avg[4];
+
/* Plus 1 for non-QoS frames */
- __le16 last_seq_ctrl[NUM_RX_DATA_QUEUES + 1];
+ __le16 last_seq_ctrl[IEEE80211_NUM_TIDS + 1];
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
-@@ -1271,6 +1271,7 @@ ieee80211_rx_h_sta_process(struct ieee80
+@@ -1383,6 +1383,7 @@ ieee80211_rx_h_sta_process(struct ieee80
struct sk_buff *skb = rx->skb;
struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
@@ -43,7 +43,7 @@
if (!sta)
return RX_CONTINUE;
-@@ -1315,6 +1316,19 @@ ieee80211_rx_h_sta_process(struct ieee80
+@@ -1433,6 +1434,19 @@ ieee80211_rx_h_sta_process(struct ieee80
ewma_add(&sta->avg_signal, -status->signal);
}
@@ -65,7 +65,7 @@
* exchange sequence.
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
-@@ -254,6 +254,8 @@ struct sta_info *sta_info_alloc(struct i
+@@ -353,6 +353,8 @@ struct sta_info *sta_info_alloc(struct i
do_posix_clock_monotonic_gettime(&uptime);
sta->last_connected = uptime.tv_sec;
ewma_init(&sta->avg_signal, 1024, 8);
@@ -76,25 +76,25 @@
kfree(sta);
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
-@@ -549,6 +549,8 @@ struct station_parameters {
- * @STATION_INFO_STA_FLAGS: @sta_flags filled
- * @STATION_INFO_BEACON_LOSS_COUNT: @beacon_loss_count filled
- * @STATION_INFO_T_OFFSET: @t_offset filled
+@@ -721,6 +721,8 @@ struct station_parameters {
+ * @STATION_INFO_LOCAL_PM: @local_pm filled
+ * @STATION_INFO_PEER_PM: @peer_pm filled
+ * @STATION_INFO_NONPEER_PM: @nonpeer_pm filled
+ * @STATION_INFO_CHAIN_SIGNAL: @chain_signal filled
+ * @STATION_INFO_CHAIN_SIGNAL_AVG: @chain_signal_avg filled
*/
enum station_info_flags {
STATION_INFO_INACTIVE_TIME = 1<<0,
-@@ -572,6 +574,8 @@ enum station_info_flags {
- STATION_INFO_STA_FLAGS = 1<<18,
- STATION_INFO_BEACON_LOSS_COUNT = 1<<19,
- STATION_INFO_T_OFFSET = 1<<20,
-+ STATION_INFO_CHAIN_SIGNAL = 1<<21,
-+ STATION_INFO_CHAIN_SIGNAL_AVG = 1<<22,
+@@ -749,6 +751,8 @@ enum station_info_flags {
+ STATION_INFO_NONPEER_PM = 1<<23,
+ STATION_INFO_RX_BYTES64 = 1<<24,
+ STATION_INFO_TX_BYTES64 = 1<<25,
++ STATION_INFO_CHAIN_SIGNAL = 1<<26,
++ STATION_INFO_CHAIN_SIGNAL_AVG = 1<<27,
};
/**
-@@ -655,6 +659,9 @@ struct sta_bss_parameters {
+@@ -842,6 +846,9 @@ struct sta_bss_parameters {
* For CFG80211_SIGNAL_TYPE_MBM, value is expressed in _dBm_.
* @signal_avg: Average signal strength, type depends on the wiphy's signal_type.
* For CFG80211_SIGNAL_TYPE_MBM, value is expressed in _dBm_.
@@ -104,7 +104,7 @@
* @txrate: current unicast bitrate from this station
* @rxrate: current unicast bitrate to this station
* @rx_packets: packets received from this station
-@@ -687,6 +694,11 @@ struct station_info {
+@@ -877,6 +884,11 @@ struct station_info {
u8 plink_state;
s8 signal;
s8 signal_avg;
@@ -135,7 +135,7 @@
u8 rs_num_delims;
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
-@@ -945,6 +945,7 @@ static int ath9k_rx_skb_preprocess(struc
+@@ -937,6 +937,7 @@ static int ath9k_rx_skb_preprocess(struc
bool *decrypt_error)
{
struct ath_hw *ah = common->ah;
@@ -143,7 +143,7 @@
/*
* everything but the rate is checked here, the rate check is done
-@@ -970,6 +971,20 @@ static int ath9k_rx_skb_preprocess(struc
+@@ -962,6 +963,20 @@ static int ath9k_rx_skb_preprocess(struc
if (rx_stats->rs_moreaggr)
rx_status->flag |= RX_FLAG_NO_SIGNAL_VAL;
@@ -164,9 +164,18 @@
return 0;
}
+@@ -1070,7 +1085,7 @@ static int ath_process_fft(struct ath_so
+ fft_sample.tlv.length = __cpu_to_be16(length);
+
+ fft_sample.freq = __cpu_to_be16(ah->curchan->chan->center_freq);
+- fft_sample.rssi = fix_rssi_inv_only(rs->rs_rssi_ctl0);
++ fft_sample.rssi = fix_rssi_inv_only(rs->rs_rssi_ctl[0]);
+ fft_sample.noise = ah->noise;
+
+ switch (len - SPECTRAL_HT20_TOTAL_DATA_LEN) {
--- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
-@@ -458,12 +458,12 @@ int ath9k_hw_process_rxdesc_edma(struct
+@@ -475,12 +475,12 @@ int ath9k_hw_process_rxdesc_edma(struct
/* XXX: Keycache */
rxs->rs_rssi = MS(rxsp->status5, AR_RxRSSICombined);
@@ -227,7 +236,7 @@
if (ads.ds_rxstatus8 & AR_RxKeyIdxValid)
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
-@@ -996,12 +996,12 @@ void ath_debug_stat_rx(struct ath_softc
+@@ -940,12 +940,12 @@ void ath_debug_stat_rx(struct ath_softc
#ifdef CONFIG_ATH9K_MAC_DEBUG
spin_lock(&sc->debug.samp_lock);
RX_SAMP_DBG(jiffies) = jiffies;
@@ -246,21 +255,21 @@
RX_SAMP_DBG(antenna) = rs->rs_antenna;
RX_SAMP_DBG(rssi) = rs->rs_rssi;
RX_SAMP_DBG(rate) = rs->rs_rate;
---- a/include/linux/nl80211.h
-+++ b/include/linux/nl80211.h
-@@ -1760,6 +1760,8 @@ enum nl80211_sta_bss_param {
- * @NL80211_STA_INFO_STA_FLAGS: Contains a struct nl80211_sta_flag_update.
- * @NL80211_STA_INFO_BEACON_LOSS: count of times beacon loss was detected (u32)
- * @NL80211_STA_INFO_T_OFFSET: timing offset with respect to this STA (s64)
+--- a/include/uapi/linux/nl80211.h
++++ b/include/uapi/linux/nl80211.h
+@@ -1918,6 +1918,8 @@ enum nl80211_sta_bss_param {
+ * @NL80211_STA_INFO_PEER_PM: peer mesh STA link-specific power mode
+ * @NL80211_STA_INFO_NONPEER_PM: neighbor mesh STA power save mode towards
+ * non-peer STA
+ * @NL80211_STA_INFO_CHAIN_SIGNAL: per-chain signal strength of last PPDU
+ * @NL80211_STA_INFO_CHAIN_SIGNAL_AVG: per-chain signal strength average
* @__NL80211_STA_INFO_AFTER_LAST: internal
* @NL80211_STA_INFO_MAX: highest possible station info attribute
*/
-@@ -1784,6 +1786,8 @@ enum nl80211_sta_info {
- NL80211_STA_INFO_STA_FLAGS,
- NL80211_STA_INFO_BEACON_LOSS,
- NL80211_STA_INFO_T_OFFSET,
+@@ -1947,6 +1949,8 @@ enum nl80211_sta_info {
+ NL80211_STA_INFO_NONPEER_PM,
+ NL80211_STA_INFO_RX_BYTES64,
+ NL80211_STA_INFO_TX_BYTES64,
+ NL80211_STA_INFO_CHAIN_SIGNAL,
+ NL80211_STA_INFO_CHAIN_SIGNAL_AVG,
@@ -268,8 +277,8 @@
__NL80211_STA_INFO_AFTER_LAST,
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
-@@ -2769,6 +2769,32 @@ nla_put_failure:
- return false;
+@@ -3082,6 +3082,32 @@ static bool nl80211_put_sta_rate(struct
+ return true;
}
+static bool nl80211_put_signal(struct sk_buff *msg, u8 mask, s8 *signal,
@@ -298,10 +307,10 @@
+ return true;
+}
+
- static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq,
+ static int nl80211_send_station(struct sk_buff *msg, u32 portid, u32 seq,
int flags,
struct cfg80211_registered_device *rdev,
-@@ -2830,6 +2856,18 @@ static int nl80211_send_station(struct s
+@@ -3153,6 +3179,18 @@ static int nl80211_send_station(struct s
default:
break;
}
@@ -322,7 +331,7 @@
NL80211_STA_INFO_TX_BITRATE))
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
-@@ -367,6 +367,7 @@ static void sta_set_sinfo(struct sta_inf
+@@ -445,6 +445,7 @@ static void sta_set_sinfo(struct sta_inf
struct ieee80211_sub_if_data *sdata = sta->sdata;
struct ieee80211_local *local = sdata->local;
struct timespec uptime;
@@ -330,7 +339,7 @@
sinfo->generation = sdata->local->sta_generation;
-@@ -406,6 +407,17 @@ static void sta_set_sinfo(struct sta_inf
+@@ -484,6 +485,17 @@ static void sta_set_sinfo(struct sta_inf
sinfo->signal = (s8)sta->last_signal;
sinfo->signal_avg = (s8) -ewma_read(&sta->avg_signal);
}
@@ -347,7 +356,7 @@
+ }
sta_set_rate_info_tx(sta, &sta->last_tx_rate, &sinfo->txrate);
-
+ sta_set_rate_info_rx(sta, &sinfo->rxrate);
--- a/drivers/net/wireless/ath/ath9k/dfs.c
+++ b/drivers/net/wireless/ath/ath9k/dfs.c
@@ -164,8 +164,8 @@ void ath9k_dfs_process_phyerr(struct ath
@@ -363,7 +372,7 @@
* hardware stores this as 8 bit signed value.
--- a/drivers/net/wireless/ath/ath9k/antenna.c
+++ b/drivers/net/wireless/ath/ath9k/antenna.c
-@@ -529,14 +529,14 @@ void ath_ant_comb_scan(struct ath_softc
+@@ -546,14 +546,14 @@ void ath_ant_comb_scan(struct ath_softc
struct ath_ant_comb *antcomb = &sc->ant_comb;
int alt_ratio = 0, alt_rssi_avg = 0, main_rssi_avg = 0, curr_alt_set;
int curr_main_set;
diff --git a/package/mac80211/patches/523-cfg80211_fix_antenna_gain.patch b/package/mac80211/patches/523-cfg80211_fix_antenna_gain.patch
deleted file mode 100644
index 98f3d9675f..0000000000
--- a/package/mac80211/patches/523-cfg80211_fix_antenna_gain.patch
+++ /dev/null
@@ -1,12 +0,0 @@
---- a/net/wireless/reg.c
-+++ b/net/wireless/reg.c
-@@ -908,8 +908,7 @@ static void handle_channel(struct wiphy
-
- chan->beacon_found = false;
- chan->flags = flags | bw_flags | map_regdom_flags(reg_rule->flags);
-- chan->max_antenna_gain = min(chan->orig_mag,
-- (int) MBI_TO_DBI(power_rule->max_antenna_gain));
-+ chan->max_antenna_gain = (int) MBI_TO_DBI(power_rule->max_antenna_gain);
- chan->max_reg_power = (int) MBM_TO_DBM(power_rule->max_eirp);
- if (chan->orig_mpwr) {
- /*
diff --git a/package/mac80211/patches/524-mac80211_configure_antenna_gain.patch b/package/mac80211/patches/523-mac80211_configure_antenna_gain.patch
index 99bdb84ff7..99bd2e3ba5 100644
--- a/package/mac80211/patches/524-mac80211_configure_antenna_gain.patch
+++ b/package/mac80211/patches/523-mac80211_configure_antenna_gain.patch
@@ -1,14 +1,14 @@
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
-@@ -851,6 +851,7 @@ enum ieee80211_smps_mode {
- * the CONF_PS flag is set.
+@@ -978,6 +978,7 @@ enum ieee80211_smps_mode {
*
- * @power_level: requested transmit power (in dBm)
+ * @power_level: requested transmit power (in dBm), backward compatibility
+ * value only that is set to the minimum of all interfaces
+ * @max_antenna_gain: maximum antenna gain adjusted by user config (in dBi)
*
* @channel: the channel to tune to
* @channel_type: the channel (HT) type
-@@ -870,6 +871,7 @@ struct ieee80211_conf {
+@@ -1000,6 +1001,7 @@ struct ieee80211_conf {
u32 flags;
int power_level, dynamic_ps_timeout;
int max_sleep_period;
@@ -16,80 +16,21 @@
u16 listen_interval;
u8 ps_dtim_period;
---- a/net/mac80211/main.c
-+++ b/net/mac80211/main.c
-@@ -101,7 +101,7 @@ int ieee80211_hw_config(struct ieee80211
- {
- struct ieee80211_channel *chan;
- int ret = 0;
-- int power;
-+ int power, ant_gain, max_power;
- enum nl80211_channel_type channel_type;
- u32 offchannel_flag;
-
-@@ -152,19 +152,31 @@ int ieee80211_hw_config(struct ieee80211
- changed |= IEEE80211_CONF_CHANGE_SMPS;
- }
-
-- if (test_bit(SCAN_SW_SCANNING, &local->scanning) ||
-- test_bit(SCAN_ONCHANNEL_SCANNING, &local->scanning) ||
-- test_bit(SCAN_HW_SCANNING, &local->scanning) ||
-- !local->ap_power_level)
-- power = chan->max_power;
-- else
-- power = min(chan->max_power, local->ap_power_level);
-+ max_power = chan->max_reg_power;
-+ if (!test_bit(SCAN_SW_SCANNING, &local->scanning) &&
-+ !test_bit(SCAN_ONCHANNEL_SCANNING, &local->scanning) &&
-+ !test_bit(SCAN_HW_SCANNING, &local->scanning) &&
-+ local->ap_power_level)
-+ max_power = min(max_power, local->ap_power_level);
-+
-+ ant_gain = chan->max_antenna_gain;
-+ if (local->user_antenna_gain > 0) {
-+ if (local->user_antenna_gain > ant_gain) {
-+ max_power -= local->user_antenna_gain - ant_gain;
-+ ant_gain = 0;
-+ } else
-+ ant_gain -= local->user_antenna_gain;
-+ }
-+
-+ power = min(chan->max_power, max_power);
-
- if (local->user_power_level >= 0)
- power = min(power, local->user_power_level);
-
-- if (local->hw.conf.power_level != power) {
-+ if (local->hw.conf.power_level != power ||
-+ local->hw.conf.max_antenna_gain != ant_gain) {
- changed |= IEEE80211_CONF_CHANGE_POWER;
-+ local->hw.conf.max_antenna_gain = ant_gain;
- local->hw.cur_power_level = power;
- local->hw.conf.power_level = power;
- }
-@@ -620,6 +632,7 @@ struct ieee80211_hw *ieee80211_alloc_hw(
- IEEE80211_RADIOTAP_MCS_HAVE_GI |
- IEEE80211_RADIOTAP_MCS_HAVE_BW;
- local->user_power_level = -1;
-+ local->user_antenna_gain = -1;
- wiphy->ht_capa_mod_mask = &mac80211_ht_capa_mod_mask;
-
- INIT_LIST_HEAD(&local->interfaces);
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
-@@ -1063,6 +1063,7 @@ struct ieee80211_local {
+@@ -1116,6 +1116,7 @@ struct ieee80211_local {
+ int dynamic_ps_forced_timeout;
- int user_power_level; /* in dBm */
- int ap_power_level; /* in dBm */
+ int user_power_level; /* in dBm, for all interfaces */
+ int user_antenna_gain; /* in dBi */
enum ieee80211_smps_mode smps_mode;
---- a/include/linux/nl80211.h
-+++ b/include/linux/nl80211.h
-@@ -1517,6 +1517,8 @@ enum nl80211_attrs {
-
- NL80211_ATTR_USER_REG_HINT_TYPE,
+--- a/include/uapi/linux/nl80211.h
++++ b/include/uapi/linux/nl80211.h
+@@ -1654,6 +1654,8 @@ enum nl80211_attrs {
+ NL80211_ATTR_STA_CAPABILITY,
+ NL80211_ATTR_STA_EXT_CAPABILITY,
+ NL80211_ATTR_WIPHY_ANTENNA_GAIN,
+
@@ -98,15 +39,15 @@
__NL80211_ATTR_AFTER_LAST,
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
-@@ -355,6 +355,7 @@ static const struct nla_policy nl80211_p
- [NL80211_ATTR_BG_SCAN_PERIOD] = { .type = NLA_U16 },
- [NL80211_ATTR_WDEV] = { .type = NLA_U64 },
- [NL80211_ATTR_USER_REG_HINT_TYPE] = { .type = NLA_U32 },
+@@ -370,6 +370,7 @@ static const struct nla_policy nl80211_p
+ [NL80211_ATTR_MAC_ADDRS] = { .type = NLA_NESTED },
+ [NL80211_ATTR_STA_CAPABILITY] = { .type = NLA_U16 },
+ [NL80211_ATTR_STA_EXT_CAPABILITY] = { .type = NLA_BINARY, },
+ [NL80211_ATTR_WIPHY_ANTENNA_GAIN] = { .type = NLA_U32 },
};
/* policy for the key attributes */
-@@ -1604,6 +1605,22 @@ static int nl80211_set_wiphy(struct sk_b
+@@ -1706,6 +1707,22 @@ static int nl80211_set_wiphy(struct sk_b
goto bad_res;
}
@@ -131,7 +72,7 @@
u32 tx_ant, rx_ant;
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
-@@ -1984,6 +1984,19 @@ static int ieee80211_get_tx_power(struct
+@@ -2212,6 +2212,19 @@ static int ieee80211_get_tx_power(struct
return 0;
}
@@ -151,7 +92,7 @@
static int ieee80211_set_wds_peer(struct wiphy *wiphy, struct net_device *dev,
const u8 *addr)
{
-@@ -3085,6 +3098,7 @@ struct cfg80211_ops mac80211_config_ops
+@@ -3375,6 +3388,7 @@ struct cfg80211_ops mac80211_config_ops
.set_wiphy_params = ieee80211_set_wiphy_params,
.set_tx_power = ieee80211_set_tx_power,
.get_tx_power = ieee80211_get_tx_power,
@@ -161,19 +102,61 @@
CFG80211_TESTMODE_CMD(ieee80211_testmode_cmd)
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
-@@ -1552,6 +1552,7 @@ struct cfg80211_gtk_rekey_data {
- * the power passed is in mBm, to get dBm use MBM_TO_DBM().
+@@ -1862,6 +1862,7 @@ struct cfg80211_gtk_rekey_data {
+ * (as advertised by the nl80211 feature flag.)
* @get_tx_power: store the current TX power into the dbm variable;
* return 0 if successful
+ * @set_antenna_gain: set antenna gain to reduce maximum tx power if necessary
*
* @set_wds_peer: set the WDS peer for a WDS interface
*
-@@ -1751,6 +1752,7 @@ struct cfg80211_ops {
- int (*set_tx_power)(struct wiphy *wiphy,
+@@ -2071,6 +2072,7 @@ struct cfg80211_ops {
enum nl80211_tx_power_setting type, int mbm);
- int (*get_tx_power)(struct wiphy *wiphy, int *dbm);
+ int (*get_tx_power)(struct wiphy *wiphy, struct wireless_dev *wdev,
+ int *dbm);
+ int (*set_antenna_gain)(struct wiphy *wiphy, int dbi);
int (*set_wds_peer)(struct wiphy *wiphy, struct net_device *dev,
const u8 *addr);
+--- a/net/mac80211/main.c
++++ b/net/mac80211/main.c
+@@ -101,7 +101,7 @@ static u32 ieee80211_hw_conf_chan(struct
+ struct ieee80211_sub_if_data *sdata;
+ struct ieee80211_channel *chan;
+ u32 changed = 0;
+- int power;
++ int power, ant_gain, max_power;
+ enum nl80211_channel_type channel_type;
+ u32 offchannel_flag;
+ bool scanning = false;
+@@ -164,8 +164,21 @@ static u32 ieee80211_hw_conf_chan(struct
+ }
+ rcu_read_unlock();
+
+- if (local->hw.conf.power_level != power) {
++ max_power = chan->max_reg_power;
++ ant_gain = chan->max_antenna_gain;
++ if (local->user_antenna_gain > 0) {
++ if (local->user_antenna_gain > ant_gain) {
++ max_power -= local->user_antenna_gain - ant_gain;
++ ant_gain = 0;
++ } else
++ ant_gain -= local->user_antenna_gain;
++ power = min(power, max_power);
++ }
++
++ if (local->hw.conf.power_level != power ||
++ local->hw.conf.max_antenna_gain != ant_gain) {
+ changed |= IEEE80211_CONF_CHANGE_POWER;
++ local->hw.conf.max_antenna_gain = ant_gain;
+ local->hw.cur_power_level = power;
+ local->hw.conf.power_level = power;
+ }
+@@ -612,6 +625,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;
++ local->user_antenna_gain = 0;
+ local->user_power_level = IEEE80211_UNSET_POWER_LEVEL;
+ wiphy->ht_capa_mod_mask = &mac80211_ht_capa_mod_mask;
+
diff --git a/package/mac80211/patches/525-ath9k_use_configured_antenna_gain.patch b/package/mac80211/patches/524-ath9k_use_configured_antenna_gain.patch
index 04bd2b3af0..d249fd3780 100644
--- a/package/mac80211/patches/525-ath9k_use_configured_antenna_gain.patch
+++ b/package/mac80211/patches/524-ath9k_use_configured_antenna_gain.patch
@@ -10,7 +10,7 @@
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
-@@ -2830,7 +2830,7 @@ void ath9k_hw_apply_txpower(struct ath_h
+@@ -2817,7 +2817,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);
@@ -21,7 +21,7 @@
if (ant_gain > max_gain)
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
-@@ -1256,7 +1256,10 @@ int ath9k_config(struct ieee80211_hw *hw
+@@ -1277,7 +1277,10 @@ int ath9k_config(struct ieee80211_hw *hw
}
if (changed & IEEE80211_CONF_CHANGE_POWER) {
diff --git a/package/mac80211/patches/526-cfg80211_fix_max_reg_power.patch b/package/mac80211/patches/526-cfg80211_fix_max_reg_power.patch
deleted file mode 100644
index 6f8d53f952..0000000000
--- a/package/mac80211/patches/526-cfg80211_fix_max_reg_power.patch
+++ /dev/null
@@ -1,21 +0,0 @@
---- a/net/wireless/reg.c
-+++ b/net/wireless/reg.c
-@@ -901,7 +901,7 @@ static void handle_channel(struct wiphy
- map_regdom_flags(reg_rule->flags) | bw_flags;
- chan->max_antenna_gain = chan->orig_mag =
- (int) MBI_TO_DBI(power_rule->max_antenna_gain);
-- chan->max_power = chan->orig_mpwr =
-+ chan->max_reg_power = chan->max_power = chan->orig_mpwr =
- (int) MBM_TO_DBM(power_rule->max_eirp);
- return;
- }
-@@ -1323,7 +1323,8 @@ static void handle_channel_custom(struct
-
- chan->flags |= map_regdom_flags(reg_rule->flags) | bw_flags;
- chan->max_antenna_gain = (int) MBI_TO_DBI(power_rule->max_antenna_gain);
-- chan->max_power = (int) MBM_TO_DBM(power_rule->max_eirp);
-+ chan->max_reg_power = chan->max_power =
-+ (int) MBM_TO_DBM(power_rule->max_eirp);
- }
-
- static void handle_band_custom(struct wiphy *wiphy, enum ieee80211_band band,
diff --git a/package/mac80211/patches/540-ath9k_extra_leds.patch b/package/mac80211/patches/530-ath9k_extra_leds.patch
index 290853426b..fd7596f480 100644
--- a/package/mac80211/patches/540-ath9k_extra_leds.patch
+++ b/package/mac80211/patches/530-ath9k_extra_leds.patch
@@ -1,17 +1,17 @@
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
-@@ -536,6 +536,9 @@ struct ath9k_wow_pattern {
- #ifdef CONFIG_MAC80211_LEDS
+@@ -551,6 +551,9 @@ struct ath9k_wow_pattern {
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);
+int ath_create_gpio_led(struct ath_softc *sc, int gpio, const char *name,
+ const char *trigger, bool active_low);
+
#else
static inline void ath_init_leds(struct ath_softc *sc)
{
-@@ -652,6 +655,13 @@ struct ath9k_vif_iter_data {
- int nadhocs; /* number of adhoc vifs */
+@@ -685,6 +688,13 @@ enum spectral_mode {
+ SPECTRAL_CHANSCAN,
};
+struct ath_led {
@@ -24,7 +24,7 @@
struct ath_softc {
struct ieee80211_hw *hw;
struct device *dev;
-@@ -693,9 +703,8 @@ struct ath_softc {
+@@ -726,9 +736,8 @@ struct ath_softc {
struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS];
#ifdef CONFIG_MAC80211_LEDS
@@ -38,7 +38,7 @@
struct ath9k_hw_cal_data caldata;
--- a/drivers/net/wireless/ath/ath9k/gpio.c
+++ b/drivers/net/wireless/ath/ath9k/gpio.c
-@@ -24,22 +24,89 @@
+@@ -24,40 +24,102 @@
static void ath_led_brightness(struct led_classdev *led_cdev,
enum led_brightness brightness)
{
@@ -135,16 +135,7 @@
if (AR_SREV_9100(sc->sc_ah))
return;
-@@ -57,26 +124,15 @@ void ath_init_leds(struct ath_softc *sc)
- sc->sc_ah->led_pin = ATH_LED_PIN_DEF;
- }
-- /* Configure gpio 1 for output */
-- ath9k_hw_cfg_output(sc->sc_ah, sc->sc_ah->led_pin,
-- AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
-- /* LED off, active low */
-- ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 1);
--
- if (!led_blink)
- sc->led_cdev.default_trigger =
- ieee80211_get_radio_led_name(sc->hw);
@@ -167,11 +158,11 @@
- sc->led_registered = true;
+ ath_create_gpio_led(sc, sc->sc_ah->led_pin, led_name, trigger, 1);
}
- #endif
+ 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
-@@ -811,7 +811,7 @@ int ath9k_init_device(u16 devid, struct
+@@ -870,7 +870,7 @@ int ath9k_init_device(u16 devid, struct
#ifdef CONFIG_MAC80211_LEDS
/* must be initialized before ieee80211_register_hw */
@@ -182,7 +173,7 @@
#endif
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
-@@ -1254,6 +1254,61 @@ static const struct file_operations fops
+@@ -1482,6 +1482,61 @@ static const struct file_operations fops
.llseek = default_llseek,
};
@@ -244,15 +235,14 @@
#ifdef CONFIG_ATH9K_MAC_DEBUG
void ath9k_debug_samp_bb_mac(struct ath_softc *sc)
-@@ -1687,6 +1742,11 @@ int ath9k_init_debug(struct ath_hw *ah)
- &fops_samps);
- #endif
-
+@@ -2115,6 +2170,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);
+#ifdef CONFIG_MAC80211_LEDS
+ debugfs_create_file("gpio_led", S_IWUSR,
+ sc->debug.debugfs_phy, sc, &fops_gpio_led);
+#endif
-+
- debugfs_create_u32("gpio_mask", S_IRUSR | S_IWUSR,
- sc->debug.debugfs_phy, &sc->sc_ah->gpio_mask);
-
+ debugfs_create_file("dma", S_IRUSR, sc->debug.debugfs_phy, sc,
+ &fops_dma);
+ debugfs_create_file("interrupt", S_IRUSR, sc->debug.debugfs_phy, sc,
diff --git a/package/mac80211/patches/530-ath9k_fix_initvals.patch b/package/mac80211/patches/530-ath9k_fix_initvals.patch
deleted file mode 100644
index d86e718f05..0000000000
--- a/package/mac80211/patches/530-ath9k_fix_initvals.patch
+++ /dev/null
@@ -1,208 +0,0 @@
---- a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h
-+++ b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h
-@@ -534,108 +534,108 @@ static const u32 ar9300_2p2_baseband_cor
-
- static const u32 ar9300Modes_high_power_tx_gain_table_2p2[][5] = {
- /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
-- {0x0000a2dc, 0x000cfff0, 0x000cfff0, 0x03aaa352, 0x03aaa352},
-- {0x0000a2e0, 0x000f0000, 0x000f0000, 0x03ccc584, 0x03ccc584},
-- {0x0000a2e4, 0x03f00000, 0x03f00000, 0x03f0f800, 0x03f0f800},
-+ {0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352},
-+ {0x0000a2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584},
-+ {0x0000a2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800},
- {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
-- {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9},
-- {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
-- {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002},
-- {0x0000a508, 0x0a000020, 0x0a000020, 0x08000004, 0x08000004},
-- {0x0000a50c, 0x10000023, 0x10000023, 0x0b000200, 0x0b000200},
-- {0x0000a510, 0x15000028, 0x15000028, 0x0f000202, 0x0f000202},
-- {0x0000a514, 0x1b00002b, 0x1b00002b, 0x12000400, 0x12000400},
-- {0x0000a518, 0x1f020028, 0x1f020028, 0x16000402, 0x16000402},
-- {0x0000a51c, 0x2502002b, 0x2502002b, 0x19000404, 0x19000404},
-- {0x0000a520, 0x2a04002a, 0x2a04002a, 0x1c000603, 0x1c000603},
-- {0x0000a524, 0x2e06002a, 0x2e06002a, 0x21000a02, 0x21000a02},
-- {0x0000a528, 0x3302202d, 0x3302202d, 0x25000a04, 0x25000a04},
-- {0x0000a52c, 0x3804202c, 0x3804202c, 0x28000a20, 0x28000a20},
-- {0x0000a530, 0x3c06202c, 0x3c06202c, 0x2c000e20, 0x2c000e20},
-- {0x0000a534, 0x4108202d, 0x4108202d, 0x30000e22, 0x30000e22},
-- {0x0000a538, 0x4506402d, 0x4506402d, 0x34000e24, 0x34000e24},
-- {0x0000a53c, 0x4906222d, 0x4906222d, 0x38001640, 0x38001640},
-- {0x0000a540, 0x4d062231, 0x4d062231, 0x3c001660, 0x3c001660},
-- {0x0000a544, 0x50082231, 0x50082231, 0x3f001861, 0x3f001861},
-- {0x0000a548, 0x5608422e, 0x5608422e, 0x43001a81, 0x43001a81},
-- {0x0000a54c, 0x5a08442e, 0x5a08442e, 0x47001a83, 0x47001a83},
-- {0x0000a550, 0x5e0a4431, 0x5e0a4431, 0x4a001c84, 0x4a001c84},
-- {0x0000a554, 0x640a4432, 0x640a4432, 0x4e001ce3, 0x4e001ce3},
-- {0x0000a558, 0x680a4434, 0x680a4434, 0x52001ce5, 0x52001ce5},
-- {0x0000a55c, 0x6c0a6434, 0x6c0a6434, 0x56001ce9, 0x56001ce9},
-- {0x0000a560, 0x6f0a6633, 0x6f0a6633, 0x5a001ceb, 0x5a001ceb},
-- {0x0000a564, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
-- {0x0000a568, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
-- {0x0000a56c, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
-- {0x0000a570, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
-- {0x0000a574, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
-- {0x0000a578, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
-- {0x0000a57c, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
-- {0x0000a580, 0x00800000, 0x00800000, 0x00800000, 0x00800000},
-- {0x0000a584, 0x06800003, 0x06800003, 0x04800002, 0x04800002},
-- {0x0000a588, 0x0a800020, 0x0a800020, 0x08800004, 0x08800004},
-- {0x0000a58c, 0x10800023, 0x10800023, 0x0b800200, 0x0b800200},
-- {0x0000a590, 0x15800028, 0x15800028, 0x0f800202, 0x0f800202},
-- {0x0000a594, 0x1b80002b, 0x1b80002b, 0x12800400, 0x12800400},
-- {0x0000a598, 0x1f820028, 0x1f820028, 0x16800402, 0x16800402},
-- {0x0000a59c, 0x2582002b, 0x2582002b, 0x19800404, 0x19800404},
-- {0x0000a5a0, 0x2a84002a, 0x2a84002a, 0x1c800603, 0x1c800603},
-- {0x0000a5a4, 0x2e86002a, 0x2e86002a, 0x21800a02, 0x21800a02},
-- {0x0000a5a8, 0x3382202d, 0x3382202d, 0x25800a04, 0x25800a04},
-- {0x0000a5ac, 0x3884202c, 0x3884202c, 0x28800a20, 0x28800a20},
-- {0x0000a5b0, 0x3c86202c, 0x3c86202c, 0x2c800e20, 0x2c800e20},
-- {0x0000a5b4, 0x4188202d, 0x4188202d, 0x30800e22, 0x30800e22},
-- {0x0000a5b8, 0x4586402d, 0x4586402d, 0x34800e24, 0x34800e24},
-- {0x0000a5bc, 0x4986222d, 0x4986222d, 0x38801640, 0x38801640},
-- {0x0000a5c0, 0x4d862231, 0x4d862231, 0x3c801660, 0x3c801660},
-- {0x0000a5c4, 0x50882231, 0x50882231, 0x3f801861, 0x3f801861},
-- {0x0000a5c8, 0x5688422e, 0x5688422e, 0x43801a81, 0x43801a81},
-- {0x0000a5cc, 0x5a88442e, 0x5a88442e, 0x47801a83, 0x47801a83},
-- {0x0000a5d0, 0x5e8a4431, 0x5e8a4431, 0x4a801c84, 0x4a801c84},
-- {0x0000a5d4, 0x648a4432, 0x648a4432, 0x4e801ce3, 0x4e801ce3},
-- {0x0000a5d8, 0x688a4434, 0x688a4434, 0x52801ce5, 0x52801ce5},
-- {0x0000a5dc, 0x6c8a6434, 0x6c8a6434, 0x56801ce9, 0x56801ce9},
-- {0x0000a5e0, 0x6f8a6633, 0x6f8a6633, 0x5a801ceb, 0x5a801ceb},
-- {0x0000a5e4, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec},
-- {0x0000a5e8, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec},
-- {0x0000a5ec, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec},
-- {0x0000a5f0, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec},
-- {0x0000a5f4, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec},
-- {0x0000a5f8, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec},
-- {0x0000a5fc, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec},
-+ {0x0000a410, 0x000050d8, 0x000050d8, 0x000050d9, 0x000050d9},
-+ {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000},
-+ {0x0000a504, 0x04002222, 0x04002222, 0x04000002, 0x04000002},
-+ {0x0000a508, 0x09002421, 0x09002421, 0x08000004, 0x08000004},
-+ {0x0000a50c, 0x0d002621, 0x0d002621, 0x0b000200, 0x0b000200},
-+ {0x0000a510, 0x13004620, 0x13004620, 0x0f000202, 0x0f000202},
-+ {0x0000a514, 0x19004a20, 0x19004a20, 0x11000400, 0x11000400},
-+ {0x0000a518, 0x1d004e20, 0x1d004e20, 0x15000402, 0x15000402},
-+ {0x0000a51c, 0x21005420, 0x21005420, 0x19000404, 0x19000404},
-+ {0x0000a520, 0x26005e20, 0x26005e20, 0x1b000603, 0x1b000603},
-+ {0x0000a524, 0x2b005e40, 0x2b005e40, 0x1f000a02, 0x1f000a02},
-+ {0x0000a528, 0x2f005e42, 0x2f005e42, 0x23000a04, 0x23000a04},
-+ {0x0000a52c, 0x33005e44, 0x33005e44, 0x26000a20, 0x26000a20},
-+ {0x0000a530, 0x38005e65, 0x38005e65, 0x2a000e20, 0x2a000e20},
-+ {0x0000a534, 0x3c005e69, 0x3c005e69, 0x2e000e22, 0x2e000e22},
-+ {0x0000a538, 0x40005e6b, 0x40005e6b, 0x31000e24, 0x31000e24},
-+ {0x0000a53c, 0x44005e6d, 0x44005e6d, 0x34001640, 0x34001640},
-+ {0x0000a540, 0x49005e72, 0x49005e72, 0x38001660, 0x38001660},
-+ {0x0000a544, 0x4e005eb2, 0x4e005eb2, 0x3b001861, 0x3b001861},
-+ {0x0000a548, 0x53005f12, 0x53005f12, 0x3e001a81, 0x3e001a81},
-+ {0x0000a54c, 0x59025eb2, 0x59025eb2, 0x42001a83, 0x42001a83},
-+ {0x0000a550, 0x5e025f12, 0x5e025f12, 0x44001c84, 0x44001c84},
-+ {0x0000a554, 0x61027f12, 0x61027f12, 0x48001ce3, 0x48001ce3},
-+ {0x0000a558, 0x6702bf12, 0x6702bf12, 0x4c001ce5, 0x4c001ce5},
-+ {0x0000a55c, 0x6b02bf14, 0x6b02bf14, 0x50001ce9, 0x50001ce9},
-+ {0x0000a560, 0x6f02bf16, 0x6f02bf16, 0x54001ceb, 0x54001ceb},
-+ {0x0000a564, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
-+ {0x0000a568, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
-+ {0x0000a56c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
-+ {0x0000a570, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
-+ {0x0000a574, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
-+ {0x0000a578, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
-+ {0x0000a57c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
-+ {0x0000a580, 0x00802220, 0x00802220, 0x00800000, 0x00800000},
-+ {0x0000a584, 0x04802222, 0x04802222, 0x04800002, 0x04800002},
-+ {0x0000a588, 0x09802421, 0x09802421, 0x08800004, 0x08800004},
-+ {0x0000a58c, 0x0d802621, 0x0d802621, 0x0b800200, 0x0b800200},
-+ {0x0000a590, 0x13804620, 0x13804620, 0x0f800202, 0x0f800202},
-+ {0x0000a594, 0x19804a20, 0x19804a20, 0x11800400, 0x11800400},
-+ {0x0000a598, 0x1d804e20, 0x1d804e20, 0x15800402, 0x15800402},
-+ {0x0000a59c, 0x21805420, 0x21805420, 0x19800404, 0x19800404},
-+ {0x0000a5a0, 0x26805e20, 0x26805e20, 0x1b800603, 0x1b800603},
-+ {0x0000a5a4, 0x2b805e40, 0x2b805e40, 0x1f800a02, 0x1f800a02},
-+ {0x0000a5a8, 0x2f805e42, 0x2f805e42, 0x23800a04, 0x23800a04},
-+ {0x0000a5ac, 0x33805e44, 0x33805e44, 0x26800a20, 0x26800a20},
-+ {0x0000a5b0, 0x38805e65, 0x38805e65, 0x2a800e20, 0x2a800e20},
-+ {0x0000a5b4, 0x3c805e69, 0x3c805e69, 0x2e800e22, 0x2e800e22},
-+ {0x0000a5b8, 0x40805e6b, 0x40805e6b, 0x31800e24, 0x31800e24},
-+ {0x0000a5bc, 0x44805e6d, 0x44805e6d, 0x34801640, 0x34801640},
-+ {0x0000a5c0, 0x49805e72, 0x49805e72, 0x38801660, 0x38801660},
-+ {0x0000a5c4, 0x4e805eb2, 0x4e805eb2, 0x3b801861, 0x3b801861},
-+ {0x0000a5c8, 0x53805f12, 0x53805f12, 0x3e801a81, 0x3e801a81},
-+ {0x0000a5cc, 0x59825eb2, 0x59825eb2, 0x42801a83, 0x42801a83},
-+ {0x0000a5d0, 0x5e825f12, 0x5e825f12, 0x44801c84, 0x44801c84},
-+ {0x0000a5d4, 0x61827f12, 0x61827f12, 0x48801ce3, 0x48801ce3},
-+ {0x0000a5d8, 0x6782bf12, 0x6782bf12, 0x4c801ce5, 0x4c801ce5},
-+ {0x0000a5dc, 0x6b82bf14, 0x6b82bf14, 0x50801ce9, 0x50801ce9},
-+ {0x0000a5e0, 0x6f82bf16, 0x6f82bf16, 0x54801ceb, 0x54801ceb},
-+ {0x0000a5e4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
-+ {0x0000a5e8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
-+ {0x0000a5ec, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
-+ {0x0000a5f0, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
-+ {0x0000a5f4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
-+ {0x0000a5f8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
-+ {0x0000a5fc, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
- {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
- {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
-- {0x0000a608, 0x01804601, 0x01804601, 0x00000000, 0x00000000},
-- {0x0000a60c, 0x01804601, 0x01804601, 0x00000000, 0x00000000},
-- {0x0000a610, 0x01804601, 0x01804601, 0x00000000, 0x00000000},
-- {0x0000a614, 0x01804601, 0x01804601, 0x01404000, 0x01404000},
-- {0x0000a618, 0x01804601, 0x01804601, 0x01404501, 0x01404501},
-- {0x0000a61c, 0x01804601, 0x01804601, 0x02008501, 0x02008501},
-- {0x0000a620, 0x03408d02, 0x03408d02, 0x0280ca03, 0x0280ca03},
-- {0x0000a624, 0x0300cc03, 0x0300cc03, 0x03010c04, 0x03010c04},
-- {0x0000a628, 0x03410d04, 0x03410d04, 0x04014c04, 0x04014c04},
-- {0x0000a62c, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005},
-- {0x0000a630, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005},
-- {0x0000a634, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005},
-- {0x0000a638, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005},
-- {0x0000a63c, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005},
-- {0x0000b2dc, 0x000cfff0, 0x000cfff0, 0x03aaa352, 0x03aaa352},
-- {0x0000b2e0, 0x000f0000, 0x000f0000, 0x03ccc584, 0x03ccc584},
-- {0x0000b2e4, 0x03f00000, 0x03f00000, 0x03f0f800, 0x03f0f800},
-+ {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
-+ {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
-+ {0x0000a610, 0x00804000, 0x00804000, 0x00000000, 0x00000000},
-+ {0x0000a614, 0x00804201, 0x00804201, 0x01404000, 0x01404000},
-+ {0x0000a618, 0x0280c802, 0x0280c802, 0x01404501, 0x01404501},
-+ {0x0000a61c, 0x0280ca03, 0x0280ca03, 0x02008501, 0x02008501},
-+ {0x0000a620, 0x04c15104, 0x04c15104, 0x0280ca03, 0x0280ca03},
-+ {0x0000a624, 0x04c15305, 0x04c15305, 0x03010c04, 0x03010c04},
-+ {0x0000a628, 0x04c15305, 0x04c15305, 0x04014c04, 0x04014c04},
-+ {0x0000a62c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
-+ {0x0000a630, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
-+ {0x0000a634, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
-+ {0x0000a638, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
-+ {0x0000a63c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
-+ {0x0000b2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352},
-+ {0x0000b2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584},
-+ {0x0000b2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800},
- {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
-- {0x0000c2dc, 0x000cfff0, 0x000cfff0, 0x03aaa352, 0x03aaa352},
-- {0x0000c2e0, 0x000f0000, 0x000f0000, 0x03ccc584, 0x03ccc584},
-- {0x0000c2e4, 0x03f00000, 0x03f00000, 0x03f0f800, 0x03f0f800},
-+ {0x0000c2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352},
-+ {0x0000c2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584},
-+ {0x0000c2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800},
- {0x0000c2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
-- {0x00016044, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
-- {0x00016048, 0x61200001, 0x61200001, 0x66480001, 0x66480001},
-- {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
-- {0x00016444, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
-- {0x00016448, 0x61200001, 0x61200001, 0x66480001, 0x66480001},
-- {0x00016468, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
-- {0x00016844, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
-- {0x00016848, 0x61200001, 0x61200001, 0x66480001, 0x66480001},
-- {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
-+ {0x00016044, 0x056db2e6, 0x056db2e6, 0x056db2e6, 0x056db2e6},
-+ {0x00016048, 0xae480001, 0xae480001, 0xae480001, 0xae480001},
-+ {0x00016068, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c},
-+ {0x00016444, 0x056db2e6, 0x056db2e6, 0x056db2e6, 0x056db2e6},
-+ {0x00016448, 0xae480001, 0xae480001, 0xae480001, 0xae480001},
-+ {0x00016468, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c},
-+ {0x00016844, 0x056db2e6, 0x056db2e6, 0x056db2e6, 0x056db2e6},
-+ {0x00016848, 0xae480001, 0xae480001, 0xae480001, 0xae480001},
-+ {0x00016868, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c},
- };
-
- static const u32 ar9300Modes_high_ob_db_tx_gain_table_2p2[][5] = {
diff --git a/package/mac80211/patches/541-ath9k_extra_platform_leds.patch b/package/mac80211/patches/531-ath9k_extra_platform_leds.patch
index ac8ee533d9..c64c89a369 100644
--- a/package/mac80211/patches/541-ath9k_extra_platform_leds.patch
+++ b/package/mac80211/patches/531-ath9k_extra_platform_leds.patch
@@ -56,7 +56,7 @@
INIT_LIST_HEAD(&sc->leds);
-@@ -133,6 +154,12 @@ void ath_init_leds(struct ath_softc *sc)
+@@ -120,6 +141,12 @@ void ath_init_leds(struct ath_softc *sc)
trigger = ieee80211_get_radio_led_name(sc->hw);
ath_create_gpio_led(sc, sc->sc_ah->led_pin, led_name, trigger, 1);
@@ -67,5 +67,5 @@
+ for (i = 0; i < pdata->num_leds; i++)
+ ath_create_platform_led(sc, &pdata->leds[i]);
}
- #endif
+ void ath_fill_led_pin(struct ath_softc *sc)
diff --git a/package/mac80211/patches/550-mac80211_optimize_mcs_rate_mask.patch b/package/mac80211/patches/540-mac80211_optimize_mcs_rate_mask.patch
index eb46f53f45..347c920135 100644
--- a/package/mac80211/patches/550-mac80211_optimize_mcs_rate_mask.patch
+++ b/package/mac80211/patches/540-mac80211_optimize_mcs_rate_mask.patch
@@ -1,6 +1,6 @@
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
-@@ -715,6 +715,8 @@ struct ieee80211_sub_if_data {
+@@ -739,6 +739,8 @@ struct ieee80211_sub_if_data {
/* bitmap of allowed (non-MCS) rate indexes for rate control */
u32 rc_rateidx_mask[IEEE80211_NUM_BANDS];
@@ -11,7 +11,7 @@
union {
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
-@@ -2160,9 +2160,20 @@ static int ieee80211_set_bitrate_mask(st
+@@ -2386,9 +2386,20 @@ static int ieee80211_set_bitrate_mask(st
}
for (i = 0; i < IEEE80211_NUM_BANDS; i++) {
@@ -34,7 +34,7 @@
return 0;
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
-@@ -3721,7 +3721,7 @@ void ieee80211_send_bar(struct ieee80211
+@@ -4091,7 +4091,7 @@ void ieee80211_send_bar(struct ieee80211
* (deprecated; this will be removed once drivers get updated to use
* rate_idx_mask)
* @rate_idx_mask: user-requested (legacy) rate mask
@@ -43,7 +43,7 @@
* @bss: whether this frame is sent out in AP or IBSS mode
*/
struct ieee80211_tx_rate_control {
-@@ -3733,7 +3733,7 @@ struct ieee80211_tx_rate_control {
+@@ -4103,7 +4103,7 @@ struct ieee80211_tx_rate_control {
bool rts, short_preamble;
u8 max_rate_idx;
u32 rate_idx_mask;
@@ -54,7 +54,7 @@
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
-@@ -631,9 +631,11 @@ ieee80211_tx_h_rate_ctrl(struct ieee8021
+@@ -641,9 +641,11 @@ ieee80211_tx_h_rate_ctrl(struct ieee8021
txrc.max_rate_idx = -1;
else
txrc.max_rate_idx = fls(txrc.rate_idx_mask) - 1;
@@ -69,7 +69,7 @@
txrc.bss = (tx->sdata->vif.type == NL80211_IFTYPE_AP ||
tx->sdata->vif.type == NL80211_IFTYPE_MESH_POINT ||
tx->sdata->vif.type == NL80211_IFTYPE_ADHOC);
-@@ -2452,8 +2454,6 @@ struct sk_buff *ieee80211_beacon_get_tim
+@@ -2511,8 +2513,6 @@ struct sk_buff *ieee80211_beacon_get_tim
txrc.max_rate_idx = -1;
else
txrc.max_rate_idx = fls(txrc.rate_idx_mask) - 1;
@@ -80,7 +80,7 @@
--- a/net/mac80211/rate.c
+++ b/net/mac80211/rate.c
-@@ -461,9 +461,12 @@ void rate_control_get_rate(struct ieee80
+@@ -460,9 +460,12 @@ void rate_control_get_rate(struct ieee80
* the common case.
*/
mask = sdata->rc_rateidx_mask[info->band];
diff --git a/package/mac80211/patches/551-ath9k_optimize_interrupt_mitigation.patch b/package/mac80211/patches/541-ath9k_optimize_interrupt_mitigation.patch
index 2afc4deb43..95ceb3575d 100644
--- a/package/mac80211/patches/551-ath9k_optimize_interrupt_mitigation.patch
+++ b/package/mac80211/patches/541-ath9k_optimize_interrupt_mitigation.patch
@@ -1,6 +1,6 @@
--- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
-@@ -240,21 +240,19 @@ static bool ar9003_hw_get_isr(struct ath
+@@ -241,21 +241,19 @@ static bool ar9003_hw_get_isr(struct ath
*masked = isr & ATH9K_INT_COMMON;
diff --git a/package/mac80211/patches/560-ath9k_reduce_ani_interval.patch b/package/mac80211/patches/550-ath9k_reduce_ani_interval.patch
index e2a0d124a3..e2a0d124a3 100644
--- a/package/mac80211/patches/560-ath9k_reduce_ani_interval.patch
+++ b/package/mac80211/patches/550-ath9k_reduce_ani_interval.patch
diff --git a/package/mac80211/patches/561-ath9k_revert_initval_change.patch b/package/mac80211/patches/551-ath9k_revert_initval_change.patch
index ffb08bfbbd..ffb08bfbbd 100644
--- a/package/mac80211/patches/561-ath9k_revert_initval_change.patch
+++ b/package/mac80211/patches/551-ath9k_revert_initval_change.patch
diff --git a/package/mac80211/patches/563-ath9k_rx_dma_stop_check.patch b/package/mac80211/patches/552-ath9k_rx_dma_stop_check.patch
index 606eb1c63d..606eb1c63d 100644
--- a/package/mac80211/patches/563-ath9k_rx_dma_stop_check.patch
+++ b/package/mac80211/patches/552-ath9k_rx_dma_stop_check.patch
diff --git a/package/mac80211/patches/564-ath9k_debugfs_diag.patch b/package/mac80211/patches/553-ath9k_debugfs_diag.patch
index 3c7881dbd4..9618698f54 100644
--- a/package/mac80211/patches/564-ath9k_debugfs_diag.patch
+++ b/package/mac80211/patches/553-ath9k_debugfs_diag.patch
@@ -1,6 +1,6 @@
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
-@@ -1677,6 +1677,50 @@ static const struct file_operations fops
+@@ -2149,6 +2149,50 @@ static const struct file_operations fops
};
@@ -51,18 +51,18 @@
int ath9k_init_debug(struct ath_hw *ah)
{
struct ath_common *common = ath9k_hw_common(ah);
-@@ -1759,5 +1803,8 @@ int ath9k_init_debug(struct ath_hw *ah)
- debugfs_create_file("chanbw", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
- sc, &fops_chanbw);
-
+@@ -2174,6 +2218,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
+ debugfs_create_file("diag", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
+ sc, &fops_diag);
-+
- return 0;
- }
+ debugfs_create_file("dma", S_IRUSR, sc->debug.debugfs_phy, sc,
+ &fops_dma);
+ 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
-@@ -498,6 +498,12 @@ enum {
+@@ -500,6 +500,12 @@ enum {
ATH9K_RESET_COLD,
};
@@ -75,16 +75,16 @@
struct ath9k_hw_version {
u32 magic;
u16 devid;
-@@ -741,6 +747,8 @@ struct ath_hw {
+@@ -778,6 +784,8 @@ struct ath_hw {
u32 rfkill_polarity;
u32 ah_flags;
+ unsigned long diag;
+
+ bool reset_power_on;
bool htc_reset_init;
- enum nl80211_iftype opmode;
-@@ -1007,6 +1015,7 @@ void ath9k_hw_set_sta_beacon_timers(stru
+@@ -1041,6 +1049,7 @@ void ath9k_hw_set_sta_beacon_timers(stru
bool ath9k_hw_check_alive(struct ath_hw *ah);
bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode);
@@ -94,7 +94,7 @@
void ath9k_debug_sync_cause(struct ath_common *common, u32 sync_cause);
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
-@@ -1751,6 +1751,20 @@ fail:
+@@ -1747,6 +1747,20 @@ fail:
return -EINVAL;
}
@@ -115,17 +115,17 @@
int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
struct ath9k_hw_cal_data *caldata, bool fastcc)
{
-@@ -2028,6 +2042,7 @@ int ath9k_hw_reset(struct ath_hw *ah, st
+@@ -2023,6 +2037,7 @@ int ath9k_hw_reset(struct ath_hw *ah, st
}
ath9k_hw_apply_gpio_override(ah);
+ ath9k_hw_update_diag(ah);
- return 0;
- }
+ if (AR_SREV_9565(ah) && ah->shared_chain_lnadiv)
+ 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
-@@ -469,6 +469,11 @@ irqreturn_t ath_isr(int irq, void *dev)
+@@ -459,6 +459,11 @@ irqreturn_t ath_isr(int irq, void *dev)
ath9k_hw_getisr(ah, &status); /* NB: clears ISR too */
status &= ah->imask; /* discard unasked-for bits */
diff --git a/package/mac80211/patches/567-ath9k_ani_mrc_fix.patch b/package/mac80211/patches/554-ath9k_ani_mrc_fix.patch
index 80c9b2a3e1..6edc8efc02 100644
--- a/package/mac80211/patches/567-ath9k_ani_mrc_fix.patch
+++ b/package/mac80211/patches/554-ath9k_ani_mrc_fix.patch
@@ -1,6 +1,6 @@
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
-@@ -1035,6 +1035,10 @@ static bool ar9003_hw_ani_control(struct
+@@ -1075,6 +1075,10 @@ static bool ar9003_hw_ani_control(struct
* is_on == 0 means MRC CCK is OFF (more noise imm)
*/
bool is_on = param ? 1 : 0;
diff --git a/package/mac80211/patches/b01-ath9k-allow-to-disable-bands-via-platform-data.patch b/package/mac80211/patches/555-ath9k-allow-to-disable-bands-via-platform-data.patch
index 8b4ddefe91..a6cb089b76 100644
--- a/package/mac80211/patches/b01-ath9k-allow-to-disable-bands-via-platform-data.patch
+++ b/package/mac80211/patches/555-ath9k-allow-to-disable-bands-via-platform-data.patch
@@ -12,7 +12,7 @@
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
-@@ -2415,17 +2415,25 @@ int ath9k_hw_fill_cap_info(struct ath_hw
+@@ -2413,17 +2413,25 @@ int ath9k_hw_fill_cap_info(struct ath_hw
}
eeval = ah->eep_ops->get_eeprom(ah, EEP_OP_MODE);
@@ -44,22 +44,22 @@
+ return -EINVAL;
+ }
- if (AR_SREV_9485(ah) || AR_SREV_9285(ah) || AR_SREV_9330(ah))
- chip_chainmask = 1;
+ if (AR_SREV_9485(ah) ||
+ AR_SREV_9285(ah) ||
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
-@@ -927,6 +927,8 @@ struct ath_hw {
+@@ -961,6 +961,8 @@ struct ath_hw {
bool is_clk_25mhz;
int (*get_mac_revision)(void);
int (*external_reset)(void);
+ bool disable_2ghz;
+ bool disable_5ghz;
- };
- struct ath_bus_ops {
+ const struct firmware *eeprom_blob;
+ };
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
-@@ -537,6 +537,8 @@ static int ath9k_init_softc(u16 devid, s
+@@ -587,6 +587,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;
diff --git a/package/mac80211/patches/562-ath9k_add_idle_hack.patch b/package/mac80211/patches/562-ath9k_add_idle_hack.patch
deleted file mode 100644
index 7c3c0426be..0000000000
--- a/package/mac80211/patches/562-ath9k_add_idle_hack.patch
+++ /dev/null
@@ -1,20 +0,0 @@
---- a/drivers/net/wireless/ath/ath9k/main.c
-+++ b/drivers/net/wireless/ath/ath9k/main.c
-@@ -1080,6 +1080,7 @@ static void ath9k_remove_interface(struc
- ath9k_calculate_summary_state(hw, NULL);
-
- mutex_unlock(&sc->mutex);
-+ ath9k_config(hw, IEEE80211_CONF_CHANGE_IDLE);
- ath9k_ps_restore(sc);
- }
-
-@@ -1132,7 +1133,8 @@ int ath9k_config(struct ieee80211_hw *hw
- mutex_lock(&sc->mutex);
-
- if (changed & IEEE80211_CONF_CHANGE_IDLE) {
-- sc->ps_idle = !!(conf->flags & IEEE80211_CONF_IDLE);
-+ sc->ps_idle = !!(conf->flags & IEEE80211_CONF_IDLE) &&
-+ !sc->nvifs;
- if (sc->ps_idle) {
- ath_cancel_work(sc);
- ath9k_stop_btcoex(sc);
diff --git a/package/mac80211/patches/565-ath9k_disable_paprd.patch b/package/mac80211/patches/565-ath9k_disable_paprd.patch
deleted file mode 100644
index 523ac97122..0000000000
--- a/package/mac80211/patches/565-ath9k_disable_paprd.patch
+++ /dev/null
@@ -1,72 +0,0 @@
---- a/drivers/net/wireless/ath/ath9k/debug.c
-+++ b/drivers/net/wireless/ath/ath9k/debug.c
-@@ -1766,6 +1766,8 @@ int ath9k_init_debug(struct ath_hw *ah)
- sc->debug.debugfs_phy, sc, &fops_tx_chainmask);
- debugfs_create_file("disable_ani", S_IRUSR | S_IWUSR,
- sc->debug.debugfs_phy, sc, &fops_disable_ani);
-+ debugfs_create_bool("paprd", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
-+ &sc->sc_ah->config.enable_paprd);
- debugfs_create_file("regidx", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
- sc, &fops_regidx);
- debugfs_create_file("regval", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
---- a/drivers/net/wireless/ath/ath9k/hw.c
-+++ b/drivers/net/wireless/ath/ath9k/hw.c
-@@ -2523,10 +2523,6 @@ int ath9k_hw_fill_cap_info(struct ath_hw
- pCap->rx_status_len = sizeof(struct ar9003_rxs);
- pCap->tx_desc_len = sizeof(struct ar9003_txc);
- pCap->txs_len = sizeof(struct ar9003_txs);
-- if (!ah->config.paprd_disable &&
-- ah->eep_ops->get_eeprom(ah, EEP_PAPRD) &&
-- !AR_SREV_9462(ah))
-- pCap->hw_caps |= ATH9K_HW_CAP_PAPRD;
- } else {
- pCap->tx_desc_len = sizeof(struct ath_desc);
- if (AR_SREV_9280_20(ah))
---- a/drivers/net/wireless/ath/ath9k/hw.h
-+++ b/drivers/net/wireless/ath/ath9k/hw.h
-@@ -236,7 +236,6 @@ enum ath9k_hw_caps {
- ATH9K_HW_CAP_LDPC = BIT(6),
- ATH9K_HW_CAP_FASTCLOCK = BIT(7),
- ATH9K_HW_CAP_SGI_20 = BIT(8),
-- ATH9K_HW_CAP_PAPRD = BIT(9),
- ATH9K_HW_CAP_ANT_DIV_COMB = BIT(10),
- ATH9K_HW_CAP_2GHZ = BIT(11),
- ATH9K_HW_CAP_5GHZ = BIT(12),
-@@ -287,12 +286,12 @@ struct ath9k_ops_config {
- u8 pcie_clock_req;
- u32 pcie_waen;
- u8 analog_shiftreg;
-- u8 paprd_disable;
- u32 ofdm_trig_low;
- u32 ofdm_trig_high;
- u32 cck_trig_high;
- u32 cck_trig_low;
- u32 enable_ani;
-+ u32 enable_paprd;
- int serialize_regmode;
- bool rx_intr_mitigation;
- bool tx_intr_mitigation;
---- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
-+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
-@@ -2982,6 +2982,10 @@ static u32 ath9k_hw_ar9300_get_eeprom(st
- case EEP_RX_MASK:
- return pBase->txrxMask & 0xf;
- case EEP_PAPRD:
-+ if (AR_SREV_9462(ah))
-+ return false;
-+ if (!ah->config.enable_paprd);
-+ return false;
- return !!(pBase->featureEnable & BIT(5));
- case EEP_CHAIN_MASK_REDUCE:
- return (pBase->miscConfiguration >> 0x3) & 0x1;
---- a/drivers/net/wireless/ath/ath9k/link.c
-+++ b/drivers/net/wireless/ath/ath9k/link.c
-@@ -423,7 +423,7 @@ set_timer:
- cal_interval = min(cal_interval, (u32)short_cal_interval);
-
- mod_timer(&common->ani.timer, jiffies + msecs_to_jiffies(cal_interval));
-- if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_PAPRD) && ah->caldata) {
-+ if (ah->eep_ops->get_eeprom(ah, EEP_PAPRD) && ah->caldata) {
- if (!ah->caldata->paprd_done)
- ieee80211_queue_work(sc->hw, &sc->paprd_work);
- else if (!ah->paprd_table_write_done)
diff --git a/package/mac80211/patches/566-ath9k_use_ieee80211_free_txskb.patch b/package/mac80211/patches/566-ath9k_use_ieee80211_free_txskb.patch
deleted file mode 100644
index 3b75ab5da3..0000000000
--- a/package/mac80211/patches/566-ath9k_use_ieee80211_free_txskb.patch
+++ /dev/null
@@ -1,149 +0,0 @@
---- a/drivers/net/wireless/ath/ath9k/xmit.c
-+++ b/drivers/net/wireless/ath/ath9k/xmit.c
-@@ -66,8 +66,7 @@ static void ath_tx_update_baw(struct ath
- static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc,
- struct ath_txq *txq,
- struct ath_atx_tid *tid,
-- struct sk_buff *skb,
-- bool dequeue);
-+ struct sk_buff *skb);
-
- enum {
- MCS_HT20,
-@@ -176,7 +175,15 @@ static void ath_tx_flush_tid(struct ath_
- fi = get_frame_info(skb);
- bf = fi->bf;
-
-- if (bf && fi->retries) {
-+ if (!bf) {
-+ bf = ath_tx_setup_buffer(sc, txq, tid, skb);
-+ if (!bf) {
-+ ieee80211_free_txskb(sc->hw, skb);
-+ continue;
-+ }
-+ }
-+
-+ if (fi->retries) {
- list_add_tail(&bf->list, &bf_head);
- ath_tx_update_baw(sc, tid, bf->bf_state.seqno);
- ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0);
-@@ -789,10 +796,13 @@ static enum ATH_AGGR_STATUS ath_tx_form_
- fi = get_frame_info(skb);
- bf = fi->bf;
- if (!fi->bf)
-- bf = ath_tx_setup_buffer(sc, txq, tid, skb, true);
-+ bf = ath_tx_setup_buffer(sc, txq, tid, skb);
-
-- if (!bf)
-+ if (!bf) {
-+ __skb_unlink(skb, &tid->buf_q);
-+ ieee80211_free_txskb(sc->hw, skb);
- continue;
-+ }
-
- bf->bf_state.bf_type = BUF_AMPDU | BUF_AGGR;
- seqno = bf->bf_state.seqno;
-@@ -1735,9 +1745,11 @@ static void ath_tx_send_ampdu(struct ath
- return;
- }
-
-- bf = ath_tx_setup_buffer(sc, txctl->txq, tid, skb, false);
-- if (!bf)
-+ bf = ath_tx_setup_buffer(sc, txctl->txq, tid, skb);
-+ if (!bf) {
-+ ieee80211_free_txskb(sc->hw, skb);
- return;
-+ }
-
- bf->bf_state.bf_type = BUF_AMPDU;
- INIT_LIST_HEAD(&bf_head);
-@@ -1761,11 +1773,6 @@ static void ath_tx_send_normal(struct at
- struct ath_buf *bf;
-
- bf = fi->bf;
-- if (!bf)
-- bf = ath_tx_setup_buffer(sc, txq, tid, skb, false);
--
-- if (!bf)
-- return;
-
- INIT_LIST_HEAD(&bf_head);
- list_add_tail(&bf->list, &bf_head);
-@@ -1839,8 +1846,7 @@ u8 ath_txchainmask_reduction(struct ath_
- static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc,
- struct ath_txq *txq,
- struct ath_atx_tid *tid,
-- struct sk_buff *skb,
-- bool dequeue)
-+ struct sk_buff *skb)
- {
- struct ath_common *common = ath9k_hw_common(sc->sc_ah);
- struct ath_frame_info *fi = get_frame_info(skb);
-@@ -1852,7 +1858,7 @@ static struct ath_buf *ath_tx_setup_buff
- bf = ath_tx_get_buffer(sc);
- if (!bf) {
- ath_dbg(common, XMIT, "TX buffers are full\n");
-- goto error;
-+ return NULL;
- }
-
- ATH_TXBUF_RESET(bf);
-@@ -1881,18 +1887,12 @@ static struct ath_buf *ath_tx_setup_buff
- ath_err(ath9k_hw_common(sc->sc_ah),
- "dma_mapping_error() on TX\n");
- ath_tx_return_buffer(sc, bf);
-- goto error;
-+ return NULL;
- }
-
- fi->bf = bf;
-
- return bf;
--
--error:
-- if (dequeue)
-- __skb_unlink(skb, &tid->buf_q);
-- dev_kfree_skb_any(skb);
-- return NULL;
- }
-
- /* FIXME: tx power */
-@@ -1921,9 +1921,14 @@ static void ath_tx_start_dma(struct ath_
- */
- ath_tx_send_ampdu(sc, tid, skb, txctl);
- } else {
-- bf = ath_tx_setup_buffer(sc, txctl->txq, tid, skb, false);
-- if (!bf)
-+ bf = ath_tx_setup_buffer(sc, txctl->txq, tid, skb);
-+ if (!bf) {
-+ if (txctl->paprd)
-+ dev_kfree_skb_any(skb);
-+ else
-+ ieee80211_free_txskb(sc->hw, skb);
- return;
-+ }
-
- bf->bf_state.bfs_paprd = txctl->paprd;
-
---- a/drivers/net/wireless/ath/ath9k/main.c
-+++ b/drivers/net/wireless/ath/ath9k/main.c
-@@ -768,7 +768,7 @@ static void ath9k_tx(struct ieee80211_hw
-
- return;
- exit:
-- dev_kfree_skb_any(skb);
-+ ieee80211_free_txskb(hw, skb);
- }
-
- static void ath9k_stop(struct ieee80211_hw *hw)
---- a/drivers/net/wireless/ath/ath9k/beacon.c
-+++ b/drivers/net/wireless/ath/ath9k/beacon.c
-@@ -120,7 +120,7 @@ static void ath9k_tx_cabq(struct ieee802
-
- if (ath_tx_start(hw, skb, &txctl) != 0) {
- ath_dbg(common, XMIT, "CABQ TX failed\n");
-- dev_kfree_skb_any(skb);
-+ ieee80211_free_txskb(hw, skb);
- }
- }
-
diff --git a/package/mac80211/patches/568-ath9k_fix_stale_pointer.patch b/package/mac80211/patches/568-ath9k_fix_stale_pointer.patch
deleted file mode 100644
index 183553d3cc..0000000000
--- a/package/mac80211/patches/568-ath9k_fix_stale_pointer.patch
+++ /dev/null
@@ -1,18 +0,0 @@
---- a/drivers/net/wireless/ath/ath9k/xmit.c
-+++ b/drivers/net/wireless/ath/ath9k/xmit.c
-@@ -312,6 +312,7 @@ static struct ath_buf *ath_tx_get_buffer
- }
-
- bf = list_first_entry(&sc->tx.txbuf, struct ath_buf, list);
-+ bf->bf_next = NULL;
- list_del(&bf->list);
-
- spin_unlock_bh(&sc->tx.txbuflock);
-@@ -1778,6 +1779,7 @@ static void ath_tx_send_normal(struct at
- list_add_tail(&bf->list, &bf_head);
- bf->bf_state.bf_type = 0;
-
-+ bf->bf_next = NULL;
- bf->bf_lastbf = bf;
- ath_tx_fill_desc(sc, bf, txq, fi->framelen);
- ath_tx_txqaddbuf(sc, txq, &bf_head, false);
diff --git a/package/mac80211/patches/603-rt2x00-introduce-rt2x00eeprom.patch b/package/mac80211/patches/603-rt2x00-introduce-rt2x00eeprom.patch
index 4f35ae899f..07e72e39f4 100644
--- a/package/mac80211/patches/603-rt2x00-introduce-rt2x00eeprom.patch
+++ b/package/mac80211/patches/603-rt2x00-introduce-rt2x00eeprom.patch
@@ -101,7 +101,7 @@
+}
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
-@@ -560,6 +560,7 @@ struct rt2x00lib_ops {
+@@ -559,6 +559,7 @@ struct rt2x00lib_ops {
const u8 *data, const size_t len);
int (*load_firmware) (struct rt2x00_dev *rt2x00dev,
const u8 *data, const size_t len);
@@ -109,7 +109,7 @@
/*
* Device initialization/deinitialization handlers.
-@@ -721,6 +722,7 @@ enum rt2x00_capability_flags {
+@@ -719,6 +720,7 @@ enum rt2x00_capability_flags {
REQUIRE_SW_SEQNO,
REQUIRE_HT_TX_DESC,
REQUIRE_PS_AUTOWAKE,
@@ -117,7 +117,7 @@
/*
* Capabilities
-@@ -976,6 +978,11 @@ struct rt2x00_dev {
+@@ -988,6 +990,11 @@ struct rt2x00_dev {
const struct firmware *fw;
/*
@@ -186,29 +186,34 @@
obj-$(CONFIG_RT2X00_LIB_PCI) += rt2x00pci.o
--- a/drivers/net/wireless/rt2x00/rt2800pci.c
+++ b/drivers/net/wireless/rt2x00/rt2800pci.c
-@@ -89,20 +89,10 @@ static void rt2800pci_mcu_status(struct
+@@ -89,25 +89,11 @@ static void rt2800pci_mcu_status(struct
rt2x00pci_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0);
}
-#if defined(CONFIG_RALINK_RT288X) || defined(CONFIG_RALINK_RT305X)
- static void rt2800pci_read_eeprom_soc(struct rt2x00_dev *rt2x00dev)
+ static int rt2800pci_read_eeprom_soc(struct rt2x00_dev *rt2x00dev)
{
- void __iomem *base_addr = ioremap(0x1F040000, EEPROM_SIZE);
-
+- if (!base_addr)
+- return -ENOMEM;
+-
- memcpy_fromio(rt2x00dev->eeprom, base_addr, EEPROM_SIZE);
-
- iounmap(base_addr);
+ memcpy(rt2x00dev->eeprom, rt2x00dev->eeprom_file->data, EEPROM_SIZE);
+ return 0;
}
-#else
--static inline void rt2800pci_read_eeprom_soc(struct rt2x00_dev *rt2x00dev)
+-static inline int rt2800pci_read_eeprom_soc(struct rt2x00_dev *rt2x00dev)
-{
+- return -ENOMEM;
-}
-#endif /* CONFIG_RALINK_RT288X || CONFIG_RALINK_RT305X */
#ifdef CONFIG_PCI
static void rt2800pci_eepromregister_read(struct eeprom_93cx6 *eeprom)
-@@ -322,6 +312,20 @@ static int rt2800pci_write_firmware(stru
+@@ -331,6 +317,20 @@ static int rt2800pci_write_firmware(stru
}
/*
@@ -229,7 +234,7 @@
* Initialization functions.
*/
static bool rt2800pci_get_entry_state(struct queue_entry *entry)
-@@ -1033,6 +1037,7 @@ static const struct rt2x00lib_ops rt2800
+@@ -1046,6 +1046,7 @@ static const struct rt2x00lib_ops rt2800
.get_firmware_name = rt2800pci_get_firmware_name,
.check_firmware = rt2800_check_firmware,
.load_firmware = rt2800_load_firmware,
@@ -239,7 +244,7 @@
.get_entry_state = rt2800pci_get_entry_state,
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
-@@ -1163,6 +1163,10 @@ int rt2x00lib_probe_dev(struct rt2x00_de
+@@ -1318,6 +1318,10 @@ int rt2x00lib_probe_dev(struct rt2x00_de
rt2x00dev->hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
@@ -250,7 +255,7 @@
/*
* Initialize work.
*/
-@@ -1287,6 +1291,11 @@ void rt2x00lib_remove_dev(struct rt2x00_
+@@ -1442,6 +1446,11 @@ void rt2x00lib_remove_dev(struct rt2x00_
*/
if (rt2x00dev->drv_data)
kfree(rt2x00dev->drv_data);
diff --git a/package/mac80211/patches/604-rt2x00-add-CONFIG_RT2X00_LIB_EEPROM-option.patch b/package/mac80211/patches/604-rt2x00-add-CONFIG_RT2X00_LIB_EEPROM-option.patch
index 5331b2678d..d9f17646c7 100644
--- a/package/mac80211/patches/604-rt2x00-add-CONFIG_RT2X00_LIB_EEPROM-option.patch
+++ b/package/mac80211/patches/604-rt2x00-add-CONFIG_RT2X00_LIB_EEPROM-option.patch
@@ -1,6 +1,6 @@
--- a/config.mk
+++ b/config.mk
-@@ -624,6 +624,7 @@ export CONFIG_RT2X00=y
+@@ -640,6 +640,7 @@ export CONFIG_RT2X00=y
export CONFIG_RT2X00_LIB=m
export CONFIG_RT2800_LIB=m
export CONFIG_RT2X00_LIB_FIRMWARE=y
diff --git a/package/mac80211/patches/605-rt2x00-pci-eeprom.patch b/package/mac80211/patches/605-rt2x00-pci-eeprom.patch
index fbc86199a4..33eb28f5f6 100644
--- a/package/mac80211/patches/605-rt2x00-pci-eeprom.patch
+++ b/package/mac80211/patches/605-rt2x00-pci-eeprom.patch
@@ -4,22 +4,22 @@
rt2x00pci_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0);
}
--static void rt2800pci_read_eeprom_soc(struct rt2x00_dev *rt2x00dev)
-+static void rt2800pci_read_eeprom_file(struct rt2x00_dev *rt2x00dev)
+-static int rt2800pci_read_eeprom_soc(struct rt2x00_dev *rt2x00dev)
++static int rt2800pci_read_eeprom_file(struct rt2x00_dev *rt2x00dev)
{
memcpy(rt2x00dev->eeprom, rt2x00dev->eeprom_file->data, EEPROM_SIZE);
- }
-@@ -976,8 +976,9 @@ static irqreturn_t rt2800pci_interrupt(i
- */
- static void rt2800pci_read_eeprom(struct rt2x00_dev *rt2x00dev)
+ return 0;
+@@ -983,8 +983,9 @@ static int rt2800pci_read_eeprom(struct
{
+ int retval;
+
- if (rt2x00_is_soc(rt2x00dev))
-- rt2800pci_read_eeprom_soc(rt2x00dev);
+- retval = rt2800pci_read_eeprom_soc(rt2x00dev);
+ if (rt2x00_is_soc(rt2x00dev) ||
+ test_bit(REQUIRE_EEPROM_FILE, &rt2x00dev->cap_flags))
-+ rt2800pci_read_eeprom_file(rt2x00dev);
++ retval = rt2800pci_read_eeprom_file(rt2x00dev);
else if (rt2800pci_efuse_detect(rt2x00dev))
- rt2800pci_read_eeprom_efuse(rt2x00dev);
+ retval = rt2800pci_read_eeprom_efuse(rt2x00dev);
else
--- a/drivers/net/wireless/rt2x00/rt2x00pci.c
+++ b/drivers/net/wireless/rt2x00/rt2x00pci.c
diff --git a/package/mac80211/patches/606-rt2x00_no_realign.patch b/package/mac80211/patches/606-rt2x00_no_realign.patch
index e0a920a582..202570157e 100644
--- a/package/mac80211/patches/606-rt2x00_no_realign.patch
+++ b/package/mac80211/patches/606-rt2x00_no_realign.patch
@@ -24,7 +24,7 @@ Helmut
--- a/drivers/net/wireless/rt2x00/rt2x00queue.c
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.c
-@@ -151,36 +151,14 @@ void rt2x00queue_align_frame(struct sk_b
+@@ -162,36 +162,14 @@ void rt2x00queue_align_frame(struct sk_b
void rt2x00queue_insert_l2pad(struct sk_buff *skb, unsigned int header_length)
{
unsigned int payload_length = skb->len - header_length;
diff --git a/package/mac80211/patches/607-rt2x00-allow_disabling_bands_through_platform_data.patch b/package/mac80211/patches/607-rt2x00-allow_disabling_bands_through_platform_data.patch
index 57abb07ab6..0b0c30ed0e 100644
--- a/package/mac80211/patches/607-rt2x00-allow_disabling_bands_through_platform_data.patch
+++ b/package/mac80211/patches/607-rt2x00-allow_disabling_bands_through_platform_data.patch
@@ -12,7 +12,7 @@
#endif /* _RT2X00_PLATFORM_H */
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
-@@ -834,6 +834,22 @@ static int rt2x00lib_probe_hw_modes(stru
+@@ -939,6 +939,22 @@ static int rt2x00lib_probe_hw_modes(stru
unsigned int num_rates;
unsigned int i;
@@ -37,7 +37,7 @@
num_rates += 4;
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
-@@ -425,6 +425,7 @@ struct hw_mode_spec {
+@@ -424,6 +424,7 @@ struct hw_mode_spec {
unsigned int supported_bands;
#define SUPPORT_BAND_2GHZ 0x00000001
#define SUPPORT_BAND_5GHZ 0x00000002
diff --git a/package/mac80211/patches/608-add_platform_data_mac_addr.patch b/package/mac80211/patches/608-add_platform_data_mac_addr.patch
index c1b22e7a25..bb77df9e7d 100644
--- a/package/mac80211/patches/608-add_platform_data_mac_addr.patch
+++ b/package/mac80211/patches/608-add_platform_data_mac_addr.patch
@@ -10,7 +10,7 @@
int disable_5ghz;
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
-@@ -825,6 +825,18 @@ static void rt2x00lib_rate(struct ieee80
+@@ -930,6 +930,18 @@ static void rt2x00lib_rate(struct ieee80
entry->flags |= IEEE80211_RATE_SHORT_PREAMBLE;
}
@@ -31,7 +31,7 @@
{
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
-@@ -1280,6 +1280,7 @@ static inline void rt2x00debug_dump_fram
+@@ -1314,6 +1314,7 @@ static inline void rt2x00debug_dump_fram
*/
u32 rt2x00lib_get_bssidx(struct rt2x00_dev *rt2x00dev,
struct ieee80211_vif *vif);
diff --git a/package/mac80211/patches/610-rt2x00-fix-rt3352-ext-pa.patch b/package/mac80211/patches/610-rt2x00-fix-rt3352-ext-pa.patch
new file mode 100644
index 0000000000..bf070e68f3
--- /dev/null
+++ b/package/mac80211/patches/610-rt2x00-fix-rt3352-ext-pa.patch
@@ -0,0 +1,214 @@
+--- a/drivers/net/wireless/rt2x00/rt2800lib.c
++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
+@@ -2249,15 +2249,18 @@ static void rt2800_config_channel(struct
+ /*
+ * Change BBP settings
+ */
++ rt2800_bbp_write(rt2x00dev, 62, 0x37 - rt2x00dev->lna_gain);
++ rt2800_bbp_write(rt2x00dev, 63, 0x37 - rt2x00dev->lna_gain);
++ rt2800_bbp_write(rt2x00dev, 64, 0x37 - rt2x00dev->lna_gain);
++
+ if (rt2x00_rt(rt2x00dev, RT3352)) {
+ rt2800_bbp_write(rt2x00dev, 27, 0x0);
+ rt2800_bbp_write(rt2x00dev, 66, 0x26 + rt2x00dev->lna_gain);
+ rt2800_bbp_write(rt2x00dev, 27, 0x20);
+ rt2800_bbp_write(rt2x00dev, 66, 0x26 + rt2x00dev->lna_gain);
++ rt2800_bbp_write(rt2x00dev, 86, 0x38);
++ rt2800_bbp_write(rt2x00dev, 83, 0x6a);
+ } else {
+- rt2800_bbp_write(rt2x00dev, 62, 0x37 - rt2x00dev->lna_gain);
+- rt2800_bbp_write(rt2x00dev, 63, 0x37 - rt2x00dev->lna_gain);
+- rt2800_bbp_write(rt2x00dev, 64, 0x37 - rt2x00dev->lna_gain);
+ rt2800_bbp_write(rt2x00dev, 86, 0);
+ }
+
+@@ -3670,6 +3673,7 @@ static int rt2800_init_bbp(struct rt2x00
+ rt2800_bbp_write(rt2x00dev, 120, 0x50);
+
+ if (rt2x00_rt(rt2x00dev, RT3290) ||
++ rt2x00_rt(rt2x00dev, RT3352) ||
+ rt2x00_rt(rt2x00dev, RT5390) ||
+ rt2x00_rt(rt2x00dev, RT5392))
+ rt2800_bbp_write(rt2x00dev, 128, 0x12);
+@@ -3976,6 +3980,12 @@ static void rt2800_init_rfcsr_3290(struc
+
+ static void rt2800_init_rfcsr_3352(struct rt2x00_dev *rt2x00dev)
+ {
++ int tx0_int_pa = test_bit(CAPABILITY_INTERNAL_PA_TX0,
++ &rt2x00dev->cap_flags);
++ int tx1_int_pa = test_bit(CAPABILITY_INTERNAL_PA_TX1,
++ &rt2x00dev->cap_flags);
++ u8 rfcsr;
++
+ rt2800_rfcsr_write(rt2x00dev, 0, 0xf0);
+ rt2800_rfcsr_write(rt2x00dev, 1, 0x23);
+ rt2800_rfcsr_write(rt2x00dev, 2, 0x50);
+@@ -4009,15 +4019,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);
+- rt2800_rfcsr_write(rt2x00dev, 34, 0x01);
++ rfcsr = 0x01;
++ if (!tx0_int_pa)
++ rt2x00_set_field8(&rfcsr, RFCSR34_TX0_EXT_PA, 1);
++ if (!tx1_int_pa)
++ rt2x00_set_field8(&rfcsr, RFCSR34_TX1_EXT_PA, 1);
++ rt2800_rfcsr_write(rt2x00dev, 34, rfcsr );
+ rt2800_rfcsr_write(rt2x00dev, 35, 0x03);
+ rt2800_rfcsr_write(rt2x00dev, 36, 0xbd);
+ rt2800_rfcsr_write(rt2x00dev, 37, 0x3c);
+ rt2800_rfcsr_write(rt2x00dev, 38, 0x5f);
+ rt2800_rfcsr_write(rt2x00dev, 39, 0xc5);
+ rt2800_rfcsr_write(rt2x00dev, 40, 0x33);
+- rt2800_rfcsr_write(rt2x00dev, 41, 0x5b);
+- rt2800_rfcsr_write(rt2x00dev, 42, 0x5b);
++ rfcsr = 0x52;
++ if (tx0_int_pa) {
++ rt2x00_set_field8(&rfcsr, RFCSR41_BIT1, 1);
++ rt2x00_set_field8(&rfcsr, RFCSR41_BIT4, 1);
++ }
++ rt2800_rfcsr_write(rt2x00dev, 41, rfcsr);
++ rfcsr = 0x52;
++ if (tx1_int_pa) {
++ rt2x00_set_field8(&rfcsr, RFCSR42_BIT1, 1);
++ rt2x00_set_field8(&rfcsr, RFCSR42_BIT4, 1);
++ }
++ rt2800_rfcsr_write(rt2x00dev, 42, rfcsr);
+ rt2800_rfcsr_write(rt2x00dev, 43, 0xdb);
+ rt2800_rfcsr_write(rt2x00dev, 44, 0xdb);
+ rt2800_rfcsr_write(rt2x00dev, 45, 0xdb);
+@@ -4025,15 +4050,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);
+- rt2800_rfcsr_write(rt2x00dev, 50, 0x2d);
+- rt2800_rfcsr_write(rt2x00dev, 51, 0x7f);
+- rt2800_rfcsr_write(rt2x00dev, 52, 0x00);
+- rt2800_rfcsr_write(rt2x00dev, 53, 0x52);
+- rt2800_rfcsr_write(rt2x00dev, 54, 0x1b);
+- rt2800_rfcsr_write(rt2x00dev, 55, 0x7f);
+- rt2800_rfcsr_write(rt2x00dev, 56, 0x00);
+- rt2800_rfcsr_write(rt2x00dev, 57, 0x52);
+- rt2800_rfcsr_write(rt2x00dev, 58, 0x1b);
++ rfcsr = 0x2d;
++ if (!tx0_int_pa)
++ rt2x00_set_field8(&rfcsr, RFCSR50_TX0_EXT_PA, 1);
++ if (!tx1_int_pa)
++ rt2x00_set_field8(&rfcsr, RFCSR50_TX1_EXT_PA, 1);
++ rt2800_rfcsr_write(rt2x00dev, 50, rfcsr);
++ rt2800_rfcsr_write(rt2x00dev, 51, (tx0_int_pa ? 0x7f : 0x52));
++ rt2800_rfcsr_write(rt2x00dev, 52, (tx0_int_pa ? 0x00 : 0xc0));
++ rt2800_rfcsr_write(rt2x00dev, 53, (tx0_int_pa ? 0x52 : 0xd2));
++ rt2800_rfcsr_write(rt2x00dev, 54, (tx0_int_pa ? 0x1b : 0xc0));
++ rt2800_rfcsr_write(rt2x00dev, 55, (tx1_int_pa ? 0x7f : 0x52));
++ rt2800_rfcsr_write(rt2x00dev, 56, (tx1_int_pa ? 0x00 : 0xc0));
++ rt2800_rfcsr_write(rt2x00dev, 57, (tx0_int_pa ? 0x52 : 0x49));
++ rt2800_rfcsr_write(rt2x00dev, 58, (tx1_int_pa ? 0x1b : 0xc0));
+ rt2800_rfcsr_write(rt2x00dev, 59, 0x00);
+ rt2800_rfcsr_write(rt2x00dev, 60, 0x00);
+ rt2800_rfcsr_write(rt2x00dev, 61, 0x00);
+@@ -4949,7 +4979,8 @@ static int rt2800_init_eeprom(struct rt2
+ /*
+ * Detect if this device has Bluetooth co-existence.
+ */
+- if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_BT_COEXIST))
++ if (!rt2x00_rt(rt2x00dev, RT3352) &&
++ rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_BT_COEXIST))
+ __set_bit(CAPABILITY_BT_COEXIST, &rt2x00dev->cap_flags);
+
+ /*
+@@ -4978,6 +5009,22 @@ static int rt2800_init_eeprom(struct rt2
+ EIRP_MAX_TX_POWER_LIMIT)
+ __set_bit(CAPABILITY_POWER_LIMIT, &rt2x00dev->cap_flags);
+
++ /*
++ * Detect if device uses internal or external PA
++ */
++ rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom);
++
++ if (rt2x00_rt(rt2x00dev, RT3352)) {
++ if (!rt2x00_get_field16(eeprom,
++ EEPROM_NIC_CONF1_EXTERNAL_TX0_PA_3352))
++ __set_bit(CAPABILITY_INTERNAL_PA_TX0,
++ &rt2x00dev->cap_flags);
++ if (!rt2x00_get_field16(eeprom,
++ EEPROM_NIC_CONF1_EXTERNAL_TX1_PA_3352))
++ __set_bit(CAPABILITY_INTERNAL_PA_TX1,
++ &rt2x00dev->cap_flags);
++ }
++
+ return 0;
+ }
+
+--- a/drivers/net/wireless/rt2x00/rt2800.h
++++ b/drivers/net/wireless/rt2x00/rt2800.h
+@@ -2117,6 +2117,12 @@ struct mac_iveiv_entry {
+ #define RFCSR31_RX_CALIB FIELD8(0x7f)
+
+ /*
++ * RFCSR 34:
++ */
++#define RFCSR34_TX0_EXT_PA FIELD8(0x04)
++#define RFCSR34_TX1_EXT_PA FIELD8(0x08)
++
++/*
+ * RFCSR 38:
+ */
+ #define RFCSR38_RX_LO1_EN FIELD8(0x20)
+@@ -2127,6 +2133,18 @@ struct mac_iveiv_entry {
+ #define RFCSR39_RX_LO2_EN FIELD8(0x80)
+
+ /*
++ * RFCSR 41:
++ */
++#define RFCSR41_BIT1 FIELD8(0x01)
++#define RFCSR41_BIT4 FIELD8(0x08)
++
++/*
++ * RFCSR 42:
++ */
++#define RFCSR42_BIT1 FIELD8(0x01)
++#define RFCSR42_BIT4 FIELD8(0x08)
++
++/*
+ * RFCSR 49:
+ */
+ #define RFCSR49_TX FIELD8(0x3f)
+@@ -2135,6 +2153,8 @@ struct mac_iveiv_entry {
+ * RFCSR 50:
+ */
+ #define RFCSR50_TX FIELD8(0x3f)
++#define RFCSR50_TX0_EXT_PA FIELD8(0x02)
++#define RFCSR50_TX1_EXT_PA FIELD8(0x10)
+
+ /*
+ * RF registers
+@@ -2222,6 +2242,8 @@ struct mac_iveiv_entry {
+ * INTERNAL_TX_ALC: 0: disable, 1: enable
+ * BT_COEXIST: 0: disable, 1: enable
+ * DAC_TEST: 0: disable, 1: enable
++ * EXTERNAL_TX0_PA: 0: disable, 1: enable (only on RT3352)
++ * EXTERNAL_TX1_PA: 0: disable, 1: enable (only on RT3352)
+ */
+ #define EEPROM_NIC_CONF1 0x001b
+ #define EEPROM_NIC_CONF1_HW_RADIO FIELD16(0x0001)
+@@ -2239,6 +2261,8 @@ struct mac_iveiv_entry {
+ #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)
++#define EEPROM_NIC_CONF1_EXTERNAL_TX0_PA_3352 FIELD16(0x4000)
++#define EEPROM_NIC_CONF1_EXTERNAL_TX1_PA_3352 FIELD16(0x8000)
+
+ /*
+ * EEPROM frequency
+--- a/drivers/net/wireless/rt2x00/rt2x00.h
++++ b/drivers/net/wireless/rt2x00/rt2x00.h
+@@ -740,6 +740,8 @@ enum rt2x00_capability_flags {
+ CAPABILITY_DOUBLE_ANTENNA,
+ CAPABILITY_BT_COEXIST,
+ CAPABILITY_VCO_RECALIBRATION,
++ CAPABILITY_INTERNAL_PA_TX0,
++ CAPABILITY_INTERNAL_PA_TX1,
+ };
+
+ /*
diff --git a/package/mac80211/patches/623-rt2x00-rf_vals-rt3352-xtal20.patch b/package/mac80211/patches/611-rt2x00-rf_vals-rt3352-xtal20.patch
index 180872e844..38b56b4e5b 100644
--- a/package/mac80211/patches/623-rt2x00-rf_vals-rt3352-xtal20.patch
+++ b/package/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
-@@ -5072,6 +5072,27 @@ static const struct rf_channel rf_vals_3
+@@ -5169,6 +5169,27 @@ static const struct rf_channel rf_vals_3
{173, 0x61, 0, 9},
};
@@ -28,7 +28,7 @@
static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
{
struct hw_mode_spec *spec = &rt2x00dev->spec;
-@@ -5149,7 +5170,6 @@ static int rt2800_probe_hw_mode(struct r
+@@ -5246,7 +5267,6 @@ static int rt2800_probe_hw_mode(struct r
rt2x00_rf(rt2x00dev, RF3022) ||
rt2x00_rf(rt2x00dev, RF3290) ||
rt2x00_rf(rt2x00dev, RF3320) ||
@@ -36,7 +36,7 @@
rt2x00_rf(rt2x00dev, RF5360) ||
rt2x00_rf(rt2x00dev, RF5370) ||
rt2x00_rf(rt2x00dev, RF5372) ||
-@@ -5157,6 +5177,12 @@ static int rt2800_probe_hw_mode(struct r
+@@ -5254,6 +5274,12 @@ static int rt2800_probe_hw_mode(struct r
rt2x00_rf(rt2x00dev, RF5392)) {
spec->num_channels = 14;
spec->channels = rf_vals_3x;
@@ -49,7 +49,7 @@
} else if (rt2x00_rf(rt2x00dev, RF3052)) {
spec->supported_bands |= SUPPORT_BAND_5GHZ;
spec->num_channels = ARRAY_SIZE(rf_vals_3x);
-@@ -5250,6 +5276,19 @@ static int rt2800_probe_hw_mode(struct r
+@@ -5347,6 +5373,19 @@ static int rt2800_probe_hw_mode(struct r
return 0;
}
@@ -69,7 +69,7 @@
int rt2800_probe_hw(struct rt2x00_dev *rt2x00dev)
{
int retval;
-@@ -5275,6 +5314,15 @@ int rt2800_probe_hw(struct rt2x00_dev *r
+@@ -5372,6 +5411,15 @@ int rt2800_probe_hw(struct rt2x00_dev *r
rt2800_register_write(rt2x00dev, GPIO_CTRL, reg);
/*
@@ -87,7 +87,7 @@
retval = rt2800_probe_hw_mode(rt2x00dev);
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
-@@ -421,6 +421,7 @@ static inline struct rt2x00_intf* vif_to
+@@ -419,6 +419,7 @@ static inline struct rt2x00_intf* vif_to
* @channels: Device/chipset specific channel values (See &struct rf_channel).
* @channels_info: Additional information for channels (See &struct channel_info).
* @ht: Driver HT Capabilities (See &ieee80211_sta_ht_cap).
@@ -95,7 +95,7 @@
*/
struct hw_mode_spec {
unsigned int supported_bands;
-@@ -437,6 +438,7 @@ struct hw_mode_spec {
+@@ -435,6 +436,7 @@ struct hw_mode_spec {
const struct channel_info *channels_info;
struct ieee80211_sta_ht_cap ht;
diff --git a/package/mac80211/patches/612-rt2x00-make-wmac-loadable-via-OF-on-rt288x-305x-SoC.patch b/package/mac80211/patches/612-rt2x00-make-wmac-loadable-via-OF-on-rt288x-305x-SoC.patch
new file mode 100644
index 0000000000..bb682ff1fd
--- /dev/null
+++ b/package/mac80211/patches/612-rt2x00-make-wmac-loadable-via-OF-on-rt288x-305x-SoC.patch
@@ -0,0 +1,34 @@
+From 04dbd87265f6ba4a373b211ba324b437d224fb2d Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Sun, 17 Mar 2013 00:03:31 +0100
+Subject: [PATCH 21/38] rt2x00: make wmac loadable via OF on rt288x/305x SoC
+
+This patch ads the match table to allow loading the wmac support from a
+devicetree.
+
+Signed-off-by: John Crispin <blogic@openwrt.org>
+---
+ drivers/net/wireless/rt2x00/rt2800pci.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+--- a/drivers/net/wireless/rt2x00/rt2800pci.c
++++ b/drivers/net/wireless/rt2x00/rt2800pci.c
+@@ -1185,11 +1185,18 @@ static int rt2800soc_probe(struct platfo
+ return rt2x00soc_probe(pdev, &rt2800pci_ops);
+ }
+
++static const struct of_device_id rt2880_wmac_match[] = {
++ { .compatible = "ralink,rt2880-wmac" },
++ {},
++};
++MODULE_DEVICE_TABLE(of, rt2880_wmac_match);
++
+ static struct platform_driver rt2800soc_driver = {
+ .driver = {
+ .name = "rt2800_wmac",
+ .owner = THIS_MODULE,
+ .mod_name = KBUILD_MODNAME,
++ .of_match_table = rt2880_wmac_match,
+ },
+ .probe = rt2800soc_probe,
+ .remove = rt2x00soc_remove,
diff --git a/package/mac80211/patches/613-rt2x00-fixup-symbols.patch b/package/mac80211/patches/613-rt2x00-fixup-symbols.patch
new file mode 100644
index 0000000000..00bdbe16c7
--- /dev/null
+++ b/package/mac80211/patches/613-rt2x00-fixup-symbols.patch
@@ -0,0 +1,47 @@
+--- a/drivers/net/wireless/rt2x00/rt2800pci.c
++++ b/drivers/net/wireless/rt2x00/rt2800pci.c
+@@ -1179,7 +1179,7 @@ MODULE_DEVICE_TABLE(pci, rt2800pci_devic
+ #endif /* CONFIG_PCI */
+ MODULE_LICENSE("GPL");
+
+-#if defined(CONFIG_RALINK_RT288X) || defined(CONFIG_RALINK_RT305X)
++#if defined(CONFIG_SOC_RT288X) || defined(CONFIG_SOC_RT305X)
+ static int rt2800soc_probe(struct platform_device *pdev)
+ {
+ return rt2x00soc_probe(pdev, &rt2800pci_ops);
+@@ -1203,7 +1203,7 @@ static struct platform_driver rt2800soc_
+ .suspend = rt2x00soc_suspend,
+ .resume = rt2x00soc_resume,
+ };
+-#endif /* CONFIG_RALINK_RT288X || CONFIG_RALINK_RT305X */
++#endif /* CONFIG_SOC_RT288X || CONFIG_SOC_RT305X */
+
+ #ifdef CONFIG_PCI
+ static int rt2800pci_probe(struct pci_dev *pci_dev,
+@@ -1226,7 +1226,7 @@ static int __init rt2800pci_init(void)
+ {
+ int ret = 0;
+
+-#if defined(CONFIG_RALINK_RT288X) || defined(CONFIG_RALINK_RT305X)
++#if defined(CONFIG_SOC_RT288X) || defined(CONFIG_SOC_RT305X)
+ ret = platform_driver_register(&rt2800soc_driver);
+ if (ret)
+ return ret;
+@@ -1234,7 +1234,7 @@ static int __init rt2800pci_init(void)
+ #ifdef CONFIG_PCI
+ ret = pci_register_driver(&rt2800pci_driver);
+ if (ret) {
+-#if defined(CONFIG_RALINK_RT288X) || defined(CONFIG_RALINK_RT305X)
++#if defined(CONFIG_SOC_RT288X) || defined(CONFIG_SOC_RT305X)
+ platform_driver_unregister(&rt2800soc_driver);
+ #endif
+ return ret;
+@@ -1249,7 +1249,7 @@ static void __exit rt2800pci_exit(void)
+ #ifdef CONFIG_PCI
+ pci_unregister_driver(&rt2800pci_driver);
+ #endif
+-#if defined(CONFIG_RALINK_RT288X) || defined(CONFIG_RALINK_RT305X)
++#if defined(CONFIG_SOC_RT288X) || defined(CONFIG_SOC_RT305X)
+ platform_driver_unregister(&rt2800soc_driver);
+ #endif
+ }
diff --git a/package/mac80211/patches/614-rt2x00-of_load_eeprom_filename.patch b/package/mac80211/patches/614-rt2x00-of_load_eeprom_filename.patch
new file mode 100644
index 0000000000..2020178a69
--- /dev/null
+++ b/package/mac80211/patches/614-rt2x00-of_load_eeprom_filename.patch
@@ -0,0 +1,20 @@
+--- a/drivers/net/wireless/rt2x00/rt2800pci.c
++++ b/drivers/net/wireless/rt2x00/rt2800pci.c
+@@ -322,11 +322,17 @@ static int rt2800pci_write_firmware(stru
+ static char *rt2800pci_get_eeprom_file_name(struct rt2x00_dev *rt2x00dev)
+ {
+ struct rt2x00_platform_data *pdata;
++ struct device_node *np;
++ char *eep;
+
+ pdata = rt2x00dev->dev->platform_data;
+ if (pdata)
+ return pdata->eeprom_file_name;
+
++ np = rt2x00dev->dev->of_node;
++ if (np && !of_property_read_string(np, "ralink,eeprom", &eep))
++ return eep;
++
+ return NULL;
+ }
+
diff --git a/package/mac80211/patches/615-rt2x00-fix_20mhz_clk.patch b/package/mac80211/patches/615-rt2x00-fix_20mhz_clk.patch
new file mode 100644
index 0000000000..fa0ffa549c
--- /dev/null
+++ b/package/mac80211/patches/615-rt2x00-fix_20mhz_clk.patch
@@ -0,0 +1,29 @@
+--- a/drivers/net/wireless/rt2x00/rt2800lib.c
++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
+@@ -38,6 +38,7 @@
+ #include <linux/kernel.h>
+ #include <linux/module.h>
+ #include <linux/slab.h>
++#include <linux/clk.h>
+
+ #include "rt2x00.h"
+ #include "rt2800lib.h"
+@@ -5375,13 +5376,14 @@ static int rt2800_probe_hw_mode(struct r
+
+ int rt2800_probe_clk(struct rt2x00_dev *rt2x00dev)
+ {
+- struct rt2x00_platform_data *pdata = rt2x00dev->dev->platform_data;
+ struct hw_mode_spec *spec = &rt2x00dev->spec;
++ struct clk *clk = clk_get(rt2x00dev->dev, NULL);
+
+- if (!pdata)
+- return -EINVAL;
++ if (IS_ERR(clk))
++ return PTR_ERR(clk);
+
+- spec->clk_is_20mhz = pdata->clk_is_20mhz;
++ if (clk_get_rate(clk) == 20000000)
++ spec->clk_is_20mhz = 1;
+
+ return 0;
+ }
diff --git a/package/mac80211/patches/616-rt2x00-support-rt5350.patch b/package/mac80211/patches/616-rt2x00-support-rt5350.patch
new file mode 100644
index 0000000000..d12b550486
--- /dev/null
+++ b/package/mac80211/patches/616-rt2x00-support-rt5350.patch
@@ -0,0 +1,407 @@
+--- a/drivers/net/wireless/rt2x00/rt2800.h
++++ b/drivers/net/wireless/rt2x00/rt2800.h
+@@ -69,6 +69,7 @@
+ #define RF3322 0x000c
+ #define RF3053 0x000d
+ #define RF3290 0x3290
++#define RF5350 0x5350
+ #define RF5360 0x5360
+ #define RF5370 0x5370
+ #define RF5372 0x5372
+--- a/drivers/net/wireless/rt2x00/rt2800lib.c
++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
+@@ -2138,6 +2138,15 @@ static void rt2800_config_channel_rf53xx
+ if (rf->channel <= 14) {
+ int idx = rf->channel-1;
+
++ if (rt2x00_rt(rt2x00dev, RT5350)) {
++ static const char r59_non_bt[] = {0x0b, 0x0b,
++ 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0a,
++ 0x0a, 0x09, 0x08, 0x07, 0x07, 0x06};
++
++ rt2800_rfcsr_write(rt2x00dev, 59,
++ r59_non_bt[idx]);
++ }
++
+ if (test_bit(CAPABILITY_BT_COEXIST, &rt2x00dev->cap_flags)) {
+ if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) {
+ /* r55/r59 value array of channel 1~14 */
+@@ -2219,6 +2228,7 @@ static void rt2800_config_channel(struct
+ case RF3322:
+ rt2800_config_channel_rf3322(rt2x00dev, conf, rf, info);
+ break;
++ case RF5350:
+ case RF5360:
+ case RF5370:
+ case RF5372:
+@@ -2232,6 +2242,7 @@ static void rt2800_config_channel(struct
+
+ if (rt2x00_rf(rt2x00dev, RF3290) ||
+ rt2x00_rf(rt2x00dev, RF3322) ||
++ rt2x00_rf(rt2x00dev, RF5350) ||
+ rt2x00_rf(rt2x00dev, RF5360) ||
+ rt2x00_rf(rt2x00dev, RF5370) ||
+ rt2x00_rf(rt2x00dev, RF5372) ||
+@@ -2362,7 +2373,8 @@ static void rt2800_config_channel(struct
+ /*
+ * Clear update flag
+ */
+- if (rt2x00_rt(rt2x00dev, RT3352)) {
++ if (rt2x00_rt(rt2x00dev, RT3352) ||
++ rt2x00_rt(rt2x00dev, RT5350)) {
+ rt2800_bbp_read(rt2x00dev, 49, &bbp);
+ rt2x00_set_field8(&bbp, BBP49_UPDATE_FLAG, 0);
+ rt2800_bbp_write(rt2x00dev, 49, bbp);
+@@ -2801,6 +2813,7 @@ void rt2800_vco_calibration(struct rt2x0
+ rt2800_rfcsr_write(rt2x00dev, 7, rfcsr);
+ break;
+ case RF3290:
++ case RF5350:
+ case RF5360:
+ case RF5370:
+ case RF5372:
+@@ -3125,7 +3138,8 @@ static int rt2800_init_registers(struct
+ } else if (rt2x00_rt(rt2x00dev, RT3572)) {
+ rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000400);
+ rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606);
+- } else if (rt2x00_rt(rt2x00dev, RT5390) ||
++ } else if (rt2x00_rt(rt2x00dev, RT5350) ||
++ rt2x00_rt(rt2x00dev, RT5390) ||
+ rt2x00_rt(rt2x00dev, RT5392)) {
+ rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000404);
+ rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606);
+@@ -3507,6 +3521,10 @@ static int rt2800_init_bbp(struct rt2x00
+ rt2800_bbp_write(rt2x00dev, 4, 0x50);
+ }
+
++ if (rt2x00_rt(rt2x00dev, RT5350)) {
++ rt2800_bbp_write(rt2x00dev, 4, 0x50);
++ }
++
+ if (rt2x00_rt(rt2x00dev, RT3290) ||
+ rt2x00_rt(rt2x00dev, RT5390) ||
+ rt2x00_rt(rt2x00dev, RT5392)) {
+@@ -3519,11 +3537,13 @@ static int rt2800_init_bbp(struct rt2x00
+ rt2x00_rt(rt2x00dev, RT3290) ||
+ rt2x00_rt(rt2x00dev, RT3352) ||
+ rt2x00_rt(rt2x00dev, RT3572) ||
++ rt2x00_rt(rt2x00dev, RT5350) ||
+ rt2x00_rt(rt2x00dev, RT5390) ||
+ rt2x00_rt(rt2x00dev, RT5392))
+ rt2800_bbp_write(rt2x00dev, 31, 0x08);
+
+- if (rt2x00_rt(rt2x00dev, RT3352))
++ if (rt2x00_rt(rt2x00dev, RT3352) ||
++ rt2x00_rt(rt2x00dev, RT5350))
+ rt2800_bbp_write(rt2x00dev, 47, 0x48);
+
+ rt2800_bbp_write(rt2x00dev, 65, 0x2c);
+@@ -3531,6 +3551,7 @@ static int rt2800_init_bbp(struct rt2x00
+
+ if (rt2x00_rt(rt2x00dev, RT3290) ||
+ rt2x00_rt(rt2x00dev, RT3352) ||
++ rt2x00_rt(rt2x00dev, RT5350) ||
+ rt2x00_rt(rt2x00dev, RT5390) ||
+ rt2x00_rt(rt2x00dev, RT5392))
+ rt2800_bbp_write(rt2x00dev, 68, 0x0b);
+@@ -3540,6 +3561,7 @@ static int rt2800_init_bbp(struct rt2x00
+ rt2800_bbp_write(rt2x00dev, 73, 0x12);
+ } else if (rt2x00_rt(rt2x00dev, RT3290) ||
+ rt2x00_rt(rt2x00dev, RT3352) ||
++ rt2x00_rt(rt2x00dev, RT5350) ||
+ rt2x00_rt(rt2x00dev, RT5390) ||
+ rt2x00_rt(rt2x00dev, RT5392)) {
+ rt2800_bbp_write(rt2x00dev, 69, 0x12);
+@@ -3576,7 +3598,8 @@ static int rt2800_init_bbp(struct rt2x00
+ rt2800_bbp_write(rt2x00dev, 79, 0x18);
+ rt2800_bbp_write(rt2x00dev, 80, 0x09);
+ rt2800_bbp_write(rt2x00dev, 81, 0x33);
+- } else if (rt2x00_rt(rt2x00dev, RT3352)) {
++ } else if (rt2x00_rt(rt2x00dev, RT3352) ||
++ rt2x00_rt(rt2x00dev, RT5350)) {
+ rt2800_bbp_write(rt2x00dev, 78, 0x0e);
+ rt2800_bbp_write(rt2x00dev, 80, 0x08);
+ rt2800_bbp_write(rt2x00dev, 81, 0x37);
+@@ -3586,6 +3609,7 @@ static int rt2800_init_bbp(struct rt2x00
+
+ rt2800_bbp_write(rt2x00dev, 82, 0x62);
+ if (rt2x00_rt(rt2x00dev, RT3290) ||
++ rt2x00_rt(rt2x00dev, RT5350) ||
+ rt2x00_rt(rt2x00dev, RT5390) ||
+ rt2x00_rt(rt2x00dev, RT5392))
+ rt2800_bbp_write(rt2x00dev, 83, 0x7a);
+@@ -3595,6 +3619,7 @@ static int rt2800_init_bbp(struct rt2x00
+ if (rt2x00_rt_rev(rt2x00dev, RT2860, REV_RT2860D))
+ rt2800_bbp_write(rt2x00dev, 84, 0x19);
+ else if (rt2x00_rt(rt2x00dev, RT3290) ||
++ rt2x00_rt(rt2x00dev, RT5350) ||
+ rt2x00_rt(rt2x00dev, RT5390) ||
+ rt2x00_rt(rt2x00dev, RT5392))
+ rt2800_bbp_write(rt2x00dev, 84, 0x9a);
+@@ -3603,6 +3628,7 @@ static int rt2800_init_bbp(struct rt2x00
+
+ if (rt2x00_rt(rt2x00dev, RT3290) ||
+ rt2x00_rt(rt2x00dev, RT3352) ||
++ rt2x00_rt(rt2x00dev, RT5350) ||
+ rt2x00_rt(rt2x00dev, RT5390) ||
+ rt2x00_rt(rt2x00dev, RT5392))
+ rt2800_bbp_write(rt2x00dev, 86, 0x38);
+@@ -3617,6 +3643,7 @@ static int rt2800_init_bbp(struct rt2x00
+
+ if (rt2x00_rt(rt2x00dev, RT3290) ||
+ rt2x00_rt(rt2x00dev, RT3352) ||
++ rt2x00_rt(rt2x00dev, RT5350) ||
+ rt2x00_rt(rt2x00dev, RT5390) ||
+ rt2x00_rt(rt2x00dev, RT5392))
+ rt2800_bbp_write(rt2x00dev, 92, 0x02);
+@@ -3635,6 +3662,7 @@ static int rt2800_init_bbp(struct rt2x00
+ rt2x00_rt(rt2x00dev, RT3290) ||
+ rt2x00_rt(rt2x00dev, RT3352) ||
+ rt2x00_rt(rt2x00dev, RT3572) ||
++ rt2x00_rt(rt2x00dev, RT5350) ||
+ rt2x00_rt(rt2x00dev, RT5390) ||
+ rt2x00_rt(rt2x00dev, RT5392) ||
+ rt2800_is_305x_soc(rt2x00dev))
+@@ -3644,6 +3672,7 @@ static int rt2800_init_bbp(struct rt2x00
+
+ if (rt2x00_rt(rt2x00dev, RT3290) ||
+ rt2x00_rt(rt2x00dev, RT3352) ||
++ rt2x00_rt(rt2x00dev, RT5350) ||
+ rt2x00_rt(rt2x00dev, RT5390) ||
+ rt2x00_rt(rt2x00dev, RT5392))
+ rt2800_bbp_write(rt2x00dev, 104, 0x92);
+@@ -3654,13 +3683,15 @@ static int rt2800_init_bbp(struct rt2x00
+ rt2800_bbp_write(rt2x00dev, 105, 0x1c);
+ else if (rt2x00_rt(rt2x00dev, RT3352))
+ rt2800_bbp_write(rt2x00dev, 105, 0x34);
+- else if (rt2x00_rt(rt2x00dev, RT5390) ||
++ else if (rt2x00_rt(rt2x00dev, RT5350) ||
++ rt2x00_rt(rt2x00dev, RT5390) ||
+ rt2x00_rt(rt2x00dev, RT5392))
+ rt2800_bbp_write(rt2x00dev, 105, 0x3c);
+ else
+ rt2800_bbp_write(rt2x00dev, 105, 0x05);
+
+ if (rt2x00_rt(rt2x00dev, RT3290) ||
++ rt2x00_rt(rt2x00dev, RT5350) ||
+ rt2x00_rt(rt2x00dev, RT5390))
+ rt2800_bbp_write(rt2x00dev, 106, 0x03);
+ else if (rt2x00_rt(rt2x00dev, RT3352))
+@@ -3670,11 +3701,13 @@ static int rt2800_init_bbp(struct rt2x00
+ else
+ rt2800_bbp_write(rt2x00dev, 106, 0x35);
+
+- if (rt2x00_rt(rt2x00dev, RT3352))
++ if (rt2x00_rt(rt2x00dev, RT3352) ||
++ rt2x00_rt(rt2x00dev, RT5350))
+ rt2800_bbp_write(rt2x00dev, 120, 0x50);
+
+ if (rt2x00_rt(rt2x00dev, RT3290) ||
+ rt2x00_rt(rt2x00dev, RT3352) ||
++ rt2x00_rt(rt2x00dev, RT5350) ||
+ rt2x00_rt(rt2x00dev, RT5390) ||
+ rt2x00_rt(rt2x00dev, RT5392))
+ rt2800_bbp_write(rt2x00dev, 128, 0x12);
+@@ -3684,13 +3717,15 @@ static int rt2800_init_bbp(struct rt2x00
+ rt2800_bbp_write(rt2x00dev, 135, 0xf6);
+ }
+
+- if (rt2x00_rt(rt2x00dev, RT3352))
++ if (rt2x00_rt(rt2x00dev, RT3352) ||
++ rt2x00_rt(rt2x00dev, RT5350))
+ rt2800_bbp_write(rt2x00dev, 137, 0x0f);
+
+ if (rt2x00_rt(rt2x00dev, RT3071) ||
+ rt2x00_rt(rt2x00dev, RT3090) ||
+ rt2x00_rt(rt2x00dev, RT3390) ||
+ rt2x00_rt(rt2x00dev, RT3572) ||
++ rt2x00_rt(rt2x00dev, RT5350) ||
+ rt2x00_rt(rt2x00dev, RT5390) ||
+ rt2x00_rt(rt2x00dev, RT5392)) {
+ rt2800_bbp_read(rt2x00dev, 138, &value);
+@@ -3727,7 +3762,8 @@ static int rt2800_init_bbp(struct rt2x00
+ rt2800_bbp_write(rt2x00dev, 3, value);
+ }
+
+- if (rt2x00_rt(rt2x00dev, RT3352)) {
++ if (rt2x00_rt(rt2x00dev, RT3352) ||
++ rt2x00_rt(rt2x00dev, RT5350)) {
+ rt2800_bbp_write(rt2x00dev, 163, 0xbd);
+ /* Set ITxBF timeout to 0x9c40=1000msec */
+ rt2800_bbp_write(rt2x00dev, 179, 0x02);
+@@ -3749,6 +3785,14 @@ static int rt2800_init_bbp(struct rt2x00
+ rt2800_bbp_write(rt2x00dev, 148, 0xc8);
+ }
+
++ if (rt2x00_rt(rt2x00dev, RT5350)) {
++ rt2800_bbp_write(rt2x00dev, 150, 0x40); /* Antenna Software OFDM */
++ rt2800_bbp_write(rt2x00dev, 151, 0x30); /* Antenna Software CCK */
++ rt2800_bbp_write(rt2x00dev, 152, 0xa3);
++ rt2800_bbp_write(rt2x00dev, 154, 0); /* Clear previously selected antenna */
++ }
++
++
+ if (rt2x00_rt(rt2x00dev, RT5390) ||
+ rt2x00_rt(rt2x00dev, RT5392)) {
+ int ant, div_mode;
+@@ -4143,6 +4187,76 @@ static void rt2800_init_rfcsr_3572(struc
+ rt2800_rfcsr_write(rt2x00dev, 31, 0x10);
+ }
+
++static void rt2800_init_rfcsr_5350(struct rt2x00_dev *rt2x00dev)
++{
++ rt2800_rfcsr_write(rt2x00dev, 0, 0xf0);
++ rt2800_rfcsr_write(rt2x00dev, 1, 0x23);
++ rt2800_rfcsr_write(rt2x00dev, 2, 0x50);
++ rt2800_rfcsr_write(rt2x00dev, 3, 0x08);
++ rt2800_rfcsr_write(rt2x00dev, 4, 0x49);
++ rt2800_rfcsr_write(rt2x00dev, 5, 0x10);
++ rt2800_rfcsr_write(rt2x00dev, 6, 0xe0);
++ rt2800_rfcsr_write(rt2x00dev, 7, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 8, 0xf1);
++ rt2800_rfcsr_write(rt2x00dev, 9, 0x02);
++ rt2800_rfcsr_write(rt2x00dev, 10, 0x53);
++ rt2800_rfcsr_write(rt2x00dev, 11, 0x4a);
++ rt2800_rfcsr_write(rt2x00dev, 12, 0x46);
++ if(rt2x00dev->spec.clk_is_20mhz)
++ rt2800_rfcsr_write(rt2x00dev, 13, 0x1f);
++ else
++ rt2800_rfcsr_write(rt2x00dev, 13, 0x9f);
++ rt2800_rfcsr_write(rt2x00dev, 14, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 15, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 16, 0xc0);
++ rt2800_rfcsr_write(rt2x00dev, 18, 0x03);
++ rt2800_rfcsr_write(rt2x00dev, 19, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 20, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 21, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 22, 0x20);
++ rt2800_rfcsr_write(rt2x00dev, 23, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 24, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 25, 0x80);
++ rt2800_rfcsr_write(rt2x00dev, 26, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 27, 0x03);
++ rt2800_rfcsr_write(rt2x00dev, 28, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 29, 0xd0);
++ rt2800_rfcsr_write(rt2x00dev, 30, 0x10);
++ rt2800_rfcsr_write(rt2x00dev, 31, 0x80);
++ rt2800_rfcsr_write(rt2x00dev, 32, 0x80);
++ rt2800_rfcsr_write(rt2x00dev, 33, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 34, 0x07);
++ rt2800_rfcsr_write(rt2x00dev, 35, 0x12);
++ rt2800_rfcsr_write(rt2x00dev, 36, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 37, 0x08);
++ rt2800_rfcsr_write(rt2x00dev, 38, 0x85);
++ rt2800_rfcsr_write(rt2x00dev, 39, 0x1b);
++ rt2800_rfcsr_write(rt2x00dev, 40, 0x0b);
++ rt2800_rfcsr_write(rt2x00dev, 41, 0xbb);
++ rt2800_rfcsr_write(rt2x00dev, 42, 0xd5);
++ rt2800_rfcsr_write(rt2x00dev, 43, 0x9b);
++ rt2800_rfcsr_write(rt2x00dev, 44, 0x0c);
++ rt2800_rfcsr_write(rt2x00dev, 45, 0xa6);
++ rt2800_rfcsr_write(rt2x00dev, 46, 0x73);
++ rt2800_rfcsr_write(rt2x00dev, 47, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 48, 0x10);
++ rt2800_rfcsr_write(rt2x00dev, 49, 0x80);
++ rt2800_rfcsr_write(rt2x00dev, 50, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 51, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 52, 0x38);
++ rt2800_rfcsr_write(rt2x00dev, 53, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 54, 0x38);
++ rt2800_rfcsr_write(rt2x00dev, 55, 0x43);
++ rt2800_rfcsr_write(rt2x00dev, 56, 0x82);
++ rt2800_rfcsr_write(rt2x00dev, 57, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 58, 0x39);
++ rt2800_rfcsr_write(rt2x00dev, 59, 0x0b);
++ rt2800_rfcsr_write(rt2x00dev, 60, 0x45);
++ rt2800_rfcsr_write(rt2x00dev, 61, 0xd1);
++ rt2800_rfcsr_write(rt2x00dev, 62, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 63, 0x00);
++}
++
+ static void rt2800_init_rfcsr_5390(struct rt2x00_dev *rt2x00dev)
+ {
+ rt2800_rfcsr_write(rt2x00dev, 1, 0x0f);
+@@ -4305,6 +4419,7 @@ static int rt2800_init_rfcsr(struct rt2x
+ !rt2x00_rt(rt2x00dev, RT3352) &&
+ !rt2x00_rt(rt2x00dev, RT3390) &&
+ !rt2x00_rt(rt2x00dev, RT3572) &&
++ !rt2x00_rt(rt2x00dev, RT5350) &&
+ !rt2x00_rt(rt2x00dev, RT5390) &&
+ !rt2x00_rt(rt2x00dev, RT5392) &&
+ !rt2800_is_305x_soc(rt2x00dev))
+@@ -4355,6 +4470,9 @@ static int rt2800_init_rfcsr(struct rt2x
+ case RT3572:
+ rt2800_init_rfcsr_3572(rt2x00dev);
+ break;
++ case RT5350:
++ rt2800_init_rfcsr_5350(rt2x00dev);
++ break;
+ case RT5390:
+ rt2800_init_rfcsr_5390(rt2x00dev);
+ break;
+@@ -4751,6 +4869,12 @@ static int rt2800_validate_eeprom(struct
+ if (rt2x00_get_field16(word, EEPROM_NIC_CONF0_RXPATH) > 2)
+ rt2x00_set_field16(&word, EEPROM_NIC_CONF0_RXPATH, 2);
+ rt2x00_eeprom_write(rt2x00dev, EEPROM_NIC_CONF0, word);
++ } else if(rt2x00_rt(rt2x00dev, RT5350)) {
++ rt2x00_set_field16(&word, EEPROM_NIC_CONF0_RXPATH, 1);
++ rt2x00_set_field16(&word, EEPROM_NIC_CONF0_TXPATH, 1);
++ rt2x00_set_field16(&word, EEPROM_NIC_CONF0_RF_TYPE, RF3320);
++ rt2x00_eeprom_write(rt2x00dev, EEPROM_NIC_CONF0, word);
++ EEPROM(rt2x00dev, "rt5350: Ant: 0x%04x\n", word);
+ }
+
+ rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &word);
+@@ -4875,6 +4999,8 @@ static int rt2800_init_eeprom(struct rt2
+ rt2x00_get_field32(reg, MAC_CSR0_CHIPSET) == RT5390 ||
+ rt2x00_get_field32(reg, MAC_CSR0_CHIPSET) == RT5392)
+ rt2x00_eeprom_read(rt2x00dev, EEPROM_CHIP_ID, &value);
++ else if(rt2x00_get_field32(reg, MAC_CSR0_CHIPSET) == RT5350)
++ value = RF5350;
+ else
+ value = rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RF_TYPE);
+
+@@ -4892,6 +5018,7 @@ static int rt2800_init_eeprom(struct rt2
+ case RT3352:
+ case RT3390:
+ case RT3572:
++ case RT5350:
+ case RT5390:
+ case RT5392:
+ break;
+@@ -4913,6 +5040,7 @@ static int rt2800_init_eeprom(struct rt2
+ case RF3290:
+ case RF3320:
+ case RF3322:
++ case RF5350:
+ case RF5360:
+ case RF5370:
+ case RF5372:
+@@ -5275,7 +5403,8 @@ static int rt2800_probe_hw_mode(struct r
+ rt2x00_rf(rt2x00dev, RF5392)) {
+ spec->num_channels = 14;
+ spec->channels = rf_vals_3x;
+- } else if (rt2x00_rf(rt2x00dev, RF3322)) {
++ } else if (rt2x00_rf(rt2x00dev, RF3322) ||
++ rt2x00_rf(rt2x00dev, RF5350)) {
+ spec->num_channels = 14;
+ if (spec->clk_is_20mhz)
+ spec->channels = rf_vals_xtal20mhz_3x;
+@@ -5364,6 +5493,7 @@ static int rt2800_probe_hw_mode(struct r
+ case RF3290:
+ case RF5360:
+ case RF5370:
++ case RF5350:
+ case RF5372:
+ case RF5390:
+ case RF5392:
+--- a/drivers/net/wireless/rt2x00/rt2x00.h
++++ b/drivers/net/wireless/rt2x00/rt2x00.h
+@@ -192,6 +192,7 @@ struct rt2x00_chip {
+ #define RT3572 0x3572
+ #define RT3593 0x3593
+ #define RT3883 0x3883 /* WSOC */
++#define RT5350 0x5350 /* WSOC 2.4GHz */
+ #define RT5390 0x5390 /* 2.4GHz */
+ #define RT5392 0x5392 /* 2.4GHz */
+
diff --git a/package/mac80211/patches/617-rt2x00-load-eeprom-on-SoC-from-a-mtd-device-defines-.patch b/package/mac80211/patches/617-rt2x00-load-eeprom-on-SoC-from-a-mtd-device-defines-.patch
new file mode 100644
index 0000000000..c7d40ef7c6
--- /dev/null
+++ b/package/mac80211/patches/617-rt2x00-load-eeprom-on-SoC-from-a-mtd-device-defines-.patch
@@ -0,0 +1,102 @@
+From 339fe73f340161a624cc08e738d2244814852c3e Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Sun, 17 Mar 2013 00:55:04 +0100
+Subject: [PATCH] rt2x00: load eeprom on SoC from a mtd device defines inside
+ OF
+
+Signed-off-by: John Crispin <blogic@openwrt.org>
+---
+ drivers/net/wireless/rt2x00/Kconfig | 1 +
+ drivers/net/wireless/rt2x00/rt2800pci.c | 44 ++++++++++++++++++++++++++-----
+ 2 files changed, 39 insertions(+), 6 deletions(-)
+
+--- a/drivers/net/wireless/rt2x00/Kconfig
++++ b/drivers/net/wireless/rt2x00/Kconfig
+@@ -64,6 +64,7 @@ config RT2800PCI
+ select RT2X00_LIB_CRYPTO
+ select CRC_CCITT
+ select EEPROM_93CX6
++ select MTD if SOC_RT288X || SOC_RT305X
+ ---help---
+ This adds support for rt27xx/rt28xx/rt30xx wireless chipset family.
+ Supported chips: RT2760, RT2790, RT2860, RT2880, RT2890, RT3052,
+--- a/drivers/net/wireless/rt2x00/rt2x00eeprom.c
++++ b/drivers/net/wireless/rt2x00/rt2x00eeprom.c
+@@ -30,12 +30,77 @@
+ #include "rt2x00.h"
+ #include "rt2x00lib.h"
+
++#ifdef CONFIG_OF
++#include <linux/of.h>
++#include <linux/mtd/mtd.h>
++#include <linux/mtd/partitions.h>
++
++static struct firmware mtd_fw;
++
++static int rt2800pci_read_eeprom_mtd(struct rt2x00_dev *rt2x00dev)
++{
++ struct device_node *np = rt2x00dev->dev->of_node, *mtd_np = NULL;
++ size_t retlen, len = rt2x00dev->ops->eeprom_size;
++ int ret, size, offset = 0;
++ struct mtd_info *mtd;
++ const char *part;
++ const __be32 *list;
++ phandle phandle;
++
++ list = of_get_property(np, "ralink,mtd-eeprom", &size);
++ if (!list) {
++ dev_err(rt2x00dev->dev, "failed to load eeprom property\n");
++ return -ENOENT;
++ }
++
++ phandle = be32_to_cpup(list++);
++ if (phandle)
++ mtd_np = of_find_node_by_phandle(phandle);
++ if (!mtd_np) {
++ dev_err(rt2x00dev->dev, "failed to load mtd phandle\n");
++ return -EINVAL;
++ }
++
++ part = of_get_property(mtd_np, "label", NULL);
++ if (!part)
++ part = mtd_np->name;
++
++ mtd = get_mtd_device_nm(part);
++ if (IS_ERR(mtd)) {
++ dev_err(rt2x00dev->dev, "failed to get mtd device \"%s\"\n", part);
++ return PTR_ERR(mtd);
++ }
++
++ if (size > sizeof(*list))
++ offset = be32_to_cpup(list);
++
++ ret = mtd_read(mtd, offset, len, &retlen, (u_char *) rt2x00dev->eeprom);
++ put_mtd_device(mtd);
++
++ if (!ret) {
++ rt2x00dev->eeprom_file = &mtd_fw;
++ mtd_fw.size = len;
++ mtd_fw.data = rt2x00dev->eeprom;
++ }
++
++ return ret;
++}
++#else
++static inline int rt2800pci_read_eeprom_mtd(struct rt2x00_dev *rt2x00dev)
++{
++ return -EINVAL;
++}
++#endif
++
+ static int rt2x00lib_request_eeprom_file(struct rt2x00_dev *rt2x00dev)
+ {
+ const struct firmware *ee;
+ char *ee_name;
+ int retval;
+
++ if (!rt2800pci_read_eeprom_mtd(rt2x00dev))
++ return 0;
++
+ ee_name = rt2x00dev->ops->lib->get_eeprom_file_name(rt2x00dev);
+ if (!ee_name) {
+ ERROR(rt2x00dev,
diff --git a/package/mac80211/patches/620-rt2x00-support-rt3352.patch b/package/mac80211/patches/620-rt2x00-support-rt3352.patch
deleted file mode 100644
index b1ebd02275..0000000000
--- a/package/mac80211/patches/620-rt2x00-support-rt3352.patch
+++ /dev/null
@@ -1,455 +0,0 @@
-From 03839951515b0ea2b21d649b1fe7b63f9817d0c8 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <dgolle@allnet.de>
-Date: Sun, 9 Sep 2012 14:24:39 +0300
-Subject: [PATCH] rt2x00: add MediaTek/RaLink Rt3352 WiSoC
-
-Support for the RT3352 WiSoC was developed for and tested with the ALL5002
-devboard running OpenWrt. For now, this supports only devices with internal
-TXALC. Corrections were made according to the remarks of Stanislaw Gruszka and
-Gertjan van Wingerde, thank you guys for reviewing!
-
-Signed-off-by: Daniel Golle <dgolle@allnet.de>
-Signed-off-by: John W. Linville <linville@tuxdriver.com>
----
- drivers/net/wireless/rt2x00/rt2800.h | 5 +
- drivers/net/wireless/rt2x00/rt2800lib.c | 211 +++++++++++++++++++++++++++++++-
- drivers/net/wireless/rt2x00/rt2x00.h | 1 +
- 3 files changed, 212 insertions(+), 5 deletions(-)
-
---- a/drivers/net/wireless/rt2x00/rt2800.h
-+++ b/drivers/net/wireless/rt2x00/rt2800.h
-@@ -1943,6 +1943,11 @@ struct mac_iveiv_entry {
- #define BBP47_TSSI_ADC6 FIELD8(0x80)
-
- /*
-+ * BBP 49
-+ */
-+#define BBP49_UPDATE_FLAG FIELD8(0x01)
-+
-+/*
- * BBP 109
- */
- #define BBP109_TX0_POWER FIELD8(0x0f)
---- a/drivers/net/wireless/rt2x00/rt2800lib.c
-+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
-@@ -1615,6 +1615,7 @@ void rt2800_config_ant(struct rt2x00_dev
- case 1:
- if (rt2x00_rt(rt2x00dev, RT3070) ||
- rt2x00_rt(rt2x00dev, RT3090) ||
-+ rt2x00_rt(rt2x00dev, RT3352) ||
- rt2x00_rt(rt2x00dev, RT3390)) {
- rt2x00_eeprom_read(rt2x00dev,
- EEPROM_NIC_CONF1, &eeprom);
-@@ -2053,6 +2054,60 @@ static void rt2800_config_channel_rf3290
- }
- }
-
-+static void rt2800_config_channel_rf3322(struct rt2x00_dev *rt2x00dev,
-+ struct ieee80211_conf *conf,
-+ struct rf_channel *rf,
-+ struct channel_info *info)
-+{
-+ u8 rfcsr;
-+
-+ rt2800_rfcsr_write(rt2x00dev, 8, rf->rf1);
-+ rt2800_rfcsr_write(rt2x00dev, 9, rf->rf3);
-+
-+ rt2800_rfcsr_write(rt2x00dev, 11, 0x42);
-+ rt2800_rfcsr_write(rt2x00dev, 12, 0x1c);
-+ rt2800_rfcsr_write(rt2x00dev, 13, 0x00);
-+
-+ if (info->default_power1 > POWER_BOUND)
-+ rt2800_rfcsr_write(rt2x00dev, 47, POWER_BOUND);
-+ else
-+ rt2800_rfcsr_write(rt2x00dev, 47, info->default_power1);
-+
-+ if (info->default_power2 > POWER_BOUND)
-+ rt2800_rfcsr_write(rt2x00dev, 48, POWER_BOUND);
-+ else
-+ rt2800_rfcsr_write(rt2x00dev, 48, info->default_power2);
-+
-+ rt2800_rfcsr_read(rt2x00dev, 17, &rfcsr);
-+ if (rt2x00dev->freq_offset > FREQ_OFFSET_BOUND)
-+ rt2x00_set_field8(&rfcsr, RFCSR17_CODE, FREQ_OFFSET_BOUND);
-+ else
-+ rt2x00_set_field8(&rfcsr, RFCSR17_CODE, rt2x00dev->freq_offset);
-+
-+ rt2800_rfcsr_write(rt2x00dev, 17, rfcsr);
-+
-+ rt2800_rfcsr_read(rt2x00dev, 1, &rfcsr);
-+ rt2x00_set_field8(&rfcsr, RFCSR1_RX0_PD, 1);
-+ rt2x00_set_field8(&rfcsr, RFCSR1_TX0_PD, 1);
-+
-+ if ( rt2x00dev->default_ant.tx_chain_num == 2 )
-+ rt2x00_set_field8(&rfcsr, RFCSR1_TX1_PD, 1);
-+ else
-+ rt2x00_set_field8(&rfcsr, RFCSR1_TX1_PD, 0);
-+
-+ if ( rt2x00dev->default_ant.rx_chain_num == 2 )
-+ rt2x00_set_field8(&rfcsr, RFCSR1_RX1_PD, 1);
-+ else
-+ rt2x00_set_field8(&rfcsr, RFCSR1_RX1_PD, 0);
-+
-+ rt2x00_set_field8(&rfcsr, RFCSR1_RX2_PD, 0);
-+ rt2x00_set_field8(&rfcsr, RFCSR1_TX2_PD, 0);
-+
-+ rt2800_rfcsr_write(rt2x00dev, 1, rfcsr);
-+
-+ rt2800_rfcsr_write(rt2x00dev, 31, 80);
-+}
-+
- static void rt2800_config_channel_rf53xx(struct rt2x00_dev *rt2x00dev,
- struct ieee80211_conf *conf,
- struct rf_channel *rf,
-@@ -2182,6 +2237,9 @@ static void rt2800_config_channel(struct
- case RF3290:
- rt2800_config_channel_rf3290(rt2x00dev, conf, rf, info);
- break;
-+ case RF3322:
-+ rt2800_config_channel_rf3322(rt2x00dev, conf, rf, info);
-+ break;
- case RF5360:
- case RF5370:
- case RF5372:
-@@ -2194,6 +2252,7 @@ static void rt2800_config_channel(struct
- }
-
- if (rt2x00_rf(rt2x00dev, RF3290) ||
-+ rt2x00_rf(rt2x00dev, RF3322) ||
- rt2x00_rf(rt2x00dev, RF5360) ||
- rt2x00_rf(rt2x00dev, RF5370) ||
- rt2x00_rf(rt2x00dev, RF5372) ||
-@@ -2212,10 +2271,17 @@ static void rt2800_config_channel(struct
- /*
- * Change BBP settings
- */
-- rt2800_bbp_write(rt2x00dev, 62, 0x37 - rt2x00dev->lna_gain);
-- rt2800_bbp_write(rt2x00dev, 63, 0x37 - rt2x00dev->lna_gain);
-- rt2800_bbp_write(rt2x00dev, 64, 0x37 - rt2x00dev->lna_gain);
-- rt2800_bbp_write(rt2x00dev, 86, 0);
-+ if (rt2x00_rt(rt2x00dev, RT3352)) {
-+ rt2800_bbp_write(rt2x00dev, 27, 0x0);
-+ rt2800_bbp_write(rt2x00dev, 62, 0x26 + rt2x00dev->lna_gain);
-+ rt2800_bbp_write(rt2x00dev, 27, 0x20);
-+ rt2800_bbp_write(rt2x00dev, 62, 0x26 + rt2x00dev->lna_gain);
-+ } else {
-+ rt2800_bbp_write(rt2x00dev, 62, 0x37 - rt2x00dev->lna_gain);
-+ rt2800_bbp_write(rt2x00dev, 63, 0x37 - rt2x00dev->lna_gain);
-+ rt2800_bbp_write(rt2x00dev, 64, 0x37 - rt2x00dev->lna_gain);
-+ rt2800_bbp_write(rt2x00dev, 86, 0);
-+ }
-
- if (rf->channel <= 14) {
- if (!rt2x00_rt(rt2x00dev, RT5390) &&
-@@ -2310,6 +2376,15 @@ static void rt2800_config_channel(struct
- rt2800_register_read(rt2x00dev, CH_IDLE_STA, &reg);
- rt2800_register_read(rt2x00dev, CH_BUSY_STA, &reg);
- rt2800_register_read(rt2x00dev, CH_BUSY_STA_SEC, &reg);
-+
-+ /*
-+ * Clear update flag
-+ */
-+ if (rt2x00_rt(rt2x00dev, RT3352)) {
-+ rt2800_bbp_read(rt2x00dev, 49, &bbp);
-+ rt2x00_set_field8(&bbp, BBP49_UPDATE_FLAG, 0);
-+ rt2800_bbp_write(rt2x00dev, 49, bbp);
-+ }
- }
-
- static int rt2800_get_gain_calibration_delta(struct rt2x00_dev *rt2x00dev)
-@@ -2998,6 +3073,10 @@ static int rt2800_init_registers(struct
- rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000400);
- rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00000000);
- rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000030);
-+ } else if (rt2x00_rt(rt2x00dev, RT3352)) {
-+ rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000402);
-+ rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606);
-+ rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000000);
- } else if (rt2x00_rt(rt2x00dev, RT3572)) {
- rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000400);
- rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606);
-@@ -3378,6 +3457,11 @@ static int rt2800_init_bbp(struct rt2x00
- rt2800_wait_bbp_ready(rt2x00dev)))
- return -EACCES;
-
-+ if (rt2x00_rt(rt2x00dev, RT3352)) {
-+ rt2800_bbp_write(rt2x00dev, 3, 0x00);
-+ rt2800_bbp_write(rt2x00dev, 4, 0x50);
-+ }
-+
- if (rt2x00_rt(rt2x00dev, RT3290) ||
- rt2x00_rt(rt2x00dev, RT5390) ||
- rt2x00_rt(rt2x00dev, RT5392)) {
-@@ -3388,15 +3472,20 @@ static int rt2800_init_bbp(struct rt2x00
-
- if (rt2800_is_305x_soc(rt2x00dev) ||
- rt2x00_rt(rt2x00dev, RT3290) ||
-+ rt2x00_rt(rt2x00dev, RT3352) ||
- rt2x00_rt(rt2x00dev, RT3572) ||
- rt2x00_rt(rt2x00dev, RT5390) ||
- rt2x00_rt(rt2x00dev, RT5392))
- rt2800_bbp_write(rt2x00dev, 31, 0x08);
-
-+ if (rt2x00_rt(rt2x00dev, RT3352))
-+ rt2800_bbp_write(rt2x00dev, 47, 0x48);
-+
- rt2800_bbp_write(rt2x00dev, 65, 0x2c);
- rt2800_bbp_write(rt2x00dev, 66, 0x38);
-
- if (rt2x00_rt(rt2x00dev, RT3290) ||
-+ rt2x00_rt(rt2x00dev, RT3352) ||
- rt2x00_rt(rt2x00dev, RT5390) ||
- rt2x00_rt(rt2x00dev, RT5392))
- rt2800_bbp_write(rt2x00dev, 68, 0x0b);
-@@ -3405,6 +3494,7 @@ static int rt2800_init_bbp(struct rt2x00
- rt2800_bbp_write(rt2x00dev, 69, 0x16);
- rt2800_bbp_write(rt2x00dev, 73, 0x12);
- } else if (rt2x00_rt(rt2x00dev, RT3290) ||
-+ rt2x00_rt(rt2x00dev, RT3352) ||
- rt2x00_rt(rt2x00dev, RT5390) ||
- rt2x00_rt(rt2x00dev, RT5392)) {
- rt2800_bbp_write(rt2x00dev, 69, 0x12);
-@@ -3436,6 +3526,10 @@ static int rt2800_init_bbp(struct rt2x00
- } else if (rt2800_is_305x_soc(rt2x00dev)) {
- rt2800_bbp_write(rt2x00dev, 78, 0x0e);
- rt2800_bbp_write(rt2x00dev, 80, 0x08);
-+ } else if (rt2x00_rt(rt2x00dev, RT3352)) {
-+ rt2800_bbp_write(rt2x00dev, 78, 0x0e);
-+ rt2800_bbp_write(rt2x00dev, 80, 0x08);
-+ rt2800_bbp_write(rt2x00dev, 81, 0x37);
- } else {
- rt2800_bbp_write(rt2x00dev, 81, 0x37);
- }
-@@ -3465,18 +3559,21 @@ static int rt2800_init_bbp(struct rt2x00
- rt2800_bbp_write(rt2x00dev, 84, 0x99);
-
- if (rt2x00_rt(rt2x00dev, RT3290) ||
-+ rt2x00_rt(rt2x00dev, RT3352) ||
- rt2x00_rt(rt2x00dev, RT5390) ||
- rt2x00_rt(rt2x00dev, RT5392))
- rt2800_bbp_write(rt2x00dev, 86, 0x38);
- else
- rt2800_bbp_write(rt2x00dev, 86, 0x00);
-
-- if (rt2x00_rt(rt2x00dev, RT5392))
-+ if (rt2x00_rt(rt2x00dev, RT3352) ||
-+ rt2x00_rt(rt2x00dev, RT5392))
- rt2800_bbp_write(rt2x00dev, 88, 0x90);
-
- rt2800_bbp_write(rt2x00dev, 91, 0x04);
-
- if (rt2x00_rt(rt2x00dev, RT3290) ||
-+ rt2x00_rt(rt2x00dev, RT3352) ||
- rt2x00_rt(rt2x00dev, RT5390) ||
- rt2x00_rt(rt2x00dev, RT5392))
- rt2800_bbp_write(rt2x00dev, 92, 0x02);
-@@ -3493,6 +3590,7 @@ static int rt2800_init_bbp(struct rt2x00
- rt2x00_rt_rev_gte(rt2x00dev, RT3090, REV_RT3090E) ||
- rt2x00_rt_rev_gte(rt2x00dev, RT3390, REV_RT3390E) ||
- rt2x00_rt(rt2x00dev, RT3290) ||
-+ rt2x00_rt(rt2x00dev, RT3352) ||
- rt2x00_rt(rt2x00dev, RT3572) ||
- rt2x00_rt(rt2x00dev, RT5390) ||
- rt2x00_rt(rt2x00dev, RT5392) ||
-@@ -3502,6 +3600,7 @@ static int rt2800_init_bbp(struct rt2x00
- rt2800_bbp_write(rt2x00dev, 103, 0x00);
-
- if (rt2x00_rt(rt2x00dev, RT3290) ||
-+ rt2x00_rt(rt2x00dev, RT3352) ||
- rt2x00_rt(rt2x00dev, RT5390) ||
- rt2x00_rt(rt2x00dev, RT5392))
- rt2800_bbp_write(rt2x00dev, 104, 0x92);
-@@ -3510,6 +3609,8 @@ static int rt2800_init_bbp(struct rt2x00
- rt2800_bbp_write(rt2x00dev, 105, 0x01);
- else if (rt2x00_rt(rt2x00dev, RT3290))
- rt2800_bbp_write(rt2x00dev, 105, 0x1c);
-+ else if (rt2x00_rt(rt2x00dev, RT3352))
-+ rt2800_bbp_write(rt2x00dev, 105, 0x34);
- else if (rt2x00_rt(rt2x00dev, RT5390) ||
- rt2x00_rt(rt2x00dev, RT5392))
- rt2800_bbp_write(rt2x00dev, 105, 0x3c);
-@@ -3519,11 +3620,16 @@ static int rt2800_init_bbp(struct rt2x00
- if (rt2x00_rt(rt2x00dev, RT3290) ||
- rt2x00_rt(rt2x00dev, RT5390))
- rt2800_bbp_write(rt2x00dev, 106, 0x03);
-+ else if (rt2x00_rt(rt2x00dev, RT3352))
-+ rt2800_bbp_write(rt2x00dev, 106, 0x05);
- else if (rt2x00_rt(rt2x00dev, RT5392))
- rt2800_bbp_write(rt2x00dev, 106, 0x12);
- else
- rt2800_bbp_write(rt2x00dev, 106, 0x35);
-
-+ if (rt2x00_rt(rt2x00dev, RT3352))
-+ rt2800_bbp_write(rt2x00dev, 120, 0x50);
-+
- if (rt2x00_rt(rt2x00dev, RT3290) ||
- rt2x00_rt(rt2x00dev, RT5390) ||
- rt2x00_rt(rt2x00dev, RT5392))
-@@ -3534,6 +3640,9 @@ static int rt2800_init_bbp(struct rt2x00
- rt2800_bbp_write(rt2x00dev, 135, 0xf6);
- }
-
-+ if (rt2x00_rt(rt2x00dev, RT3352))
-+ rt2800_bbp_write(rt2x00dev, 137, 0x0f);
-+
- if (rt2x00_rt(rt2x00dev, RT3071) ||
- rt2x00_rt(rt2x00dev, RT3090) ||
- rt2x00_rt(rt2x00dev, RT3390) ||
-@@ -3574,6 +3683,28 @@ static int rt2800_init_bbp(struct rt2x00
- rt2800_bbp_write(rt2x00dev, 3, value);
- }
-
-+ if (rt2x00_rt(rt2x00dev, RT3352)) {
-+ rt2800_bbp_write(rt2x00dev, 163, 0xbd);
-+ /* Set ITxBF timeout to 0x9c40=1000msec */
-+ rt2800_bbp_write(rt2x00dev, 179, 0x02);
-+ rt2800_bbp_write(rt2x00dev, 180, 0x00);
-+ rt2800_bbp_write(rt2x00dev, 182, 0x40);
-+ rt2800_bbp_write(rt2x00dev, 180, 0x01);
-+ rt2800_bbp_write(rt2x00dev, 182, 0x9c);
-+ rt2800_bbp_write(rt2x00dev, 179, 0x00);
-+ /* Reprogram the inband interface to put right values in RXWI */
-+ rt2800_bbp_write(rt2x00dev, 142, 0x04);
-+ rt2800_bbp_write(rt2x00dev, 143, 0x3b);
-+ rt2800_bbp_write(rt2x00dev, 142, 0x06);
-+ rt2800_bbp_write(rt2x00dev, 143, 0xa0);
-+ rt2800_bbp_write(rt2x00dev, 142, 0x07);
-+ rt2800_bbp_write(rt2x00dev, 143, 0xa1);
-+ rt2800_bbp_write(rt2x00dev, 142, 0x08);
-+ rt2800_bbp_write(rt2x00dev, 143, 0xa2);
-+
-+ rt2800_bbp_write(rt2x00dev, 148, 0xc8);
-+ }
-+
- if (rt2x00_rt(rt2x00dev, RT5390) ||
- rt2x00_rt(rt2x00dev, RT5392)) {
- int ant, div_mode;
-@@ -3707,6 +3838,7 @@ static int rt2800_init_rfcsr(struct rt2x
- !rt2x00_rt(rt2x00dev, RT3071) &&
- !rt2x00_rt(rt2x00dev, RT3090) &&
- !rt2x00_rt(rt2x00dev, RT3290) &&
-+ !rt2x00_rt(rt2x00dev, RT3352) &&
- !rt2x00_rt(rt2x00dev, RT3390) &&
- !rt2x00_rt(rt2x00dev, RT3572) &&
- !rt2x00_rt(rt2x00dev, RT5390) &&
-@@ -3903,6 +4035,70 @@ static int rt2800_init_rfcsr(struct rt2x
- rt2800_rfcsr_write(rt2x00dev, 30, 0x00);
- rt2800_rfcsr_write(rt2x00dev, 31, 0x00);
- return 0;
-+ } else if (rt2x00_rt(rt2x00dev, RT3352)) {
-+ rt2800_rfcsr_write(rt2x00dev, 0, 0xf0);
-+ rt2800_rfcsr_write(rt2x00dev, 1, 0x23);
-+ rt2800_rfcsr_write(rt2x00dev, 2, 0x50);
-+ rt2800_rfcsr_write(rt2x00dev, 3, 0x18);
-+ rt2800_rfcsr_write(rt2x00dev, 4, 0x00);
-+ rt2800_rfcsr_write(rt2x00dev, 5, 0x00);
-+ rt2800_rfcsr_write(rt2x00dev, 6, 0x33);
-+ rt2800_rfcsr_write(rt2x00dev, 7, 0x00);
-+ rt2800_rfcsr_write(rt2x00dev, 8, 0xf1);
-+ rt2800_rfcsr_write(rt2x00dev, 9, 0x02);
-+ rt2800_rfcsr_write(rt2x00dev, 10, 0xd2);
-+ rt2800_rfcsr_write(rt2x00dev, 11, 0x42);
-+ rt2800_rfcsr_write(rt2x00dev, 12, 0x1c);
-+ rt2800_rfcsr_write(rt2x00dev, 13, 0x00);
-+ rt2800_rfcsr_write(rt2x00dev, 14, 0x5a);
-+ rt2800_rfcsr_write(rt2x00dev, 15, 0x00);
-+ rt2800_rfcsr_write(rt2x00dev, 16, 0x01);
-+ rt2800_rfcsr_write(rt2x00dev, 18, 0x45);
-+ rt2800_rfcsr_write(rt2x00dev, 19, 0x02);
-+ rt2800_rfcsr_write(rt2x00dev, 20, 0x00);
-+ rt2800_rfcsr_write(rt2x00dev, 21, 0x00);
-+ rt2800_rfcsr_write(rt2x00dev, 22, 0x00);
-+ rt2800_rfcsr_write(rt2x00dev, 23, 0x00);
-+ rt2800_rfcsr_write(rt2x00dev, 24, 0x00);
-+ rt2800_rfcsr_write(rt2x00dev, 25, 0x80);
-+ rt2800_rfcsr_write(rt2x00dev, 26, 0x00);
-+ rt2800_rfcsr_write(rt2x00dev, 27, 0x03);
-+ rt2800_rfcsr_write(rt2x00dev, 28, 0x03);
-+ rt2800_rfcsr_write(rt2x00dev, 29, 0x00);
-+ rt2800_rfcsr_write(rt2x00dev, 30, 0x10);
-+ rt2800_rfcsr_write(rt2x00dev, 31, 0x80);
-+ rt2800_rfcsr_write(rt2x00dev, 32, 0x80);
-+ rt2800_rfcsr_write(rt2x00dev, 33, 0x00);
-+ rt2800_rfcsr_write(rt2x00dev, 34, 0x01);
-+ rt2800_rfcsr_write(rt2x00dev, 35, 0x03);
-+ rt2800_rfcsr_write(rt2x00dev, 36, 0xbd);
-+ rt2800_rfcsr_write(rt2x00dev, 37, 0x3c);
-+ rt2800_rfcsr_write(rt2x00dev, 38, 0x5f);
-+ rt2800_rfcsr_write(rt2x00dev, 39, 0xc5);
-+ rt2800_rfcsr_write(rt2x00dev, 40, 0x33);
-+ rt2800_rfcsr_write(rt2x00dev, 41, 0x5b);
-+ rt2800_rfcsr_write(rt2x00dev, 42, 0x5b);
-+ rt2800_rfcsr_write(rt2x00dev, 43, 0xdb);
-+ rt2800_rfcsr_write(rt2x00dev, 44, 0xdb);
-+ rt2800_rfcsr_write(rt2x00dev, 45, 0xdb);
-+ rt2800_rfcsr_write(rt2x00dev, 46, 0xdd);
-+ rt2800_rfcsr_write(rt2x00dev, 47, 0x0d);
-+ rt2800_rfcsr_write(rt2x00dev, 48, 0x14);
-+ rt2800_rfcsr_write(rt2x00dev, 49, 0x00);
-+ rt2800_rfcsr_write(rt2x00dev, 50, 0x2d);
-+ rt2800_rfcsr_write(rt2x00dev, 51, 0x7f);
-+ rt2800_rfcsr_write(rt2x00dev, 52, 0x00);
-+ rt2800_rfcsr_write(rt2x00dev, 53, 0x52);
-+ rt2800_rfcsr_write(rt2x00dev, 54, 0x1b);
-+ rt2800_rfcsr_write(rt2x00dev, 55, 0x7f);
-+ rt2800_rfcsr_write(rt2x00dev, 56, 0x00);
-+ rt2800_rfcsr_write(rt2x00dev, 57, 0x52);
-+ rt2800_rfcsr_write(rt2x00dev, 58, 0x1b);
-+ rt2800_rfcsr_write(rt2x00dev, 59, 0x00);
-+ rt2800_rfcsr_write(rt2x00dev, 60, 0x00);
-+ rt2800_rfcsr_write(rt2x00dev, 61, 0x00);
-+ rt2800_rfcsr_write(rt2x00dev, 62, 0x00);
-+ rt2800_rfcsr_write(rt2x00dev, 63, 0x00);
- } else if (rt2x00_rt(rt2x00dev, RT5390)) {
- rt2800_rfcsr_write(rt2x00dev, 1, 0x0f);
- rt2800_rfcsr_write(rt2x00dev, 2, 0x80);
-@@ -4104,6 +4300,7 @@ static int rt2800_init_rfcsr(struct rt2x
- rt2800_init_rx_filter(rt2x00dev, true, 0x27, 0x19);
- } else if (rt2x00_rt(rt2x00dev, RT3071) ||
- rt2x00_rt(rt2x00dev, RT3090) ||
-+ rt2x00_rt(rt2x00dev, RT3352) ||
- rt2x00_rt(rt2x00dev, RT3390) ||
- rt2x00_rt(rt2x00dev, RT3572)) {
- drv_data->calibration_bw20 =
-@@ -4566,6 +4763,7 @@ static int rt2800_init_eeprom(struct rt2
- case RT3071:
- case RT3090:
- case RT3290:
-+ case RT3352:
- case RT3390:
- case RT3572:
- case RT5390:
-@@ -4588,6 +4786,7 @@ static int rt2800_init_eeprom(struct rt2
- case RF3052:
- case RF3290:
- case RF3320:
-+ case RF3322:
- case RF5360:
- case RF5370:
- case RF5372:
-@@ -4612,6 +4811,7 @@ static int rt2800_init_eeprom(struct rt2
-
- if (rt2x00_rt(rt2x00dev, RT3070) ||
- rt2x00_rt(rt2x00dev, RT3090) ||
-+ rt2x00_rt(rt2x00dev, RT3352) ||
- rt2x00_rt(rt2x00dev, RT3390)) {
- value = rt2x00_get_field16(eeprom,
- EEPROM_NIC_CONF1_ANT_DIVERSITY);
-@@ -4904,6 +5104,7 @@ static int rt2800_probe_hw_mode(struct r
- rt2x00_rf(rt2x00dev, RF3022) ||
- rt2x00_rf(rt2x00dev, RF3290) ||
- rt2x00_rf(rt2x00dev, RF3320) ||
-+ rt2x00_rf(rt2x00dev, RF3322) ||
- rt2x00_rf(rt2x00dev, RF5360) ||
- rt2x00_rf(rt2x00dev, RF5370) ||
- rt2x00_rf(rt2x00dev, RF5372) ||
---- a/drivers/net/wireless/rt2x00/rt2x00.h
-+++ b/drivers/net/wireless/rt2x00/rt2x00.h
-@@ -189,6 +189,7 @@ struct rt2x00_chip {
- #define RT3071 0x3071
- #define RT3090 0x3090 /* 2.4GHz PCIe */
- #define RT3290 0x3290
-+#define RT3352 0x3352 /* WSOC */
- #define RT3390 0x3390
- #define RT3572 0x3572
- #define RT3593 0x3593
diff --git a/package/mac80211/patches/621-rt2x00-fix-rt3352-lnagain.patch b/package/mac80211/patches/621-rt2x00-fix-rt3352-lnagain.patch
deleted file mode 100644
index b84c42cdf5..0000000000
--- a/package/mac80211/patches/621-rt2x00-fix-rt3352-lnagain.patch
+++ /dev/null
@@ -1,25 +0,0 @@
-From d0ae5f33c0221339a50bd1005c569934417003a5 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <dgolle@allnet.de>
-Date: Thu, 4 Oct 2012 00:34:01 +0200
-Subject: [PATCH] rt2x00/rt3352: Fix lnagain assignment to use register 66.
-To: users@rt2x00.serialmonkey.com
-Cc: gwingerde@gmail.com
-
----
- drivers/net/wireless/rt2x00/rt2800lib.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
---- a/drivers/net/wireless/rt2x00/rt2800lib.c
-+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
-@@ -2273,9 +2273,9 @@ static void rt2800_config_channel(struct
- */
- if (rt2x00_rt(rt2x00dev, RT3352)) {
- rt2800_bbp_write(rt2x00dev, 27, 0x0);
-- rt2800_bbp_write(rt2x00dev, 62, 0x26 + rt2x00dev->lna_gain);
-+ rt2800_bbp_write(rt2x00dev, 66, 0x26 + rt2x00dev->lna_gain);
- rt2800_bbp_write(rt2x00dev, 27, 0x20);
-- rt2800_bbp_write(rt2x00dev, 62, 0x26 + rt2x00dev->lna_gain);
-+ rt2800_bbp_write(rt2x00dev, 66, 0x26 + rt2x00dev->lna_gain);
- } else {
- rt2800_bbp_write(rt2x00dev, 62, 0x37 - rt2x00dev->lna_gain);
- rt2800_bbp_write(rt2x00dev, 63, 0x37 - rt2x00dev->lna_gain);
diff --git a/package/mac80211/patches/622-rt2x00-fix-rt3352-ext-pa.patch b/package/mac80211/patches/622-rt2x00-fix-rt3352-ext-pa.patch
deleted file mode 100644
index 8015a12090..0000000000
--- a/package/mac80211/patches/622-rt2x00-fix-rt3352-ext-pa.patch
+++ /dev/null
@@ -1,212 +0,0 @@
---- a/drivers/net/wireless/rt2x00/rt2800lib.c
-+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
-@@ -2271,15 +2271,18 @@ static void rt2800_config_channel(struct
- /*
- * Change BBP settings
- */
-+ rt2800_bbp_write(rt2x00dev, 62, 0x37 - rt2x00dev->lna_gain);
-+ rt2800_bbp_write(rt2x00dev, 63, 0x37 - rt2x00dev->lna_gain);
-+ rt2800_bbp_write(rt2x00dev, 64, 0x37 - rt2x00dev->lna_gain);
-+
- if (rt2x00_rt(rt2x00dev, RT3352)) {
- rt2800_bbp_write(rt2x00dev, 27, 0x0);
- rt2800_bbp_write(rt2x00dev, 66, 0x26 + rt2x00dev->lna_gain);
- rt2800_bbp_write(rt2x00dev, 27, 0x20);
- rt2800_bbp_write(rt2x00dev, 66, 0x26 + rt2x00dev->lna_gain);
-+ rt2800_bbp_write(rt2x00dev, 86, 0x38);
-+ rt2800_bbp_write(rt2x00dev, 83, 0x6a);
- } else {
-- rt2800_bbp_write(rt2x00dev, 62, 0x37 - rt2x00dev->lna_gain);
-- rt2800_bbp_write(rt2x00dev, 63, 0x37 - rt2x00dev->lna_gain);
-- rt2800_bbp_write(rt2x00dev, 64, 0x37 - rt2x00dev->lna_gain);
- rt2800_bbp_write(rt2x00dev, 86, 0);
- }
-
-@@ -3850,6 +3853,7 @@ static int rt2800_init_rfcsr(struct rt2x
- * Init RF calibration.
- */
- if (rt2x00_rt(rt2x00dev, RT3290) ||
-+ rt2x00_rt(rt2x00dev, RT3352) ||
- rt2x00_rt(rt2x00dev, RT5390) ||
- rt2x00_rt(rt2x00dev, RT5392)) {
- rt2800_rfcsr_read(rt2x00dev, 2, &rfcsr);
-@@ -4036,6 +4040,10 @@ static int rt2800_init_rfcsr(struct rt2x
- rt2800_rfcsr_write(rt2x00dev, 31, 0x00);
- return 0;
- } else if (rt2x00_rt(rt2x00dev, RT3352)) {
-+ int tx0_int_pa = test_bit(CAPABILITY_INTERNAL_PA_TX0,
-+ &rt2x00dev->cap_flags);
-+ int tx1_int_pa = test_bit(CAPABILITY_INTERNAL_PA_TX1,
-+ &rt2x00dev->cap_flags);
- rt2800_rfcsr_write(rt2x00dev, 0, 0xf0);
- rt2800_rfcsr_write(rt2x00dev, 1, 0x23);
- rt2800_rfcsr_write(rt2x00dev, 2, 0x50);
-@@ -4069,15 +4077,30 @@ static int rt2800_init_rfcsr(struct rt2x
- rt2800_rfcsr_write(rt2x00dev, 31, 0x80);
- rt2800_rfcsr_write(rt2x00dev, 32, 0x80);
- rt2800_rfcsr_write(rt2x00dev, 33, 0x00);
-- rt2800_rfcsr_write(rt2x00dev, 34, 0x01);
-+ rfcsr = 0x01;
-+ if (!tx0_int_pa)
-+ rt2x00_set_field8(&rfcsr, RFCSR34_TX0_EXT_PA, 1);
-+ if (!tx1_int_pa)
-+ rt2x00_set_field8(&rfcsr, RFCSR34_TX1_EXT_PA, 1);
-+ rt2800_rfcsr_write(rt2x00dev, 34, rfcsr );
- rt2800_rfcsr_write(rt2x00dev, 35, 0x03);
- rt2800_rfcsr_write(rt2x00dev, 36, 0xbd);
- rt2800_rfcsr_write(rt2x00dev, 37, 0x3c);
- rt2800_rfcsr_write(rt2x00dev, 38, 0x5f);
- rt2800_rfcsr_write(rt2x00dev, 39, 0xc5);
- rt2800_rfcsr_write(rt2x00dev, 40, 0x33);
-- rt2800_rfcsr_write(rt2x00dev, 41, 0x5b);
-- rt2800_rfcsr_write(rt2x00dev, 42, 0x5b);
-+ rfcsr = 0x52;
-+ if (tx0_int_pa) {
-+ rt2x00_set_field8(&rfcsr, RFCSR41_BIT1, 1);
-+ rt2x00_set_field8(&rfcsr, RFCSR41_BIT4, 1);
-+ }
-+ rt2800_rfcsr_write(rt2x00dev, 41, rfcsr);
-+ rfcsr = 0x52;
-+ if (tx1_int_pa) {
-+ rt2x00_set_field8(&rfcsr, RFCSR42_BIT1, 1);
-+ rt2x00_set_field8(&rfcsr, RFCSR42_BIT4, 1);
-+ }
-+ rt2800_rfcsr_write(rt2x00dev, 42, rfcsr);
- rt2800_rfcsr_write(rt2x00dev, 43, 0xdb);
- rt2800_rfcsr_write(rt2x00dev, 44, 0xdb);
- rt2800_rfcsr_write(rt2x00dev, 45, 0xdb);
-@@ -4085,15 +4108,20 @@ static int rt2800_init_rfcsr(struct rt2x
- rt2800_rfcsr_write(rt2x00dev, 47, 0x0d);
- rt2800_rfcsr_write(rt2x00dev, 48, 0x14);
- rt2800_rfcsr_write(rt2x00dev, 49, 0x00);
-- rt2800_rfcsr_write(rt2x00dev, 50, 0x2d);
-- rt2800_rfcsr_write(rt2x00dev, 51, 0x7f);
-- rt2800_rfcsr_write(rt2x00dev, 52, 0x00);
-- rt2800_rfcsr_write(rt2x00dev, 53, 0x52);
-- rt2800_rfcsr_write(rt2x00dev, 54, 0x1b);
-- rt2800_rfcsr_write(rt2x00dev, 55, 0x7f);
-- rt2800_rfcsr_write(rt2x00dev, 56, 0x00);
-- rt2800_rfcsr_write(rt2x00dev, 57, 0x52);
-- rt2800_rfcsr_write(rt2x00dev, 58, 0x1b);
-+ rfcsr = 0x2d;
-+ if (!tx0_int_pa)
-+ rt2x00_set_field8(&rfcsr, RFCSR50_TX0_EXT_PA, 1);
-+ if (!tx1_int_pa)
-+ rt2x00_set_field8(&rfcsr, RFCSR50_TX1_EXT_PA, 1);
-+ rt2800_rfcsr_write(rt2x00dev, 50, rfcsr);
-+ rt2800_rfcsr_write(rt2x00dev, 51, (tx0_int_pa ? 0x7f : 0x52));
-+ rt2800_rfcsr_write(rt2x00dev, 52, (tx0_int_pa ? 0x00 : 0xc0));
-+ rt2800_rfcsr_write(rt2x00dev, 53, (tx0_int_pa ? 0x52 : 0xd2));
-+ rt2800_rfcsr_write(rt2x00dev, 54, (tx0_int_pa ? 0x1b : 0xc0));
-+ rt2800_rfcsr_write(rt2x00dev, 55, (tx1_int_pa ? 0x7f : 0x52));
-+ rt2800_rfcsr_write(rt2x00dev, 56, (tx1_int_pa ? 0x00 : 0xc0));
-+ rt2800_rfcsr_write(rt2x00dev, 57, (tx0_int_pa ? 0x52 : 0x49));
-+ rt2800_rfcsr_write(rt2x00dev, 58, (tx1_int_pa ? 0x1b : 0xc0));
- rt2800_rfcsr_write(rt2x00dev, 59, 0x00);
- rt2800_rfcsr_write(rt2x00dev, 60, 0x00);
- rt2800_rfcsr_write(rt2x00dev, 61, 0x00);
-@@ -4854,7 +4882,8 @@ static int rt2800_init_eeprom(struct rt2
- /*
- * Detect if this device has Bluetooth co-existence.
- */
-- if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_BT_COEXIST))
-+ if (!rt2x00_rt(rt2x00dev, RT3352) &&
-+ rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_BT_COEXIST))
- __set_bit(CAPABILITY_BT_COEXIST, &rt2x00dev->cap_flags);
-
- /*
-@@ -4883,6 +4912,22 @@ static int rt2800_init_eeprom(struct rt2
- EIRP_MAX_TX_POWER_LIMIT)
- __set_bit(CAPABILITY_POWER_LIMIT, &rt2x00dev->cap_flags);
-
-+ /*
-+ * Detect if device uses internal or external PA
-+ */
-+ rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom);
-+
-+ if (rt2x00_rt(rt2x00dev, RT3352)) {
-+ if (!rt2x00_get_field16(eeprom,
-+ EEPROM_NIC_CONF1_EXTERNAL_TX0_PA_3352))
-+ __set_bit(CAPABILITY_INTERNAL_PA_TX0,
-+ &rt2x00dev->cap_flags);
-+ if (!rt2x00_get_field16(eeprom,
-+ EEPROM_NIC_CONF1_EXTERNAL_TX1_PA_3352))
-+ __set_bit(CAPABILITY_INTERNAL_PA_TX1,
-+ &rt2x00dev->cap_flags);
-+ }
-+
- return 0;
- }
-
---- a/drivers/net/wireless/rt2x00/rt2800.h
-+++ b/drivers/net/wireless/rt2x00/rt2800.h
-@@ -2115,6 +2115,12 @@ struct mac_iveiv_entry {
- #define RFCSR31_RX_CALIB FIELD8(0x7f)
-
- /*
-+ * RFCSR 34:
-+ */
-+#define RFCSR34_TX0_EXT_PA FIELD8(0x04)
-+#define RFCSR34_TX1_EXT_PA FIELD8(0x08)
-+
-+/*
- * RFCSR 38:
- */
- #define RFCSR38_RX_LO1_EN FIELD8(0x20)
-@@ -2125,6 +2131,18 @@ struct mac_iveiv_entry {
- #define RFCSR39_RX_LO2_EN FIELD8(0x80)
-
- /*
-+ * RFCSR 41:
-+ */
-+#define RFCSR41_BIT1 FIELD8(0x01)
-+#define RFCSR41_BIT4 FIELD8(0x08)
-+
-+/*
-+ * RFCSR 42:
-+ */
-+#define RFCSR42_BIT1 FIELD8(0x01)
-+#define RFCSR42_BIT4 FIELD8(0x08)
-+
-+/*
- * RFCSR 49:
- */
- #define RFCSR49_TX FIELD8(0x3f)
-@@ -2133,6 +2151,8 @@ struct mac_iveiv_entry {
- * RFCSR 50:
- */
- #define RFCSR50_TX FIELD8(0x3f)
-+#define RFCSR50_TX0_EXT_PA FIELD8(0x02)
-+#define RFCSR50_TX1_EXT_PA FIELD8(0x10)
-
- /*
- * RF registers
-@@ -2220,6 +2240,8 @@ struct mac_iveiv_entry {
- * INTERNAL_TX_ALC: 0: disable, 1: enable
- * BT_COEXIST: 0: disable, 1: enable
- * DAC_TEST: 0: disable, 1: enable
-+ * EXTERNAL_TX0_PA: 0: disable, 1: enable (only on RT3352)
-+ * EXTERNAL_TX1_PA: 0: disable, 1: enable (only on RT3352)
- */
- #define EEPROM_NIC_CONF1 0x001b
- #define EEPROM_NIC_CONF1_HW_RADIO FIELD16(0x0001)
-@@ -2237,6 +2259,8 @@ struct mac_iveiv_entry {
- #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)
-+#define EEPROM_NIC_CONF1_EXTERNAL_TX0_PA_3352 FIELD16(0x4000)
-+#define EEPROM_NIC_CONF1_EXTERNAL_TX1_PA_3352 FIELD16(0x8000)
-
- /*
- * EEPROM frequency
---- a/drivers/net/wireless/rt2x00/rt2x00.h
-+++ b/drivers/net/wireless/rt2x00/rt2x00.h
-@@ -743,6 +743,8 @@ enum rt2x00_capability_flags {
- CAPABILITY_DOUBLE_ANTENNA,
- CAPABILITY_BT_COEXIST,
- CAPABILITY_VCO_RECALIBRATION,
-+ CAPABILITY_INTERNAL_PA_TX0,
-+ CAPABILITY_INTERNAL_PA_TX1,
- };
-
- /*
diff --git a/package/mac80211/patches/700-mwl8k-missing-pci-id-for-WNR854T.patch b/package/mac80211/patches/700-mwl8k-missing-pci-id-for-WNR854T.patch
index 7ebc4f12d5..80fde275cd 100644
--- a/package/mac80211/patches/700-mwl8k-missing-pci-id-for-WNR854T.patch
+++ b/package/mac80211/patches/700-mwl8k-missing-pci-id-for-WNR854T.patch
@@ -1,6 +1,6 @@
--- a/drivers/net/wireless/mwl8k.c
+++ b/drivers/net/wireless/mwl8k.c
-@@ -5302,6 +5302,7 @@ MODULE_FIRMWARE("mwl8k/fmimage_8366.fw")
+@@ -5497,6 +5497,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) = {
diff --git a/package/mac80211/patches/701-mwl8k-don-t-overwrite-regulatory-settings.patch b/package/mac80211/patches/701-mwl8k-don-t-overwrite-regulatory-settings.patch
new file mode 100644
index 0000000000..890debc47f
--- /dev/null
+++ b/package/mac80211/patches/701-mwl8k-don-t-overwrite-regulatory-settings.patch
@@ -0,0 +1,70 @@
+From f340b99171e923eb6b54c1d0c22c15b45df40647 Mon Sep 17 00:00:00 2001
+From: Jonas Gorski <jogo@openwrt.org>
+Date: Mon, 11 Mar 2013 17:17:28 +0100
+Subject: [PATCH] mwl8k: don't overwrite regulatory settings
+
+Currently the caps are parsed on every firmware reload, causing any
+channel flags to be cleared.
+When there is a firmware to interface mode mismatch, the triggered
+firmware reload causes a reset of the regulatory settings, causing all
+channels to become available:
+
+root@openrouter:/# iw phy phy0 info
+Wiphy phy0
+ Band 1:
+ (...)
+ Frequencies:
+ * 2412 MHz [1] (0.0 dBm)
+ * 2417 MHz [2] (0.0 dBm)
+ * 2422 MHz [3] (0.0 dBm)
+ * 2427 MHz [4] (0.0 dBm)
+ * 2432 MHz [5] (0.0 dBm)
+ * 2437 MHz [6] (0.0 dBm)
+ * 2442 MHz [7] (0.0 dBm)
+ * 2447 MHz [8] (0.0 dBm)
+ * 2452 MHz [9] (0.0 dBm)
+ * 2457 MHz [10] (0.0 dBm)
+ * 2462 MHz [11] (0.0 dBm)
+ * 2467 MHz [12] (0.0 dBm)
+ * 2472 MHz [13] (0.0 dBm)
+ * 2484 MHz [14] (0.0 dBm)
+ (...)
+
+To prevent this, only parse the caps on the first firmware load during
+hardware probe, and store them locally to know we have already parsed
+them.
+
+Signed-off-by: Jonas Gorski <jogo@openwrt.org>
+---
+ drivers/net/wireless/mwl8k.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/drivers/net/wireless/mwl8k.c
++++ b/drivers/net/wireless/mwl8k.c
+@@ -232,6 +232,7 @@ struct mwl8k_priv {
+ u16 num_mcaddrs;
+ u8 hw_rev;
+ u32 fw_rev;
++ u32 caps;
+
+ /*
+ * Running count of TX packets in flight, to avoid
+@@ -2401,6 +2402,9 @@ mwl8k_set_caps(struct ieee80211_hw *hw,
+ {
+ struct mwl8k_priv *priv = hw->priv;
+
++ if (priv->caps)
++ return;
++
+ if ((caps & MWL8K_CAP_2GHZ4) || !(caps & MWL8K_CAP_BAND_MASK)) {
+ mwl8k_setup_2ghz_band(hw);
+ if (caps & MWL8K_CAP_MIMO)
+@@ -2412,6 +2416,8 @@ mwl8k_set_caps(struct ieee80211_hw *hw,
+ if (caps & MWL8K_CAP_MIMO)
+ mwl8k_set_ht_caps(hw, &priv->band_50, caps);
+ }
++
++ priv->caps = caps;
+ }
+
+ static int mwl8k_cmd_get_hw_spec_sta(struct ieee80211_hw *hw)
diff --git a/package/mac80211/patches/702-mwl8k-always-apply-configuration-even-when-device-is.patch b/package/mac80211/patches/702-mwl8k-always-apply-configuration-even-when-device-is.patch
new file mode 100644
index 0000000000..ff254790d7
--- /dev/null
+++ b/package/mac80211/patches/702-mwl8k-always-apply-configuration-even-when-device-is.patch
@@ -0,0 +1,44 @@
+From 5d1ed64614ccb21c26bc0ee321e9c51b6359ceb8 Mon Sep 17 00:00:00 2001
+From: Jonas Gorski <jogo@openwrt.org>
+Date: Mon, 25 Mar 2013 15:37:42 +0100
+Subject: [PATCH] mwl8k: always apply configuration even when device is idle
+
+Fix settings not being applied when the device is idle and the firmware
+gets reloaded (because of changing from STA to AP mode). This caused
+the device using the wrong channel (and likely band), e.g. a 5 GHz only
+card still defaulted to channel 6 in the 2.4 GHz band when left
+unconfigured.
+
+This issue was always present, but only made visible with "mwl8k: Do not
+call mwl8k_cmd_set_rf_channel unconditionally" (0f4316b9), since before
+that the channel was (re-)configured at the next _config call even when
+it did not change from the mac80211 perspective.
+
+Signed-off-by: Jonas Gorski <jogo@openwrt.org>
+---
+ drivers/net/wireless/mwl8k.c | 10 ++++------
+ 1 file changed, 4 insertions(+), 6 deletions(-)
+
+--- a/drivers/net/wireless/mwl8k.c
++++ b/drivers/net/wireless/mwl8k.c
+@@ -4818,16 +4818,14 @@ static int mwl8k_config(struct ieee80211
+ struct mwl8k_priv *priv = hw->priv;
+ int rc;
+
+- if (conf->flags & IEEE80211_CONF_IDLE) {
+- mwl8k_cmd_radio_disable(hw);
+- return 0;
+- }
+-
+ rc = mwl8k_fw_lock(hw);
+ if (rc)
+ return rc;
+
+- rc = mwl8k_cmd_radio_enable(hw);
++ if (conf->flags & IEEE80211_CONF_IDLE)
++ rc = mwl8k_cmd_radio_disable(hw);
++ else
++ rc = mwl8k_cmd_radio_enable(hw);
+ if (rc)
+ goto out;
+
diff --git a/package/mac80211/patches/800-b43-gpio-mask-module-option.patch b/package/mac80211/patches/800-b43-gpio-mask-module-option.patch
index 55ab0aa3a2..d8fb06de57 100644
--- a/package/mac80211/patches/800-b43-gpio-mask-module-option.patch
+++ b/package/mac80211/patches/800-b43-gpio-mask-module-option.patch
@@ -1,6 +1,6 @@
--- a/drivers/net/wireless/b43/b43.h
+++ b/drivers/net/wireless/b43/b43.h
-@@ -807,6 +807,7 @@ struct b43_wldev {
+@@ -812,6 +812,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,
-@@ -2688,10 +2693,10 @@ static int b43_gpio_init(struct b43_wlde
+@@ -2740,10 +2745,10 @@ static int b43_gpio_init(struct b43_wlde
u32 mask, set;
b43_maskset32(dev, B43_MMIO_MACCTL, ~B43_MACCTL_GPOUTSMSK, 0);
diff --git a/package/mac80211/patches/810-b43_no_pio.patch b/package/mac80211/patches/810-b43_no_pio.patch
index f511795b17..5b4c22e520 100644
--- a/package/mac80211/patches/810-b43_no_pio.patch
+++ b/package/mac80211/patches/810-b43_no_pio.patch
@@ -11,7 +11,7 @@
b43-$(CONFIG_B43_PCMCIA) += pcmcia.o
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
-@@ -1885,10 +1885,12 @@ static void b43_do_interrupt_thread(stru
+@@ -1909,10 +1909,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]);
diff --git a/package/mac80211/patches/820-b43-add-antenna-control.patch b/package/mac80211/patches/820-b43-add-antenna-control.patch
index 551213d5f9..8b6255f2c0 100644
--- a/package/mac80211/patches/820-b43-add-antenna-control.patch
+++ b/package/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
-@@ -1529,7 +1529,7 @@ static void b43_write_beacon_template(st
+@@ -1553,7 +1553,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. */
-@@ -3049,8 +3049,8 @@ static int b43_chip_init(struct b43_wlde
+@@ -3101,8 +3101,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);
-@@ -3794,7 +3794,6 @@ static int b43_op_config(struct ieee8021
+@@ -3846,7 +3846,6 @@ static int b43_op_config(struct ieee8021
struct b43_wldev *dev;
struct b43_phy *phy;
struct ieee80211_conf *conf = &hw->conf;
@@ -28,7 +28,7 @@
int err = 0;
bool reload_bss = false;
-@@ -3848,11 +3847,9 @@ static int b43_op_config(struct ieee8021
+@@ -3900,11 +3899,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) {
-@@ -4974,6 +4971,47 @@ static int b43_op_get_survey(struct ieee
+@@ -5030,6 +5027,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,
-@@ -4995,6 +5033,8 @@ static const struct ieee80211_ops b43_hw
+@@ -5051,6 +5089,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.
-@@ -5241,6 +5281,8 @@ static int b43_one_core_attach(struct b4
+@@ -5297,6 +5337,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;
-@@ -5331,6 +5373,9 @@ static struct b43_wl *b43_wireless_init(
+@@ -5387,6 +5429,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
-@@ -808,6 +808,8 @@ struct b43_wldev {
+@@ -813,6 +813,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 */
diff --git a/package/mac80211/patches/830-b43-workaround-pcie-bcm4716.patch b/package/mac80211/patches/830-b43-workaround-pcie-bcm4716.patch
index ce9ad7d5c4..bd10f996c2 100644
--- a/package/mac80211/patches/830-b43-workaround-pcie-bcm4716.patch
+++ b/package/mac80211/patches/830-b43-workaround-pcie-bcm4716.patch
@@ -19,7 +19,7 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
--- a/drivers/net/wireless/b43/b43.h
+++ b/drivers/net/wireless/b43/b43.h
-@@ -1048,6 +1048,32 @@ static inline bool b43_using_pio_transfe
+@@ -1053,6 +1053,32 @@ static inline bool b43_using_pio_transfe
return dev->__using_pio_transfers;
}
diff --git a/package/mac80211/patches/849-brcmsmac-add-device-found-on-some-SoCs-like-the-bcm4.patch b/package/mac80211/patches/849-brcmsmac-add-device-found-on-some-SoCs-like-the-bcm4.patch
deleted file mode 100644
index f70a261f03..0000000000
--- a/package/mac80211/patches/849-brcmsmac-add-device-found-on-some-SoCs-like-the-bcm4.patch
+++ /dev/null
@@ -1,39 +0,0 @@
---- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
-+++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
-@@ -94,6 +94,7 @@ MODULE_FIRMWARE("brcm/bcm43xx_hdr-0.fw")
-
- /* recognized BCMA Core IDs */
- static struct bcma_device_id brcms_coreid_table[] = {
-+// BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 17, BCMA_ANY_CLASS),
- BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 23, BCMA_ANY_CLASS),
- BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 24, BCMA_ANY_CLASS),
- BCMA_CORETABLE_END
---- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
-+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
-@@ -734,7 +734,7 @@ static void brcms_c_ucode_bsinit(struct
- brcms_c_write_mhf(wlc_hw, wlc_hw->band->mhfs);
-
- /* do band-specific ucode IHR, SHM, and SCR inits */
-- if (D11REV_IS(wlc_hw->corerev, 23)) {
-+ if (D11REV_IS(wlc_hw->corerev, 17) || D11REV_IS(wlc_hw->corerev, 23)) {
- if (BRCMS_ISNPHY(wlc_hw->band))
- brcms_c_write_inits(wlc_hw, ucode->d11n0bsinitvals16);
- else
-@@ -2259,7 +2259,7 @@ static void brcms_ucode_download(struct
- if (wlc_hw->ucode_loaded)
- return;
-
-- if (D11REV_IS(wlc_hw->corerev, 23)) {
-+ if (D11REV_IS(wlc_hw->corerev, 17) || D11REV_IS(wlc_hw->corerev, 23)) {
- if (BRCMS_ISNPHY(wlc_hw->band)) {
- brcms_ucode_write(wlc_hw, ucode->bcm43xx_16_mimo,
- ucode->bcm43xx_16_mimosz);
-@@ -3221,7 +3221,7 @@ static void brcms_b_coreinit(struct brcm
-
- sflags = bcma_aread32(core, BCMA_IOST);
-
-- if (D11REV_IS(wlc_hw->corerev, 23)) {
-+ if (D11REV_IS(wlc_hw->corerev, 17) || D11REV_IS(wlc_hw->corerev, 23)) {
- if (BRCMS_ISNPHY(wlc_hw->band))
- brcms_c_write_inits(wlc_hw, ucode->d11n0initvals16);
- else
diff --git a/package/mac80211/patches/850-brcmsmac-add-support-for-BCM43224.patch b/package/mac80211/patches/850-brcmsmac-add-support-for-BCM43224.patch
deleted file mode 100644
index b135c7d3ff..0000000000
--- a/package/mac80211/patches/850-brcmsmac-add-support-for-BCM43224.patch
+++ /dev/null
@@ -1,29 +0,0 @@
---- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
-+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
-@@ -4135,6 +4135,7 @@ void brcms_c_wme_setparams(struct brcms_
- M_EDCF_QINFO +
- wme_ac2fifo[aci] * M_EDCF_QLEN + i,
- *shm_entry++);
-+ printk("dummy\n");
- }
-
- if (suspend) {
-@@ -4537,7 +4538,8 @@ static int brcms_b_attach(struct brcms_c
-
- /* check device id(srom, nvram etc.) to set bands */
- if (wlc_hw->deviceid == BCM43224_D11N_ID ||
-- wlc_hw->deviceid == BCM43224_D11N_ID_VEN1)
-+ wlc_hw->deviceid == BCM43224_D11N_ID_VEN1 ||
-+ wlc_hw->deviceid == BCM43224_CHIP_ID)
- /* Dualband boards */
- wlc_hw->_nbands = 2;
- else
-@@ -5797,7 +5799,7 @@ static bool brcms_c_chipmatch_pci(struct
- return false;
- }
-
-- if (device == BCM43224_D11N_ID_VEN1)
-+ if (device == BCM43224_D11N_ID_VEN1 || device == BCM43224_CHIP_ID)
- return true;
- if ((device == BCM43224_D11N_ID) || (device == BCM43225_D11N2G_ID))
- return true;
diff --git a/package/mac80211/patches/851-brcmsmac-start-adding-support-for-core-rev-28.patch b/package/mac80211/patches/850-brcmsmac-start-adding-support-for-core-rev-28.patch
index 198af613cc..a84107df7d 100644
--- a/package/mac80211/patches/851-brcmsmac-start-adding-support-for-core-rev-28.patch
+++ b/package/mac80211/patches/850-brcmsmac-start-adding-support-for-core-rev-28.patch
@@ -1,7 +1,7 @@
--- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
-@@ -97,6 +97,7 @@ static struct bcma_device_id brcms_corei
- // BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 17, BCMA_ANY_CLASS),
+@@ -99,6 +99,7 @@ static struct bcma_device_id brcms_corei
+ BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 17, BCMA_ANY_CLASS),
BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 23, BCMA_ANY_CLASS),
BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 24, BCMA_ANY_CLASS),
+// BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 28, BCMA_ANY_CLASS),
@@ -10,7 +10,7 @@
MODULE_DEVICE_TABLE(bcma, brcms_coreid_table);
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
-@@ -734,7 +734,7 @@ static void brcms_c_ucode_bsinit(struct
+@@ -717,7 +717,7 @@ static void brcms_c_ucode_bsinit(struct
brcms_c_write_mhf(wlc_hw, wlc_hw->band->mhfs);
/* do band-specific ucode IHR, SHM, and SCR inits */
@@ -19,7 +19,7 @@
if (BRCMS_ISNPHY(wlc_hw->band))
brcms_c_write_inits(wlc_hw, ucode->d11n0bsinitvals16);
else
-@@ -2259,7 +2259,7 @@ static void brcms_ucode_download(struct
+@@ -2257,7 +2257,7 @@ static void brcms_ucode_download(struct
if (wlc_hw->ucode_loaded)
return;
@@ -28,7 +28,7 @@
if (BRCMS_ISNPHY(wlc_hw->band)) {
brcms_ucode_write(wlc_hw, ucode->bcm43xx_16_mimo,
ucode->bcm43xx_16_mimosz);
-@@ -3221,7 +3221,7 @@ static void brcms_b_coreinit(struct brcm
+@@ -3207,7 +3207,7 @@ static void brcms_b_coreinit(struct brcm
sflags = bcma_aread32(core, BCMA_IOST);
@@ -37,7 +37,7 @@
if (BRCMS_ISNPHY(wlc_hw->band))
brcms_c_write_inits(wlc_hw, ucode->d11n0initvals16);
else
-@@ -5818,6 +5818,8 @@ static bool brcms_c_chipmatch_soc(struct
+@@ -5663,6 +5663,8 @@ static bool brcms_c_chipmatch_soc(struct
if (chipinfo->id == BCMA_CHIP_ID_BCM4716)
return true;
diff --git a/package/mac80211/patches/860-brcmsmac-implement-ieee80211_ops-get_tsf-and-set_tsf.patch b/package/mac80211/patches/860-brcmsmac-implement-ieee80211_ops-get_tsf-and-set_tsf.patch
new file mode 100644
index 0000000000..33991bcf62
--- /dev/null
+++ b/package/mac80211/patches/860-brcmsmac-implement-ieee80211_ops-get_tsf-and-set_tsf.patch
@@ -0,0 +1,121 @@
+--- a/drivers/net/wireless/brcm80211/brcmsmac/d11.h
++++ b/drivers/net/wireless/brcm80211/brcmsmac/d11.h
+@@ -457,6 +457,7 @@ struct d11regs {
+ /*== maccontrol register ==*/
+ #define MCTL_GMODE (1U << 31)
+ #define MCTL_DISCARD_PMQ (1 << 30)
++#define MCTL_TBTTHOLD (1 << 28)
+ #define MCTL_WAKE (1 << 26)
+ #define MCTL_HPS (1 << 25)
+ #define MCTL_PROMISC (1 << 24)
+--- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
++++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
+@@ -741,6 +741,28 @@ static void brcms_ops_flush(struct ieee8
+ "ret=%d\n", jiffies_to_msecs(ret));
+ }
+
++static u64 brcms_ops_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
++{
++ struct brcms_info *wl = hw->priv;
++ u64 tsf;
++
++ spin_lock_bh(&wl->lock);
++ tsf = brcms_c_tsf_get(wl->wlc);
++ spin_unlock_bh(&wl->lock);
++
++ return tsf;
++}
++
++static void brcms_ops_set_tsf(struct ieee80211_hw *hw,
++ struct ieee80211_vif *vif, u64 tsf)
++{
++ struct brcms_info *wl = hw->priv;
++
++ spin_lock_bh(&wl->lock);
++ brcms_c_tsf_set(wl->wlc, tsf);
++ spin_unlock_bh(&wl->lock);
++}
++
+ static const struct ieee80211_ops brcms_ops = {
+ .tx = brcms_ops_tx,
+ .start = brcms_ops_start,
+@@ -757,6 +779,8 @@ static const struct ieee80211_ops brcms_
+ .ampdu_action = brcms_ops_ampdu_action,
+ .rfkill_poll = brcms_ops_rfkill_poll,
+ .flush = brcms_ops_flush,
++ .get_tsf = brcms_ops_get_tsf,
++ .set_tsf = brcms_ops_set_tsf,
+ };
+
+ void brcms_dpc(unsigned long data)
+--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
++++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
+@@ -5545,6 +5545,20 @@ int brcms_c_set_rateset(struct brcms_c_i
+ return bcmerror;
+ }
+
++static void brcms_c_time_lock(struct brcms_c_info *wlc)
++{
++ bcma_set32(wlc->hw->d11core, D11REGOFFS(maccontrol), MCTL_TBTTHOLD);
++ /* Commit the write */
++ bcma_read32(wlc->hw->d11core, D11REGOFFS(maccontrol));
++}
++
++static void brcms_c_time_unlock(struct brcms_c_info *wlc)
++{
++ bcma_mask32(wlc->hw->d11core, D11REGOFFS(maccontrol), ~MCTL_TBTTHOLD);
++ /* Commit the write */
++ bcma_read32(wlc->hw->d11core, D11REGOFFS(maccontrol));
++}
++
+ int brcms_c_set_beacon_period(struct brcms_c_info *wlc, u16 period)
+ {
+ if (period == 0)
+@@ -7530,6 +7544,36 @@ void brcms_c_set_beacon_listen_interval(
+ brcms_c_bcn_li_upd(wlc);
+ }
+
++u64 brcms_c_tsf_get(struct brcms_c_info *wlc)
++{
++ u32 tsf_h, tsf_l;
++ u64 tsf;
++
++ brcms_b_read_tsf(wlc->hw, &tsf_l, &tsf_h);
++
++ tsf = tsf_h;
++ tsf <<= 32;
++ tsf |= tsf_l;
++
++ return tsf;
++}
++
++void brcms_c_tsf_set(struct brcms_c_info *wlc, u64 tsf)
++{
++ u32 tsf_h, tsf_l;
++
++ brcms_c_time_lock(wlc);
++
++ tsf_l = tsf;
++ tsf_h = (tsf >> 32);
++
++ /* read the tsf timer low, then high to get an atomic read */
++ bcma_write32(wlc->hw->d11core, D11REGOFFS(tsf_timerlow), tsf_l);
++ bcma_write32(wlc->hw->d11core, D11REGOFFS(tsf_timerhigh), tsf_h);
++
++ brcms_c_time_unlock(wlc);
++}
++
+ int brcms_c_set_tx_power(struct brcms_c_info *wlc, int txpwr)
+ {
+ uint qdbm;
+--- a/drivers/net/wireless/brcm80211/brcmsmac/pub.h
++++ b/drivers/net/wireless/brcm80211/brcmsmac/pub.h
+@@ -326,6 +326,8 @@ extern void brcms_c_set_shortslot_overri
+ s8 sslot_override);
+ extern void brcms_c_set_beacon_listen_interval(struct brcms_c_info *wlc,
+ u8 interval);
++extern u64 brcms_c_tsf_get(struct brcms_c_info *wlc);
++extern void brcms_c_tsf_set(struct brcms_c_info *wlc, u64 tsf);
+ extern int brcms_c_set_tx_power(struct brcms_c_info *wlc, int txpwr);
+ extern int brcms_c_get_tx_power(struct brcms_c_info *wlc);
+ extern bool brcms_c_check_radio_disabled(struct brcms_c_info *wlc);
diff --git a/package/mac80211/patches/861-brcmsmac-add-interface-type-to-brcms_bss_cfg.patch b/package/mac80211/patches/861-brcmsmac-add-interface-type-to-brcms_bss_cfg.patch
new file mode 100644
index 0000000000..21b1e0e4d7
--- /dev/null
+++ b/package/mac80211/patches/861-brcmsmac-add-interface-type-to-brcms_bss_cfg.patch
@@ -0,0 +1,66 @@
+--- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
++++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
+@@ -367,9 +367,10 @@ brcms_ops_add_interface(struct ieee80211
+ }
+
+ spin_lock_bh(&wl->lock);
+- memcpy(wl->pub->cur_etheraddr, vif->addr, sizeof(vif->addr));
+ wl->mute_tx = false;
+ brcms_c_mute(wl->wlc, false);
++ if (vif->type == NL80211_IFTYPE_STATION)
++ brcms_c_start_station(wl->wlc, vif->addr);
+ spin_unlock_bh(&wl->lock);
+
+ return 0;
+--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
++++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
+@@ -2165,6 +2165,12 @@ void brcms_b_switch_macfreq(struct brcms
+ }
+ }
+
++void brcms_c_start_station(struct brcms_c_info *wlc, u8 *addr)
++{
++ memcpy(wlc->pub->cur_etheraddr, addr, sizeof(wlc->pub->cur_etheraddr));
++ wlc->bsscfg->type = BRCMS_TYPE_STATION;
++}
++
+ /* Initialize GPIOs that are controlled by D11 core */
+ static void brcms_c_gpio_init(struct brcms_c_info *wlc)
+ {
+--- a/drivers/net/wireless/brcm80211/brcmsmac/main.h
++++ b/drivers/net/wireless/brcm80211/brcmsmac/main.h
+@@ -576,10 +576,17 @@ struct antsel_info {
+ struct brcms_antselcfg antcfg_cur; /* current antenna config (auto) */
+ };
+
++enum brcms_bss_type {
++ BRCMS_TYPE_STATION,
++ BRCMS_TYPE_AP,
++ BRCMS_TYPE_ADHOC,
++};
++
+ /*
+ * BSS configuration state
+ *
+ * wlc: wlc to which this bsscfg belongs to.
++ * type: interface type
+ * up: is this configuration up operational
+ * enable: is this configuration enabled
+ * associated: is BSS in ASSOCIATED state
+@@ -599,6 +606,7 @@ struct antsel_info {
+ */
+ struct brcms_bss_cfg {
+ struct brcms_c_info *wlc;
++ enum brcms_bss_type type;
+ bool up;
+ bool enable;
+ bool associated;
+--- a/drivers/net/wireless/brcm80211/brcmsmac/pub.h
++++ b/drivers/net/wireless/brcm80211/brcmsmac/pub.h
+@@ -333,5 +333,6 @@ extern int brcms_c_get_tx_power(struct b
+ extern bool brcms_c_check_radio_disabled(struct brcms_c_info *wlc);
+ extern void brcms_c_mute(struct brcms_c_info *wlc, bool on);
+ extern bool brcms_c_tx_flush_completed(struct brcms_c_info *wlc);
++extern void brcms_c_start_station(struct brcms_c_info *wlc, u8 *addr);
+
+ #endif /* _BRCM_PUB_H_ */
diff --git a/package/mac80211/patches/862-brcmsmac-remove-brcms_bss_cfg-BSS.patch b/package/mac80211/patches/862-brcmsmac-remove-brcms_bss_cfg-BSS.patch
new file mode 100644
index 0000000000..1fafd63a28
--- /dev/null
+++ b/package/mac80211/patches/862-brcmsmac-remove-brcms_bss_cfg-BSS.patch
@@ -0,0 +1,79 @@
+--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
++++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
+@@ -1071,7 +1071,7 @@ brcms_b_txstatus(struct brcms_hardware *
+
+ static void brcms_c_tbtt(struct brcms_c_info *wlc)
+ {
+- if (!wlc->bsscfg->BSS)
++ if (wlc->bsscfg->type == BRCMS_TYPE_ADHOC)
+ /*
+ * DirFrmQ is now valid...defer setting until end
+ * of ATIM window
+@@ -3061,16 +3061,8 @@ static bool brcms_c_ps_allowed(struct br
+ if (wlc->filter_flags & FIF_PROMISC_IN_BSS)
+ return false;
+
+- if (cfg->associated) {
+- /*
+- * disallow PS when one of the following
+- * bsscfg specific conditions meets
+- */
+- if (!cfg->BSS)
+- return false;
+-
++ if (cfg->associated)
+ return false;
+- }
+
+ return true;
+ }
+@@ -5080,8 +5072,9 @@ int brcms_c_up(struct brcms_c_info *wlc)
+ struct brcms_bss_cfg *bsscfg = wlc->bsscfg;
+ mboolset(wlc->pub->radio_disabled,
+ WL_RADIO_HW_DISABLE);
+-
+- if (bsscfg->enable && bsscfg->BSS)
++ if (bsscfg->enable &&
++ (bsscfg->type == BRCMS_TYPE_STATION ||
++ bsscfg->type == BRCMS_TYPE_ADHOC))
+ brcms_err(wlc->hw->d11core,
+ "wl%d: up: rfdisable -> "
+ "bsscfg_disable()\n",
+@@ -7390,7 +7383,8 @@ void brcms_c_update_beacon(struct brcms_
+ {
+ struct brcms_bss_cfg *bsscfg = wlc->bsscfg;
+
+- if (bsscfg->up && !bsscfg->BSS)
++ if (bsscfg->up && (bsscfg->type == BRCMS_TYPE_AP ||
++ bsscfg->type == BRCMS_TYPE_ADHOC))
+ /* Clear the soft intmask */
+ wlc->defmacintmask &= ~MI_BCNTPL;
+ }
+@@ -7465,7 +7459,8 @@ void brcms_c_update_probe_resp(struct br
+ struct brcms_bss_cfg *bsscfg = wlc->bsscfg;
+
+ /* update AP or IBSS probe responses */
+- if (bsscfg->up && !bsscfg->BSS)
++ if (bsscfg->up && (bsscfg->type == BRCMS_TYPE_AP ||
++ bsscfg->type == BRCMS_TYPE_ADHOC))
+ brcms_c_bss_update_probe_resp(wlc, bsscfg, suspend);
+ }
+
+--- a/drivers/net/wireless/brcm80211/brcmsmac/main.h
++++ b/drivers/net/wireless/brcm80211/brcmsmac/main.h
+@@ -590,7 +590,6 @@ enum brcms_bss_type {
+ * up: is this configuration up operational
+ * enable: is this configuration enabled
+ * associated: is BSS in ASSOCIATED state
+- * BSS: infraustructure or adhoc
+ * SSID_len: the length of SSID
+ * SSID: SSID string
+ *
+@@ -610,7 +609,6 @@ struct brcms_bss_cfg {
+ bool up;
+ bool enable;
+ bool associated;
+- bool BSS;
+ u8 SSID_len;
+ u8 SSID[IEEE80211_MAX_SSID_LEN];
+ u8 BSSID[ETH_ALEN];
diff --git a/package/mac80211/patches/863-brcmsmac-remove-brcms_bss_cfg-associated.patch b/package/mac80211/patches/863-brcmsmac-remove-brcms_bss_cfg-associated.patch
new file mode 100644
index 0000000000..79a4b688d6
--- /dev/null
+++ b/package/mac80211/patches/863-brcmsmac-remove-brcms_bss_cfg-associated.patch
@@ -0,0 +1,74 @@
+--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
++++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
+@@ -3051,8 +3051,6 @@ static void brcms_b_antsel_set(struct br
+ */
+ static bool brcms_c_ps_allowed(struct brcms_c_info *wlc)
+ {
+- struct brcms_bss_cfg *cfg = wlc->bsscfg;
+-
+ /* disallow PS when one of the following global conditions meets */
+ if (!wlc->pub->associated)
+ return false;
+@@ -3061,9 +3059,6 @@ static bool brcms_c_ps_allowed(struct br
+ if (wlc->filter_flags & FIF_PROMISC_IN_BSS)
+ return false;
+
+- if (cfg->associated)
+- return false;
+-
+ return true;
+ }
+
+@@ -3821,7 +3816,7 @@ static void brcms_c_set_home_chanspec(st
+ if (wlc->home_chanspec != chanspec) {
+ wlc->home_chanspec = chanspec;
+
+- if (wlc->bsscfg->associated)
++ if (wlc->pub->associated)
+ wlc->bsscfg->current_bss->chanspec = chanspec;
+ }
+ }
+@@ -5435,7 +5430,7 @@ static void brcms_c_ofdm_rateset_war(str
+ u8 r;
+ bool war = false;
+
+- if (wlc->bsscfg->associated)
++ if (wlc->pub->associated)
+ r = wlc->bsscfg->current_bss->rateset.rates[0];
+ else
+ r = wlc->default_bss->rateset.rates[0];
+@@ -5529,7 +5524,7 @@ int brcms_c_set_rateset(struct brcms_c_i
+ /* merge rateset coming in with the current mcsset */
+ if (wlc->pub->_n_enab & SUPPORT_11N) {
+ struct brcms_bss_info *mcsset_bss;
+- if (wlc->bsscfg->associated)
++ if (wlc->pub->associated)
+ mcsset_bss = wlc->bsscfg->current_bss;
+ else
+ mcsset_bss = wlc->default_bss;
+@@ -7500,7 +7495,6 @@ void brcms_c_scan_stop(struct brcms_c_in
+ void brcms_c_associate_upd(struct brcms_c_info *wlc, bool state)
+ {
+ wlc->pub->associated = state;
+- wlc->bsscfg->associated = state;
+ }
+
+ /*
+--- a/drivers/net/wireless/brcm80211/brcmsmac/main.h
++++ b/drivers/net/wireless/brcm80211/brcmsmac/main.h
+@@ -589,7 +589,6 @@ enum brcms_bss_type {
+ * type: interface type
+ * up: is this configuration up operational
+ * enable: is this configuration enabled
+- * associated: is BSS in ASSOCIATED state
+ * SSID_len: the length of SSID
+ * SSID: SSID string
+ *
+@@ -608,7 +607,6 @@ struct brcms_bss_cfg {
+ enum brcms_bss_type type;
+ bool up;
+ bool enable;
+- bool associated;
+ u8 SSID_len;
+ u8 SSID[IEEE80211_MAX_SSID_LEN];
+ u8 BSSID[ETH_ALEN];
diff --git a/package/mac80211/patches/864-brcmsmac-remove-brcms_bss_cfg-enable.patch b/package/mac80211/patches/864-brcmsmac-remove-brcms_bss_cfg-enable.patch
new file mode 100644
index 0000000000..9f5c4da7fe
--- /dev/null
+++ b/package/mac80211/patches/864-brcmsmac-remove-brcms_bss_cfg-enable.patch
@@ -0,0 +1,32 @@
+--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
++++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
+@@ -5067,9 +5067,8 @@ int brcms_c_up(struct brcms_c_info *wlc)
+ struct brcms_bss_cfg *bsscfg = wlc->bsscfg;
+ mboolset(wlc->pub->radio_disabled,
+ WL_RADIO_HW_DISABLE);
+- if (bsscfg->enable &&
+- (bsscfg->type == BRCMS_TYPE_STATION ||
+- bsscfg->type == BRCMS_TYPE_ADHOC))
++ if (bsscfg->type == BRCMS_TYPE_STATION ||
++ bsscfg->type == BRCMS_TYPE_ADHOC)
+ brcms_err(wlc->hw->d11core,
+ "wl%d: up: rfdisable -> "
+ "bsscfg_disable()\n",
+--- a/drivers/net/wireless/brcm80211/brcmsmac/main.h
++++ b/drivers/net/wireless/brcm80211/brcmsmac/main.h
+@@ -588,7 +588,6 @@ enum brcms_bss_type {
+ * wlc: wlc to which this bsscfg belongs to.
+ * type: interface type
+ * up: is this configuration up operational
+- * enable: is this configuration enabled
+ * SSID_len: the length of SSID
+ * SSID: SSID string
+ *
+@@ -606,7 +605,6 @@ struct brcms_bss_cfg {
+ struct brcms_c_info *wlc;
+ enum brcms_bss_type type;
+ bool up;
+- bool enable;
+ u8 SSID_len;
+ u8 SSID[IEEE80211_MAX_SSID_LEN];
+ u8 BSSID[ETH_ALEN];
diff --git a/package/mac80211/patches/865-brcmsmac-remove-brcms_bss_cfg-up.patch b/package/mac80211/patches/865-brcmsmac-remove-brcms_bss_cfg-up.patch
new file mode 100644
index 0000000000..b596d799f6
--- /dev/null
+++ b/package/mac80211/patches/865-brcmsmac-remove-brcms_bss_cfg-up.patch
@@ -0,0 +1,51 @@
+--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
++++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
+@@ -7377,8 +7377,8 @@ void brcms_c_update_beacon(struct brcms_
+ {
+ struct brcms_bss_cfg *bsscfg = wlc->bsscfg;
+
+- if (bsscfg->up && (bsscfg->type == BRCMS_TYPE_AP ||
+- bsscfg->type == BRCMS_TYPE_ADHOC))
++ if (wlc->pub->up && (bsscfg->type == BRCMS_TYPE_AP ||
++ bsscfg->type == BRCMS_TYPE_ADHOC))
+ /* Clear the soft intmask */
+ wlc->defmacintmask &= ~MI_BCNTPL;
+ }
+@@ -7453,8 +7453,8 @@ void brcms_c_update_probe_resp(struct br
+ struct brcms_bss_cfg *bsscfg = wlc->bsscfg;
+
+ /* update AP or IBSS probe responses */
+- if (bsscfg->up && (bsscfg->type == BRCMS_TYPE_AP ||
+- bsscfg->type == BRCMS_TYPE_ADHOC))
++ if (wlc->pub->up && (bsscfg->type == BRCMS_TYPE_AP ||
++ bsscfg->type == BRCMS_TYPE_ADHOC))
+ brcms_c_bss_update_probe_resp(wlc, bsscfg, suspend);
+ }
+
+@@ -7807,7 +7807,7 @@ void brcms_c_init(struct brcms_c_info *w
+ brcms_c_set_bssid(wlc->bsscfg);
+
+ /* Update tsf_cfprep if associated and up */
+- if (wlc->pub->associated && wlc->bsscfg->up) {
++ if (wlc->pub->associated && wlc->pub->up) {
+ u32 bi;
+
+ /* get beacon period and convert to uS */
+--- a/drivers/net/wireless/brcm80211/brcmsmac/main.h
++++ b/drivers/net/wireless/brcm80211/brcmsmac/main.h
+@@ -587,7 +587,6 @@ enum brcms_bss_type {
+ *
+ * wlc: wlc to which this bsscfg belongs to.
+ * type: interface type
+- * up: is this configuration up operational
+ * SSID_len: the length of SSID
+ * SSID: SSID string
+ *
+@@ -604,7 +603,6 @@ enum brcms_bss_type {
+ struct brcms_bss_cfg {
+ struct brcms_c_info *wlc;
+ enum brcms_bss_type type;
+- bool up;
+ u8 SSID_len;
+ u8 SSID[IEEE80211_MAX_SSID_LEN];
+ u8 BSSID[ETH_ALEN];
diff --git a/package/mac80211/patches/866-brcmsmac-remove-brcms_bss_cfg-cur_etheraddr.patch b/package/mac80211/patches/866-brcmsmac-remove-brcms_bss_cfg-cur_etheraddr.patch
new file mode 100644
index 0000000000..0571932e8c
--- /dev/null
+++ b/package/mac80211/patches/866-brcmsmac-remove-brcms_bss_cfg-cur_etheraddr.patch
@@ -0,0 +1,30 @@
+--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
++++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
+@@ -3766,7 +3766,7 @@ static int brcms_c_set_mac(struct brcms_
+ struct brcms_c_info *wlc = bsscfg->wlc;
+
+ /* enter the MAC addr into the RXE match registers */
+- brcms_c_set_addrmatch(wlc, RCM_MAC_OFFSET, bsscfg->cur_etheraddr);
++ brcms_c_set_addrmatch(wlc, RCM_MAC_OFFSET, wlc->pub->cur_etheraddr);
+
+ brcms_c_ampdu_macaddr_upd(wlc);
+
+@@ -7359,7 +7359,7 @@ brcms_c_bcn_prb_template(struct brcms_c_
+ /* A1 filled in by MAC for prb resp, broadcast for bcn */
+ if (type == IEEE80211_STYPE_BEACON)
+ memcpy(&h->da, &ether_bcast, ETH_ALEN);
+- memcpy(&h->sa, &cfg->cur_etheraddr, ETH_ALEN);
++ memcpy(&h->sa, &wlc->pub->cur_etheraddr, ETH_ALEN);
+ memcpy(&h->bssid, &cfg->BSSID, ETH_ALEN);
+
+ /* SEQ filled in by MAC */
+--- a/drivers/net/wireless/brcm80211/brcmsmac/main.h
++++ b/drivers/net/wireless/brcm80211/brcmsmac/main.h
+@@ -606,7 +606,6 @@ struct brcms_bss_cfg {
+ u8 SSID_len;
+ u8 SSID[IEEE80211_MAX_SSID_LEN];
+ u8 BSSID[ETH_ALEN];
+- u8 cur_etheraddr[ETH_ALEN];
+ struct brcms_bss_info *current_bss;
+ };
+
diff --git a/package/mac80211/patches/867-brcmsmac-remove-brcms_pub-bcmerr.patch b/package/mac80211/patches/867-brcmsmac-remove-brcms_pub-bcmerr.patch
new file mode 100644
index 0000000000..2e7c166c36
--- /dev/null
+++ b/package/mac80211/patches/867-brcmsmac-remove-brcms_pub-bcmerr.patch
@@ -0,0 +1,21 @@
+--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
++++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
+@@ -4327,7 +4327,6 @@ static void brcms_c_info_init(struct brc
+
+ /* WME QoS mode is Auto by default */
+ wlc->pub->_ampdu = AMPDU_AGG_HOST;
+- wlc->pub->bcmerror = 0;
+ }
+
+ static uint brcms_c_attach_module(struct brcms_c_info *wlc)
+--- a/drivers/net/wireless/brcm80211/brcmsmac/pub.h
++++ b/drivers/net/wireless/brcm80211/brcmsmac/pub.h
+@@ -164,8 +164,6 @@ struct brcms_pub {
+
+ u8 cur_etheraddr[ETH_ALEN]; /* our local ethernet address */
+
+- int bcmerror; /* last bcm error */
+-
+ u32 radio_disabled; /* bit vector for radio disabled reasons */
+
+ u16 boardrev; /* version # of particular board */
diff --git a/package/mac80211/patches/868-brcmsmac-write-beacon-period-to-hardware.patch b/package/mac80211/patches/868-brcmsmac-write-beacon-period-to-hardware.patch
new file mode 100644
index 0000000000..fb10e1ba6e
--- /dev/null
+++ b/package/mac80211/patches/868-brcmsmac-write-beacon-period-to-hardware.patch
@@ -0,0 +1,23 @@
+--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
++++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
+@@ -5553,10 +5553,20 @@ static void brcms_c_time_unlock(struct b
+
+ int brcms_c_set_beacon_period(struct brcms_c_info *wlc, u16 period)
+ {
++ u32 bcnint_us;
++
+ if (period == 0)
+ return -EINVAL;
+
+ wlc->default_bss->beacon_period = period;
++
++ bcnint_us = period << 10;
++ brcms_c_time_lock(wlc);
++ bcma_write32(wlc->hw->d11core, D11REGOFFS(tsf_cfprep),
++ (bcnint_us << CFPREP_CBI_SHIFT));
++ bcma_write32(wlc->hw->d11core, D11REGOFFS(tsf_cfpstart), bcnint_us);
++ brcms_c_time_unlock(wlc);
++
+ return 0;
+ }
+
diff --git a/package/mac80211/patches/869-brcmsmac-add-beacon-template-support.patch b/package/mac80211/patches/869-brcmsmac-add-beacon-template-support.patch
new file mode 100644
index 0000000000..cbed0f1015
--- /dev/null
+++ b/package/mac80211/patches/869-brcmsmac-add-beacon-template-support.patch
@@ -0,0 +1,266 @@
+--- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
++++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
+@@ -1,5 +1,6 @@
+ /*
+ * Copyright (c) 2010 Broadcom Corporation
++ * Copyright (c) 2013 Hauke Mehrtens <hauke@hauke-m.de>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+@@ -522,9 +523,17 @@ brcms_ops_bss_info_changed(struct ieee80
+ brcms_c_set_addrmatch(wl->wlc, RCM_BSSID_OFFSET, info->bssid);
+ spin_unlock_bh(&wl->lock);
+ }
+- if (changed & BSS_CHANGED_BEACON)
++ if (changed & BSS_CHANGED_BEACON) {
+ /* Beacon data changed, retrieve new beacon (beaconing modes) */
+- brcms_err(core, "%s: beacon changed\n", __func__);
++ struct sk_buff *beacon;
++ u16 tim_offset = 0;
++
++ spin_lock_bh(&wl->lock);
++ beacon = ieee80211_beacon_get_tim(hw, vif, &tim_offset, NULL);
++ brcms_c_set_new_beacon(wl->wlc, beacon, tim_offset,
++ info->dtim_period);
++ spin_unlock_bh(&wl->lock);
++ }
+
+ if (changed & BSS_CHANGED_BEACON_ENABLED) {
+ /* Beaconing should be enabled/disabled (beaconing modes) */
+--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
++++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
+@@ -1,5 +1,6 @@
+ /*
+ * Copyright (c) 2010 Broadcom Corporation
++ * Copyright (c) 2013 Hauke Mehrtens <hauke@hauke-m.de>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+@@ -450,6 +451,8 @@ static void brcms_c_detach_mfree(struct
+ kfree(wlc->corestate);
+ kfree(wlc->hw->bandstate[0]);
+ kfree(wlc->hw);
++ if (wlc->beacon)
++ dev_kfree_skb_any(wlc->beacon);
+
+ /* free the wlc */
+ kfree(wlc);
+@@ -4086,10 +4089,14 @@ void brcms_c_wme_setparams(struct brcms_
+ *shm_entry++);
+ }
+
+- if (suspend) {
++ if (suspend)
+ brcms_c_suspend_mac_and_wait(wlc);
++
++ brcms_c_update_beacon(wlc);
++ brcms_c_update_probe_resp(wlc, false);
++
++ if (suspend)
+ brcms_c_enable_mac(wlc);
+- }
+ }
+
+ static void brcms_c_edcf_setparams(struct brcms_c_info *wlc, bool suspend)
+@@ -7379,6 +7386,107 @@ int brcms_c_get_header_len(void)
+ return TXOFF;
+ }
+
++static void brcms_c_beacon_write(struct brcms_c_info *wlc,
++ struct sk_buff *beacon, u16 tim_offset,
++ u16 dtim_period, bool bcn0, bool bcn1)
++{
++ size_t len;
++ struct ieee80211_tx_info *tx_info;
++ struct brcms_hardware *wlc_hw = wlc->hw;
++ struct ieee80211_hw *ieee_hw = brcms_c_pub(wlc)->ieee_hw;
++
++ /* Get tx_info */
++ tx_info = IEEE80211_SKB_CB(beacon);
++
++ len = min_t(size_t, beacon->len, BCN_TMPL_LEN);
++ wlc->bcn_rspec = ieee80211_get_tx_rate(ieee_hw, tx_info)->hw_value;
++
++ brcms_c_compute_plcp(wlc, wlc->bcn_rspec,
++ len + FCS_LEN - D11_PHY_HDR_LEN, beacon->data);
++
++ /* "Regular" and 16 MBSS but not for 4 MBSS */
++ /* Update the phytxctl for the beacon based on the rspec */
++ brcms_c_beacon_phytxctl_txant_upd(wlc, wlc->bcn_rspec);
++
++ if (bcn0) {
++ /* write the probe response into the template region */
++ brcms_b_write_template_ram(wlc_hw, T_BCN0_TPL_BASE,
++ (len + 3) & ~3, beacon->data);
++
++ /* write beacon length to SCR */
++ brcms_b_write_shm(wlc_hw, M_BCN0_FRM_BYTESZ, (u16) len);
++ }
++ if (bcn1) {
++ /* write the probe response into the template region */
++ brcms_b_write_template_ram(wlc_hw, T_BCN1_TPL_BASE,
++ (len + 3) & ~3, beacon->data);
++
++ /* write beacon length to SCR */
++ brcms_b_write_shm(wlc_hw, M_BCN1_FRM_BYTESZ, (u16) len);
++ }
++
++ if (tim_offset != 0) {
++ brcms_b_write_shm(wlc_hw, M_TIMBPOS_INBEACON,
++ tim_offset + D11B_PHY_HDR_LEN);
++ brcms_b_write_shm(wlc_hw, M_DOT11_DTIMPERIOD, dtim_period);
++ } else {
++ brcms_b_write_shm(wlc_hw, M_TIMBPOS_INBEACON,
++ len + D11B_PHY_HDR_LEN);
++ brcms_b_write_shm(wlc_hw, M_DOT11_DTIMPERIOD, 0);
++ }
++}
++
++static void brcms_c_update_beacon_hw(struct brcms_c_info *wlc,
++ struct sk_buff *beacon, u16 tim_offset,
++ u16 dtim_period)
++{
++ struct brcms_hardware *wlc_hw = wlc->hw;
++ struct bcma_device *core = wlc_hw->d11core;
++
++ /* Hardware beaconing for this config */
++ u32 both_valid = MCMD_BCN0VLD | MCMD_BCN1VLD;
++
++ /* Check if both templates are in use, if so sched. an interrupt
++ * that will call back into this routine
++ */
++ if ((bcma_read32(core, D11REGOFFS(maccommand)) & both_valid) == both_valid)
++ /* clear any previous status */
++ bcma_write32(core, D11REGOFFS(macintstatus), MI_BCNTPL);
++
++ if (wlc->beacon_template_virgin) {
++ wlc->beacon_template_virgin = false;
++ brcms_c_beacon_write(wlc, beacon, tim_offset, dtim_period, true,
++ true);
++ /* mark beacon0 valid */
++ bcma_set32(core, D11REGOFFS(maccommand), MCMD_BCN0VLD);
++ return;
++ }
++
++ /* Check that after scheduling the interrupt both of the
++ * templates are still busy. if not clear the int. & remask
++ */
++ if ((bcma_read32(core, D11REGOFFS(maccommand)) & both_valid) == both_valid) {
++ wlc->defmacintmask |= MI_BCNTPL;
++ return;
++ }
++
++ if (!(bcma_read32(core, D11REGOFFS(maccommand)) & MCMD_BCN0VLD)) {
++ brcms_c_beacon_write(wlc, beacon, tim_offset, dtim_period, true,
++ false);
++ /* mark beacon0 valid */
++ bcma_set32(core, D11REGOFFS(maccommand), MCMD_BCN0VLD);
++ return;
++ }
++ if (!(bcma_read32(core, D11REGOFFS(maccommand)) & MCMD_BCN1VLD)) {
++ brcms_c_beacon_write(wlc, beacon, tim_offset, dtim_period,
++ false, true);
++ /* mark beacon0 valid */
++ bcma_set32(core, D11REGOFFS(maccommand), MCMD_BCN1VLD);
++ return;
++ }
++ return;
++}
++
+ /*
+ * Update all beacons for the system.
+ */
+@@ -7387,9 +7495,31 @@ void brcms_c_update_beacon(struct brcms_
+ struct brcms_bss_cfg *bsscfg = wlc->bsscfg;
+
+ if (wlc->pub->up && (bsscfg->type == BRCMS_TYPE_AP ||
+- bsscfg->type == BRCMS_TYPE_ADHOC))
++ bsscfg->type == BRCMS_TYPE_ADHOC)) {
+ /* Clear the soft intmask */
+ wlc->defmacintmask &= ~MI_BCNTPL;
++ if (!wlc->beacon)
++ return;
++ brcms_c_update_beacon_hw(wlc, wlc->beacon,
++ wlc->beacon_tim_offset,
++ wlc->beacon_dtim_period);
++ }
++}
++
++void brcms_c_set_new_beacon(struct brcms_c_info *wlc, struct sk_buff *beacon,
++ u16 tim_offset, u16 dtim_period)
++{
++ if (!beacon)
++ return;
++ if (wlc->beacon)
++ dev_kfree_skb_any(wlc->beacon);
++ wlc->beacon = beacon;
++
++ /* add PLCP */
++ skb_push(wlc->beacon, D11_PHY_HDR_LEN);
++ wlc->beacon_tim_offset = tim_offset;
++ wlc->beacon_dtim_period = dtim_period;
++ brcms_c_update_beacon(wlc);
+ }
+
+ /* Write ssid into shared memory */
+@@ -7788,6 +7918,10 @@ bool brcms_c_dpc(struct brcms_c_info *wl
+ brcms_rfkill_set_hw_state(wlc->wl);
+ }
+
++ /* BCN template is available */
++ if (macintstatus & MI_BCNTPL)
++ brcms_c_update_beacon(wlc);
++
+ /* it isn't done and needs to be resched if macintstatus is non-zero */
+ return wlc->macintstatus != 0;
+
+@@ -7919,6 +8053,7 @@ brcms_c_attach(struct brcms_info *wl, st
+ pub->unit = unit;
+ pub->_piomode = piomode;
+ wlc->bandinit_pending = false;
++ wlc->beacon_template_virgin = true;
+
+ /* populate struct brcms_c_info with default values */
+ brcms_c_info_init(wlc, unit);
+--- a/drivers/net/wireless/brcm80211/brcmsmac/main.h
++++ b/drivers/net/wireless/brcm80211/brcmsmac/main.h
+@@ -492,6 +492,8 @@ struct brcms_c_info {
+ bool radio_monitor;
+ bool going_down;
+
++ bool beacon_template_virgin;
++
+ struct brcms_timer *wdtimer;
+ struct brcms_timer *radio_timer;
+
+@@ -561,6 +563,10 @@ struct brcms_c_info {
+
+ struct wiphy *wiphy;
+ struct scb pri_scb;
++
++ struct sk_buff *beacon;
++ u16 beacon_tim_offset;
++ u16 beacon_dtim_period;
+ };
+
+ /* antsel module specific state */
+@@ -630,7 +636,6 @@ extern u16 brcms_c_compute_rtscts_dur(st
+ extern void brcms_c_inval_dma_pkts(struct brcms_hardware *hw,
+ struct ieee80211_sta *sta,
+ void (*dma_callback_fn));
+-extern void brcms_c_update_beacon(struct brcms_c_info *wlc);
+ extern void brcms_c_update_probe_resp(struct brcms_c_info *wlc, bool suspend);
+ extern int brcms_c_set_nmode(struct brcms_c_info *wlc);
+ extern void brcms_c_beacon_phytxctl_txant_upd(struct brcms_c_info *wlc,
+--- a/drivers/net/wireless/brcm80211/brcmsmac/pub.h
++++ b/drivers/net/wireless/brcm80211/brcmsmac/pub.h
+@@ -332,5 +332,9 @@ extern bool brcms_c_check_radio_disabled
+ extern void brcms_c_mute(struct brcms_c_info *wlc, bool on);
+ extern bool brcms_c_tx_flush_completed(struct brcms_c_info *wlc);
+ extern void brcms_c_start_station(struct brcms_c_info *wlc, u8 *addr);
++extern void brcms_c_update_beacon(struct brcms_c_info *wlc);
++extern void brcms_c_set_new_beacon(struct brcms_c_info *wlc,
++ struct sk_buff *beacon, u16 tim_offset,
++ u16 dtim_period);
+
+ #endif /* _BRCM_PUB_H_ */
diff --git a/package/mac80211/patches/870-brcmsmac-react-on-changing-SSID.patch b/package/mac80211/patches/870-brcmsmac-react-on-changing-SSID.patch
new file mode 100644
index 0000000000..34969ad351
--- /dev/null
+++ b/package/mac80211/patches/870-brcmsmac-react-on-changing-SSID.patch
@@ -0,0 +1,43 @@
+--- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
++++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
+@@ -523,6 +523,12 @@ brcms_ops_bss_info_changed(struct ieee80
+ brcms_c_set_addrmatch(wl->wlc, RCM_BSSID_OFFSET, info->bssid);
+ spin_unlock_bh(&wl->lock);
+ }
++ if (changed & BSS_CHANGED_SSID) {
++ /* BSSID changed, for whatever reason (IBSS and managed mode) */
++ spin_lock_bh(&wl->lock);
++ brcms_c_set_ssid(wl->wlc, info->ssid, info->ssid_len);
++ spin_unlock_bh(&wl->lock);
++ }
+ if (changed & BSS_CHANGED_BEACON) {
+ /* Beacon data changed, retrieve new beacon (beaconing modes) */
+ struct sk_buff *beacon;
+--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
++++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
+@@ -3785,6 +3785,15 @@ static void brcms_c_set_bssid(struct brc
+ brcms_c_set_addrmatch(bsscfg->wlc, RCM_BSSID_OFFSET, bsscfg->BSSID);
+ }
+
++void brcms_c_set_ssid(struct brcms_c_info *wlc, u8 *ssid, size_t ssid_len)
++{
++ u8 len = min_t(u8, sizeof(wlc->bsscfg->SSID), ssid_len);
++ memset(wlc->bsscfg->SSID, 0, sizeof(wlc->bsscfg->SSID));
++
++ memcpy(wlc->bsscfg->SSID, ssid, len);
++ wlc->bsscfg->SSID_len = len;
++}
++
+ static void brcms_b_set_shortslot(struct brcms_hardware *wlc_hw, bool shortslot)
+ {
+ wlc_hw->shortslot = shortslot;
+--- a/drivers/net/wireless/brcm80211/brcmsmac/pub.h
++++ b/drivers/net/wireless/brcm80211/brcmsmac/pub.h
+@@ -336,5 +336,7 @@ extern void brcms_c_update_beacon(struct
+ extern void brcms_c_set_new_beacon(struct brcms_c_info *wlc,
+ struct sk_buff *beacon, u16 tim_offset,
+ u16 dtim_period);
++extern void brcms_c_set_ssid(struct brcms_c_info *wlc, u8 *ssid,
++ size_t ssid_len);
+
+ #endif /* _BRCM_PUB_H_ */
diff --git a/package/mac80211/patches/871-brcmsmac-add-support-for-probe-response-template.patch b/package/mac80211/patches/871-brcmsmac-add-support-for-probe-response-template.patch
new file mode 100644
index 0000000000..27dbfeab2c
--- /dev/null
+++ b/package/mac80211/patches/871-brcmsmac-add-support-for-probe-response-template.patch
@@ -0,0 +1,216 @@
+--- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
++++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
+@@ -541,6 +541,15 @@ brcms_ops_bss_info_changed(struct ieee80
+ spin_unlock_bh(&wl->lock);
+ }
+
++ if (changed & BSS_CHANGED_AP_PROBE_RESP) {
++ struct sk_buff *probe_resp;
++
++ spin_lock_bh(&wl->lock);
++ probe_resp = ieee80211_proberesp_get(hw, vif);
++ brcms_c_set_new_probe_resp(wl->wlc, probe_resp);
++ spin_unlock_bh(&wl->lock);
++ }
++
+ if (changed & BSS_CHANGED_BEACON_ENABLED) {
+ /* Beaconing should be enabled/disabled (beaconing modes) */
+ brcms_err(core, "%s: Beacon enabled: %s\n", __func__,
+@@ -1039,6 +1048,8 @@ static int ieee_hw_init(struct ieee80211
+ hw->channel_change_time = 7 * 1000;
+ hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
+
++ hw->wiphy->flags |= WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD;
++
+ hw->rate_control_algorithm = "minstrel_ht";
+
+ hw->sta_data_size = 0;
+--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
++++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
+@@ -453,6 +453,8 @@ static void brcms_c_detach_mfree(struct
+ kfree(wlc->hw);
+ if (wlc->beacon)
+ dev_kfree_skb_any(wlc->beacon);
++ if (wlc->probe_resp)
++ dev_kfree_skb_any(wlc->probe_resp);
+
+ /* free the wlc */
+ kfree(wlc);
+@@ -7327,69 +7329,6 @@ brcms_c_mod_prb_rsp_rate_table(struct br
+ }
+ }
+
+-/* Max buffering needed for beacon template/prb resp template is 142 bytes.
+- *
+- * PLCP header is 6 bytes.
+- * 802.11 A3 header is 24 bytes.
+- * Max beacon frame body template length is 112 bytes.
+- * Max probe resp frame body template length is 110 bytes.
+- *
+- * *len on input contains the max length of the packet available.
+- *
+- * The *len value is set to the number of bytes in buf used, and starts
+- * with the PLCP and included up to, but not including, the 4 byte FCS.
+- */
+-static void
+-brcms_c_bcn_prb_template(struct brcms_c_info *wlc, u16 type,
+- u32 bcn_rspec,
+- struct brcms_bss_cfg *cfg, u16 *buf, int *len)
+-{
+- static const u8 ether_bcast[ETH_ALEN] = {255, 255, 255, 255, 255, 255};
+- struct cck_phy_hdr *plcp;
+- struct ieee80211_mgmt *h;
+- int hdr_len, body_len;
+-
+- hdr_len = D11_PHY_HDR_LEN + DOT11_MAC_HDR_LEN;
+-
+- /* calc buffer size provided for frame body */
+- body_len = *len - hdr_len;
+- /* return actual size */
+- *len = hdr_len + body_len;
+-
+- /* format PHY and MAC headers */
+- memset(buf, 0, hdr_len);
+-
+- plcp = (struct cck_phy_hdr *) buf;
+-
+- /*
+- * PLCP for Probe Response frames are filled in from
+- * core's rate table
+- */
+- if (type == IEEE80211_STYPE_BEACON)
+- /* fill in PLCP */
+- brcms_c_compute_plcp(wlc, bcn_rspec,
+- (DOT11_MAC_HDR_LEN + body_len + FCS_LEN),
+- (u8 *) plcp);
+-
+- /* "Regular" and 16 MBSS but not for 4 MBSS */
+- /* Update the phytxctl for the beacon based on the rspec */
+- brcms_c_beacon_phytxctl_txant_upd(wlc, bcn_rspec);
+-
+- h = (struct ieee80211_mgmt *)&plcp[1];
+-
+- /* fill in 802.11 header */
+- h->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | type);
+-
+- /* DUR is 0 for multicast bcn, or filled in by MAC for prb resp */
+- /* A1 filled in by MAC for prb resp, broadcast for bcn */
+- if (type == IEEE80211_STYPE_BEACON)
+- memcpy(&h->da, &ether_bcast, ETH_ALEN);
+- memcpy(&h->sa, &wlc->pub->cur_etheraddr, ETH_ALEN);
+- memcpy(&h->bssid, &cfg->BSSID, ETH_ALEN);
+-
+- /* SEQ filled in by MAC */
+-}
+-
+ int brcms_c_get_header_len(void)
+ {
+ return TXOFF;
+@@ -7531,6 +7470,20 @@ void brcms_c_set_new_beacon(struct brcms
+ brcms_c_update_beacon(wlc);
+ }
+
++void brcms_c_set_new_probe_resp(struct brcms_c_info *wlc,
++ struct sk_buff *probe_resp)
++{
++ if (!probe_resp)
++ return;
++ if (wlc->probe_resp)
++ dev_kfree_skb_any(wlc->probe_resp);
++ wlc->probe_resp = probe_resp;
++
++ /* add PLCP */
++ skb_push(wlc->probe_resp, D11_PHY_HDR_LEN);
++ brcms_c_update_probe_resp(wlc, false);
++}
++
+ /* Write ssid into shared memory */
+ static void
+ brcms_c_shm_ssid_upd(struct brcms_c_info *wlc, struct brcms_bss_cfg *cfg)
+@@ -7550,30 +7503,19 @@ brcms_c_shm_ssid_upd(struct brcms_c_info
+ static void
+ brcms_c_bss_update_probe_resp(struct brcms_c_info *wlc,
+ struct brcms_bss_cfg *cfg,
++ struct sk_buff *probe_resp,
+ bool suspend)
+ {
+- u16 *prb_resp;
+- int len = BCN_TMPL_LEN;
++ int len;
+
+- prb_resp = kmalloc(BCN_TMPL_LEN, GFP_ATOMIC);
+- if (!prb_resp)
+- return;
+-
+- /*
+- * write the probe response to hardware, or save in
+- * the config structure
+- */
+-
+- /* create the probe response template */
+- brcms_c_bcn_prb_template(wlc, IEEE80211_STYPE_PROBE_RESP, 0,
+- cfg, prb_resp, &len);
++ len = min_t(size_t, probe_resp->len, BCN_TMPL_LEN);
+
+ if (suspend)
+ brcms_c_suspend_mac_and_wait(wlc);
+
+ /* write the probe response into the template region */
+ brcms_b_write_template_ram(wlc->hw, T_PRS_TPL_BASE,
+- (len + 3) & ~3, prb_resp);
++ (len + 3) & ~3, probe_resp->data);
+
+ /* write the length of the probe response frame (+PLCP/-FCS) */
+ brcms_b_write_shm(wlc->hw, M_PRB_RESP_FRM_LEN, (u16) len);
+@@ -7587,13 +7529,11 @@ brcms_c_bss_update_probe_resp(struct brc
+ * PLCP header for the call to brcms_c_mod_prb_rsp_rate_table()
+ * by subtracting the PLCP len and adding the FCS.
+ */
+- len += (-D11_PHY_HDR_LEN + FCS_LEN);
+- brcms_c_mod_prb_rsp_rate_table(wlc, (u16) len);
++ brcms_c_mod_prb_rsp_rate_table(wlc,
++ (u16)len + FCS_LEN - D11_PHY_HDR_LEN);
+
+ if (suspend)
+ brcms_c_enable_mac(wlc);
+-
+- kfree(prb_resp);
+ }
+
+ void brcms_c_update_probe_resp(struct brcms_c_info *wlc, bool suspend)
+@@ -7602,8 +7542,12 @@ void brcms_c_update_probe_resp(struct br
+
+ /* update AP or IBSS probe responses */
+ if (wlc->pub->up && (bsscfg->type == BRCMS_TYPE_AP ||
+- bsscfg->type == BRCMS_TYPE_ADHOC))
+- brcms_c_bss_update_probe_resp(wlc, bsscfg, suspend);
++ bsscfg->type == BRCMS_TYPE_ADHOC)) {
++ if (!wlc->probe_resp)
++ return;
++ brcms_c_bss_update_probe_resp(wlc, bsscfg, wlc->probe_resp,
++ suspend);
++ }
+ }
+
+ int brcms_b_xmtfifo_sz_get(struct brcms_hardware *wlc_hw, uint fifo,
+--- a/drivers/net/wireless/brcm80211/brcmsmac/main.h
++++ b/drivers/net/wireless/brcm80211/brcmsmac/main.h
+@@ -567,6 +567,7 @@ struct brcms_c_info {
+ struct sk_buff *beacon;
+ u16 beacon_tim_offset;
+ u16 beacon_dtim_period;
++ struct sk_buff *probe_resp;
+ };
+
+ /* antsel module specific state */
+--- a/drivers/net/wireless/brcm80211/brcmsmac/pub.h
++++ b/drivers/net/wireless/brcm80211/brcmsmac/pub.h
+@@ -336,6 +336,8 @@ extern void brcms_c_update_beacon(struct
+ extern void brcms_c_set_new_beacon(struct brcms_c_info *wlc,
+ struct sk_buff *beacon, u16 tim_offset,
+ u16 dtim_period);
++extern void brcms_c_set_new_probe_resp(struct brcms_c_info *wlc,
++ struct sk_buff *probe_resp);
+ extern void brcms_c_set_ssid(struct brcms_c_info *wlc, u8 *ssid,
+ size_t ssid_len);
+
diff --git a/package/mac80211/patches/872-brcmsmac-deactivate-ucode-sending-probe-responses.patch b/package/mac80211/patches/872-brcmsmac-deactivate-ucode-sending-probe-responses.patch
new file mode 100644
index 0000000000..9c150b1547
--- /dev/null
+++ b/package/mac80211/patches/872-brcmsmac-deactivate-ucode-sending-probe-responses.patch
@@ -0,0 +1,59 @@
+--- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
++++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
+@@ -554,6 +554,12 @@ brcms_ops_bss_info_changed(struct ieee80
+ /* Beaconing should be enabled/disabled (beaconing modes) */
+ brcms_err(core, "%s: Beacon enabled: %s\n", __func__,
+ info->enable_beacon ? "true" : "false");
++ if (info->enable_beacon &&
++ hw->wiphy->flags & WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD) {
++ brcms_c_enable_probe_resp(wl->wlc, true);
++ } else {
++ brcms_c_enable_probe_resp(wl->wlc, false);
++ }
+ }
+
+ if (changed & BSS_CHANGED_CQM) {
+@@ -1048,7 +1054,12 @@ static int ieee_hw_init(struct ieee80211
+ hw->channel_change_time = 7 * 1000;
+ hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
+
+- hw->wiphy->flags |= WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD;
++ /*
++ * deactivate sending probe responses by ucude, because this will
++ * cause problems when WPS is used.
++ *
++ * hw->wiphy->flags |= WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD;
++ */
+
+ hw->rate_control_algorithm = "minstrel_ht";
+
+--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
++++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
+@@ -7484,6 +7484,17 @@ void brcms_c_set_new_probe_resp(struct b
+ brcms_c_update_probe_resp(wlc, false);
+ }
+
++void brcms_c_enable_probe_resp(struct brcms_c_info *wlc, bool enable)
++{
++ /*
++ * prevent ucode from sending probe responses by setting the timeout
++ * to 1, it can not send it in that time frame.
++ */
++ wlc->prb_resp_timeout = enable ? BRCMS_PRB_RESP_TIMEOUT : 1;
++ brcms_b_write_shm(wlc->hw, M_PRS_MAXTIME, wlc->prb_resp_timeout);
++ /* TODO: if (enable) => also deactivate receiving of probe request */
++}
++
+ /* Write ssid into shared memory */
+ static void
+ brcms_c_shm_ssid_upd(struct brcms_c_info *wlc, struct brcms_bss_cfg *cfg)
+--- a/drivers/net/wireless/brcm80211/brcmsmac/pub.h
++++ b/drivers/net/wireless/brcm80211/brcmsmac/pub.h
+@@ -338,6 +338,7 @@ extern void brcms_c_set_new_beacon(struc
+ u16 dtim_period);
+ extern void brcms_c_set_new_probe_resp(struct brcms_c_info *wlc,
+ struct sk_buff *probe_resp);
++extern void brcms_c_enable_probe_resp(struct brcms_c_info *wlc, bool enable);
+ extern void brcms_c_set_ssid(struct brcms_c_info *wlc, u8 *ssid,
+ size_t ssid_len);
+
diff --git a/package/mac80211/patches/873-brcmsmac-activate-AP-support.patch b/package/mac80211/patches/873-brcmsmac-activate-AP-support.patch
new file mode 100644
index 0000000000..83b3aa808e
--- /dev/null
+++ b/package/mac80211/patches/873-brcmsmac-activate-AP-support.patch
@@ -0,0 +1,79 @@
+--- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
++++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
+@@ -359,10 +359,11 @@ brcms_ops_add_interface(struct ieee80211
+ {
+ struct brcms_info *wl = hw->priv;
+
+- /* Just STA for now */
+- if (vif->type != NL80211_IFTYPE_STATION) {
++ /* Just STA and AP for now */
++ if (vif->type != NL80211_IFTYPE_STATION &&
++ vif->type != NL80211_IFTYPE_AP) {
+ brcms_err(wl->wlc->hw->d11core,
+- "%s: Attempt to add type %d, only STA for now\n",
++ "%s: Attempt to add type %d, only STA and AP for now\n",
+ __func__, vif->type);
+ return -EOPNOTSUPP;
+ }
+@@ -372,6 +373,9 @@ brcms_ops_add_interface(struct ieee80211
+ brcms_c_mute(wl->wlc, false);
+ if (vif->type == NL80211_IFTYPE_STATION)
+ brcms_c_start_station(wl->wlc, vif->addr);
++ else if (vif->type == NL80211_IFTYPE_AP)
++ brcms_c_start_ap(wl->wlc, vif->addr, vif->bss_conf.bssid,
++ vif->bss_conf.ssid, vif->bss_conf.ssid_len);
+ spin_unlock_bh(&wl->lock);
+
+ return 0;
+@@ -1052,7 +1056,8 @@ static int ieee_hw_init(struct ieee80211
+
+ /* channel change time is dependent on chip and band */
+ hw->channel_change_time = 7 * 1000;
+- hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
++ hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
++ BIT(NL80211_IFTYPE_AP);
+
+ /*
+ * deactivate sending probe responses by ucude, because this will
+--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
++++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
+@@ -2176,6 +2176,18 @@ void brcms_c_start_station(struct brcms_
+ wlc->bsscfg->type = BRCMS_TYPE_STATION;
+ }
+
++void brcms_c_start_ap(struct brcms_c_info *wlc, u8 *addr, const u8 *bssid,
++ u8 *ssid, size_t ssid_len)
++{
++ brcms_c_set_ssid(wlc, ssid, ssid_len);
++
++ memcpy(wlc->pub->cur_etheraddr, addr, sizeof(wlc->pub->cur_etheraddr));
++ memcpy(wlc->bsscfg->BSSID, bssid, sizeof(wlc->bsscfg->BSSID));
++ wlc->bsscfg->type = BRCMS_TYPE_AP;
++
++ brcms_b_mctrl(wlc->hw, MCTL_AP | MCTL_INFRA, MCTL_AP | MCTL_INFRA);
++}
++
+ /* Initialize GPIOs that are controlled by D11 core */
+ static void brcms_c_gpio_init(struct brcms_c_info *wlc)
+ {
+@@ -3064,6 +3076,9 @@ static bool brcms_c_ps_allowed(struct br
+ if (wlc->filter_flags & FIF_PROMISC_IN_BSS)
+ return false;
+
++ if (wlc->bsscfg->type == BRCMS_TYPE_AP)
++ return false;
++
+ return true;
+ }
+
+--- a/drivers/net/wireless/brcm80211/brcmsmac/pub.h
++++ b/drivers/net/wireless/brcm80211/brcmsmac/pub.h
+@@ -332,6 +332,8 @@ extern bool brcms_c_check_radio_disabled
+ extern void brcms_c_mute(struct brcms_c_info *wlc, bool on);
+ extern bool brcms_c_tx_flush_completed(struct brcms_c_info *wlc);
+ extern void brcms_c_start_station(struct brcms_c_info *wlc, u8 *addr);
++extern void brcms_c_start_ap(struct brcms_c_info *wlc, u8 *addr,
++ const u8 *bssid, u8 *ssid, size_t ssid_len);
+ extern void brcms_c_update_beacon(struct brcms_c_info *wlc);
+ extern void brcms_c_set_new_beacon(struct brcms_c_info *wlc,
+ struct sk_buff *beacon, u16 tim_offset,
diff --git a/package/mac80211/patches/874-brcmsmac-add-support-for-adhoc-mode.patch b/package/mac80211/patches/874-brcmsmac-add-support-for-adhoc-mode.patch
new file mode 100644
index 0000000000..d1c740793a
--- /dev/null
+++ b/package/mac80211/patches/874-brcmsmac-add-support-for-adhoc-mode.patch
@@ -0,0 +1,74 @@
+--- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
++++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
+@@ -359,11 +359,12 @@ brcms_ops_add_interface(struct ieee80211
+ {
+ struct brcms_info *wl = hw->priv;
+
+- /* Just STA and AP for now */
++ /* Just STA, AP and ADHOC for now */
+ if (vif->type != NL80211_IFTYPE_STATION &&
+- vif->type != NL80211_IFTYPE_AP) {
++ vif->type != NL80211_IFTYPE_AP &&
++ vif->type != NL80211_IFTYPE_ADHOC) {
+ brcms_err(wl->wlc->hw->d11core,
+- "%s: Attempt to add type %d, only STA and AP for now\n",
++ "%s: Attempt to add type %d, only STA, AP and AdHoc for now\n",
+ __func__, vif->type);
+ return -EOPNOTSUPP;
+ }
+@@ -376,6 +377,8 @@ brcms_ops_add_interface(struct ieee80211
+ else if (vif->type == NL80211_IFTYPE_AP)
+ brcms_c_start_ap(wl->wlc, vif->addr, vif->bss_conf.bssid,
+ vif->bss_conf.ssid, vif->bss_conf.ssid_len);
++ else if (vif->type == NL80211_IFTYPE_ADHOC)
++ brcms_c_start_adhoc(wl->wlc, vif->addr);
+ spin_unlock_bh(&wl->lock);
+
+ return 0;
+@@ -1057,7 +1060,8 @@ static int ieee_hw_init(struct ieee80211
+ /* channel change time is dependent on chip and band */
+ hw->channel_change_time = 7 * 1000;
+ hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
+- BIT(NL80211_IFTYPE_AP);
++ BIT(NL80211_IFTYPE_AP) |
++ BIT(NL80211_IFTYPE_ADHOC);
+
+ /*
+ * deactivate sending probe responses by ucude, because this will
+--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
++++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
+@@ -2188,6 +2188,14 @@ void brcms_c_start_ap(struct brcms_c_inf
+ brcms_b_mctrl(wlc->hw, MCTL_AP | MCTL_INFRA, MCTL_AP | MCTL_INFRA);
+ }
+
++void brcms_c_start_adhoc(struct brcms_c_info *wlc, u8 *addr)
++{
++ memcpy(wlc->pub->cur_etheraddr, addr, sizeof(wlc->pub->cur_etheraddr));
++ wlc->bsscfg->type = BRCMS_TYPE_ADHOC;
++
++ brcms_b_mctrl(wlc->hw, MCTL_AP | MCTL_INFRA, 0);
++}
++
+ /* Initialize GPIOs that are controlled by D11 core */
+ static void brcms_c_gpio_init(struct brcms_c_info *wlc)
+ {
+@@ -3079,6 +3087,9 @@ static bool brcms_c_ps_allowed(struct br
+ if (wlc->bsscfg->type == BRCMS_TYPE_AP)
+ return false;
+
++ if (wlc->bsscfg->type == BRCMS_TYPE_ADHOC)
++ return false;
++
+ return true;
+ }
+
+--- a/drivers/net/wireless/brcm80211/brcmsmac/pub.h
++++ b/drivers/net/wireless/brcm80211/brcmsmac/pub.h
+@@ -334,6 +334,7 @@ extern bool brcms_c_tx_flush_completed(s
+ extern void brcms_c_start_station(struct brcms_c_info *wlc, u8 *addr);
+ extern void brcms_c_start_ap(struct brcms_c_info *wlc, u8 *addr,
+ const u8 *bssid, u8 *ssid, size_t ssid_len);
++extern void brcms_c_start_adhoc(struct brcms_c_info *wlc, u8 *addr);
+ extern void brcms_c_update_beacon(struct brcms_c_info *wlc);
+ extern void brcms_c_set_new_beacon(struct brcms_c_info *wlc,
+ struct sk_buff *beacon, u16 tim_offset,
diff --git a/package/mac80211/patches/875-brcmsmac-remove-extra-regulation-restriction.patch b/package/mac80211/patches/875-brcmsmac-remove-extra-regulation-restriction.patch
new file mode 100644
index 0000000000..dd1393ae5d
--- /dev/null
+++ b/package/mac80211/patches/875-brcmsmac-remove-extra-regulation-restriction.patch
@@ -0,0 +1,31 @@
+--- a/drivers/net/wireless/brcm80211/brcmsmac/channel.c
++++ b/drivers/net/wireless/brcm80211/brcmsmac/channel.c
+@@ -59,23 +59,16 @@
+
+ #define BRCM_2GHZ_2412_2462 REG_RULE(2412-10, 2462+10, 40, 0, 19, 0)
+ #define BRCM_2GHZ_2467_2472 REG_RULE(2467-10, 2472+10, 20, 0, 19, \
+- NL80211_RRF_PASSIVE_SCAN | \
+- NL80211_RRF_NO_IBSS)
++ 0)
+
+ #define BRCM_5GHZ_5180_5240 REG_RULE(5180-10, 5240+10, 40, 0, 21, \
+- NL80211_RRF_PASSIVE_SCAN | \
+- NL80211_RRF_NO_IBSS)
++ 0)
+ #define BRCM_5GHZ_5260_5320 REG_RULE(5260-10, 5320+10, 40, 0, 21, \
+- NL80211_RRF_PASSIVE_SCAN | \
+- NL80211_RRF_DFS | \
+- NL80211_RRF_NO_IBSS)
++ 0)
+ #define BRCM_5GHZ_5500_5700 REG_RULE(5500-10, 5700+10, 40, 0, 21, \
+- NL80211_RRF_PASSIVE_SCAN | \
+- NL80211_RRF_DFS | \
+- NL80211_RRF_NO_IBSS)
++ 0)
+ #define BRCM_5GHZ_5745_5825 REG_RULE(5745-10, 5825+10, 40, 0, 21, \
+- NL80211_RRF_PASSIVE_SCAN | \
+- NL80211_RRF_NO_IBSS)
++ 0)
+
+ static const struct ieee80211_regdomain brcms_regdom_x2 = {
+ .n_reg_rules = 6,
diff --git a/package/mac80211/patches/b02-rt2x00-add-multiple-ap.patch b/package/mac80211/patches/b02-rt2x00-add-multiple-ap.patch
deleted file mode 100644
index 4f06e79dec..0000000000
--- a/package/mac80211/patches/b02-rt2x00-add-multiple-ap.patch
+++ /dev/null
@@ -1,94 +0,0 @@
---- a/drivers/net/wireless/rt2x00/rt2x00.h
-+++ b/drivers/net/wireless/rt2x00/rt2x00.h
-@@ -750,6 +750,14 @@ enum rt2x00_capability_flags {
- };
-
- /*
-+ * Interface combinations
-+ */
-+enum {
-+ IF_COMB_AP = 0,
-+ NUM_IF_COMB,
-+};
-+
-+/*
- * rt2x00 device structure.
- */
- struct rt2x00_dev {
-@@ -876,6 +884,12 @@ struct rt2x00_dev {
- unsigned int intf_beaconing;
-
- /*
-+ * Interface combinations
-+ */
-+ struct ieee80211_iface_limit if_limits_ap;
-+ struct ieee80211_iface_combination if_combinations[NUM_IF_COMB];
-+
-+ /*
- * Link quality
- */
- struct link link;
---- a/drivers/net/wireless/rt2x00/rt2x00dev.c
-+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
-@@ -1146,6 +1146,34 @@ void rt2x00lib_stop(struct rt2x00_dev *r
- rt2x00dev->intf_associated = 0;
- }
-
-+static inline void rt2x00lib_set_if_combinations(struct rt2x00_dev *rt2x00dev)
-+{
-+ struct ieee80211_iface_limit *if_limit;
-+ struct ieee80211_iface_combination *if_combination;
-+
-+ /*
-+ * Build up AP interface limits structure.
-+ */
-+ if_limit = &rt2x00dev->if_limits_ap;
-+ if_limit->max = rt2x00dev->ops->max_ap_intf;
-+ if_limit->types = BIT(NL80211_IFTYPE_AP);
-+
-+ /*
-+ * Build up AP interface combinations structure.
-+ */
-+ if_combination = &rt2x00dev->if_combinations[IF_COMB_AP];
-+ if_combination->limits = if_limit;
-+ if_combination->n_limits = 1;
-+ if_combination->max_interfaces = if_limit->max;
-+ if_combination->num_different_channels = 1;
-+
-+ /*
-+ * Finally, specify the possible combinations to mac80211.
-+ */
-+ rt2x00dev->hw->wiphy->iface_combinations = rt2x00dev->if_combinations;
-+ rt2x00dev->hw->wiphy->n_iface_combinations = 1;
-+}
-+
- /*
- * driver allocation handlers.
- */
-@@ -1165,6 +1193,11 @@ int rt2x00lib_probe_dev(struct rt2x00_de
- }
- }
-
-+ /*
-+ * Set possible interface combinations.
-+ */
-+ rt2x00lib_set_if_combinations(rt2x00dev);
-+
- spin_lock_init(&rt2x00dev->irqmask_lock);
- mutex_init(&rt2x00dev->csr_mutex);
-
---- a/drivers/net/wireless/rt2x00/rt2x00mac.c
-+++ b/drivers/net/wireless/rt2x00/rt2x00mac.c
-@@ -243,10 +243,9 @@ int rt2x00mac_add_interface(struct ieee8
- return -ENOBUFS;
-
- /*
-- * Check if we exceeded the maximum amount
-- * of supported interfaces.
-+ * We don't support multiple STA interfaces.
- */
-- if (rt2x00dev->intf_sta_count >= rt2x00dev->ops->max_sta_intf)
-+ if (rt2x00dev->intf_sta_count)
- return -ENOBUFS;
-
- break;