mac80211: update to 2013-02-22 from trunk + backports
authornbd <nbd@3c298f89-4303-0410-b956-a3cf2f4a3e73>
Sun, 28 Apr 2013 12:37:09 +0000 (12:37 +0000)
committernbd <nbd@3c298f89-4303-0410-b956-a3cf2f4a3e73>
Sun, 28 Apr 2013 12:37:09 +0000 (12:37 +0000)
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

148 files changed:
Config.in
package/mac80211/Makefile
package/mac80211/files/b43-fwcutter-fw-dirname.patch [deleted file]
package/mac80211/files/host_bin/b43-fwsquash.py [deleted file]
package/mac80211/files/lib/wifi/mac80211.sh
package/mac80211/patches/000-disable_ethernet.patch [deleted file]
package/mac80211/patches/001-disable_b44.patch [deleted file]
package/mac80211/patches/001-disable_rfkill.patch [new file with mode: 0644]
package/mac80211/patches/002-disable_rfkill.patch [deleted file]
package/mac80211/patches/002-disable_ssb_build.patch [new file with mode: 0644]
package/mac80211/patches/003-disable_bt.patch [deleted file]
package/mac80211/patches/003-disable_codel.patch [new file with mode: 0644]
package/mac80211/patches/004-use_env_for_bash.patch [new file with mode: 0644]
package/mac80211/patches/005-disable_ssb_build.patch [deleted file]
package/mac80211/patches/006-disable_bcma_build.patch [deleted file]
package/mac80211/patches/007-remove_misc_drivers.patch [deleted file]
package/mac80211/patches/008-disable_mesh.patch [deleted file]
package/mac80211/patches/009-remove_mac80211_module_dependence.patch [deleted file]
package/mac80211/patches/010-add_include_for_bcma.patch [new file with mode: 0644]
package/mac80211/patches/010-no_pcmcia.patch [deleted file]
package/mac80211/patches/011-no_sdio.patch [deleted file]
package/mac80211/patches/013-disable_b43_nphy.patch [deleted file]
package/mac80211/patches/015-remove-rt2x00-options.patch [deleted file]
package/mac80211/patches/016-remove_pid_algo.patch [deleted file]
package/mac80211/patches/017-remove_ath9k_rc.patch [deleted file]
package/mac80211/patches/018-revert_printk_va_format.patch [deleted file]
package/mac80211/patches/019-remove_ath5k_pci_option.patch [deleted file]
package/mac80211/patches/020-disable_tty_set_termios.patch [new file with mode: 0644]
package/mac80211/patches/021-add_include_for_bcma.patch [deleted file]
package/mac80211/patches/022-remove_crc8_and_cordic.patch [deleted file]
package/mac80211/patches/023-ath9k_disable_btcoex.patch [deleted file]
package/mac80211/patches/030-disable_tty_set_termios.patch [deleted file]
package/mac80211/patches/030-wext.patch [new file with mode: 0644]
package/mac80211/patches/040-linux_3_9_compat.patch [new file with mode: 0644]
package/mac80211/patches/050-compat_firmware.patch [deleted file]
package/mac80211/patches/060-compat_add_module_pci_driver.patch [deleted file]
package/mac80211/patches/070-disable_codel.patch [deleted file]
package/mac80211/patches/071-add_codel_ifdef.patch [deleted file]
package/mac80211/patches/100-disable_pcmcia_compat.patch [deleted file]
package/mac80211/patches/110-disable_usb_compat.patch [deleted file]
package/mac80211/patches/130-mesh_pathtbl_backport.patch
package/mac80211/patches/150-disable_addr_notifier.patch [new file with mode: 0644]
package/mac80211/patches/300-pending_work.patch
package/mac80211/patches/310-ap_scan.patch
package/mac80211/patches/320-ath9k_no_eeprom_name.patch [new file with mode: 0644]
package/mac80211/patches/321-bcma_backport.patch [new file with mode: 0644]
package/mac80211/patches/400-ath_move_debug_code.patch
package/mac80211/patches/401-ath9k_blink_default.patch
package/mac80211/patches/402-ath9k-fix-invalid-mac-address-handling.patch
package/mac80211/patches/403-ath_regd_optional.patch
package/mac80211/patches/405-regd_no_assoc_hints.patch
package/mac80211/patches/410-ath9k_allow_adhoc_and_ap.patch
package/mac80211/patches/411-ath5k_allow_adhoc_and_ap.patch
package/mac80211/patches/412-mac80211_allow_adhoc_and_ap.patch [deleted file]
package/mac80211/patches/420-ath5k_disable_fast_cc.patch
package/mac80211/patches/500-ath9k_eeprom_debugfs.patch
package/mac80211/patches/501-ath9k-eeprom_endianess.patch
package/mac80211/patches/502-ath9k_ahb_init.patch
package/mac80211/patches/510-ath9k_intr_mitigation_tweak.patch
package/mac80211/patches/511-ath9k_reduce_rxbuf.patch
package/mac80211/patches/512-ath9k_channelbw_debugfs.patch
package/mac80211/patches/513-mac80211_reduce_txqueuelen.patch [deleted file]
package/mac80211/patches/520-mac80211_cur_txpower.patch
package/mac80211/patches/521-ath9k_cur_txpower.patch
package/mac80211/patches/522-ath9k_per_chain_signal_strength.patch
package/mac80211/patches/523-cfg80211_fix_antenna_gain.patch [deleted file]
package/mac80211/patches/523-mac80211_configure_antenna_gain.patch [new file with mode: 0644]
package/mac80211/patches/524-ath9k_use_configured_antenna_gain.patch [new file with mode: 0644]
package/mac80211/patches/524-mac80211_configure_antenna_gain.patch [deleted file]
package/mac80211/patches/525-ath9k_use_configured_antenna_gain.patch [deleted file]
package/mac80211/patches/526-cfg80211_fix_max_reg_power.patch [deleted file]
package/mac80211/patches/530-ath9k_extra_leds.patch [new file with mode: 0644]
package/mac80211/patches/530-ath9k_fix_initvals.patch [deleted file]
package/mac80211/patches/531-ath9k_extra_platform_leds.patch [new file with mode: 0644]
package/mac80211/patches/540-ath9k_extra_leds.patch [deleted file]
package/mac80211/patches/540-mac80211_optimize_mcs_rate_mask.patch [new file with mode: 0644]
package/mac80211/patches/541-ath9k_extra_platform_leds.patch [deleted file]
package/mac80211/patches/541-ath9k_optimize_interrupt_mitigation.patch [new file with mode: 0644]
package/mac80211/patches/550-ath9k_reduce_ani_interval.patch [new file with mode: 0644]
package/mac80211/patches/550-mac80211_optimize_mcs_rate_mask.patch [deleted file]
package/mac80211/patches/551-ath9k_optimize_interrupt_mitigation.patch [deleted file]
package/mac80211/patches/551-ath9k_revert_initval_change.patch [new file with mode: 0644]
package/mac80211/patches/552-ath9k_rx_dma_stop_check.patch [new file with mode: 0644]
package/mac80211/patches/553-ath9k_debugfs_diag.patch [new file with mode: 0644]
package/mac80211/patches/554-ath9k_ani_mrc_fix.patch [new file with mode: 0644]
package/mac80211/patches/555-ath9k-allow-to-disable-bands-via-platform-data.patch [new file with mode: 0644]
package/mac80211/patches/560-ath9k_reduce_ani_interval.patch [deleted file]
package/mac80211/patches/561-ath9k_revert_initval_change.patch [deleted file]
package/mac80211/patches/562-ath9k_add_idle_hack.patch [deleted file]
package/mac80211/patches/563-ath9k_rx_dma_stop_check.patch [deleted file]
package/mac80211/patches/564-ath9k_debugfs_diag.patch [deleted file]
package/mac80211/patches/565-ath9k_disable_paprd.patch [deleted file]
package/mac80211/patches/566-ath9k_use_ieee80211_free_txskb.patch [deleted file]
package/mac80211/patches/567-ath9k_ani_mrc_fix.patch [deleted file]
package/mac80211/patches/568-ath9k_fix_stale_pointer.patch [deleted file]
package/mac80211/patches/603-rt2x00-introduce-rt2x00eeprom.patch
package/mac80211/patches/604-rt2x00-add-CONFIG_RT2X00_LIB_EEPROM-option.patch
package/mac80211/patches/605-rt2x00-pci-eeprom.patch
package/mac80211/patches/606-rt2x00_no_realign.patch
package/mac80211/patches/607-rt2x00-allow_disabling_bands_through_platform_data.patch
package/mac80211/patches/608-add_platform_data_mac_addr.patch
package/mac80211/patches/610-rt2x00-fix-rt3352-ext-pa.patch [new file with mode: 0644]
package/mac80211/patches/611-rt2x00-rf_vals-rt3352-xtal20.patch [new file with mode: 0644]
package/mac80211/patches/612-rt2x00-make-wmac-loadable-via-OF-on-rt288x-305x-SoC.patch [new file with mode: 0644]
package/mac80211/patches/613-rt2x00-fixup-symbols.patch [new file with mode: 0644]
package/mac80211/patches/614-rt2x00-of_load_eeprom_filename.patch [new file with mode: 0644]
package/mac80211/patches/615-rt2x00-fix_20mhz_clk.patch [new file with mode: 0644]
package/mac80211/patches/616-rt2x00-support-rt5350.patch [new file with mode: 0644]
package/mac80211/patches/617-rt2x00-load-eeprom-on-SoC-from-a-mtd-device-defines-.patch [new file with mode: 0644]
package/mac80211/patches/620-rt2x00-support-rt3352.patch [deleted file]
package/mac80211/patches/621-rt2x00-fix-rt3352-lnagain.patch [deleted file]
package/mac80211/patches/622-rt2x00-fix-rt3352-ext-pa.patch [deleted file]
package/mac80211/patches/623-rt2x00-rf_vals-rt3352-xtal20.patch [deleted file]
package/mac80211/patches/700-mwl8k-missing-pci-id-for-WNR854T.patch
package/mac80211/patches/701-mwl8k-don-t-overwrite-regulatory-settings.patch [new file with mode: 0644]
package/mac80211/patches/702-mwl8k-always-apply-configuration-even-when-device-is.patch [new file with mode: 0644]
package/mac80211/patches/800-b43-gpio-mask-module-option.patch
package/mac80211/patches/810-b43_no_pio.patch
package/mac80211/patches/820-b43-add-antenna-control.patch
package/mac80211/patches/830-b43-workaround-pcie-bcm4716.patch
package/mac80211/patches/849-brcmsmac-add-device-found-on-some-SoCs-like-the-bcm4.patch [deleted file]
package/mac80211/patches/850-brcmsmac-add-support-for-BCM43224.patch [deleted file]
package/mac80211/patches/850-brcmsmac-start-adding-support-for-core-rev-28.patch [new file with mode: 0644]
package/mac80211/patches/851-brcmsmac-start-adding-support-for-core-rev-28.patch [deleted file]
package/mac80211/patches/860-brcmsmac-implement-ieee80211_ops-get_tsf-and-set_tsf.patch [new file with mode: 0644]
package/mac80211/patches/861-brcmsmac-add-interface-type-to-brcms_bss_cfg.patch [new file with mode: 0644]
package/mac80211/patches/862-brcmsmac-remove-brcms_bss_cfg-BSS.patch [new file with mode: 0644]
package/mac80211/patches/863-brcmsmac-remove-brcms_bss_cfg-associated.patch [new file with mode: 0644]
package/mac80211/patches/864-brcmsmac-remove-brcms_bss_cfg-enable.patch [new file with mode: 0644]
package/mac80211/patches/865-brcmsmac-remove-brcms_bss_cfg-up.patch [new file with mode: 0644]
package/mac80211/patches/866-brcmsmac-remove-brcms_bss_cfg-cur_etheraddr.patch [new file with mode: 0644]
package/mac80211/patches/867-brcmsmac-remove-brcms_pub-bcmerr.patch [new file with mode: 0644]
package/mac80211/patches/868-brcmsmac-write-beacon-period-to-hardware.patch [new file with mode: 0644]
package/mac80211/patches/869-brcmsmac-add-beacon-template-support.patch [new file with mode: 0644]
package/mac80211/patches/870-brcmsmac-react-on-changing-SSID.patch [new file with mode: 0644]
package/mac80211/patches/871-brcmsmac-add-support-for-probe-response-template.patch [new file with mode: 0644]
package/mac80211/patches/872-brcmsmac-deactivate-ucode-sending-probe-responses.patch [new file with mode: 0644]
package/mac80211/patches/873-brcmsmac-activate-AP-support.patch [new file with mode: 0644]
package/mac80211/patches/874-brcmsmac-add-support-for-adhoc-mode.patch [new file with mode: 0644]
package/mac80211/patches/875-brcmsmac-remove-extra-regulation-restriction.patch [new file with mode: 0644]
package/mac80211/patches/b01-ath9k-allow-to-disable-bands-via-platform-data.patch [deleted file]
package/mac80211/patches/b02-rt2x00-add-multiple-ap.patch [deleted file]
tools/Makefile
tools/b43-tools/Makefile [new file with mode: 0644]
tools/b43-tools/files/b43-fwsquash.py [new file with mode: 0755]
tools/b43-tools/patches/001-fw-dirname.patch [new file with mode: 0644]
tools/b43-tools/patches/002-no_libfl.patch [new file with mode: 0644]
tools/b43-tools/patches/100-b43-asm-fix-compile-error-undefined-reference-to-yyd.patch [new file with mode: 0644]

index 19c8edf..5b4522e 100644 (file)
--- a/Config.in
+++ b/Config.in
@@ -284,6 +284,9 @@ menu "Global build settings"
                bool "Enable printk timestamps"
                default y
 
                bool "Enable printk timestamps"
                default y
 
+       config KERNEL_RELAY
+               bool
+
        comment "Package build options"
 
        config DEBUG
        comment "Package build options"
 
        config DEBUG
index a36069c..670c1b7 100644 (file)
@@ -10,17 +10,19 @@ include $(INCLUDE_DIR)/kernel.mk
 
 PKG_NAME:=mac80211
 
 
 PKG_NAME:=mac80211
 
-PKG_VERSION:=2012-09-07
-PKG_RELEASE:=3
+PKG_VERSION:=2013-02-22
+PKG_RELEASE:=1
 PKG_SOURCE_URL:=http://mirror2.openwrt.org/sources
 PKG_SOURCE_URL:=http://mirror2.openwrt.org/sources
-PKG_MD5SUM:=59e0a114ee4b755a6e47cb6cd0f32ebc
+PKG_MD5SUM:=de1a03ca1f72748d4523672c8facbf7e
 
 PKG_SOURCE:=compat-wireless-$(PKG_VERSION).tar.bz2
 PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/compat-wireless-$(PKG_VERSION)
 PKG_BUILD_PARALLEL:=1
 
 
 PKG_SOURCE:=compat-wireless-$(PKG_VERSION).tar.bz2
 PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/compat-wireless-$(PKG_VERSION)
 PKG_BUILD_PARALLEL:=1
 
+PKG_MAINTAINER:=Felix Fietkau <nbd@openwrt.org>
+
 PKG_DRIVERS = \
 PKG_DRIVERS = \
-       ath5k libertas-usb libertas-sd p54-common p54-pci p54-usb p54-spi \
+       adm8211 ath5k libertas-usb libertas-sd p54-common p54-pci p54-usb p54-spi \
        rt2x00-lib rt2x00-pci rt2x00-usb rt2x00-soc rt2800-lib rt2400-pci \
        rt2500-pci rt2500-usb rt61-pci rt73-usb rt2800-pci rt2800-usb \
        rtl8180 rtl8187 zd1211rw mac80211-hwsim carl9170 b43 b43legacy \
        rt2x00-lib rt2x00-pci rt2x00-usb rt2x00-soc rt2800-lib rt2400-pci \
        rt2500-pci rt2500-usb rt61-pci rt73-usb rt2800-pci rt2800-usb \
        rtl8180 rtl8187 zd1211rw mac80211-hwsim carl9170 b43 b43legacy \
@@ -39,7 +41,7 @@ PKG_CONFIG_DEPENDS:= \
        CONFIG_PACKAGE_B43_N_PHY \
        CONFIG_ATH_USER_REGD \
 
        CONFIG_PACKAGE_B43_N_PHY \
        CONFIG_ATH_USER_REGD \
 
-CARL9170_FW_VERSION:=1.9.4
+CARL9170_FW_VERSION:=1.9.6
 
 include $(INCLUDE_DIR)/package.mk
 
 
 include $(INCLUDE_DIR)/package.mk
 
@@ -78,23 +80,22 @@ define KernelPackage/mac80211
 endef
 
 define KernelPackage/mac80211/config
 endef
 
 define KernelPackage/mac80211/config
-       menu "Configuration"
-               depends on PACKAGE_kmod-mac80211
+  if PACKAGE_kmod-mac80211
 
        config PACKAGE_MAC80211_DEBUGFS
                bool "Export mac80211 internals in DebugFS"
 
        config PACKAGE_MAC80211_DEBUGFS
                bool "Export mac80211 internals in DebugFS"
+               select KERNEL_DEBUG_FS
+               select KERNEL_RELAY if PACKAGE_kmod-ath9k-common
                default y
                help
                  Select this to see extensive information about
                  the internal state of mac80211 in debugfs.
 
                default y
                help
                  Select this to see extensive information about
                  the internal state of mac80211 in debugfs.
 
-                 Say N unless you know you need this.
-
        config PACKAGE_MAC80211_MESH
                bool "Enable 802.11s mesh support"
                default y
 
        config PACKAGE_MAC80211_MESH
                bool "Enable 802.11s mesh support"
                default y
 
-       endmenu
+  endif
 endef
 
 define KernelPackage/mac80211/description
 endef
 
 define KernelPackage/mac80211/description
@@ -102,12 +103,12 @@ Generic IEEE 802.11 Networking Stack (mac80211)
 endef
 
 PKG_LINUX_FIRMWARE_NAME:=linux-firmware
 endef
 
 PKG_LINUX_FIRMWARE_NAME:=linux-firmware
-PKG_LINUX_FIRMWARE_VERSION:=375e9548bf75a5664256d47a2f9e14b79181e02d
+PKG_LINUX_FIRMWARE_VERSION:=6942dba419d2ebf8c15514972e89734fd7a8cebc
 PKG_LINUX_FIRMWARE_SOURCE:=$(PKG_LINUX_FIRMWARE_NAME)-$(PKG_LINUX_FIRMWARE_VERSION).tar.bz2
 PKG_LINUX_FIRMWARE_PROTO:=git
 PKG_LINUX_FIRMWARE_SOURCE:=$(PKG_LINUX_FIRMWARE_NAME)-$(PKG_LINUX_FIRMWARE_VERSION).tar.bz2
 PKG_LINUX_FIRMWARE_PROTO:=git
-# PKG_LINUX_FIRMWARE_SOURCE_URL:=git://git.infradead.org/users/dwmw2/linux-firmware.git
 PKG_LINUX_FIRMWARE_SOURCE_URL:=git://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git
 PKG_LINUX_FIRMWARE_SUBDIR:=$(PKG_LINUX_FIRMWARE_NAME)-$(PKG_LINUX_FIRMWARE_VERSION)
 PKG_LINUX_FIRMWARE_SOURCE_URL:=git://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git
 PKG_LINUX_FIRMWARE_SUBDIR:=$(PKG_LINUX_FIRMWARE_NAME)-$(PKG_LINUX_FIRMWARE_VERSION)
+PKG_LINUX_FIRMWARE_MIRROR_MD5SUM:=a5f8c27af9e43f0ad24d7f821c5a781e
 
 define Download/linux-firmware
   FILE:=$(PKG_LINUX_FIRMWARE_SOURCE)
 
 define Download/linux-firmware
   FILE:=$(PKG_LINUX_FIRMWARE_SOURCE)
@@ -116,6 +117,7 @@ define Download/linux-firmware
   PROTO:=$(PKG_LINUX_FIRMWARE_PROTO)
   VERSION:=$(PKG_LINUX_FIRMWARE_VERSION)
   SUBDIR:=$(PKG_LINUX_FIRMWARE_SUBDIR)
   PROTO:=$(PKG_LINUX_FIRMWARE_PROTO)
   VERSION:=$(PKG_LINUX_FIRMWARE_VERSION)
   SUBDIR:=$(PKG_LINUX_FIRMWARE_SUBDIR)
+  MIRROR_MD5SUM:=$(PKG_LINUX_FIRMWARE_MIRROR_MD5SUM)
 endef
 $(eval $(call Download,linux-firmware))
 
 endef
 $(eval $(call Download,linux-firmware))
 
@@ -149,7 +151,7 @@ $(eval $(call Download,p54spi))
 define Download/carl9170
   FILE:=$(CARL9170_FW)-$(CARL9170_FW_VERSION)
   URL:=http://downloads.openwrt.org/sources/
 define Download/carl9170
   FILE:=$(CARL9170_FW)-$(CARL9170_FW_VERSION)
   URL:=http://downloads.openwrt.org/sources/
-  MD5SUM:=30e2ae80c33b3008d271556d1a14e3ea
+  MD5SUM:=2fa6ed98d53d0b5fbcc136d1cf5e9609
 endef
 $(eval $(call Download,carl9170))
 
 endef
 $(eval $(call Download,carl9170))
 
@@ -215,12 +217,11 @@ $(call KernelPackage/rt2x00/Default)
 endef
 
 define KernelPackage/rt2x00-lib/config
 endef
 
 define KernelPackage/rt2x00-lib/config
-       menu "Configuration"
-               depends PACKAGE_kmod-rt2x00-lib
+  if PACKAGE_kmod-rt2x00-lib
 
        config PACKAGE_RT2X00_LIB_DEBUGFS
                bool "Enable rt2x00 debugfs support"
 
        config PACKAGE_RT2X00_LIB_DEBUGFS
                bool "Enable rt2x00 debugfs support"
-               depends PACKAGE_MAC80211_DEBUGFS
+               depends on PACKAGE_MAC80211_DEBUGFS
                help
                  Enable creation of debugfs files for the rt2x00 drivers.
                  These debugfs files support both reading and writing of the
                help
                  Enable creation of debugfs files for the rt2x00 drivers.
                  These debugfs files support both reading and writing of the
@@ -231,7 +232,7 @@ define KernelPackage/rt2x00-lib/config
                help
                  Enable debugging output for all rt2x00 modules
 
                help
                  Enable debugging output for all rt2x00 modules
 
-       endmenu
+  endif
 endef
 
 define KernelPackage/rt2x00-pci
 endef
 
 define KernelPackage/rt2x00-pci
@@ -362,10 +363,16 @@ define KernelPackage/zd1211rw
   AUTOLOAD:=$(call AutoLoad,60,zd1211rw)
 endef
 
   AUTOLOAD:=$(call AutoLoad,60,zd1211rw)
 endef
 
-define KernelPackage/ath/config
-       menu "Configuration"
-               depends on PACKAGE_kmod-ath
+define KernelPackage/adm8211
+  $(call KernelPackage/mac80211/Default)
+  TITLE:=ADMTek 8211 support
+  DEPENDS+=@PCI_SUPPORT +kmod-mac80211 +kmod-eeprom-93cx6
+  FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/adm8211.ko
+  AUTOLOAD:=$(call AutoLoad,60,adm8211)
+endef
 
 
+define KernelPackage/ath/config
+  if PACKAGE_kmod-ath
        config ATH_USER_REGD
                bool "Force Atheros drivers to respect the user's regdomain settings"
                help
        config ATH_USER_REGD
                bool "Force Atheros drivers to respect the user's regdomain settings"
                help
@@ -382,8 +389,7 @@ define KernelPackage/ath/config
                help
                  Say Y, if you want to debug atheros wireless drivers.
                  Right now only ath9k makes use of this.
                help
                  Say Y, if you want to debug atheros wireless drivers.
                  Right now only ath9k makes use of this.
-
-       endmenu
+  endif
 endef
 
 define KernelPackage/ath
 endef
 
 define KernelPackage/ath
@@ -643,66 +649,92 @@ define KernelPackage/iwlagn/description
 endef
 
 define KernelPackage/iwlagn/config
 endef
 
 define KernelPackage/iwlagn/config
-       menu "Configuration"
-               depends on PACKAGE_kmod-iwlagn
+  if PACKAGE_kmod-iwlagn
 
        config IWL5000_FW
                bool "Intel 5000 Firmware"
                default y
                help
                  Download and install firmware for:
 
        config IWL5000_FW
                bool "Intel 5000 Firmware"
                default y
                help
                  Download and install firmware for:
-                   Intel 5000 wireless card into /lib/firmware.
+                   Intel Wireless WiFi 5100AGN, 5300AGN, and 5350AGN
 
        config IWL5150_FW
                bool "Intel 5150 Firmware"
                default y
                help
                  Download and install firmware for:
 
        config IWL5150_FW
                bool "Intel 5150 Firmware"
                default y
                help
                  Download and install firmware for:
-                   Intel 5150 wireless card into /lib/firmware.
+                   Intel Wireless WiFi 5150AGN
 
        config IWL1000_FW
                bool "Intel 1000 Firmware"
                default y
                help
                  Download and install firmware for:
 
        config IWL1000_FW
                bool "Intel 1000 Firmware"
                default y
                help
                  Download and install firmware for:
-                   Intel 1000 wireless card into /lib/firmware.
+                   Intel Centrino Wireless-N 1000
 
        config IWL6000_FW
                bool "Intel 6000 Firmware"
                default y
                help
                  Download and install firmware for:
 
        config IWL6000_FW
                bool "Intel 6000 Firmware"
                default y
                help
                  Download and install firmware for:
-                   Intel 6000 wireless card into /lib/firmware.
+                   Intel Centrino Ultimate-N 6300 and Advanced-N 6200
 
        config IWL6050_FW
                bool "Intel 6050 Firmware"
                default y
                help
                  Download and install firmware for:
 
        config IWL6050_FW
                bool "Intel 6050 Firmware"
                default y
                help
                  Download and install firmware for:
-                   Intel 6050 wireless card into /lib/firmware.
+                   Intel Centrino Advanced-N + WiMAX 6250 and Wireless-N + WiMAX 6150
 
        config IWL6005_FW
                bool "Intel 6005 Firmware"
                default y
                help
                  Download and install firmware for:
 
        config IWL6005_FW
                bool "Intel 6005 Firmware"
                default y
                help
                  Download and install firmware for:
-                   Intel 6005 wireless card into /lib/firmware.
+                   Intel Centrino Advanced-N 6205
 
        config IWL6030_FW
                bool "Intel 6030 Firmware"
                default y
                help
                  Download and install firmware for:
 
        config IWL6030_FW
                bool "Intel 6030 Firmware"
                default y
                help
                  Download and install firmware for:
-                   Intel 6030 wireless card into /lib/firmware.
+                   Intel Centrino Advanced-N 6230, Wireless-N 1030, Wireless-N 130 and Advanced-N 6235
 
        config IWL100_FW
                bool "Intel 100 Firmware"
                default y
                help
                  Download and install firmware for:
 
        config IWL100_FW
                bool "Intel 100 Firmware"
                default y
                help
                  Download and install firmware for:
-                   Intel 100 wireless card into /lib/firmware.
+                   Intel Centrino Wireless-N 100
+
+       config IWL2000_FW
+               bool "Intel 2000 Firmware"
+               default y
+               help
+                 Download and install firmware for:
+                   Intel Centrino Wireless-N 2200
 
 
-       endmenu
+       config IWL2030_FW
+               bool "Intel 2030 Firmware"
+               default y
+               help
+                 Download and install firmware for:
+                   Intel Centrino Wireless-N 2230
+
+       config IWL105_FW
+               bool "Intel 105 Firmware"
+               default y
+               help
+                 Download and install firmware for:
+                   Intel Centrino Wireless-N 105
+
+       config IWL135_FW
+               bool "Intel 135 Firmware"
+               default y
+               help
+                 Download and install firmware for:
+                   Intel Centrino Wireless-N 135
+  endif
 endef
 
 define KernelPackage/iwl-legacy
 endef
 
 define KernelPackage/iwl-legacy
@@ -822,35 +854,6 @@ PKG_B43_FWV3_SOURCE:=$(PKG_B43_FWV3_NAME)-$(PKG_B43_FWV3_VERSION).o
 PKG_B43_FWV3_SOURCE_URL:=http://downloads.openwrt.org/sources/
 PKG_B43_FWV3_MD5SUM:=e08665c5c5b66beb9c3b2dd54aa80cb3
 
 PKG_B43_FWV3_SOURCE_URL:=http://downloads.openwrt.org/sources/
 PKG_B43_FWV3_MD5SUM:=e08665c5c5b66beb9c3b2dd54aa80cb3
 
-ifeq ($(CONFIG_B43_OPENFIRMWARE),y)
-  PKG_B43_FWCUTTER_NAME:=b43-fwcutter
-  PKG_B43_FWCUTTER_VERSION:=3e69531aa65b8f664a0ab00dfc3e2eefeb0cb417
-  PKG_B43_FWCUTTER_SOURCE:=$(PKG_B43_FWCUTTER_NAME)-$(PKG_B43_FWCUTTER_VERSION).tar.bz2
-  PKG_B43_FWCUTTER_PROTO:=git
-  PKG_B43_FWCUTTER_SOURCE_URL:=http://git.bu3sch.de/git/b43-tools.git
-  PKG_B43_FWCUTTER_SUBDIR:=$(PKG_B43_FWCUTTER_NAME)-$(PKG_B43_FWCUTTER_VERSION)
-  PKG_B43_FWCUTTER_OBJECT:=$(PKG_B43_FWCUTTER_NAME)-$(PKG_B43_FWCUTTER_VERSION)/fwcutter/
-else
-  PKG_B43_FWCUTTER_NAME:=b43-fwcutter
-  PKG_B43_FWCUTTER_VERSION:=015
-  PKG_B43_FWCUTTER_SOURCE:=$(PKG_B43_FWCUTTER_NAME)-$(PKG_B43_FWCUTTER_VERSION).tar.bz2
-  PKG_B43_FWCUTTER_PROTO:=default
-  PKG_B43_FWCUTTER_SOURCE_URL:=http://bu3sch.de/b43/fwcutter/
-  PKG_B43_FWCUTTER_MD5SUM:=628e030565222a107bc40300313cbe76
-  PKG_B43_FWCUTTER_SUBDIR:=b43-fwcutter-$(PKG_B43_FWCUTTER_VERSION)
-  PKG_B43_FWCUTTER_OBJECT:=$(PKG_B43_FWCUTTER_NAME)-$(PKG_B43_FWCUTTER_VERSION)/
-endif
-
-define Download/b43-common
-  FILE:=$(PKG_B43_FWCUTTER_SOURCE)
-  URL:=$(PKG_B43_FWCUTTER_SOURCE_URL)
-  MD5SUM:=$(PKG_B43_FWCUTTER_MD5SUM)
-  PROTO:=$(PKG_B43_FWCUTTER_PROTO)
-  VERSION:=$(PKG_B43_FWCUTTER_VERSION)
-  SUBDIR:=$(PKG_B43_FWCUTTER_SUBDIR)
-endef
-$(eval $(call Download,b43-common))
-
 define Download/b43
   FILE:=$(PKG_B43_FWV4_SOURCE)
   URL:=$(PKG_B43_FWV4_SOURCE_URL)
 define Download/b43
   FILE:=$(PKG_B43_FWV4_SOURCE)
   URL:=$(PKG_B43_FWV4_SOURCE_URL)
@@ -865,27 +868,21 @@ define Download/b43legacy
 endef
 $(eval $(call Download,b43legacy))
 
 endef
 $(eval $(call Download,b43legacy))
 
-define KernelPackage/b43-common
+
+define KernelPackage/b43
   $(call KernelPackage/mac80211/Default)
   $(call KernelPackage/mac80211/Default)
-  TITLE:=Generic stuff for Broadcom wireless devices
+  TITLE:=Broadcom 43xx wireless support
   URL:=http://linuxwireless.org/en/users/Drivers/b43
   KCONFIG:= \
        CONFIG_HW_RANDOM=y
   URL:=http://linuxwireless.org/en/users/Drivers/b43
   KCONFIG:= \
        CONFIG_HW_RANDOM=y
-  DEPENDS+= +kmod-mac80211 +!(TARGET_brcm47xx||TARGET_brcm63xx):kmod-ssb
-endef
-
-define KernelPackage/b43
-$(call KernelPackage/b43-common)
-  DEPENDS+= +@DRIVER_11N_SUPPORT +!TARGET_brcm47xx:kmod-bcma
-  TITLE:=Broadcom 43xx wireless support
+  DEPENDS+= +kmod-mac80211 +!TARGET_brcm47xx:kmod-bcma +!(TARGET_brcm47xx||TARGET_brcm63xx):kmod-ssb
   FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/b43/b43.ko
   AUTOLOAD:=$(call AutoLoad,30,b43)
   MENU:=1
 endef
 
 define KernelPackage/b43/config
   FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/b43/b43.ko
   AUTOLOAD:=$(call AutoLoad,30,b43)
   MENU:=1
 endef
 
 define KernelPackage/b43/config
-       menu "Configuration"
-               depends on PACKAGE_kmod-b43
+  if PACKAGE_kmod-b43
 
        choice
                prompt "b43 firmware version"
 
        choice
                prompt "b43 firmware version"
@@ -917,7 +914,7 @@ define KernelPackage/b43/config
                  This firmware is mostly untested. It is needed for some N-PHY devices.
 
                  If unsure, select the "stable" firmware.
                  This firmware is mostly untested. It is needed for some N-PHY devices.
 
                  If unsure, select the "stable" firmware.
-   
+
        config B43_FW_5_100_138
                bool "Firmware 666.2 from driver 5.100.138 (stable)"
                help
        config B43_FW_5_100_138
                bool "Firmware 666.2 from driver 5.100.138 (stable)"
                help
@@ -956,7 +953,7 @@ define KernelPackage/b43/config
        config B43_FW_SQUASH_COREREVS
                string "Core revisions to include"
                depends on B43_FW_SQUASH
        config B43_FW_SQUASH_COREREVS
                string "Core revisions to include"
                depends on B43_FW_SQUASH
-               default "5,6,7,8,9,10,11,13,14,15,16"
+               default "5,6,7,8,9,10,11,13,15,16,29"
                help
                  This is a comma seperated list of core revision numbers.
 
                help
                  This is a comma seperated list of core revision numbers.
 
@@ -969,7 +966,7 @@ define KernelPackage/b43/config
        config B43_FW_SQUASH_PHYTYPES
                string "PHY types to include"
                depends on B43_FW_SQUASH
        config B43_FW_SQUASH_PHYTYPES
                string "PHY types to include"
                depends on B43_FW_SQUASH
-               default "G,LP,N"
+               default "G,LP,N,HT"
                help
                  This is a comma seperated list of PHY types:
                    A  => A-PHY
                help
                  This is a comma seperated list of PHY types:
                    A  => A-PHY
@@ -1008,7 +1005,9 @@ define KernelPackage/b43/config
                bool "Enable support for N-PHYs"
                default y
                help
                bool "Enable support for N-PHYs"
                default y
                help
-                 Enable support for BCM4321 and BCM4322.
+                 Enable support for N-PHY. This includes support for the following devices:
+                 PCI: BCM4321, BCM4322, BCM43222, BCM43224, BCM43225
+                 SoC: BCM4716, BCM4717, BCM4718
 
                  Currently only 11g speed is available.
 
 
                  Currently only 11g speed is available.
 
@@ -1016,11 +1015,14 @@ define KernelPackage/b43/config
 
        config PACKAGE_B43_PHY_HT
                bool "Enable support for HT-PHYs"
 
        config PACKAGE_B43_PHY_HT
                bool "Enable support for HT-PHYs"
-               default n
+               default y
                help
                help
-                 Currently broken.
+                 Enable support for HT-PHY. This includes support for the following devices:
+                 PCI: BCM4331
 
 
-                 If unsure, say N.
+                 Currently only 11g speed is available.
+
+                 If unsure, say Y.
 
        config PACKAGE_B43_PHY_LCN
                bool "Enable support for LCN-PHYs"
 
        config PACKAGE_B43_PHY_LCN
                bool "Enable support for LCN-PHYs"
@@ -1031,7 +1033,7 @@ define KernelPackage/b43/config
 
                  If unsure, say N.
 
 
                  If unsure, say N.
 
-       endmenu
+  endif
 endef
 
 define KernelPackage/b43/description
 endef
 
 define KernelPackage/b43/description
@@ -1039,16 +1041,19 @@ Kernel module for Broadcom 43xx wireless support (mac80211 stack) new
 endef
 
 define KernelPackage/b43legacy
 endef
 
 define KernelPackage/b43legacy
-$(call KernelPackage/b43-common)
+  $(call KernelPackage/mac80211/Default)
   TITLE:=Broadcom 43xx-legacy wireless support
   TITLE:=Broadcom 43xx-legacy wireless support
+  URL:=http://linuxwireless.org/en/users/Drivers/b43
+  KCONFIG:= \
+       CONFIG_HW_RANDOM=y
+  DEPENDS+= +kmod-mac80211 +!(TARGET_brcm47xx||TARGET_brcm63xx):kmod-ssb
   FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/b43legacy/b43legacy.ko
   AUTOLOAD:=$(call AutoLoad,30,b43legacy)
   MENU:=1
 endef
 
 define KernelPackage/b43legacy/config
   FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/b43legacy/b43legacy.ko
   AUTOLOAD:=$(call AutoLoad,30,b43legacy)
   MENU:=1
 endef
 
 define KernelPackage/b43legacy/config
-       menu "Configuration"
-               depends on PACKAGE_kmod-b43legacy
+  if PACKAGE_kmod-b43legacy
 
        config B43LEGACY_FW_SQUASH
                bool "Remove unnecessary firmware files"
 
        config B43LEGACY_FW_SQUASH
                bool "Remove unnecessary firmware files"
@@ -1073,7 +1078,7 @@ define KernelPackage/b43legacy/config
                  Example (keep files for rev2 and rev4):
                    2,4
 
                  Example (keep files for rev2 and rev4):
                    2,4
 
-       endmenu
+  endif
 endef
 
 define KernelPackage/b43legacy/description
 endef
 
 define KernelPackage/b43legacy/description
@@ -1096,17 +1101,30 @@ define KernelPackage/brcmutil/description
 endef
 
 define KernelPackage/brcmutil/config
 endef
 
 define KernelPackage/brcmutil/config
-       menu "Configuration"
-               depends on PACKAGE_kmod-brcmutil
+  if PACKAGE_kmod-brcmutil
 
        config PACKAGE_BRCM80211_DEBUG
                bool "Broadcom wireless driver debugging"
                help
                  Say Y, if you want to debug brcmsmac and brcmfmac wireless driver.
 
 
        config PACKAGE_BRCM80211_DEBUG
                bool "Broadcom wireless driver debugging"
                help
                  Say Y, if you want to debug brcmsmac and brcmfmac wireless driver.
 
-       endmenu
+  endif
 endef
 
 endef
 
+PKG_BRCMSMAC_FW_NAME:=broadcom-wl
+PKG_BRCMSMAC_FW_VERSION:=5.100.138
+PKG_BRCMSMAC_FW_OBJECT:=$(PKG_BRCMSMAC_FW_NAME)-$(PKG_BRCMSMAC_FW_VERSION)/linux/wl_apsta.o
+PKG_BRCMSMAC_FW_SOURCE:=$(PKG_BRCMSMAC_FW_NAME)-$(PKG_BRCMSMAC_FW_VERSION).tar.bz2
+PKG_BRCMSMAC_FW_SOURCE_URL:=http://www.lwfinger.com/b43-firmware/
+PKG_BRCMSMAC_FW_MD5SUM:=f4e357b09eaf5d8b1f1920cf3493a555
+
+define Download/brcmsmac
+  FILE:=$(PKG_BRCMSMAC_FW_SOURCE)
+  URL:=$(PKG_BRCMSMAC_FW_SOURCE_URL)
+  MD5SUM:=$(PKG_BRCMSMAC_FW_MD5SUM)
+endef
+$(eval $(call Download,brcmsmac))
+
 define KernelPackage/brcmsmac
   $(call KernelPackage/mac80211/Default)
   TITLE:=Broadcom IEEE802.11n PCIe SoftMAC WLAN driver
 define KernelPackage/brcmsmac
   $(call KernelPackage/mac80211/Default)
   TITLE:=Broadcom IEEE802.11n PCIe SoftMAC WLAN driver
@@ -1114,12 +1132,31 @@ define KernelPackage/brcmsmac
   DEPENDS+= +kmod-mac80211 +@DRIVER_11N_SUPPORT +!TARGET_brcm47xx:kmod-bcma +kmod-lib-cordic +kmod-lib-crc8 +kmod-brcmutil
   FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/brcm80211/brcmsmac/brcmsmac.ko
   AUTOLOAD:=$(call AutoLoad,31,brcmsmac)
   DEPENDS+= +kmod-mac80211 +@DRIVER_11N_SUPPORT +!TARGET_brcm47xx:kmod-bcma +kmod-lib-cordic +kmod-lib-crc8 +kmod-brcmutil
   FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/brcm80211/brcmsmac/brcmsmac.ko
   AUTOLOAD:=$(call AutoLoad,31,brcmsmac)
+  MENU:=1
 endef
 
 define KernelPackage/brcmsmac/description
  Kernel module for Broadcom IEEE802.11n PCIe Wireless cards
 endef
 
 endef
 
 define KernelPackage/brcmsmac/description
  Kernel module for Broadcom IEEE802.11n PCIe Wireless cards
 endef
 
+define KernelPackage/brcmsmac/config
+  if PACKAGE_kmod-brcmsmac
+
+       config BRCMSMAC_USE_FW_FROM_WL
+               bool "Use firmware extracted from broadcom proprietary driver"
+               default y
+               help
+                 Instead of using the official brcmsmac firmware a firmware
+                 version 666.2 extracted from the proprietary Broadcom driver
+                 is used. This is needed to get core rev 17 used in bcm4716
+                 to work.
+
+                 If unsure, say Y.
+
+  endif
+endef
+
+
 define KernelPackage/brcmfmac
   $(call KernelPackage/mac80211/Default)
   TITLE:=Broadcom IEEE802.11n USB FullMAC WLAN driver
 define KernelPackage/brcmfmac
   $(call KernelPackage/mac80211/Default)
   TITLE:=Broadcom IEEE802.11n USB FullMAC WLAN driver
@@ -1177,7 +1214,7 @@ BUILDFLAGS:= \
 MAKE_OPTS:= \
        CROSS_COMPILE="$(KERNEL_CROSS)" \
        ARCH="$(LINUX_KARCH)" \
 MAKE_OPTS:= \
        CROSS_COMPILE="$(KERNEL_CROSS)" \
        ARCH="$(LINUX_KARCH)" \
-       EXTRA_CFLAGS="$(BUILDFLAGS)" \
+       EXTRA_CFLAGS="$(BUILDFLAGS) -Wno-undef" \
        $(foreach opt,$(CONFOPTS),CONFIG_$(opt)=m) \
        CONFIG_CFG80211_INTERNAL_REGDB=y \
        CONFIG_CFG80211=$(if $(CONFIG_PACKAGE_kmod-cfg80211),m) \
        $(foreach opt,$(CONFOPTS),CONFIG_$(opt)=m) \
        CONFIG_CFG80211_INTERNAL_REGDB=y \
        CONFIG_CFG80211=$(if $(CONFIG_PACKAGE_kmod-cfg80211),m) \
@@ -1204,6 +1241,7 @@ MAKE_OPTS:= \
        CONFIG_B43_PHY_LCN=$(if $(CONFIG_PACKAGE_B43_PHY_LCN),y) \
        CONFIG_B43_BCMA=y \
        CONFIG_B43_SSB=y \
        CONFIG_B43_PHY_LCN=$(if $(CONFIG_PACKAGE_B43_PHY_LCN),y) \
        CONFIG_B43_BCMA=y \
        CONFIG_B43_SSB=y \
+       CONFIG_ATH_CARDS=$(if $(CONFIG_PACKAGE_kmod-ath),m) \
        CONFIG_ATH_COMMON=$(if $(CONFIG_PACKAGE_kmod-ath),m) \
        CONFIG_ATH_DEBUG=$(if $(CONFIG_PACKAGE_ATH_DEBUG),y) \
        CONFIG_ATH9K_PKTLOG=$(if $(CONFIG_PACKAGE_ATH_DEBUG),y) \
        CONFIG_ATH_COMMON=$(if $(CONFIG_PACKAGE_kmod-ath),m) \
        CONFIG_ATH_DEBUG=$(if $(CONFIG_PACKAGE_ATH_DEBUG),y) \
        CONFIG_ATH9K_PKTLOG=$(if $(CONFIG_PACKAGE_ATH_DEBUG),y) \
@@ -1219,6 +1257,8 @@ MAKE_OPTS:= \
        CONFIG_ATH9K_HW=$(if $(CONFIG_PACKAGE_kmod-ath9k-common),m) \
        CONFIG_ATH9K_COMMON=$(if $(CONFIG_PACKAGE_kmod-ath9k-common),m) \
        CONFIG_ATH9K_DEBUGFS=$(if $(CONFIG_PACKAGE_MAC80211_DEBUGFS),y) \
        CONFIG_ATH9K_HW=$(if $(CONFIG_PACKAGE_kmod-ath9k-common),m) \
        CONFIG_ATH9K_COMMON=$(if $(CONFIG_PACKAGE_kmod-ath9k-common),m) \
        CONFIG_ATH9K_DEBUGFS=$(if $(CONFIG_PACKAGE_MAC80211_DEBUGFS),y) \
+       CONFIG_AR5523= \
+       CONFIG_WIL6210= \
        CONFIG_CARL9170=$(if $(CONFIG_PACKAGE_kmod-carl9170),m) \
        CONFIG_CARL9170_DEBUGFS=$(if $(CONFIG_PACKAGE_MAC80211_DEBUGFS),y) \
        CONFIG_COMPAT_ZD1211RW=$(if $(CONFIG_PACKAGE_kmod-zd1211rw),m) \
        CONFIG_CARL9170=$(if $(CONFIG_PACKAGE_kmod-carl9170),m) \
        CONFIG_CARL9170_DEBUGFS=$(if $(CONFIG_PACKAGE_MAC80211_DEBUGFS),y) \
        CONFIG_COMPAT_ZD1211RW=$(if $(CONFIG_PACKAGE_kmod-zd1211rw),m) \
@@ -1273,7 +1313,7 @@ MAKE_OPTS:= \
        CONFIG_MWL8K=$(if $(CONFIG_PACKAGE_kmod-mwl8k),m) \
        CONFIG_ATMEL= \
        CONFIG_PCMCIA_ATMEL= \
        CONFIG_MWL8K=$(if $(CONFIG_PACKAGE_kmod-mwl8k),m) \
        CONFIG_ATMEL= \
        CONFIG_PCMCIA_ATMEL= \
-       CONFIG_ADM8211= \
+       CONFIG_ADM8211=$(if $(CONFIG_PACKAGE_kmod-adm8211),m) \
        CONFIG_USB_NET_RNDIS_HOST= \
        CONFIG_USB_NET_RNDIS_WLAN= \
        CONFIG_USB_NET_CDCETHER= \
        CONFIG_USB_NET_RNDIS_HOST= \
        CONFIG_USB_NET_RNDIS_WLAN= \
        CONFIG_USB_NET_CDCETHER= \
@@ -1300,11 +1340,6 @@ MAKE_OPTS:= \
        CONFIG_ATH6KL= \
        CONFIG_MAC80211_RC_MINSTREL_HT=y \
        MADWIFI= \
        CONFIG_ATH6KL= \
        CONFIG_MAC80211_RC_MINSTREL_HT=y \
        MADWIFI= \
-       CONFIG_B44= \
-       CONFIG_ATL1= \
-       CONFIG_ATL2= \
-       CONFIG_ATL1E= \
-       CONFIG_ATL1C= \
        CONFIG_BRCMUTIL=$(if $(CONFIG_PACKAGE_kmod-brcmutil),m) \
        CONFIG_BRCMSMAC=$(if $(CONFIG_PACKAGE_kmod-brcmsmac),m) \
        CONFIG_BRCMFMAC=$(if $(CONFIG_PACKAGE_kmod-brcmfmac),m) \
        CONFIG_BRCMUTIL=$(if $(CONFIG_PACKAGE_kmod-brcmutil),m) \
        CONFIG_BRCMSMAC=$(if $(CONFIG_PACKAGE_kmod-brcmsmac),m) \
        CONFIG_BRCMFMAC=$(if $(CONFIG_PACKAGE_kmod-brcmfmac),m) \
@@ -1320,6 +1355,40 @@ ifeq ($(CONFIG_PACKAGE_kmod-libertas-sd)$(CONFIG_PACKAGE_kmod-libertas-usb)$(CON
   MAKE_OPTS += CONFIG_COMPAT_KFIFO=
 endif
 
   MAKE_OPTS += CONFIG_COMPAT_KFIFO=
 endif
 
+DISABLE_CONFIG = \
+       COMPAT_BLUETOOTH.* \
+       COMPAT_CORDIC \
+       COMPAT_CRC8 \
+       COMPAT_MDIO \
+       COMPAT_NETWORK_MODULES \
+       COMPAT_NET_USB_MODULES \
+       COMPAT_VAR_MODULES \
+       COMPAT_RFKILL \
+       COMPAT_RFKILL_.* \
+       COMPAT_STAGING \
+       \
+       B43_PCMCIA \
+       B43_SDIO \
+       BCMA.* \
+       COMPAT_ATH9K_RATE_CONTROL \
+       HID_GENERIC \
+       MAC80211_RC_PID \
+       PCMCIA \
+       RFKILL_BACKPORT.* \
+       SSB \
+       SSB_SDIOHOST \
+       \
+       ATH5K_PCI \
+       ATH9K_BTCOEX_SUPPORT \
+       B43_PHY_N \
+       B43_PHY_HT \
+       B43_BCMA.* \
+       MAC80211_MESH \
+       RT2X00_LIB_PCI \
+       RT2X00_LIB_USB \
+       COMPAT_MWIFIEX
+
+
 define Build/Prepare
        rm -rf $(PKG_BUILD_DIR)
        mkdir -p $(PKG_BUILD_DIR)
 define Build/Prepare
        rm -rf $(PKG_BUILD_DIR)
        mkdir -p $(PKG_BUILD_DIR)
@@ -1329,15 +1398,23 @@ define Build/Prepare
        $(TAR) -C $(PKG_BUILD_DIR) -xzf $(DL_DIR)/$(IPW2200_NAME)-$(IPW2200_VERSION).tgz
        $(TAR) -C $(PKG_BUILD_DIR) -xjf $(DL_DIR)/$(ZD1211FW_NAME)-$(ZD1211FW_VERSION).tar.bz2
        $(TAR) -C $(PKG_BUILD_DIR) -xjf $(DL_DIR)/$(PKG_LINUX_FIRMWARE_SOURCE)
        $(TAR) -C $(PKG_BUILD_DIR) -xzf $(DL_DIR)/$(IPW2200_NAME)-$(IPW2200_VERSION).tgz
        $(TAR) -C $(PKG_BUILD_DIR) -xjf $(DL_DIR)/$(ZD1211FW_NAME)-$(ZD1211FW_VERSION).tar.bz2
        $(TAR) -C $(PKG_BUILD_DIR) -xjf $(DL_DIR)/$(PKG_LINUX_FIRMWARE_SOURCE)
-       rm -rf $(PKG_BUILD_DIR)/include/linux/ssb
-       rm -rf $(PKG_BUILD_DIR)/include/linux/bcma
-       rm -rf $(PKG_BUILD_DIR)/include/net/bluetooth/
-       rm -f $(PKG_BUILD_DIR)/include/linux/eeprom_93cx6.h
-       rm -f $(PKG_BUILD_DIR)/include/linux/wl12xx.h
-       rm -f $(PKG_BUILD_DIR)/include/linux/spi/libertas_spi.h
-       rm -f $(PKG_BUILD_DIR)/include/net/ieee80211.h
+       rm -rf \
+               $(PKG_BUILD_DIR)/include/linux/ssb \
+               $(PKG_BUILD_DIR)/include/linux/bcma \
+               $(PKG_BUILD_DIR)/include/net/bluetooth
+
+       rm -f \
+               $(PKG_BUILD_DIR)/include/linux/cordic.h \
+               $(PKG_BUILD_DIR)/include/linux/crc8.h \
+               $(PKG_BUILD_DIR)/include/linux/eeprom_93cx6.h \
+               $(PKG_BUILD_DIR)/include/linux/wl12xx.h \
+               $(PKG_BUILD_DIR)/include/linux/spi/libertas_spi.h \
+               $(PKG_BUILD_DIR)/include/net/ieee80211.h
+
        echo 'compat-wireless-$(PKG_VERSION)-$(PKG_RELEASE)-$(REVISION)' > $(PKG_BUILD_DIR)/compat_version
        $(CP) ./files/regdb.txt $(PKG_BUILD_DIR)/net/wireless/db.txt
        echo 'compat-wireless-$(PKG_VERSION)-$(PKG_RELEASE)-$(REVISION)' > $(PKG_BUILD_DIR)/compat_version
        $(CP) ./files/regdb.txt $(PKG_BUILD_DIR)/net/wireless/db.txt
+
+       sed -i $(foreach config,$(DISABLE_CONFIG),-e 's,^\([    ]*export *CONFIG_$(config)=\),# \1,') $(PKG_BUILD_DIR)/config.mk
 endef
 
 ifneq ($(CONFIG_PACKAGE_kmod-cfg80211)$(CONFIG_PACKAGE_kmod-lib80211),)
 endef
 
 ifneq ($(CONFIG_PACKAGE_kmod-cfg80211)$(CONFIG_PACKAGE_kmod-lib80211),)
@@ -1368,12 +1445,11 @@ define Build/InstallDev
 endef
 
 define KernelPackage/libertas-usb/install
 endef
 
 define KernelPackage/libertas-usb/install
-       $(INSTALL_DIR) $(1)/lib/firmware
+       $(INSTALL_DIR) $(1)/lib/firmware/libertas
        $(INSTALL_DATA) \
                $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/libertas/usb8388_v9.bin \
        $(INSTALL_DATA) \
                $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/libertas/usb8388_v9.bin \
-               $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/libertas/usb8388_v5.bin \
                $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/libertas/usb8682.bin \
                $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/libertas/usb8682.bin \
-               $(1)/lib/firmware/
+               $(1)/lib/firmware/libertas/
 endef
 
 define KernelPackage/libertas-sd/install
 endef
 
 define KernelPackage/libertas-sd/install
@@ -1383,8 +1459,6 @@ define KernelPackage/libertas-sd/install
                $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/libertas/sd8385.bin \
                $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/libertas/sd8686_v9_helper.bin \
                $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/libertas/sd8686_v9.bin \
                $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/libertas/sd8385.bin \
                $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/libertas/sd8686_v9_helper.bin \
                $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/libertas/sd8686_v9.bin \
-               $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/libertas/sd8686_v8_helper.bin \
-               $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/libertas/sd8686_v8.bin \
                $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/libertas/sd8688_helper.bin \
                $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/libertas/sd8688.bin \
                $(1)/lib/firmware/libertas
                $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/libertas/sd8688_helper.bin \
                $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/libertas/sd8688.bin \
                $(1)/lib/firmware/libertas
@@ -1426,7 +1500,10 @@ endef
 
 define KernelPackage/rt2800-pci/install
        $(INSTALL_DIR) $(1)/lib/firmware
 
 define KernelPackage/rt2800-pci/install
        $(INSTALL_DIR) $(1)/lib/firmware
-       $(INSTALL_DATA) $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/rt2860.bin $(1)/lib/firmware/
+       $(INSTALL_DATA) \
+               $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/rt2860.bin \
+               $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/rt3290.bin \
+               $(1)/lib/firmware
 endef
 
 define KernelPackage/rt2800-usb/install
 endef
 
 define KernelPackage/rt2800-usb/install
@@ -1437,9 +1514,9 @@ endef
 define KernelPackage/wl12xx/install
        $(INSTALL_DIR) $(1)/lib/firmware/ti-connectivity
        $(INSTALL_DATA) \
 define KernelPackage/wl12xx/install
        $(INSTALL_DIR) $(1)/lib/firmware/ti-connectivity
        $(INSTALL_DATA) \
-               $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/ti-connectivity/wl127x-fw-4-mr.bin \
-               $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/ti-connectivity/wl127x-fw-4-plt.bin \
-               $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/ti-connectivity/wl127x-fw-4-sr.bin \
+               $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/ti-connectivity/wl127x-fw-5-mr.bin \
+               $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/ti-connectivity/wl127x-fw-5-plt.bin \
+               $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/ti-connectivity/wl127x-fw-5-sr.bin \
                $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/ti-connectivity/wl1271-nvs.bin \
                $(1)/lib/firmware/ti-connectivity
 endef
                $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/ti-connectivity/wl1271-nvs.bin \
                $(1)/lib/firmware/ti-connectivity
 endef
@@ -1461,7 +1538,7 @@ endef
 define KernelPackage/mwl8k/install
        $(INSTALL_DIR) $(1)/lib/firmware/mwl8k
        $(INSTALL_DATA) \
 define KernelPackage/mwl8k/install
        $(INSTALL_DIR) $(1)/lib/firmware/mwl8k
        $(INSTALL_DATA) \
-               $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/mwl8k/fmimage_8366_ap-2.fw \
+               $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/mwl8k/fmimage_8366_ap-3.fw \
                $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/mwl8k/fmimage_8366.fw \
                $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/mwl8k/helper_8366.fw \
                $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/mwl8k/fmimage_8687.fw \
                $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/mwl8k/fmimage_8366.fw \
                $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/mwl8k/helper_8366.fw \
                $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/mwl8k/fmimage_8687.fw \
@@ -1480,7 +1557,7 @@ define KernelPackage/net-ipw2200/install
 endef
 
 define KernelPackage/iwlagn/install
 endef
 
 define KernelPackage/iwlagn/install
-        $(INSTALL_DIR) $(1)/lib/firmware
+       $(INSTALL_DIR) $(1)/lib/firmware
 ifneq ($(CONFIG_IWL5000_FW),)
        $(INSTALL_DATA) $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/iwlwifi-5000-5.ucode $(1)/lib/firmware
 endif
 ifneq ($(CONFIG_IWL5000_FW),)
        $(INSTALL_DATA) $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/iwlwifi-5000-5.ucode $(1)/lib/firmware
 endif
@@ -1497,45 +1574,40 @@ ifneq ($(CONFIG_IWL6050_FW),)
        $(INSTALL_DATA) $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/iwlwifi-6050-5.ucode $(1)/lib/firmware
 endif
 ifneq ($(CONFIG_IWL6005_FW),)
        $(INSTALL_DATA) $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/iwlwifi-6050-5.ucode $(1)/lib/firmware
 endif
 ifneq ($(CONFIG_IWL6005_FW),)
-       $(INSTALL_DATA) $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/iwlwifi-6000g2a-5.ucode $(1)/lib/firmware
+       $(INSTALL_DATA) $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/iwlwifi-6000g2a-6.ucode $(1)/lib/firmware
 endif
 ifneq ($(CONFIG_IWL6030_FW),)
 endif
 ifneq ($(CONFIG_IWL6030_FW),)
-       $(INSTALL_DATA) $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/iwlwifi-6000g2b-5.ucode $(1)/lib/firmware
+       $(INSTALL_DATA) $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/iwlwifi-6000g2b-6.ucode $(1)/lib/firmware
 endif
 ifneq ($(CONFIG_IWL100_FW),)
        $(INSTALL_DATA) $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/iwlwifi-100-5.ucode $(1)/lib/firmware
 endif
 endif
 ifneq ($(CONFIG_IWL100_FW),)
        $(INSTALL_DATA) $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/iwlwifi-100-5.ucode $(1)/lib/firmware
 endif
+ifneq ($(CONFIG_IWL2000_FW),)
+       $(INSTALL_DATA) $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/iwlwifi-2000-6.ucode $(1)/lib/firmware
+endif
+ifneq ($(CONFIG_IWL2030_FW),)
+       $(INSTALL_DATA) $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/iwlwifi-2030-6.ucode $(1)/lib/firmware
+endif
+ifneq ($(CONFIG_IWL105_FW),)
+       $(INSTALL_DATA) $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/iwlwifi-105-6.ucode $(1)/lib/firmware
+endif
+ifneq ($(CONFIG_IWL135_FW),)
+       $(INSTALL_DATA) $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/iwlwifi-135-6.ucode $(1)/lib/firmware
+endif
 endef
 
 define KernelPackage/iwl3945/install
 endef
 
 define KernelPackage/iwl3945/install
-        $(INSTALL_DIR) $(1)/lib/firmware
+       $(INSTALL_DIR) $(1)/lib/firmware
        $(INSTALL_DATA) $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/iwlwifi-3945-2.ucode $(1)/lib/firmware
 endef
 
 define KernelPackage/iwl4965/install
        $(INSTALL_DATA) $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/iwlwifi-3945-2.ucode $(1)/lib/firmware
 endef
 
 define KernelPackage/iwl4965/install
-        $(INSTALL_DIR) $(1)/lib/firmware
+       $(INSTALL_DIR) $(1)/lib/firmware
        $(INSTALL_DATA) $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/iwlwifi-4965-2.ucode $(1)/lib/firmware
 endef
 
        $(INSTALL_DATA) $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/iwlwifi-4965-2.ucode $(1)/lib/firmware
 endef
 
-define Build/b43-common
-       tar xjf "$(DL_DIR)/$(PKG_B43_FWCUTTER_SOURCE)" -C "$(PKG_BUILD_DIR)"
-       patch -p1 -d  "$(PKG_BUILD_DIR)/$(PKG_B43_FWCUTTER_OBJECT)" < ./files/b43-fwcutter-fw-dirname.patch
-       $(MAKE) -C "$(PKG_BUILD_DIR)/$(PKG_B43_FWCUTTER_OBJECT)" \
-               CFLAGS="-I$(STAGING_DIR_HOST)/include -include endian.h" \
-               QUIET_SPARSE=:
-       $(INSTALL_BIN) $(PKG_BUILD_DIR)/$(PKG_B43_FWCUTTER_OBJECT)/b43-fwcutter $(STAGING_DIR_HOST)/bin/
-ifeq ($(CONFIG_B43_OPENFIRMWARE),y)
-       $(INSTALL_DIR) $(STAGING_DIR_HOST)/bin/
-       $(MAKE) -C "$(PKG_BUILD_DIR)/$(PKG_B43_FWCUTTER_SUBDIR)/assembler/"
-       $(INSTALL_BIN) $(PKG_BUILD_DIR)/$(PKG_B43_FWCUTTER_SUBDIR)/assembler/b43-asm $(STAGING_DIR_HOST)/bin/
-       $(INSTALL_BIN) $(PKG_BUILD_DIR)/$(PKG_B43_FWCUTTER_SUBDIR)/assembler/b43-asm.bin $(STAGING_DIR_HOST)/bin/
-endif
-       $(INSTALL_BIN) ./files/host_bin/b43-fwsquash.py $(STAGING_DIR_HOST)/bin/
-endef
-
 define KernelPackage/b43/install
        rm -rf $(1)/lib/firmware/
 define KernelPackage/b43/install
        rm -rf $(1)/lib/firmware/
-       $(call Build/b43-common)
 ifeq ($(CONFIG_B43_OPENFIRMWARE),y)
        tar xzf "$(DL_DIR)/$(PKG_B43_FWV4_SOURCE)" -C "$(PKG_BUILD_DIR)"
 else
 ifeq ($(CONFIG_B43_OPENFIRMWARE),y)
        tar xzf "$(DL_DIR)/$(PKG_B43_FWV4_SOURCE)" -C "$(PKG_BUILD_DIR)"
 else
@@ -1557,9 +1629,7 @@ endif
 endef
 
 define KernelPackage/b43legacy/install
 endef
 
 define KernelPackage/b43legacy/install
-       $(call Build/b43-common)
        $(INSTALL_DIR) $(1)/lib/firmware/
        $(INSTALL_DIR) $(1)/lib/firmware/
-
        b43-fwcutter --unsupported -w $(1)/lib/firmware/ $(DL_DIR)/$(PKG_B43_FWV3_SOURCE)
 ifneq ($(CONFIG_B43LEGACY_FW_SQUASH),)
        b43-fwsquash.py "G" "$(CONFIG_B43LEGACY_FW_SQUASH_COREREVS)" "$(1)/lib/firmware/b43legacy"
        b43-fwcutter --unsupported -w $(1)/lib/firmware/ $(DL_DIR)/$(PKG_B43_FWV3_SOURCE)
 ifneq ($(CONFIG_B43LEGACY_FW_SQUASH),)
        b43-fwsquash.py "G" "$(CONFIG_B43LEGACY_FW_SQUASH_COREREVS)" "$(1)/lib/firmware/b43legacy"
@@ -1568,10 +1638,15 @@ endef
 
 define KernelPackage/brcmsmac/install
        $(INSTALL_DIR) $(1)/lib/firmware/brcm
 
 define KernelPackage/brcmsmac/install
        $(INSTALL_DIR) $(1)/lib/firmware/brcm
+ifeq ($(CONFIG_BRCMSMAC_USE_FW_FROM_WL),y)
+       tar xjf "$(DL_DIR)/$(PKG_BRCMSMAC_FW_SOURCE)" -C "$(PKG_BUILD_DIR)"
+       b43-fwcutter --brcmsmac -w $(1)/lib/firmware/ $(PKG_BUILD_DIR)/$(PKG_BRCMSMAC_FW_OBJECT)
+else
        $(INSTALL_DATA) \
                $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/brcm/bcm43xx-0.fw \
                $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/brcm/bcm43xx_hdr-0.fw \
                $(1)/lib/firmware/brcm/
        $(INSTALL_DATA) \
                $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/brcm/bcm43xx-0.fw \
                $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/brcm/bcm43xx_hdr-0.fw \
                $(1)/lib/firmware/brcm/
+endif
 endef
 
 define KernelPackage/brcmfmac/install
 endef
 
 define KernelPackage/brcmfmac/install
@@ -1581,6 +1656,7 @@ define KernelPackage/brcmfmac/install
                $(1)/lib/firmware/brcm/
 endef
 
                $(1)/lib/firmware/brcm/
 endef
 
+$(eval $(call KernelPackage,adm8211))
 $(eval $(call KernelPackage,ath5k))
 $(eval $(call KernelPackage,lib80211))
 $(eval $(call KernelPackage,libertas-usb))
 $(eval $(call KernelPackage,ath5k))
 $(eval $(call KernelPackage,lib80211))
 $(eval $(call KernelPackage,libertas-usb))
diff --git a/package/mac80211/files/b43-fwcutter-fw-dirname.patch b/package/mac80211/files/b43-fwcutter-fw-dirname.patch
deleted file mode 100644 (file)
index c2f49ab..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
---- a/fwcutter.c
-+++ b/fwcutter.c
-@@ -48,13 +48,8 @@
- #include "fwcutter.h"
- #include "fwcutter_list.h"
--#if defined(__DragonFly__) || defined(__FreeBSD__)
--#define V3_FW_DIRNAME "v3"
--#define V4_FW_DIRNAME "v4"
--#else
- #define V3_FW_DIRNAME "b43legacy"
- #define V4_FW_DIRNAME "b43"
--#endif
- static struct cmdline_args cmdargs;
diff --git a/package/mac80211/files/host_bin/b43-fwsquash.py b/package/mac80211/files/host_bin/b43-fwsquash.py
deleted file mode 100755 (executable)
index cd88181..0000000
+++ /dev/null
@@ -1,122 +0,0 @@
-#!/usr/bin/env python
-#
-# b43 firmware file squasher
-# Removes unnecessary firmware files
-#
-# Copyright (c) 2009 Michael Buesch <mb@bu3sch.de>
-#
-# Licensed under the GNU/GPL version 2 or (at your option) any later version.
-#
-
-import sys
-import os
-
-def usage():
-       print("Usage: %s PHYTYPES COREREVS /path/to/extracted/firmware" % sys.argv[0])
-       print("")
-       print("PHYTYPES is a comma separated list of:")
-       print("A         => A-PHY")
-       print("AG        => Dual A-PHY G-PHY")
-       print("G         => G-PHY")
-       print("LP        => LP-PHY")
-       print("N         => N-PHY")
-       print("HT        => HT-PHY")
-       print("LCN       => LCN-PHY")
-       print("")
-       print("COREREVS is a comma separated list of core revision numbers.")
-
-if len(sys.argv) != 4:
-       usage()
-       sys.exit(1)
-
-phytypes = sys.argv[1]
-corerevs = sys.argv[2]
-fwpath = sys.argv[3]
-
-phytypes = phytypes.split(',')
-try:
-       corerevs = map(lambda r: int(r), corerevs.split(','))
-except ValueError:
-       print("ERROR: \"%s\" is not a valid COREREVS string\n" % corerevs)
-       usage()
-       sys.exit(1)
-
-
-fwfiles = os.listdir(fwpath)
-fwfiles = filter(lambda str: str.endswith(".fw"), fwfiles)
-if not fwfiles:
-       print("ERROR: No firmware files found in %s" % fwpath)
-       sys.exit(1)
-
-required_fwfiles = []
-
-def revs_match(revs_a, revs_b):
-       for rev in revs_a:
-               if rev in revs_b:
-                       return True
-       return False
-
-def phytypes_match(types_a, types_b):
-       for type in types_a:
-               type = type.strip().upper()
-               if type in types_b:
-                       return True
-       return False
-
-revmapping = {
-       "ucode2.fw"             : (2,3,),
-       "ucode4.fw"             : (4,),
-       "ucode5.fw"             : (5,6,7,8,9,10,),
-       "ucode11.fw"            : (11,12,),
-       "ucode13.fw"            : (13,),
-       "ucode14.fw"            : (14,),
-       "ucode15.fw"            : (15,),
-       "ucode16_mimo.fw"       : (16,),
-       "ucode24_mimo.fw"       : (24,),
-       "ucode29_mimo.fw"       : (29,),
-       "pcm4.fw"               : (1,2,3,4,),
-       "pcm5.fw"               : (5,6,7,8,9,10,),
-}
-
-initvalmapping = {
-       "a0g1initvals5.fw"      : ( (5,6,7,8,9,10,),    ("AG",), ),
-       "a0g0initvals5.fw"      : ( (5,6,7,8,9,10,),    ("A", "AG",), ),
-       "b0g0initvals2.fw"      : ( (2,4,),             ("G",), ),
-       "b0g0initvals5.fw"      : ( (5,6,7,8,9,10,),    ("G",), ),
-       "b0g0initvals13.fw"     : ( (13,),              ("G",), ),
-       "n0initvals11.fw"       : ( (11,12,),           ("N",), ),
-       "n0initvals16.fw"       : ( (16,),              ("N",), ),
-       "lp0initvals13.fw"      : ( (13,),              ("LP",), ),
-       "lp0initvals14.fw"      : ( (14,),              ("LP",), ),
-       "lp0initvals15.fw"      : ( (15,),              ("LP",), ),
-       "lcn0initvals24.fw"     : ( (24,),              ("LCN",), ),
-       "ht0initvals29.fw"      : ( (29,),              ("HT",), ),
-       "a0g1bsinitvals5.fw"    : ( (5,6,7,8,9,10,),    ("AG",), ),
-       "a0g0bsinitvals5.fw"    : ( (5,6,7,8,9,10,),    ("A", "AG"), ),
-       "b0g0bsinitvals5.fw"    : ( (5,6,7,8,9,10,),    ("G",), ),
-       "n0bsinitvals11.fw"     : ( (11,12,),           ("N",), ),
-       "n0bsinitvals16.fw"     : ( (16,),              ("N",), ),
-       "lp0bsinitvals13.fw"    : ( (13,),              ("LP",), ),
-       "lp0bsinitvals14.fw"    : ( (14,),              ("LP",), ),
-       "lp0bsinitvals15.fw"    : ( (15,),              ("LP",), ),
-       "lcn0bsinitvals24.fw"   : ( (24,),              ("LCN",), ),
-       "ht0bsinitvals29.fw"    : ( (29,),              ("HT",), ),
-}
-
-for f in fwfiles:
-       if f in revmapping:
-               if revs_match(corerevs, revmapping[f]):
-                       required_fwfiles += [f]
-               continue
-       if f in initvalmapping:
-               if revs_match(corerevs, initvalmapping[f][0]) and\
-                  phytypes_match(phytypes, initvalmapping[f][1]):
-                       required_fwfiles += [f]
-               continue
-       print("WARNING: Firmware file %s not found in the mapping lists" % f)
-
-for f in fwfiles:
-       if f not in required_fwfiles:
-               print("Deleting %s" % f)
-               os.unlink(fwpath + '/' + f)
-
index c3fbc50..081dc4d 100644 (file)
@@ -6,8 +6,6 @@ mac80211_hostapd_setup_base() {
        local ifname="$2"
 
        cfgfile="/var/run/hostapd-$phy.conf"
        local ifname="$2"
 
        cfgfile="/var/run/hostapd-$phy.conf"
-       macfile="/var/run/hostapd-$phy.maclist"
-       [ -e "$macfile" ] && rm -f "$macfile"
 
        config_get device "$vif" device
        config_get country "$device" country
 
        config_get device "$vif" device
        config_get country "$device" country
@@ -16,7 +14,6 @@ mac80211_hostapd_setup_base() {
        config_get beacon_int "$device" beacon_int
        config_get basic_rate_list "$device" basic_rate
        config_get_bool noscan "$device" noscan
        config_get beacon_int "$device" beacon_int
        config_get basic_rate_list "$device" basic_rate
        config_get_bool noscan "$device" noscan
-       config_get_bool short_preamble "$device" short_preamble "0"
 
        hostapd_set_log_options base_cfg "$device"
 
 
        hostapd_set_log_options base_cfg "$device"
 
@@ -51,24 +48,6 @@ mac80211_hostapd_setup_base() {
        config_get_bool country_ie "$device" country_ie "$country_ie"
        [ "$country_ie" -gt 0 ] && append base_cfg "ieee80211d=1" "$N"
 
        config_get_bool country_ie "$device" country_ie "$country_ie"
        [ "$country_ie" -gt 0 ] && append base_cfg "ieee80211d=1" "$N"
 
-       config_get macfilter "$vif" macfilter
-       case "$macfilter" in
-               allow)
-                       append base_cfg "macaddr_acl=1" "$N"
-                       append base_cfg "accept_mac_file=$macfile" "$N"
-                       ;;
-               deny)
-                       append base_cfg "macaddr_acl=0" "$N"
-                       append base_cfg "deny_mac_file=$macfile" "$N"
-                       ;;
-       esac
-       config_get maclist "$vif" maclist
-       [ -n "$maclist" ] && {
-               for mac in $maclist; do
-                       echo "$mac" >> $macfile
-               done
-       }
-
        local br brval brstr
        [ -n "$basic_rate_list" ] && {
                for br in $basic_rate_list; do
        local br brval brstr
        [ -n "$basic_rate_list" ] && {
                for br in $basic_rate_list; do
@@ -78,8 +57,6 @@ mac80211_hostapd_setup_base() {
                done
        }
 
                done
        }
 
-       append base_cfg "preamble=$short_preamble" "$N"
-       
        cat >> "$cfgfile" <<EOF
 ctrl_interface=/var/run/hostapd-$phy
 driver=nl80211
        cat >> "$cfgfile" <<EOF
 ctrl_interface=/var/run/hostapd-$phy
 driver=nl80211
@@ -184,26 +161,46 @@ mac80211_start_vif() {
        set_wifi_up "$vif" "$ifname"
 }
 
        set_wifi_up "$vif" "$ifname"
 }
 
-find_mac80211_phy() {
-       local device="$1"
+lookup_phy() {
+       [ -n "$phy" ] && {
+               [ -d /sys/class/ieee80211/$phy ] && return
+       }
+
+       local devpath
+       config_get devpath "$device" path
+       [ -n "$devpath" -a -d "/sys/devices/$devpath/ieee80211" ] && {
+               phy="$(ls /sys/devices/$devpath/ieee80211 | grep -m 1 phy)"
+               [ -n "$phy" ] && return
+       }
 
        local macaddr="$(config_get "$device" macaddr | tr 'A-Z' 'a-z')"
 
        local macaddr="$(config_get "$device" macaddr | tr 'A-Z' 'a-z')"
-       config_get phy "$device" phy
-       [ -z "$phy" -a -n "$macaddr" ] && {
-               for phy in $(ls /sys/class/ieee80211 2>/dev/null); do
-                       [ "$macaddr" = "$(cat /sys/class/ieee80211/${phy}/macaddress)" ] || continue
-                       config_set "$device" phy "$phy"
-                       break
+       [ -n "$macaddr" ] && {
+               for _phy in $(ls /sys/class/ieee80211 2>/dev/null); do
+                       [ "$macaddr" = "$(cat /sys/class/ieee80211/${_phy}/macaddress)" ] || continue
+                       phy="$_phy"
+                       return
                done
                done
-               config_get phy "$device" phy
        }
        }
+       phy=
+       return
+}
+
+find_mac80211_phy() {
+       local device="$1"
+
+       config_get phy "$device" phy
+       lookup_phy
        [ -n "$phy" -a -d "/sys/class/ieee80211/$phy" ] || {
                echo "PHY for wifi device $1 not found"
                return 1
        }
        [ -n "$phy" -a -d "/sys/class/ieee80211/$phy" ] || {
                echo "PHY for wifi device $1 not found"
                return 1
        }
+       config_set "$device" phy "$phy"
+
+       config_get macaddr "$device" macaddr
        [ -z "$macaddr" ] && {
                config_set "$device" macaddr "$(cat /sys/class/ieee80211/${phy}/macaddress)"
        }
        [ -z "$macaddr" ] && {
                config_set "$device" macaddr "$(cat /sys/class/ieee80211/${phy}/macaddress)"
        }
+
        return 0
 }
 
        return 0
 }
 
@@ -593,12 +590,20 @@ detect_mac80211() {
                }
                iw phy "$dev" info | grep -q '2412 MHz' || { mode_band="a"; channel="36"; }
 
                }
                iw phy "$dev" info | grep -q '2412 MHz' || { mode_band="a"; channel="36"; }
 
+               if [ -x /usr/bin/readlink ]; then
+                       path="$(readlink -f /sys/class/ieee80211/${dev}/device)"
+                       path="${path##/sys/devices/}"
+                       dev_id="        option path     '$path'"
+               else
+                       dev_id="        option macaddr  $(cat /sys/class/ieee80211/${dev}/macaddress)"
+               fi
+
                cat <<EOF
 config wifi-device  radio$devidx
        option type     mac80211
        option channel  ${channel}
                cat <<EOF
 config wifi-device  radio$devidx
        option type     mac80211
        option channel  ${channel}
-       option macaddr  $(cat /sys/class/ieee80211/${dev}/macaddress)
        option hwmode   11${mode_11n}${mode_band}
        option hwmode   11${mode_11n}${mode_band}
+$dev_id
 $ht_capab
        # REMOVE THIS LINE TO ENABLE WIFI:
        option disabled 1
 $ht_capab
        # REMOVE THIS LINE TO ENABLE WIFI:
        option disabled 1
diff --git a/package/mac80211/patches/000-disable_ethernet.patch b/package/mac80211/patches/000-disable_ethernet.patch
deleted file mode 100644 (file)
index 08f908b..0000000
+++ /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 (file)
index 389dac1..0000000
+++ /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 (file)
index 0000000..7af485f
--- /dev/null
@@ -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 (file)
index 685006b..0000000
+++ /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 (file)
index 0000000..ef184c4
--- /dev/null
@@ -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 (file)
index b56ccbd..0000000
+++ /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/003-disable_codel.patch b/package/mac80211/patches/003-disable_codel.patch
new file mode 100644 (file)
index 0000000..0d6d749
--- /dev/null
@@ -0,0 +1,19 @@
+--- a/compat/scripts/gen-compat-config.sh
++++ b/compat/scripts/gen-compat-config.sh
+@@ -66,16 +66,3 @@ if [[ ${CONFIG_COMPAT_KERNEL_2_6_36} = "
+               echo "export CONFIG_COMPAT_KFIFO=y"
+       fi
+ fi
+-
+-if [[ ${CONFIG_COMPAT_KERNEL_3_5} = "y" ]]; then
+-      # We don't have 2.6.24 backport support yet for Codel / FQ CoDel
+-      # For those who want to try this is what is required that I can tell
+-      # so far:
+-      #  * struct Qdisc_ops
+-      #       - init and change callback ops use a different argument dataype
+-      #       - you need to parse data received from userspace differently
+-      if [[ ${CONFIG_COMPAT_KERNEL_2_6_25} != "y" ]]; then
+-              echo "export CONFIG_COMPAT_NET_SCH_CODEL=m"
+-              echo "export CONFIG_COMPAT_NET_SCH_FQ_CODEL=m"
+-      fi
+-fi
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 (file)
index 0000000..0ae3820
--- /dev/null
@@ -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 (file)
index d42a612..0000000
+++ /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 (file)
index da11ad4..0000000
+++ /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 (file)
index 9e7f651..0000000
+++ /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 (file)
index d5a0ac8..0000000
+++ /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 (file)
index 2bc46c4..0000000
+++ /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/010-add_include_for_bcma.patch b/package/mac80211/patches/010-add_include_for_bcma.patch
new file mode 100644 (file)
index 0000000..e2e856e
--- /dev/null
@@ -0,0 +1,11 @@
+--- a/include/linux/compat-3.0.h
++++ b/include/linux/compat-3.0.h
+@@ -36,6 +36,8 @@ static inline struct page *shmem_read_ma
+ #endif
++#include <linux/mod_devicetable.h>
++
+ /*
+  * since commit 1c5cae815d19ffe02bdfda1260949ef2b1806171
+  * "net: call dev_alloc_name from register_netdevice" dev_alloc_name is
diff --git a/package/mac80211/patches/010-no_pcmcia.patch b/package/mac80211/patches/010-no_pcmcia.patch
deleted file mode 100644 (file)
index af6a754..0000000
+++ /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 (file)
index 4d364e0..0000000
+++ /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 (file)
index ba37bad..0000000
+++ /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 (file)
index 66c0d67..0000000
+++ /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 (file)
index 7180a63..0000000
+++ /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 (file)
index 99b5209..0000000
+++ /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 (file)
index fa2237c..0000000
+++ /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 (file)
index d0149d3..0000000
+++ /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/020-disable_tty_set_termios.patch b/package/mac80211/patches/020-disable_tty_set_termios.patch
new file mode 100644 (file)
index 0000000..fc5d4d6
--- /dev/null
@@ -0,0 +1,16 @@
+--- a/compat/compat-2.6.39.c
++++ b/compat/compat-2.6.39.c
+@@ -12,6 +12,7 @@
+ #include <linux/tty.h>
+ #include <linux/sched.h>
++#ifdef CONFIG_COMPAT_BLUETOOTH
+ #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27))
+ /*
+  *            Termios Helper Methods
+@@ -111,4 +112,4 @@ int tty_set_termios(struct tty_struct *t
+ }
+ EXPORT_SYMBOL_GPL(tty_set_termios);
+ #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)) */
+-
++#endif
diff --git a/package/mac80211/patches/021-add_include_for_bcma.patch b/package/mac80211/patches/021-add_include_for_bcma.patch
deleted file mode 100644 (file)
index e2e856e..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
---- a/include/linux/compat-3.0.h
-+++ b/include/linux/compat-3.0.h
-@@ -36,6 +36,8 @@ static inline struct page *shmem_read_ma
- #endif
-+#include <linux/mod_devicetable.h>
-+
- /*
-  * since commit 1c5cae815d19ffe02bdfda1260949ef2b1806171
-  * "net: call dev_alloc_name from register_netdevice" dev_alloc_name is
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 (file)
index 13ad2c8..0000000
+++ /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 (file)
index 37ae2d5..0000000
+++ /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-disable_tty_set_termios.patch b/package/mac80211/patches/030-disable_tty_set_termios.patch
deleted file mode 100644 (file)
index fc5d4d6..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
---- a/compat/compat-2.6.39.c
-+++ b/compat/compat-2.6.39.c
-@@ -12,6 +12,7 @@
- #include <linux/tty.h>
- #include <linux/sched.h>
-+#ifdef CONFIG_COMPAT_BLUETOOTH
- #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27))
- /*
-  *            Termios Helper Methods
-@@ -111,4 +112,4 @@ int tty_set_termios(struct tty_struct *t
- }
- EXPORT_SYMBOL_GPL(tty_set_termios);
- #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)) */
--
-+#endif
diff --git a/package/mac80211/patches/030-wext.patch b/package/mac80211/patches/030-wext.patch
new file mode 100644 (file)
index 0000000..cb52e7c
--- /dev/null
@@ -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 (file)
index 0000000..d83c39c
--- /dev/null
@@ -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 (file)
index e4b91a3..0000000
+++ /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 (file)
index 277ca3d..0000000
+++ /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/070-disable_codel.patch b/package/mac80211/patches/070-disable_codel.patch
deleted file mode 100644 (file)
index 0d6d749..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
---- a/compat/scripts/gen-compat-config.sh
-+++ b/compat/scripts/gen-compat-config.sh
-@@ -66,16 +66,3 @@ if [[ ${CONFIG_COMPAT_KERNEL_2_6_36} = "
-               echo "export CONFIG_COMPAT_KFIFO=y"
-       fi
- fi
--
--if [[ ${CONFIG_COMPAT_KERNEL_3_5} = "y" ]]; then
--      # We don't have 2.6.24 backport support yet for Codel / FQ CoDel
--      # For those who want to try this is what is required that I can tell
--      # so far:
--      #  * struct Qdisc_ops
--      #       - init and change callback ops use a different argument dataype
--      #       - you need to parse data received from userspace differently
--      if [[ ${CONFIG_COMPAT_KERNEL_2_6_25} != "y" ]]; then
--              echo "export CONFIG_COMPAT_NET_SCH_CODEL=m"
--              echo "export CONFIG_COMPAT_NET_SCH_FQ_CODEL=m"
--      fi
--fi
diff --git a/package/mac80211/patches/071-add_codel_ifdef.patch b/package/mac80211/patches/071-add_codel_ifdef.patch
deleted file mode 100644 (file)
index 86b4151..0000000
+++ /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 (file)
index 6092755..0000000
+++ /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 (file)
index d6287fd..0000000
+++ /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
index fbe3e3a..1322099 100644 (file)
 --- a/net/mac80211/mesh_pathtbl.c
 +++ b/net/mac80211/mesh_pathtbl.c
 --- 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());
        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)
                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 (file)
index 0000000..9714696
--- /dev/null
@@ -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
index ad9c500..d3867c4 100644 (file)
---- 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;
+-      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);
  
  
-+              channels[count].max_power = AR5K_TUNE_MAX_TXPOWER/2;
+-      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
 --- 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);
                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);
                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);
                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 &&
            sdata->vif.type != NL80211_IFTYPE_MESH_POINT &&
            sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
            sdata->vif.type != NL80211_IFTYPE_AP &&
            sdata->vif.type != NL80211_IFTYPE_ADHOC)
                return -EINVAL;
  
            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
 --- 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),
        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),
                            TEST(AUTH), TEST(ASSOC), TEST(PS_STA),
                            TEST(PS_DRIVER), TEST(AUTHORIZED),
                            TEST(SHORT_PREAMBLE),
                            TEST(TDLS_PEER_AUTH), TEST(4ADDR_EVENT),
 --- a/net/mac80211/iface.c
 +++ b/net/mac80211/iface.c
                            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;
        struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
        struct net_device *dev = wdev->netdev;
        struct ieee80211_local *local = sdata->local;
        u32 changed = 0;
        int res;
        u32 hw_reconf_flags = 0;
        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);
  
  
        set_bit(SDATA_STATE_RUNNING, &sdata->state);
  
  
        /*
         * set_multicast_list will be invoked by the networking core
  
        /*
         * 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;
  }
  
        dev->destructor = free_netdev;
  }
  
 +
 +      if (elems.ht_cap_elem)
 +              ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband,
 +
 +      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);
 +
 +      if (elems.wmm_param)
 +              set_sta_flag(sta, WLAN_STA_WME);
  static void ieee80211_iface_work(struct work_struct *work)
  {
        struct ieee80211_sub_if_data *sdata =
  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;
                                break;
                        ieee80211_mesh_rx_queued_mgmt(sdata, skb);
                        break;
                        break;
 --- a/net/mac80211/rx.c
 +++ b/net/mac80211/rx.c
                        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 &&
                    sdata->vif.type != NL80211_IFTYPE_MESH_POINT &&
                    sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
                    sdata->vif.type != NL80211_IFTYPE_AP &&
                    sdata->vif.type != NL80211_IFTYPE_ADHOC)
                        break;
  
                    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 &&
  
        if (!ieee80211_vif_is_mesh(&sdata->vif) &&
            sdata->vif.type != NL80211_IFTYPE_ADHOC &&
                break;
        case cpu_to_le16(IEEE80211_STYPE_ASSOC_RESP):
        case cpu_to_le16(IEEE80211_STYPE_REASSOC_RESP):
                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:
                }
                break;
        case NL80211_IFTYPE_WDS:
   * @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.
   * @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,
        WLAN_STA_AUTHORIZED,
        WLAN_STA_SHORT_PREAMBLE,
        WLAN_STA_WME,
        WLAN_STA_CLEAR_PS_FILT,
        WLAN_STA_MFP,
        WLAN_STA_BLOCK_BA,
        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);
-@@ -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));
--      local->power_constr_level = 0;
-+      local->ap_power_level = 0;
+@@ -467,7 +478,7 @@ minstrel_ht_tx_status(void *priv, struct
  
  
-       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);
+       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--;
        }
  
        }
  
--      /* 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
- {
-       struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
-       u8 frame_buf[DEAUTH_DISASSOC_LEN];
-+      bool tx = !req->local_state_change;
+@@ -536,7 +547,7 @@ minstrel_calc_retransmit(struct minstrel
+       mr->retry_updated = true;
  
  
-       mutex_lock(&ifmgd->mtx);
+       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;
  
  
-@@ -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);
-       }
+       /* Contention time for first 2 tries */
+       ctime = (t_slot * cw) >> 1;
+@@ -616,6 +627,7 @@ minstrel_get_sample_rate(struct minstrel
+ {
+       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;
  
  
---- 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;
++
+       /*
+-       * 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.
+        */
+-      if (!mp->has_mrr && (mr->probability > MINSTREL_FRAC(95, 100)))
++      if (mr->probability > MINSTREL_FRAC(95, 100))
+               return -1;
  
        /*
  
        /*
-@@ -674,7 +674,7 @@ int __must_check __sta_info_destroy(stru
-        * will be sufficient.
+        * Make sure that lower rates get sampled only occasionally,
+        * if the link is working perfectly.
         */
         */
-       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]);
+-      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--;
  
  
- #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);
-       }
+       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
  
  
---- 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;
-       }
+ struct mcs_group {
+@@ -85,6 +80,7 @@ struct minstrel_ht_sta {
  
  
-@@ -431,7 +431,7 @@ void ieee80211_add_pending_skbs_fn(struc
-               struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+       /* best probability rate */
+       unsigned int max_prob_rate;
++      unsigned int max_prob_streams;
  
  
-               if (WARN_ON(!info->control.vif)) {
--                      kfree_skb(skb);
-+                      ieee80211_free_txskb(&local->hw, skb);
-                       continue;
-               }
+       /* 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;
  
  
-@@ -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;
- };
++      /* Use chip chainmask only for calibration */
+       ar9003_hw_set_chain_masks(ah, ah->caps.rx_chainmask, ah->caps.tx_chainmask);
  
  
- /**
---- 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;
--      }
+       if (rtt) {
+@@ -1150,6 +1151,9 @@ skip_tx_iqcal:
+               ar9003_hw_rtt_disable(ah);
+       }
  
  
-       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;
-       /*
-        * 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;
-       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;
+               }
  
  
-                       if (WARN_ON(!info->control.vif)) {
--                              kfree_skb(skb);
-+                              ieee80211_free_txskb(&local->hw, skb);
-                               continue;
+-              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;
+               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.
index 67a9dca..b8f2671 100644 (file)
@@ -1,11 +1,11 @@
 --- a/net/mac80211/cfg.c
 +++ b/net/mac80211/cfg.c
 --- 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 (file)
index 0000000..438094b
--- /dev/null
@@ -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 (file)
index 0000000..cf9f412
--- /dev/null
@@ -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);
+       /*
index 256da42..c91128d 100644 (file)
@@ -1,6 +1,6 @@
 --- a/drivers/net/wireless/ath/Makefile
 +++ b/drivers/net/wireless/ath/Makefile
 --- 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 \
  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
  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. */
  #endif /* CONFIG_ATH_DEBUG */
  
  /** Returns string describing opmode, or NULL if unknown mode. */
index 10c7636..421e785 100644 (file)
@@ -1,6 +1,6 @@
 --- a/drivers/net/wireless/ath/ath9k/init.c
 +++ b/drivers/net/wireless/ath/ath9k/init.c
 --- 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");
  
  module_param_named(nohwcrypt, ath9k_modparam_nohwcrypt, int, 0444);
  MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption");
  
index 7c59e1f..40c4cb7 100644 (file)
@@ -8,7 +8,7 @@
  #include <asm/unaligned.h>
  
  #include "hw.h"
  #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;
        }
                common->macaddr[2 * i] = eeval >> 8;
                common->macaddr[2 * i + 1] = eeval & 0xff;
        }
index 1854c27..683417b 100644 (file)
@@ -1,8 +1,8 @@
 --- a/drivers/net/wireless/ath/regd.c
 +++ b/drivers/net/wireless/ath/regd.c
 --- 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;
  
 +#ifdef ATH_USER_REGD
 +      return;
@@ -11,9 +11,9 @@
        for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
  
                if (!wiphy->bands[band])
        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;
  
 +#ifdef ATH_USER_REGD
 +      return;
@@ -22,7 +22,7 @@
        sband = wiphy->bands[IEEE80211_BAND_2GHZ];
        if (!sband)
                return;
        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;
  
        struct ieee80211_channel *ch;
        unsigned int i;
  
@@ -33,7 +33,7 @@
        if (!wiphy->bands[IEEE80211_BAND_5GHZ])
                return;
  
        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;
  
  {
        const struct ieee80211_regdomain *regd;
  
index 8a5c2a2..938ac42 100644 (file)
@@ -1,20 +1,19 @@
 --- a/net/wireless/reg.c
 +++ b/net/wireless/reg.c
 --- 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;
        enum environment_cap env = ENVIRON_ANY;
-       struct regulatory_request *request;
+       struct regulatory_request *request, *lr;
  
 +      return;
 +
        mutex_lock(&reg_mutex);
  
 +      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;
  
  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);
        restore_regulatory_settings(false);
+ }
index aabf3c3..7a07eb6 100644 (file)
@@ -1,10 +1,10 @@
 --- a/drivers/net/wireless/ath/ath9k/init.c
 +++ b/drivers/net/wireless/ath/ath9k/init.c
 --- 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
  #endif
-+                               BIT(NL80211_IFTYPE_ADHOC) |
                                 BIT(NL80211_IFTYPE_AP) |
                                 BIT(NL80211_IFTYPE_P2P_GO) },
                                 BIT(NL80211_IFTYPE_AP) |
                                 BIT(NL80211_IFTYPE_P2P_GO) },
++      { .max = 1,     .types = BIT(NL80211_IFTYPE_ADHOC) },
  };
  };
+ static const struct ieee80211_iface_combination if_comb = {
index 8e02950..22d9113 100644 (file)
@@ -18,7 +18,7 @@
                goto end;
 --- a/drivers/net/wireless/ath/ath5k/base.c
 +++ b/drivers/net/wireless/ath/ath5k/base.c
                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 +
        }
  
        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);
                        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
  
        intval = ah->bintval & AR5K_BEACON_PERIOD;
        if (ah->opmode == NL80211_IFTYPE_AP && ah->num_ap_vifs
                intval /= ATH_BCBUF;    /* staggered multi-bss beacons */
                if (intval < 15)
                        ATH5K_WARN(ah, "intval %u is too low, min 15\n",
                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_MESH_POINT) |
  #endif
-+                               BIT(NL80211_IFTYPE_ADHOC) |
                                 BIT(NL80211_IFTYPE_AP) },
                                 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 (file)
index 93f3556..0000000
+++ /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
index bd661c6..48b8467 100644 (file)
@@ -1,6 +1,6 @@
 --- a/drivers/net/wireless/ath/ath5k/reset.c
 +++ b/drivers/net/wireless/ath/ath5k/reset.c
 --- 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;
  
        tsf_lo = 0;
        mode = 0;
  
@@ -8,7 +8,7 @@
        /*
         * Sanity check for fast flag
         * Fast channel change only available
        /*
         * 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))
         */
        if (fast && (ah->ah_radio != AR5K_RF2413) &&
        (ah->ah_radio != AR5K_RF5413))
index 0fa054a..285fce2 100644 (file)
@@ -1,8 +1,8 @@
 --- a/drivers/net/wireless/ath/ath9k/debug.c
 +++ b/drivers/net/wireless/ath/ath9k/debug.c
 --- 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)
  
 +static ssize_t read_file_eeprom(struct file *file, char __user *user_buf,
 +                           size_t count, loff_t *ppos)
  int ath9k_init_debug(struct ath_hw *ah)
  {
        struct ath_common *common = ath9k_hw_common(ah);
  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);
  
 +      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,
index 52ae70f..06c34b7 100644 (file)
@@ -1,6 +1,6 @@
 --- a/drivers/net/wireless/ath/ath9k/eeprom_def.c
 +++ b/drivers/net/wireless/ath/ath9k/eeprom_def.c
 --- 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);
  {
        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;
        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;
        }
  
                return false;
        }
  
  
 --- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c
 +++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
  
 --- 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_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
 --- 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)) {
        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
 --- 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
  #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
        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;
                ah->is_clk_25mhz = pdata->is_clk_25mhz;
                ah->get_mac_revision = pdata->get_mac_revision;
                ah->external_reset = pdata->external_reset;
index 7d3df6b..8884163 100644 (file)
@@ -1,6 +1,6 @@
 --- a/drivers/net/wireless/ath/ath9k/init.c
 +++ b/drivers/net/wireless/ath/ath9k/init.c
 --- 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;
        }
  
                goto err_out;
        }
  
index b6591b0..855b336 100644 (file)
@@ -1,6 +1,6 @@
 --- a/drivers/net/wireless/ath/ath9k/hw.c
 +++ b/drivers/net/wireless/ath/ath9k/hw.c
 --- 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) {
                REG_WRITE(ah, AR_OBS, 8);
  
        if (ah->config.rx_intr_mitigation) {
index db13fea..8d8c5fd 100644 (file)
@@ -1,6 +1,6 @@
 --- a/drivers/net/wireless/ath/ath9k/ath9k.h
 +++ b/drivers/net/wireless/ath/ath9k/ath9k.h
 --- 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 */
  /***********/
  
  /* RX / TX */
  /***********/
  
index 15111e9..4156773 100644 (file)
@@ -1,6 +1,6 @@
 --- a/drivers/net/wireless/ath/ath9k/ath9k.h
 +++ b/drivers/net/wireless/ath/ath9k/ath9k.h
 --- 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;
  
        struct ieee80211_hw *hw;
        struct device *dev;
  
@@ -8,9 +8,9 @@
        struct survey_info *cur_survey;
        struct survey_info survey[ATH9K_NUM_CHANNELS];
  
        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);
  
 +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
  
 --- 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
  };
  
        .owner = THIS_MODULE
  };
  
  int ath9k_init_debug(struct ath_hw *ah)
  {
        struct ath_common *common = ath9k_hw_common(ah);
  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("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);
 +      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
 --- 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)
  }
  
 -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;
  {
        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;
  
        if ((changed & IEEE80211_CONF_CHANGE_CHANNEL) || reset_channel) {
                struct ieee80211_channel *curchan = hw->conf.channel;
  
                if (ah->curchan)
                        old_pos = ah->curchan - &ah->channels[0];
  
                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));
                }
  
                        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 (file)
index 25f4fdd..0000000
+++ /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))
index 54f2e50..f0ed3d9 100644 (file)
@@ -1,27 +1,29 @@
 --- a/include/net/mac80211.h
 +++ b/include/net/mac80211.h
 --- 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;
        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;
  };
        netdev_features_t netdev_features;
  };
 --- a/net/mac80211/cfg.c
 +++ b/net/mac80211/cfg.c
 --- 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_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
 --- 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;
  
        if (local->hw.conf.power_level != power) {
                changed |= IEEE80211_CONF_CHANGE_POWER;
index 14b59e5..f4c1f5d 100644 (file)
@@ -1,6 +1,6 @@
 --- a/drivers/net/wireless/ath/ath9k/main.c
 +++ b/drivers/net/wireless/ath/ath9k/main.c
 --- 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;
                }
  
                        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
                /*
                 * 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);
                sc->config.txpowlimit = 2 * conf->power_level;
                ath9k_cmn_update_txpow(ah, sc->curtxpow,
                                       sc->config.txpowlimit, &sc->curtxpow);
index 9df453c..6808cc4 100644 (file)
@@ -1,6 +1,6 @@
 --- a/include/net/mac80211.h
 +++ b/include/net/mac80211.h
 --- 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_*
   * @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
 + * @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 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
 --- 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_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 */
 +
 +      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
  
 --- 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;
        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;
  
        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);
        }
  
                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
         * 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);
        do_posix_clock_monotonic_gettime(&uptime);
        sta->last_connected = uptime.tv_sec;
        ewma_init(&sta->avg_signal, 1024, 8);
                kfree(sta);
 --- a/include/net/cfg80211.h
 +++ b/include/net/cfg80211.h
                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,
 + * @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_.
   *    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_.
   * @txrate: current unicast bitrate from this station
   * @rxrate: current unicast bitrate to this station
   * @rx_packets: packets received from this station
   * @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;
        u8 plink_state;
        s8 signal;
        s8 signal_avg;
        u8 rs_num_delims;
 --- a/drivers/net/wireless/ath/ath9k/recv.c
 +++ b/drivers/net/wireless/ath/ath9k/recv.c
        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;
                                   bool *decrypt_error)
  {
        struct ath_hw *ah = common->ah;
  
        /*
         * everything but the rate is checked here, the rate check is done
  
        /*
         * 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;
  
        if (rx_stats->rs_moreaggr)
                rx_status->flag |= RX_FLAG_NO_SIGNAL_VAL;
  
        return 0;
  }
  
        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
 --- 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);
  
        /* XXX: Keycache */
        rxs->rs_rssi = MS(rxsp->status5, AR_RxRSSICombined);
        if (ads.ds_rxstatus8 & AR_RxKeyIdxValid)
 --- a/drivers/net/wireless/ath/ath9k/debug.c
 +++ b/drivers/net/wireless/ath/ath9k/debug.c
        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;
  #ifdef CONFIG_ATH9K_MAC_DEBUG
        spin_lock(&sc->debug.samp_lock);
        RX_SAMP_DBG(jiffies) = jiffies;
        RX_SAMP_DBG(antenna) = rs->rs_antenna;
        RX_SAMP_DBG(rssi) = rs->rs_rssi;
        RX_SAMP_DBG(rate) = rs->rs_rate;
        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
   */
 + * @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,
  
 +      NL80211_STA_INFO_CHAIN_SIGNAL,
 +      NL80211_STA_INFO_CHAIN_SIGNAL_AVG,
  
        __NL80211_STA_INFO_AFTER_LAST,
 --- a/net/wireless/nl80211.c
 +++ b/net/wireless/nl80211.c
        __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,
  }
  
 +static bool nl80211_put_signal(struct sk_buff *msg, u8 mask, s8 *signal,
 +      return true;
 +}
 +
 +      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,
                                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;
        }
        default:
                break;
        }
                                          NL80211_STA_INFO_TX_BITRATE))
 --- a/net/mac80211/cfg.c
 +++ b/net/mac80211/cfg.c
                                          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;
        struct ieee80211_sub_if_data *sdata = sta->sdata;
        struct ieee80211_local *local = sdata->local;
        struct timespec uptime;
  
        sinfo->generation = sdata->local->sta_generation;
  
  
        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);
        }
                        sinfo->signal = (s8)sta->last_signal;
                sinfo->signal_avg = (s8) -ewma_read(&sta->avg_signal);
        }
 +      }
  
        sta_set_rate_info_tx(sta, &sta->last_tx_rate, &sinfo->txrate);
 +      }
  
        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
 --- 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
         * hardware stores this as 8 bit signed value.
 --- a/drivers/net/wireless/ath/ath9k/antenna.c
 +++ b/drivers/net/wireless/ath/ath9k/antenna.c
         * 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;
        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 (file)
index 98f3d96..0000000
+++ /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/523-mac80211_configure_antenna_gain.patch b/package/mac80211/patches/523-mac80211_configure_antenna_gain.patch
new file mode 100644 (file)
index 0000000..99bd2e3
--- /dev/null
@@ -0,0 +1,162 @@
+--- a/include/net/mac80211.h
++++ b/include/net/mac80211.h
+@@ -978,6 +978,7 @@ enum ieee80211_smps_mode {
+  *
+  * @power_level: requested transmit power (in dBm), backward compatibility
+  *    value only that is set to the minimum of all interfaces
++ * @max_antenna_gain: maximum antenna gain adjusted by user config (in dBi)
+  *
+  * @channel: the channel to tune to
+  * @channel_type: the channel (HT) type
+@@ -1000,6 +1001,7 @@ struct ieee80211_conf {
+       u32 flags;
+       int power_level, dynamic_ps_timeout;
+       int max_sleep_period;
++      int max_antenna_gain;
+       u16 listen_interval;
+       u8 ps_dtim_period;
+--- a/net/mac80211/ieee80211_i.h
++++ b/net/mac80211/ieee80211_i.h
+@@ -1116,6 +1116,7 @@ struct ieee80211_local {
+       int dynamic_ps_forced_timeout;
+       int user_power_level; /* in dBm, for all interfaces */
++      int user_antenna_gain; /* in dBi */
+       enum ieee80211_smps_mode smps_mode;
+--- 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,
++
+       /* add attributes here, update the policy in nl80211.c */
+       __NL80211_ATTR_AFTER_LAST,
+--- a/net/wireless/nl80211.c
++++ b/net/wireless/nl80211.c
+@@ -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 */
+@@ -1706,6 +1707,22 @@ static int nl80211_set_wiphy(struct sk_b
+                       goto bad_res;
+       }
++      if (info->attrs[NL80211_ATTR_WIPHY_ANTENNA_GAIN]) {
++              int idx, dbi = 0;
++
++              if (!rdev->ops->set_antenna_gain) {
++                      result = -EOPNOTSUPP;
++                      goto bad_res;
++              }
++
++              idx = NL80211_ATTR_WIPHY_ANTENNA_GAIN;
++              dbi = nla_get_u32(info->attrs[idx]);
++
++              result = rdev->ops->set_antenna_gain(&rdev->wiphy, dbi);
++              if (result)
++                      goto bad_res;
++      }
++
+       if (info->attrs[NL80211_ATTR_WIPHY_ANTENNA_TX] &&
+           info->attrs[NL80211_ATTR_WIPHY_ANTENNA_RX]) {
+               u32 tx_ant, rx_ant;
+--- a/net/mac80211/cfg.c
++++ b/net/mac80211/cfg.c
+@@ -2212,6 +2212,19 @@ static int ieee80211_get_tx_power(struct
+       return 0;
+ }
++static int ieee80211_set_antenna_gain(struct wiphy *wiphy, int dbi)
++{
++      struct ieee80211_local *local = wiphy_priv(wiphy);
++
++      if (dbi < 0)
++              return -EINVAL;
++
++      local->user_antenna_gain = dbi;
++      ieee80211_hw_config(local, 0);
++
++      return 0;
++}
++
+ static int ieee80211_set_wds_peer(struct wiphy *wiphy, struct net_device *dev,
+                                 const u8 *addr)
+ {
+@@ -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,
++      .set_antenna_gain = ieee80211_set_antenna_gain,
+       .set_wds_peer = ieee80211_set_wds_peer,
+       .rfkill_poll = ieee80211_rfkill_poll,
+       CFG80211_TESTMODE_CMD(ieee80211_testmode_cmd)
+--- a/include/net/cfg80211.h
++++ b/include/net/cfg80211.h
+@@ -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
+  *
+@@ -2071,6 +2072,7 @@ struct cfg80211_ops {
+                               enum nl80211_tx_power_setting type, int mbm);
+       int     (*get_tx_power)(struct wiphy *wiphy, struct wireless_dev *wdev,
+                               int *dbm);
++      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/524-ath9k_use_configured_antenna_gain.patch b/package/mac80211/patches/524-ath9k_use_configured_antenna_gain.patch
new file mode 100644 (file)
index 0000000..d249fd3
--- /dev/null
@@ -0,0 +1,34 @@
+--- a/drivers/net/wireless/ath/ath.h
++++ b/drivers/net/wireless/ath/ath.h
+@@ -73,6 +73,7 @@ struct ath_regulatory {
+       u16 max_power_level;
+       u16 current_rd;
+       int16_t power_limit;
++      int16_t max_antenna_gain;
+       struct reg_dmn_pair_mapping *regpair;
+ };
+--- a/drivers/net/wireless/ath/ath9k/hw.c
++++ b/drivers/net/wireless/ath/ath9k/hw.c
+@@ -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);
+-      max_gain = chan_pwr - new_pwr + channel->max_antenna_gain * 2;
++      max_gain = chan_pwr - new_pwr + reg->max_antenna_gain * 2;
+       ant_gain = get_antenna_gain(ah, chan);
+       if (ant_gain > max_gain)
+--- a/drivers/net/wireless/ath/ath9k/main.c
++++ b/drivers/net/wireless/ath/ath9k/main.c
+@@ -1277,7 +1277,10 @@ int ath9k_config(struct ieee80211_hw *hw
+       }
+       if (changed & IEEE80211_CONF_CHANGE_POWER) {
++              struct ath_regulatory *reg = ath9k_hw_regulatory(ah);
++
+               ath_dbg(common, CONFIG, "Set power: %d\n", conf->power_level);
++              reg->max_antenna_gain = conf->max_antenna_gain;
+               sc->config.txpowlimit = 2 * conf->power_level;
+               ath9k_cmn_update_txpow(ah, sc->curtxpow,
+                                      sc->config.txpowlimit, &sc->curtxpow);
diff --git a/package/mac80211/patches/524-mac80211_configure_antenna_gain.patch b/package/mac80211/patches/524-mac80211_configure_antenna_gain.patch
deleted file mode 100644 (file)
index 99bdb84..0000000
+++ /dev/null
@@ -1,179 +0,0 @@
---- a/include/net/mac80211.h
-+++ b/include/net/mac80211.h
-@@ -851,6 +851,7 @@ enum ieee80211_smps_mode {
-  *    the CONF_PS flag is set.
-  *
-  * @power_level: requested transmit power (in dBm)
-+ * @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 {
-       u32 flags;
-       int power_level, dynamic_ps_timeout;
-       int max_sleep_period;
-+      int max_antenna_gain;
-       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 {
-       int user_power_level; /* in dBm */
-       int ap_power_level; /* in dBm */
-+      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,
-+      NL80211_ATTR_WIPHY_ANTENNA_GAIN,
-+
-       /* add attributes here, update the policy in nl80211.c */
-       __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 },
-+      [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
-                       goto bad_res;
-       }
-+      if (info->attrs[NL80211_ATTR_WIPHY_ANTENNA_GAIN]) {
-+              int idx, dbi = 0;
-+
-+              if (!rdev->ops->set_antenna_gain) {
-+                      result = -EOPNOTSUPP;
-+                      goto bad_res;
-+              }
-+
-+              idx = NL80211_ATTR_WIPHY_ANTENNA_GAIN;
-+              dbi = nla_get_u32(info->attrs[idx]);
-+
-+              result = rdev->ops->set_antenna_gain(&rdev->wiphy, dbi);
-+              if (result)
-+                      goto bad_res;
-+      }
-+
-       if (info->attrs[NL80211_ATTR_WIPHY_ANTENNA_TX] &&
-           info->attrs[NL80211_ATTR_WIPHY_ANTENNA_RX]) {
-               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
-       return 0;
- }
-+static int ieee80211_set_antenna_gain(struct wiphy *wiphy, int dbi)
-+{
-+      struct ieee80211_local *local = wiphy_priv(wiphy);
-+
-+      if (dbi < 0)
-+              return -EINVAL;
-+
-+      local->user_antenna_gain = dbi;
-+      ieee80211_hw_config(local, 0);
-+
-+      return 0;
-+}
-+
- 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 
-       .set_wiphy_params = ieee80211_set_wiphy_params,
-       .set_tx_power = ieee80211_set_tx_power,
-       .get_tx_power = ieee80211_get_tx_power,
-+      .set_antenna_gain = ieee80211_set_antenna_gain,
-       .set_wds_peer = ieee80211_set_wds_peer,
-       .rfkill_poll = ieee80211_rfkill_poll,
-       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().
-  * @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,
-                               enum nl80211_tx_power_setting type, int mbm);
-       int     (*get_tx_power)(struct wiphy *wiphy, 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);
diff --git a/package/mac80211/patches/525-ath9k_use_configured_antenna_gain.patch b/package/mac80211/patches/525-ath9k_use_configured_antenna_gain.patch
deleted file mode 100644 (file)
index 04bd2b3..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
---- a/drivers/net/wireless/ath/ath.h
-+++ b/drivers/net/wireless/ath/ath.h
-@@ -73,6 +73,7 @@ struct ath_regulatory {
-       u16 max_power_level;
-       u16 current_rd;
-       int16_t power_limit;
-+      int16_t max_antenna_gain;
-       struct reg_dmn_pair_mapping *regpair;
- };
---- a/drivers/net/wireless/ath/ath9k/hw.c
-+++ b/drivers/net/wireless/ath/ath9k/hw.c
-@@ -2830,7 +2830,7 @@ void ath9k_hw_apply_txpower(struct ath_h
-       channel = chan->chan;
-       chan_pwr = min_t(int, channel->max_power * 2, MAX_RATE_POWER);
-       new_pwr = min_t(int, chan_pwr, reg->power_limit);
--      max_gain = chan_pwr - new_pwr + channel->max_antenna_gain * 2;
-+      max_gain = chan_pwr - new_pwr + reg->max_antenna_gain * 2;
-       ant_gain = get_antenna_gain(ah, chan);
-       if (ant_gain > max_gain)
---- a/drivers/net/wireless/ath/ath9k/main.c
-+++ b/drivers/net/wireless/ath/ath9k/main.c
-@@ -1256,7 +1256,10 @@ int ath9k_config(struct ieee80211_hw *hw
-       }
-       if (changed & IEEE80211_CONF_CHANGE_POWER) {
-+              struct ath_regulatory *reg = ath9k_hw_regulatory(ah);
-+
-               ath_dbg(common, CONFIG, "Set power: %d\n", conf->power_level);
-+              reg->max_antenna_gain = conf->max_antenna_gain;
-               sc->config.txpowlimit = 2 * conf->power_level;
-               ath9k_cmn_update_txpow(ah, sc->curtxpow,
-                                      sc->config.txpowlimit, &sc->curtxpow);
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 (file)
index 6f8d53f..0000000
+++ /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/530-ath9k_extra_leds.patch b/package/mac80211/patches/530-ath9k_extra_leds.patch
new file mode 100644 (file)
index 0000000..fd7596f
--- /dev/null
@@ -0,0 +1,248 @@
+--- a/drivers/net/wireless/ath/ath9k/ath9k.h
++++ b/drivers/net/wireless/ath/ath9k/ath9k.h
+@@ -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)
+ {
+@@ -685,6 +688,13 @@ enum spectral_mode {
+       SPECTRAL_CHANSCAN,
+ };
++struct ath_led {
++      struct list_head list;
++      struct ath_softc *sc;
++      const struct gpio_led *gpio;
++      struct led_classdev cdev;
++};
++
+ struct ath_softc {
+       struct ieee80211_hw *hw;
+       struct device *dev;
+@@ -726,9 +736,8 @@ struct ath_softc {
+       struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS];
+ #ifdef CONFIG_MAC80211_LEDS
+-      bool led_registered;
+-      char led_name[32];
+-      struct led_classdev led_cdev;
++      const char *led_default_trigger;
++      struct list_head leds;
+ #endif
+       struct ath9k_hw_cal_data caldata;
+--- a/drivers/net/wireless/ath/ath9k/gpio.c
++++ b/drivers/net/wireless/ath/ath9k/gpio.c
+@@ -24,40 +24,102 @@
+ static void ath_led_brightness(struct led_classdev *led_cdev,
+                              enum led_brightness brightness)
+ {
+-      struct ath_softc *sc = container_of(led_cdev, struct ath_softc, led_cdev);
+-      ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, (brightness == LED_OFF));
++      struct ath_led *led = container_of(led_cdev, struct ath_led, cdev);
++      struct ath_softc *sc = led->sc;
++
++      ath9k_ps_wakeup(sc);
++      ath9k_hw_set_gpio(sc->sc_ah, led->gpio->gpio,
++                        (brightness != LED_OFF) ^ led->gpio->active_low);
++      ath9k_ps_restore(sc);
++}
++
++static int ath_add_led(struct ath_softc *sc, struct ath_led *led)
++{
++      const struct gpio_led *gpio = led->gpio;
++      int ret;
++
++      led->cdev.name = gpio->name;
++      led->cdev.default_trigger = gpio->default_trigger;
++      led->cdev.brightness_set = ath_led_brightness;
++
++      ret = led_classdev_register(wiphy_dev(sc->hw->wiphy), &led->cdev);
++      if (ret < 0)
++              return ret;
++
++      led->sc = sc;
++      list_add(&led->list, &sc->leds);
++
++      /* Configure gpio for output */
++      ath9k_hw_cfg_output(sc->sc_ah, gpio->gpio,
++                          AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
++
++      /* LED off */
++      ath9k_hw_set_gpio(sc->sc_ah, gpio->gpio, gpio->active_low);
++
++      return 0;
++}
++
++int ath_create_gpio_led(struct ath_softc *sc, int gpio_num, const char *name,
++                      const char *trigger, bool active_low)
++{
++      struct ath_led *led;
++      struct gpio_led *gpio;
++      char *_name;
++      int ret;
++
++      led = kzalloc(sizeof(*led) + sizeof(*gpio) + strlen(name) + 1,
++                    GFP_KERNEL);
++      if (!led)
++              return -ENOMEM;
++
++      led->gpio = gpio = (struct gpio_led *) (led + 1);
++      _name = (char *) (led->gpio + 1);
++
++      strcpy(_name, name);
++      gpio->name = _name;
++      gpio->gpio = gpio_num;
++      gpio->active_low = active_low;
++      gpio->default_trigger = trigger;
++
++      ret = ath_add_led(sc, led);
++      if (unlikely(ret < 0))
++              kfree(led);
++
++      return ret;
+ }
+ void ath_deinit_leds(struct ath_softc *sc)
+ {
+-      if (!sc->led_registered)
+-              return;
++      struct ath_led *led;
+-      ath_led_brightness(&sc->led_cdev, LED_OFF);
+-      led_classdev_unregister(&sc->led_cdev);
++      while (!list_empty(&sc->leds)) {
++              led = list_first_entry(&sc->leds, struct ath_led, list);
++              list_del(&led->list);
++              ath_led_brightness(&led->cdev, LED_OFF);
++              led_classdev_unregister(&led->cdev);
++              kfree(led);
++      }
+ }
+ void ath_init_leds(struct ath_softc *sc)
+ {
+-      int ret;
++      char led_name[32];
++      const char *trigger;
++
++      INIT_LIST_HEAD(&sc->leds);
+       if (AR_SREV_9100(sc->sc_ah))
+               return;
+-      if (!led_blink)
+-              sc->led_cdev.default_trigger =
+-                      ieee80211_get_radio_led_name(sc->hw);
+-
+-      snprintf(sc->led_name, sizeof(sc->led_name),
+-              "ath9k-%s", wiphy_name(sc->hw->wiphy));
+-      sc->led_cdev.name = sc->led_name;
+-      sc->led_cdev.brightness_set = ath_led_brightness;
++      snprintf(led_name, sizeof(led_name), "ath9k-%s",
++               wiphy_name(sc->hw->wiphy));
+-      ret = led_classdev_register(wiphy_dev(sc->hw->wiphy), &sc->led_cdev);
+-      if (ret < 0)
+-              return;
++      if (led_blink)
++              trigger = sc->led_default_trigger;
++      else
++              trigger = ieee80211_get_radio_led_name(sc->hw);
+-      sc->led_registered = true;
++      ath_create_gpio_led(sc, sc->sc_ah->led_pin, led_name, trigger, 1);
+ }
+ 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
+@@ -870,7 +870,7 @@ int ath9k_init_device(u16 devid, struct 
+ #ifdef CONFIG_MAC80211_LEDS
+       /* must be initialized before ieee80211_register_hw */
+-      sc->led_cdev.default_trigger = ieee80211_create_tpt_led_trigger(sc->hw,
++      sc->led_default_trigger = ieee80211_create_tpt_led_trigger(sc->hw,
+               IEEE80211_TPT_LEDTRIG_FL_RADIO, ath9k_tpt_blink,
+               ARRAY_SIZE(ath9k_tpt_blink));
+ #endif
+--- a/drivers/net/wireless/ath/ath9k/debug.c
++++ b/drivers/net/wireless/ath/ath9k/debug.c
+@@ -1482,6 +1482,61 @@ static const struct file_operations fops
+       .llseek = default_llseek,
+ };
++#ifdef CONFIG_MAC80211_LEDS
++
++static ssize_t write_file_gpio_led(struct file *file, const char __user *ubuf,
++                                 size_t count, loff_t *ppos)
++{
++      struct ath_softc *sc = file->private_data;
++      char buf[32], *str, *name, *c;
++      ssize_t len;
++      unsigned int gpio;
++      bool active_low = false;
++
++      len = min(count, sizeof(buf) - 1);
++      if (copy_from_user(buf, ubuf, len))
++              return -EFAULT;
++
++      buf[len] = '\0';
++      name = strchr(buf, ',');
++      if (!name)
++              return -EINVAL;
++
++      *(name++) = 0;
++      if (!*name)
++              return -EINVAL;
++
++      c = strchr(name, '\n');
++      if (c)
++              *c = 0;
++
++      str = buf;
++      if (*str == '!') {
++              str++;
++              active_low = true;
++      }
++
++      if (kstrtouint(str, 0, &gpio) < 0)
++              return -EINVAL;
++
++      if (gpio >= sc->sc_ah->caps.num_gpio_pins)
++              return -EINVAL;
++
++      if (ath_create_gpio_led(sc, gpio, name, NULL, active_low) < 0)
++              return -EINVAL;
++
++      return count;
++}
++
++static const struct file_operations fops_gpio_led = {
++      .write = write_file_gpio_led,
++      .open = simple_open,
++      .owner = THIS_MODULE,
++      .llseek = default_llseek,
++};
++
++#endif
++
+ #ifdef CONFIG_ATH9K_MAC_DEBUG
+ void ath9k_debug_samp_bb_mac(struct ath_softc *sc)
+@@ -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_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 (file)
index d86e718..0000000
+++ /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/531-ath9k_extra_platform_leds.patch b/package/mac80211/patches/531-ath9k_extra_platform_leds.patch
new file mode 100644 (file)
index 0000000..c64c89a
--- /dev/null
@@ -0,0 +1,71 @@
+--- a/include/linux/ath9k_platform.h
++++ b/include/linux/ath9k_platform.h
+@@ -33,6 +33,9 @@ struct ath9k_platform_data {
+       bool is_clk_25mhz;
+       int (*get_mac_revision)(void);
+       int (*external_reset)(void);
++
++      int num_leds;
++      const struct gpio_led *leds;
+ };
+ #endif /* _LINUX_ATH9K_PLATFORM_H */
+--- a/drivers/net/wireless/ath/ath9k/gpio.c
++++ b/drivers/net/wireless/ath/ath9k/gpio.c
+@@ -14,6 +14,7 @@
+  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+  */
++#include <linux/ath9k_platform.h>
+ #include "ath9k.h"
+ /********************************/
+@@ -88,6 +89,24 @@ int ath_create_gpio_led(struct ath_softc
+       return ret;
+ }
++static int ath_create_platform_led(struct ath_softc *sc,
++                                 const struct gpio_led *gpio)
++{
++      struct ath_led *led;
++      int ret;
++
++      led = kzalloc(sizeof(*led), GFP_KERNEL);
++      if (!led)
++              return -ENOMEM;
++
++      led->gpio = gpio;
++      ret = ath_add_led(sc, led);
++      if (ret < 0)
++              kfree(led);
++
++      return ret;
++}
++
+ void ath_deinit_leds(struct ath_softc *sc)
+ {
+       struct ath_led *led;
+@@ -103,8 +122,10 @@ void ath_deinit_leds(struct ath_softc *s
+ void ath_init_leds(struct ath_softc *sc)
+ {
++      struct ath9k_platform_data *pdata = sc->dev->platform_data;
+       char led_name[32];
+       const char *trigger;
++      int i;
+       INIT_LIST_HEAD(&sc->leds);
+@@ -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);
++
++      if (!pdata)
++              return;
++
++      for (i = 0; i < pdata->num_leds; i++)
++              ath_create_platform_led(sc, &pdata->leds[i]);
+ }
+ void ath_fill_led_pin(struct ath_softc *sc)
diff --git a/package/mac80211/patches/540-ath9k_extra_leds.patch b/package/mac80211/patches/540-ath9k_extra_leds.patch
deleted file mode 100644 (file)
index 2908534..0000000
+++ /dev/null
@@ -1,258 +0,0 @@
---- 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
- void ath_init_leds(struct ath_softc *sc);
- void ath_deinit_leds(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 */
- };
-+struct ath_led {
-+      struct list_head list;
-+      struct ath_softc *sc;
-+      const struct gpio_led *gpio;
-+      struct led_classdev cdev;
-+};
-+
- struct ath_softc {
-       struct ieee80211_hw *hw;
-       struct device *dev;
-@@ -693,9 +703,8 @@ struct ath_softc {
-       struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS];
- #ifdef CONFIG_MAC80211_LEDS
--      bool led_registered;
--      char led_name[32];
--      struct led_classdev led_cdev;
-+      const char *led_default_trigger;
-+      struct list_head leds;
- #endif
-       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 @@
- static void ath_led_brightness(struct led_classdev *led_cdev,
-                              enum led_brightness brightness)
- {
--      struct ath_softc *sc = container_of(led_cdev, struct ath_softc, led_cdev);
--      ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, (brightness == LED_OFF));
-+      struct ath_led *led = container_of(led_cdev, struct ath_led, cdev);
-+      struct ath_softc *sc = led->sc;
-+
-+      ath9k_ps_wakeup(sc);
-+      ath9k_hw_set_gpio(sc->sc_ah, led->gpio->gpio,
-+                        (brightness != LED_OFF) ^ led->gpio->active_low);
-+      ath9k_ps_restore(sc);
-+}
-+
-+static int ath_add_led(struct ath_softc *sc, struct ath_led *led)
-+{
-+      const struct gpio_led *gpio = led->gpio;
-+      int ret;
-+
-+      led->cdev.name = gpio->name;
-+      led->cdev.default_trigger = gpio->default_trigger;
-+      led->cdev.brightness_set = ath_led_brightness;
-+
-+      ret = led_classdev_register(wiphy_dev(sc->hw->wiphy), &led->cdev);
-+      if (ret < 0)
-+              return ret;
-+
-+      led->sc = sc;
-+      list_add(&led->list, &sc->leds);
-+
-+      /* Configure gpio for output */
-+      ath9k_hw_cfg_output(sc->sc_ah, gpio->gpio,
-+                          AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
-+
-+      /* LED off */
-+      ath9k_hw_set_gpio(sc->sc_ah, gpio->gpio, gpio->active_low);
-+
-+      return 0;
-+}
-+
-+int ath_create_gpio_led(struct ath_softc *sc, int gpio_num, const char *name,
-+                      const char *trigger, bool active_low)
-+{
-+      struct ath_led *led;
-+      struct gpio_led *gpio;
-+      char *_name;
-+      int ret;
-+
-+      led = kzalloc(sizeof(*led) + sizeof(*gpio) + strlen(name) + 1,
-+                    GFP_KERNEL);
-+      if (!led)
-+              return -ENOMEM;
-+
-+      led->gpio = gpio = (struct gpio_led *) (led + 1);
-+      _name = (char *) (led->gpio + 1);
-+
-+      strcpy(_name, name);
-+      gpio->name = _name;
-+      gpio->gpio = gpio_num;
-+      gpio->active_low = active_low;
-+      gpio->default_trigger = trigger;
-+
-+      ret = ath_add_led(sc, led);
-+      if (unlikely(ret < 0))
-+              kfree(led);
-+
-+      return ret;
- }
- void ath_deinit_leds(struct ath_softc *sc)
- {
--      if (!sc->led_registered)
--              return;
-+      struct ath_led *led;
--      ath_led_brightness(&sc->led_cdev, LED_OFF);
--      led_classdev_unregister(&sc->led_cdev);
-+      while (!list_empty(&sc->leds)) {
-+              led = list_first_entry(&sc->leds, struct ath_led, list);
-+              list_del(&led->list);
-+              ath_led_brightness(&led->cdev, LED_OFF);
-+              led_classdev_unregister(&led->cdev);
-+              kfree(led);
-+      }
- }
- void ath_init_leds(struct ath_softc *sc)
- {
--      int ret;
-+      char led_name[32];
-+      const char *trigger;
-+
-+      INIT_LIST_HEAD(&sc->leds);
-       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);
--
--      snprintf(sc->led_name, sizeof(sc->led_name),
--              "ath9k-%s", wiphy_name(sc->hw->wiphy));
--      sc->led_cdev.name = sc->led_name;
--      sc->led_cdev.brightness_set = ath_led_brightness;
-+      snprintf(led_name, sizeof(led_name), "ath9k-%s",
-+               wiphy_name(sc->hw->wiphy));
--      ret = led_classdev_register(wiphy_dev(sc->hw->wiphy), &sc->led_cdev);
--      if (ret < 0)
--              return;
-+      if (led_blink)
-+              trigger = sc->led_default_trigger;
-+      else
-+              trigger = ieee80211_get_radio_led_name(sc->hw);
--      sc->led_registered = true;
-+      ath_create_gpio_led(sc, sc->sc_ah->led_pin, led_name, trigger, 1);
- }
- #endif
---- 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 
- #ifdef CONFIG_MAC80211_LEDS
-       /* must be initialized before ieee80211_register_hw */
--      sc->led_cdev.default_trigger = ieee80211_create_tpt_led_trigger(sc->hw,
-+      sc->led_default_trigger = ieee80211_create_tpt_led_trigger(sc->hw,
-               IEEE80211_TPT_LEDTRIG_FL_RADIO, ath9k_tpt_blink,
-               ARRAY_SIZE(ath9k_tpt_blink));
- #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
-       .llseek = default_llseek,
- };
-+#ifdef CONFIG_MAC80211_LEDS
-+
-+static ssize_t write_file_gpio_led(struct file *file, const char __user *ubuf,
-+                                 size_t count, loff_t *ppos)
-+{
-+      struct ath_softc *sc = file->private_data;
-+      char buf[32], *str, *name, *c;
-+      ssize_t len;
-+      unsigned int gpio;
-+      bool active_low = false;
-+
-+      len = min(count, sizeof(buf) - 1);
-+      if (copy_from_user(buf, ubuf, len))
-+              return -EFAULT;
-+
-+      buf[len] = '\0';
-+      name = strchr(buf, ',');
-+      if (!name)
-+              return -EINVAL;
-+
-+      *(name++) = 0;
-+      if (!*name)
-+              return -EINVAL;
-+
-+      c = strchr(name, '\n');
-+      if (c)
-+              *c = 0;
-+
-+      str = buf;
-+      if (*str == '!') {
-+              str++;
-+              active_low = true;
-+      }
-+
-+      if (kstrtouint(str, 0, &gpio) < 0)
-+              return -EINVAL;
-+
-+      if (gpio >= sc->sc_ah->caps.num_gpio_pins)
-+              return -EINVAL;
-+
-+      if (ath_create_gpio_led(sc, gpio, name, NULL, active_low) < 0)
-+              return -EINVAL;
-+
-+      return count;
-+}
-+
-+static const struct file_operations fops_gpio_led = {
-+      .write = write_file_gpio_led,
-+      .open = simple_open,
-+      .owner = THIS_MODULE,
-+      .llseek = default_llseek,
-+};
-+
-+#endif
-+
- #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
-+#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);
diff --git a/package/mac80211/patches/540-mac80211_optimize_mcs_rate_mask.patch b/package/mac80211/patches/540-mac80211_optimize_mcs_rate_mask.patch
new file mode 100644 (file)
index 0000000..347c920
--- /dev/null
@@ -0,0 +1,98 @@
+--- a/net/mac80211/ieee80211_i.h
++++ b/net/mac80211/ieee80211_i.h
+@@ -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];
++
++      bool rc_has_mcs_mask[IEEE80211_NUM_BANDS];
+       u8  rc_rateidx_mcs_mask[IEEE80211_NUM_BANDS][IEEE80211_HT_MCS_MASK_LEN];
+       union {
+--- a/net/mac80211/cfg.c
++++ b/net/mac80211/cfg.c
+@@ -2386,9 +2386,20 @@ static int ieee80211_set_bitrate_mask(st
+       }
+       for (i = 0; i < IEEE80211_NUM_BANDS; i++) {
++              struct ieee80211_supported_band *sband = wiphy->bands[i];
++
+               sdata->rc_rateidx_mask[i] = mask->control[i].legacy;
+               memcpy(sdata->rc_rateidx_mcs_mask[i], mask->control[i].mcs,
+                      sizeof(mask->control[i].mcs));
++
++              sdata->rc_has_mcs_mask[i] = false;
++              if (!sband)
++                      continue;
++
++              if (memcmp(sdata->rc_rateidx_mcs_mask[i],
++                         sband->ht_cap.mcs.rx_mask,
++                         sizeof(sband->ht_cap.mcs.rx_mask)) != 0)
++                      sdata->rc_has_mcs_mask[i] = true;
+       }
+       return 0;
+--- a/include/net/mac80211.h
++++ b/include/net/mac80211.h
+@@ -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
+- * @rate_idx_mcs_mask: user-requested MCS rate mask
++ * @rate_idx_mcs_mask: user-requested MCS rate mask (NULL if not in use)
+  * @bss: whether this frame is sent out in AP or IBSS mode
+  */
+ 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;
+-      u8 rate_idx_mcs_mask[IEEE80211_HT_MCS_MASK_LEN];
++      u8 *rate_idx_mcs_mask;
+       bool bss;
+ };
+--- a/net/mac80211/tx.c
++++ b/net/mac80211/tx.c
+@@ -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;
+-      memcpy(txrc.rate_idx_mcs_mask,
+-             tx->sdata->rc_rateidx_mcs_mask[info->band],
+-             sizeof(txrc.rate_idx_mcs_mask));
++
++      if (tx->sdata->rc_has_mcs_mask[info->band])
++              txrc.rate_idx_mcs_mask =
++                      tx->sdata->rc_rateidx_mcs_mask[info->band];
++
+       txrc.bss = (tx->sdata->vif.type == NL80211_IFTYPE_AP ||
+                   tx->sdata->vif.type == NL80211_IFTYPE_MESH_POINT ||
+                   tx->sdata->vif.type == NL80211_IFTYPE_ADHOC);
+@@ -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;
+-      memcpy(txrc.rate_idx_mcs_mask, sdata->rc_rateidx_mcs_mask[band],
+-             sizeof(txrc.rate_idx_mcs_mask));
+       txrc.bss = true;
+       rate_control_get_rate(sdata, NULL, &txrc);
+--- a/net/mac80211/rate.c
++++ b/net/mac80211/rate.c
+@@ -460,9 +460,12 @@ void rate_control_get_rate(struct ieee80
+        * the common case.
+        */
+       mask = sdata->rc_rateidx_mask[info->band];
+-      memcpy(mcs_mask, sdata->rc_rateidx_mcs_mask[info->band],
+-             sizeof(mcs_mask));
+-      if (mask != (1 << txrc->sband->n_bitrates) - 1) {
++      if (mask != (1 << txrc->sband->n_bitrates) - 1 || txrc->rate_idx_mcs_mask) {
++              if (txrc->rate_idx_mcs_mask)
++                      memcpy(mcs_mask, txrc->rate_idx_mcs_mask, sizeof(mcs_mask));
++              else
++                      memset(mcs_mask, 0xff, sizeof(mcs_mask));
++
+               if (sta) {
+                       /* Filter out rates that the STA does not support */
+                       mask &= sta->sta.supp_rates[info->band];
diff --git a/package/mac80211/patches/541-ath9k_extra_platform_leds.patch b/package/mac80211/patches/541-ath9k_extra_platform_leds.patch
deleted file mode 100644 (file)
index ac8ee53..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
---- a/include/linux/ath9k_platform.h
-+++ b/include/linux/ath9k_platform.h
-@@ -33,6 +33,9 @@ struct ath9k_platform_data {
-       bool is_clk_25mhz;
-       int (*get_mac_revision)(void);
-       int (*external_reset)(void);
-+
-+      int num_leds;
-+      const struct gpio_led *leds;
- };
- #endif /* _LINUX_ATH9K_PLATFORM_H */
---- a/drivers/net/wireless/ath/ath9k/gpio.c
-+++ b/drivers/net/wireless/ath/ath9k/gpio.c
-@@ -14,6 +14,7 @@
-  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-  */
-+#include <linux/ath9k_platform.h>
- #include "ath9k.h"
- /********************************/
-@@ -88,6 +89,24 @@ int ath_create_gpio_led(struct ath_softc
-       return ret;
- }
-+static int ath_create_platform_led(struct ath_softc *sc,
-+                                 const struct gpio_led *gpio)
-+{
-+      struct ath_led *led;
-+      int ret;
-+
-+      led = kzalloc(sizeof(*led), GFP_KERNEL);
-+      if (!led)
-+              return -ENOMEM;
-+
-+      led->gpio = gpio;
-+      ret = ath_add_led(sc, led);
-+      if (ret < 0)
-+              kfree(led);
-+
-+      return ret;
-+}
-+
- void ath_deinit_leds(struct ath_softc *sc)
- {
-       struct ath_led *led;
-@@ -103,8 +122,10 @@ void ath_deinit_leds(struct ath_softc *s
- void ath_init_leds(struct ath_softc *sc)
- {
-+      struct ath9k_platform_data *pdata = sc->dev->platform_data;
-       char led_name[32];
-       const char *trigger;
-+      int i;
-       INIT_LIST_HEAD(&sc->leds);
-@@ -133,6 +154,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);
-+
-+      if (!pdata)
-+              return;
-+
-+      for (i = 0; i < pdata->num_leds; i++)
-+              ath_create_platform_led(sc, &pdata->leds[i]);
- }
- #endif
diff --git a/package/mac80211/patches/541-ath9k_optimize_interrupt_mitigation.patch b/package/mac80211/patches/541-ath9k_optimize_interrupt_mitigation.patch
new file mode 100644 (file)
index 0000000..95ceb35
--- /dev/null
@@ -0,0 +1,30 @@
+--- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c
++++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
+@@ -241,21 +241,19 @@ static bool ar9003_hw_get_isr(struct ath
+               *masked = isr & ATH9K_INT_COMMON;
+-              if (ah->config.rx_intr_mitigation)
++              if (ah->config.rx_intr_mitigation) {
+                       if (isr & (AR_ISR_RXMINTR | AR_ISR_RXINTM))
+                               *masked |= ATH9K_INT_RXLP;
+-
+-              if (ah->config.tx_intr_mitigation)
+-                      if (isr & (AR_ISR_TXMINTR | AR_ISR_TXINTM))
+-                              *masked |= ATH9K_INT_TX;
+-
+-              if (isr & (AR_ISR_LP_RXOK | AR_ISR_RXERR))
++              } else if (isr & (AR_ISR_LP_RXOK | AR_ISR_RXERR))
+                       *masked |= ATH9K_INT_RXLP;
+               if (isr & AR_ISR_HP_RXOK)
+                       *masked |= ATH9K_INT_RXHP;
+-              if (isr & (AR_ISR_TXOK | AR_ISR_TXERR | AR_ISR_TXEOL)) {
++              if (ah->config.tx_intr_mitigation) {
++                      if (isr & (AR_ISR_TXMINTR | AR_ISR_TXINTM))
++                              *masked |= ATH9K_INT_TX;
++              } else if (isr & (AR_ISR_TXOK | AR_ISR_TXERR | AR_ISR_TXEOL)) {
+                       *masked |= ATH9K_INT_TX;
+                       if (!(pCap->hw_caps & ATH9K_HW_CAP_RAC_SUPPORTED)) {
diff --git a/package/mac80211/patches/550-ath9k_reduce_ani_interval.patch b/package/mac80211/patches/550-ath9k_reduce_ani_interval.patch
new file mode 100644 (file)
index 0000000..e2a0d12
--- /dev/null
@@ -0,0 +1,11 @@
+--- a/drivers/net/wireless/ath/ath9k/ani.h
++++ b/drivers/net/wireless/ath/ath9k/ani.h
+@@ -51,7 +51,7 @@
+ #define ATH9K_ANI_PERIOD                  300
+ /* in ms */
+-#define ATH9K_ANI_POLLINTERVAL            1000
++#define ATH9K_ANI_POLLINTERVAL            100
+ #define HAL_NOISE_IMMUNE_MAX              4
+ #define HAL_SPUR_IMMUNE_MAX               7
diff --git a/package/mac80211/patches/550-mac80211_optimize_mcs_rate_mask.patch b/package/mac80211/patches/550-mac80211_optimize_mcs_rate_mask.patch
deleted file mode 100644 (file)
index eb46f53..0000000
+++ /dev/null
@@ -1,98 +0,0 @@
---- a/net/mac80211/ieee80211_i.h
-+++ b/net/mac80211/ieee80211_i.h
-@@ -715,6 +715,8 @@ struct ieee80211_sub_if_data {
-       /* bitmap of allowed (non-MCS) rate indexes for rate control */
-       u32 rc_rateidx_mask[IEEE80211_NUM_BANDS];
-+
-+      bool rc_has_mcs_mask[IEEE80211_NUM_BANDS];
-       u8  rc_rateidx_mcs_mask[IEEE80211_NUM_BANDS][IEEE80211_HT_MCS_MASK_LEN];
-       union {
---- a/net/mac80211/cfg.c
-+++ b/net/mac80211/cfg.c
-@@ -2160,9 +2160,20 @@ static int ieee80211_set_bitrate_mask(st
-       }
-       for (i = 0; i < IEEE80211_NUM_BANDS; i++) {
-+              struct ieee80211_supported_band *sband = wiphy->bands[i];
-+
-               sdata->rc_rateidx_mask[i] = mask->control[i].legacy;
-               memcpy(sdata->rc_rateidx_mcs_mask[i], mask->control[i].mcs,
-                      sizeof(mask->control[i].mcs));
-+
-+              sdata->rc_has_mcs_mask[i] = false;
-+              if (!sband)
-+                      continue;
-+
-+              if (memcmp(sdata->rc_rateidx_mcs_mask[i],
-+                         sband->ht_cap.mcs.rx_mask,
-+                         sizeof(sband->ht_cap.mcs.rx_mask)) != 0)
-+                      sdata->rc_has_mcs_mask[i] = true;
-       }
-       return 0;
---- a/include/net/mac80211.h
-+++ b/include/net/mac80211.h
-@@ -3721,7 +3721,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
-- * @rate_idx_mcs_mask: user-requested MCS rate mask
-+ * @rate_idx_mcs_mask: user-requested MCS rate mask (NULL if not in use)
-  * @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 {
-       bool rts, short_preamble;
-       u8 max_rate_idx;
-       u32 rate_idx_mask;
--      u8 rate_idx_mcs_mask[IEEE80211_HT_MCS_MASK_LEN];
-+      u8 *rate_idx_mcs_mask;
-       bool bss;
- };
---- a/net/mac80211/tx.c
-+++ b/net/mac80211/tx.c
-@@ -631,9 +631,11 @@ ieee80211_tx_h_rate_ctrl(struct ieee8021
-               txrc.max_rate_idx = -1;
-       else
-               txrc.max_rate_idx = fls(txrc.rate_idx_mask) - 1;
--      memcpy(txrc.rate_idx_mcs_mask,
--             tx->sdata->rc_rateidx_mcs_mask[info->band],
--             sizeof(txrc.rate_idx_mcs_mask));
-+
-+      if (tx->sdata->rc_has_mcs_mask[info->band])
-+              txrc.rate_idx_mcs_mask =
-+                      tx->sdata->rc_rateidx_mcs_mask[info->band];
-+
-       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
-               txrc.max_rate_idx = -1;
-       else
-               txrc.max_rate_idx = fls(txrc.rate_idx_mask) - 1;
--      memcpy(txrc.rate_idx_mcs_mask, sdata->rc_rateidx_mcs_mask[band],
--             sizeof(txrc.rate_idx_mcs_mask));
-       txrc.bss = true;
-       rate_control_get_rate(sdata, NULL, &txrc);
---- a/net/mac80211/rate.c
-+++ b/net/mac80211/rate.c
-@@ -461,9 +461,12 @@ void rate_control_get_rate(struct ieee80
-        * the common case.
-        */
-       mask = sdata->rc_rateidx_mask[info->band];
--      memcpy(mcs_mask, sdata->rc_rateidx_mcs_mask[info->band],
--             sizeof(mcs_mask));
--      if (mask != (1 << txrc->sband->n_bitrates) - 1) {
-+      if (mask != (1 << txrc->sband->n_bitrates) - 1 || txrc->rate_idx_mcs_mask) {
-+              if (txrc->rate_idx_mcs_mask)
-+                      memcpy(mcs_mask, txrc->rate_idx_mcs_mask, sizeof(mcs_mask));
-+              else
-+                      memset(mcs_mask, 0xff, sizeof(mcs_mask));
-+
-               if (sta) {
-                       /* Filter out rates that the STA does not support */
-                       mask &= sta->sta.supp_rates[info->band];
diff --git a/package/mac80211/patches/551-ath9k_optimize_interrupt_mitigation.patch b/package/mac80211/patches/551-ath9k_optimize_interrupt_mitigation.patch
deleted file mode 100644 (file)
index 2afc4de..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
---- 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
-               *masked = isr & ATH9K_INT_COMMON;
--              if (ah->config.rx_intr_mitigation)
-+              if (ah->config.rx_intr_mitigation) {
-                       if (isr & (AR_ISR_RXMINTR | AR_ISR_RXINTM))
-                               *masked |= ATH9K_INT_RXLP;
--
--              if (ah->config.tx_intr_mitigation)
--                      if (isr & (AR_ISR_TXMINTR | AR_ISR_TXINTM))
--                              *masked |= ATH9K_INT_TX;
--
--              if (isr & (AR_ISR_LP_RXOK | AR_ISR_RXERR))
-+              } else if (isr & (AR_ISR_LP_RXOK | AR_ISR_RXERR))
-                       *masked |= ATH9K_INT_RXLP;
-               if (isr & AR_ISR_HP_RXOK)
-                       *masked |= ATH9K_INT_RXHP;
--              if (isr & (AR_ISR_TXOK | AR_ISR_TXERR | AR_ISR_TXEOL)) {
-+              if (ah->config.tx_intr_mitigation) {
-+                      if (isr & (AR_ISR_TXMINTR | AR_ISR_TXINTM))
-+                              *masked |= ATH9K_INT_TX;
-+              } else if (isr & (AR_ISR_TXOK | AR_ISR_TXERR | AR_ISR_TXEOL)) {
-                       *masked |= ATH9K_INT_TX;
-                       if (!(pCap->hw_caps & ATH9K_HW_CAP_RAC_SUPPORTED)) {
diff --git a/package/mac80211/patches/551-ath9k_revert_initval_change.patch b/package/mac80211/patches/551-ath9k_revert_initval_change.patch
new file mode 100644 (file)
index 0000000..ffb08bf
--- /dev/null
@@ -0,0 +1,19 @@
+--- a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h
++++ b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h
+@@ -958,11 +958,11 @@ static const u32 ar9300Common_rx_gain_ta
+       {0x0000a074, 0x00000000},
+       {0x0000a078, 0x00000000},
+       {0x0000a07c, 0x00000000},
+-      {0x0000a080, 0x1a1a1a1a},
+-      {0x0000a084, 0x1a1a1a1a},
+-      {0x0000a088, 0x1a1a1a1a},
+-      {0x0000a08c, 0x1a1a1a1a},
+-      {0x0000a090, 0x171a1a1a},
++      {0x0000a080, 0x22222229},
++      {0x0000a084, 0x1d1d1d1d},
++      {0x0000a088, 0x1d1d1d1d},
++      {0x0000a08c, 0x1d1d1d1d},
++      {0x0000a090, 0x171d1d1d},
+       {0x0000a094, 0x11111717},
+       {0x0000a098, 0x00030311},
+       {0x0000a09c, 0x00000000},
diff --git a/package/mac80211/patches/552-ath9k_rx_dma_stop_check.patch b/package/mac80211/patches/552-ath9k_rx_dma_stop_check.patch
new file mode 100644 (file)
index 0000000..606eb1c
--- /dev/null
@@ -0,0 +1,28 @@
+--- a/drivers/net/wireless/ath/ath9k/mac.c
++++ b/drivers/net/wireless/ath/ath9k/mac.c
+@@ -689,7 +689,7 @@ bool ath9k_hw_stopdmarecv(struct ath_hw 
+ {
+ #define AH_RX_STOP_DMA_TIMEOUT 10000   /* usec */
+       struct ath_common *common = ath9k_hw_common(ah);
+-      u32 mac_status, last_mac_status = 0;
++      u32 mac_status = 0, last_mac_status = 0;
+       int i;
+       /* Enable access to the DMA observation bus */
+@@ -719,6 +719,16 @@ bool ath9k_hw_stopdmarecv(struct ath_hw 
+       }
+       if (i == 0) {
++              if (!AR_SREV_9300_20_OR_LATER(ah) &&
++                  (mac_status & 0x700) == 0) {
++                      /*
++                       * DMA is idle but the MAC is still stuck
++                       * processing events
++                       */
++                      *reset = true;
++                      return true;
++              }
++
+               ath_err(common,
+                       "DMA failed to stop in %d ms AR_CR=0x%08x AR_DIAG_SW=0x%08x DMADBG_7=0x%08x\n",
+                       AH_RX_STOP_DMA_TIMEOUT / 1000,
diff --git a/package/mac80211/patches/553-ath9k_debugfs_diag.patch b/package/mac80211/patches/553-ath9k_debugfs_diag.patch
new file mode 100644 (file)
index 0000000..9618698
--- /dev/null
@@ -0,0 +1,139 @@
+--- a/drivers/net/wireless/ath/ath9k/debug.c
++++ b/drivers/net/wireless/ath/ath9k/debug.c
+@@ -2149,6 +2149,50 @@ static const struct file_operations fops
+ };
++static ssize_t read_file_diag(struct file *file, char __user *user_buf,
++                           size_t count, loff_t *ppos)
++{
++      struct ath_softc *sc = file->private_data;
++      struct ath_hw *ah = sc->sc_ah;
++      char buf[32];
++      unsigned int len;
++
++      len = sprintf(buf, "0x%08lx\n", ah->diag);
++      return simple_read_from_buffer(user_buf, count, ppos, buf, len);
++}
++
++static ssize_t write_file_diag(struct file *file, const char __user *user_buf,
++                           size_t count, loff_t *ppos)
++{
++      struct ath_softc *sc = file->private_data;
++      struct ath_hw *ah = sc->sc_ah;
++      unsigned long diag;
++      char buf[32];
++      ssize_t len;
++
++      len = min(count, sizeof(buf) - 1);
++      if (copy_from_user(buf, user_buf, len))
++              return -EFAULT;
++
++      buf[len] = '\0';
++      if (strict_strtoul(buf, 0, &diag))
++              return -EINVAL;
++
++      ah->diag = diag;
++      ath9k_hw_update_diag(ah);
++
++      return count;
++}
++
++static const struct file_operations fops_diag = {
++      .read = read_file_diag,
++      .write = write_file_diag,
++      .open = simple_open,
++      .owner = THIS_MODULE,
++      .llseek = default_llseek,
++};
++
++
+ int ath9k_init_debug(struct ath_hw *ah)
+ {
+       struct ath_common *common = ath9k_hw_common(ah);
+@@ -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);
+       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
+@@ -500,6 +500,12 @@ enum {
+       ATH9K_RESET_COLD,
+ };
++enum {
++      ATH_DIAG_DISABLE_RX,
++      ATH_DIAG_DISABLE_TX,
++      ATH_DIAG_TRIGGER_ERROR,
++};
++
+ struct ath9k_hw_version {
+       u32 magic;
+       u16 devid;
+@@ -778,6 +784,8 @@ struct ath_hw {
+       u32 rfkill_polarity;
+       u32 ah_flags;
++      unsigned long diag;
++
+       bool reset_power_on;
+       bool htc_reset_init;
+@@ -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);
++void ath9k_hw_update_diag(struct ath_hw *ah);
+ #ifdef CONFIG_ATH9K_DEBUGFS
+ 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
+@@ -1747,6 +1747,20 @@ fail:
+       return -EINVAL;
+ }
++void ath9k_hw_update_diag(struct ath_hw *ah)
++{
++      if (test_bit(ATH_DIAG_DISABLE_RX, &ah->diag))
++              REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_DIS);
++      else
++              REG_CLR_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_DIS);
++
++      if (test_bit(ATH_DIAG_DISABLE_TX, &ah->diag))
++              REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_LOOP_BACK);
++      else
++              REG_CLR_BIT(ah, AR_DIAG_SW, AR_DIAG_LOOP_BACK);
++}
++EXPORT_SYMBOL(ath9k_hw_update_diag);
++
+ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
+                  struct ath9k_hw_cal_data *caldata, bool fastcc)
+ {
+@@ -2023,6 +2037,7 @@ int ath9k_hw_reset(struct ath_hw *ah, st
+       }
+       ath9k_hw_apply_gpio_override(ah);
++      ath9k_hw_update_diag(ah);
+       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
+@@ -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 */
++      if (test_bit(ATH_DIAG_TRIGGER_ERROR, &ah->diag)) {
++              status |= ATH9K_INT_FATAL;
++              clear_bit(ATH_DIAG_TRIGGER_ERROR, &ah->diag);
++      }
++
+       /*
+        * If there are no status bits set, then this interrupt was not
+        * for me (should have been caught above).
diff --git a/package/mac80211/patches/554-ath9k_ani_mrc_fix.patch b/package/mac80211/patches/554-ath9k_ani_mrc_fix.patch
new file mode 100644 (file)
index 0000000..6edc8ef
--- /dev/null
@@ -0,0 +1,13 @@
+--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
++++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
+@@ -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;
++
++              if (ah->caps.rx_chainmask == 1)
++                      break;
++
+               REG_RMW_FIELD(ah, AR_PHY_MRC_CCK_CTRL,
+                             AR_PHY_MRC_CCK_ENABLE, is_on);
+               REG_RMW_FIELD(ah, AR_PHY_MRC_CCK_CTRL,
diff --git a/package/mac80211/patches/555-ath9k-allow-to-disable-bands-via-platform-data.patch b/package/mac80211/patches/555-ath9k-allow-to-disable-bands-via-platform-data.patch
new file mode 100644 (file)
index 0000000..a6cb089
--- /dev/null
@@ -0,0 +1,70 @@
+--- a/include/linux/ath9k_platform.h
++++ b/include/linux/ath9k_platform.h
+@@ -31,6 +31,9 @@ struct ath9k_platform_data {
+       bool endian_check;
+       bool is_clk_25mhz;
++      bool disable_2ghz;
++      bool disable_5ghz;
++
+       int (*get_mac_revision)(void);
+       int (*external_reset)(void);
+--- a/drivers/net/wireless/ath/ath9k/hw.c
++++ b/drivers/net/wireless/ath/ath9k/hw.c
+@@ -2413,17 +2413,25 @@ int ath9k_hw_fill_cap_info(struct ath_hw
+       }
+       eeval = ah->eep_ops->get_eeprom(ah, EEP_OP_MODE);
+-      if ((eeval & (AR5416_OPFLAGS_11G | AR5416_OPFLAGS_11A)) == 0) {
+-              ath_err(common,
+-                      "no band has been marked as supported in EEPROM\n");
+-              return -EINVAL;
++
++      if (eeval & AR5416_OPFLAGS_11A) {
++              if (ah->disable_5ghz)
++                      ath_warn(common, "disabling 5GHz band\n");
++              else
++                      pCap->hw_caps |= ATH9K_HW_CAP_5GHZ;
+       }
+-      if (eeval & AR5416_OPFLAGS_11A)
+-              pCap->hw_caps |= ATH9K_HW_CAP_5GHZ;
++      if (eeval & AR5416_OPFLAGS_11G) {
++              if (ah->disable_2ghz)
++                      ath_warn(common, "disabling 2GHz band\n");
++              else
++                      pCap->hw_caps |= ATH9K_HW_CAP_2GHZ;
++      }
+-      if (eeval & AR5416_OPFLAGS_11G)
+-              pCap->hw_caps |= ATH9K_HW_CAP_2GHZ;
++      if ((pCap->hw_caps & (ATH9K_HW_CAP_2GHZ | ATH9K_HW_CAP_5GHZ)) == 0) {
++              ath_err(common, "both bands are disabled\n");
++              return -EINVAL;
++      }
+       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
+@@ -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;
+       const struct firmware *eeprom_blob;
+ };
+--- a/drivers/net/wireless/ath/ath9k/init.c
++++ b/drivers/net/wireless/ath/ath9k/init.c
+@@ -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;
++              ah->disable_2ghz = pdata->disable_2ghz;
++              ah->disable_5ghz = pdata->disable_5ghz;
+               if (!pdata->endian_check)
+                       ah->ah_flags |= AH_NO_EEP_SWAP;
+       }
diff --git a/package/mac80211/patches/560-ath9k_reduce_ani_interval.patch b/package/mac80211/patches/560-ath9k_reduce_ani_interval.patch
deleted file mode 100644 (file)
index e2a0d12..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
---- a/drivers/net/wireless/ath/ath9k/ani.h
-+++ b/drivers/net/wireless/ath/ath9k/ani.h
-@@ -51,7 +51,7 @@
- #define ATH9K_ANI_PERIOD                  300
- /* in ms */
--#define ATH9K_ANI_POLLINTERVAL            1000
-+#define ATH9K_ANI_POLLINTERVAL            100
- #define HAL_NOISE_IMMUNE_MAX              4
- #define HAL_SPUR_IMMUNE_MAX               7
diff --git a/package/mac80211/patches/561-ath9k_revert_initval_change.patch b/package/mac80211/patches/561-ath9k_revert_initval_change.patch
deleted file mode 100644 (file)
index ffb08bf..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
---- a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h
-+++ b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h
-@@ -958,11 +958,11 @@ static const u32 ar9300Common_rx_gain_ta
-       {0x0000a074, 0x00000000},
-       {0x0000a078, 0x00000000},
-       {0x0000a07c, 0x00000000},
--      {0x0000a080, 0x1a1a1a1a},
--      {0x0000a084, 0x1a1a1a1a},
--      {0x0000a088, 0x1a1a1a1a},
--      {0x0000a08c, 0x1a1a1a1a},
--      {0x0000a090, 0x171a1a1a},
-+      {0x0000a080, 0x22222229},
-+      {0x0000a084, 0x1d1d1d1d},
-+      {0x0000a088, 0x1d1d1d1d},
-+      {0x0000a08c, 0x1d1d1d1d},
-+      {0x0000a090, 0x171d1d1d},
-       {0x0000a094, 0x11111717},
-       {0x0000a098, 0x00030311},
-       {0x0000a09c, 0x00000000},
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 (file)
index 7c3c042..0000000
+++ /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/563-ath9k_rx_dma_stop_check.patch b/package/mac80211/patches/563-ath9k_rx_dma_stop_check.patch
deleted file mode 100644 (file)
index 606eb1c..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
---- a/drivers/net/wireless/ath/ath9k/mac.c
-+++ b/drivers/net/wireless/ath/ath9k/mac.c
-@@ -689,7 +689,7 @@ bool ath9k_hw_stopdmarecv(struct ath_hw 
- {
- #define AH_RX_STOP_DMA_TIMEOUT 10000   /* usec */
-       struct ath_common *common = ath9k_hw_common(ah);
--      u32 mac_status, last_mac_status = 0;
-+      u32 mac_status = 0, last_mac_status = 0;
-       int i;
-       /* Enable access to the DMA observation bus */
-@@ -719,6 +719,16 @@ bool ath9k_hw_stopdmarecv(struct ath_hw 
-       }
-       if (i == 0) {
-+              if (!AR_SREV_9300_20_OR_LATER(ah) &&
-+                  (mac_status & 0x700) == 0) {
-+                      /*
-+                       * DMA is idle but the MAC is still stuck
-+                       * processing events
-+                       */
-+                      *reset = true;
-+                      return true;
-+              }
-+
-               ath_err(common,
-                       "DMA failed to stop in %d ms AR_CR=0x%08x AR_DIAG_SW=0x%08x DMADBG_7=0x%08x\n",
-                       AH_RX_STOP_DMA_TIMEOUT / 1000,
diff --git a/package/mac80211/patches/564-ath9k_debugfs_diag.patch b/package/mac80211/patches/564-ath9k_debugfs_diag.patch
deleted file mode 100644 (file)
index 3c7881d..0000000
+++ /dev/null
@@ -1,139 +0,0 @@
---- 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
- };
-+static ssize_t read_file_diag(struct file *file, char __user *user_buf,
-+                           size_t count, loff_t *ppos)
-+{
-+      struct ath_softc *sc = file->private_data;
-+      struct ath_hw *ah = sc->sc_ah;
-+      char buf[32];
-+      unsigned int len;
-+
-+      len = sprintf(buf, "0x%08lx\n", ah->diag);
-+      return simple_read_from_buffer(user_buf, count, ppos, buf, len);
-+}
-+
-+static ssize_t write_file_diag(struct file *file, const char __user *user_buf,
-+                           size_t count, loff_t *ppos)
-+{
-+      struct ath_softc *sc = file->private_data;
-+      struct ath_hw *ah = sc->sc_ah;
-+      unsigned long diag;
-+      char buf[32];
-+      ssize_t len;
-+
-+      len = min(count, sizeof(buf) - 1);
-+      if (copy_from_user(buf, user_buf, len))
-+              return -EFAULT;
-+
-+      buf[len] = '\0';
-+      if (strict_strtoul(buf, 0, &diag))
-+              return -EINVAL;
-+
-+      ah->diag = diag;
-+      ath9k_hw_update_diag(ah);
-+
-+      return count;
-+}
-+
-+static const struct file_operations fops_diag = {
-+      .read = read_file_diag,
-+      .write = write_file_diag,
-+      .open = simple_open,
-+      .owner = THIS_MODULE,
-+      .llseek = default_llseek,
-+};
-+
-+
- 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);
-+      debugfs_create_file("diag", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
-+                          sc, &fops_diag);
-+
-       return 0;
- }
---- a/drivers/net/wireless/ath/ath9k/hw.h
-+++ b/drivers/net/wireless/ath/ath9k/hw.h
-@@ -498,6 +498,12 @@ enum {
-       ATH9K_RESET_COLD,
- };
-+enum {
-+      ATH_DIAG_DISABLE_RX,
-+      ATH_DIAG_DISABLE_TX,
-+      ATH_DIAG_TRIGGER_ERROR,
-+};
-+
- struct ath9k_hw_version {
-       u32 magic;
-       u16 devid;
-@@ -741,6 +747,8 @@ struct ath_hw {
-       u32 rfkill_polarity;
-       u32 ah_flags;
-+      unsigned long diag;
-+
-       bool htc_reset_init;
-       enum nl80211_iftype opmode;
-@@ -1007,6 +1015,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);
-+void ath9k_hw_update_diag(struct ath_hw *ah);
- #ifdef CONFIG_ATH9K_DEBUGFS
- 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:
-       return -EINVAL;
- }
-+void ath9k_hw_update_diag(struct ath_hw *ah)
-+{
-+      if (test_bit(ATH_DIAG_DISABLE_RX, &ah->diag))
-+              REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_DIS);
-+      else
-+              REG_CLR_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_DIS);
-+
-+      if (test_bit(ATH_DIAG_DISABLE_TX, &ah->diag))
-+              REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_LOOP_BACK);
-+      else
-+              REG_CLR_BIT(ah, AR_DIAG_SW, AR_DIAG_LOOP_BACK);
-+}
-+EXPORT_SYMBOL(ath9k_hw_update_diag);
-+
- 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
-       }
-       ath9k_hw_apply_gpio_override(ah);
-+      ath9k_hw_update_diag(ah);
-       return 0;
- }
---- 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)
-       ath9k_hw_getisr(ah, &status);   /* NB: clears ISR too */
-       status &= ah->imask;    /* discard unasked-for bits */
-+      if (test_bit(ATH_DIAG_TRIGGER_ERROR, &ah->diag)) {
-+              status |= ATH9K_INT_FATAL;
-+              clear_bit(ATH_DIAG_TRIGGER_ERROR, &ah->diag);
-+      }
-+
-       /*
-        * If there are no status bits set, then this interrupt was not
-        * for me (should have been caught above).
diff --git a/package/mac80211/patches/565-ath9k_disable_paprd.patch b/package/mac80211/patches/565-ath9k_disable_paprd.patch
deleted file mode 100644 (file)
index 523ac97..0000000
+++ /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 (file)
index 3b75ab5..0000000
+++ /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/567-ath9k_ani_mrc_fix.patch b/package/mac80211/patches/567-ath9k_ani_mrc_fix.patch
deleted file mode 100644 (file)
index 80c9b2a..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
---- 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
-                * is_on == 0 means MRC CCK is OFF (more noise imm)
-                */
-               bool is_on = param ? 1 : 0;
-+
-+              if (ah->caps.rx_chainmask == 1)
-+                      break;
-+
-               REG_RMW_FIELD(ah, AR_PHY_MRC_CCK_CTRL,
-                             AR_PHY_MRC_CCK_ENABLE, is_on);
-               REG_RMW_FIELD(ah, AR_PHY_MRC_CCK_CTRL,
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 (file)
index 183553d..0000000
+++ /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);
index 4f35ae8..07e72e3 100644 (file)
 +}
 --- a/drivers/net/wireless/rt2x00/rt2x00.h
 +++ b/drivers/net/wireless/rt2x00/rt2x00.h
 +}
 --- 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);
                               const u8 *data, const size_t len);
        int (*load_firmware) (struct rt2x00_dev *rt2x00dev,
                              const u8 *data, const size_t len);
  
        /*
         * Device initialization/deinitialization handlers.
  
        /*
         * 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,
        REQUIRE_SW_SEQNO,
        REQUIRE_HT_TX_DESC,
        REQUIRE_PS_AUTOWAKE,
  
        /*
         * Capabilities
  
        /*
         * Capabilities
-@@ -976,6 +978,11 @@ struct rt2x00_dev {
+@@ -988,6 +990,11 @@ struct rt2x00_dev {
        const struct firmware *fw;
  
        /*
        const struct firmware *fw;
  
        /*
  obj-$(CONFIG_RT2X00_LIB_PCI)          += rt2x00pci.o
 --- a/drivers/net/wireless/rt2x00/rt2800pci.c
 +++ b/drivers/net/wireless/rt2x00/rt2800pci.c
  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)
        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);
 -
  {
 -      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);
 -      memcpy_fromio(rt2x00dev->eeprom, base_addr, EEPROM_SIZE);
 -
 -      iounmap(base_addr);
 +      memcpy(rt2x00dev->eeprom, rt2x00dev->eeprom_file->data, EEPROM_SIZE);
+       return 0;
  }
 -#else
  }
 -#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)
 -}
 -#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
  }
  
  /*
  }
  
  /*
   * Initialization functions.
   */
  static bool rt2800pci_get_entry_state(struct queue_entry *entry)
   * 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,
        .get_firmware_name      = rt2800pci_get_firmware_name,
        .check_firmware         = rt2800_check_firmware,
        .load_firmware          = rt2800_load_firmware,
        .get_entry_state        = rt2800pci_get_entry_state,
 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c
 +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
        .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;
  
  
        rt2x00dev->hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
  
        /*
         * Initialize work.
         */
        /*
         * 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);
         */
        if (rt2x00dev->drv_data)
                kfree(rt2x00dev->drv_data);
index 5331b26..d9f1764 100644 (file)
@@ -1,6 +1,6 @@
 --- a/config.mk
 +++ b/config.mk
 --- 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
  export CONFIG_RT2X00_LIB=m
  export CONFIG_RT2800_LIB=m
  export CONFIG_RT2X00_LIB_FIRMWARE=y
index fbc8619..33eb28f 100644 (file)
@@ -4,22 +4,22 @@
        rt2x00pci_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0);
  }
  
        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);
  {
        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))
 -      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))
 +      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))
        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
        else
 --- a/drivers/net/wireless/rt2x00/rt2x00pci.c
 +++ b/drivers/net/wireless/rt2x00/rt2x00pci.c
index e0a920a..2025701 100644 (file)
@@ -24,7 +24,7 @@ Helmut
 
 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c
 +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c
 
 --- 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;
  void rt2x00queue_insert_l2pad(struct sk_buff *skb, unsigned int header_length)
  {
        unsigned int payload_length = skb->len - header_length;
index 57abb07..0b0c30e 100644 (file)
@@ -12,7 +12,7 @@
  #endif /* _RT2X00_PLATFORM_H */
 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c
 +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
  #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;
  
        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
                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
        unsigned int supported_bands;
  #define SUPPORT_BAND_2GHZ     0x00000001
  #define SUPPORT_BAND_5GHZ     0x00000002
index c1b22e7..bb77df9 100644 (file)
@@ -10,7 +10,7 @@
        int disable_5ghz;
 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c
 +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
        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;
  }
  
                entry->flags |= IEEE80211_RATE_SHORT_PREAMBLE;
  }
  
@@ -31,7 +31,7 @@
  {
 --- a/drivers/net/wireless/rt2x00/rt2x00.h
 +++ b/drivers/net/wireless/rt2x00/rt2x00.h
  {
 --- 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);
   */
  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 (file)
index 0000000..bf070e6
--- /dev/null
@@ -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/611-rt2x00-rf_vals-rt3352-xtal20.patch b/package/mac80211/patches/611-rt2x00-rf_vals-rt3352-xtal20.patch
new file mode 100644 (file)
index 0000000..38b56b4
--- /dev/null
@@ -0,0 +1,115 @@
+--- a/drivers/net/wireless/rt2x00/rt2800lib.c
++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
+@@ -5169,6 +5169,27 @@ static const struct rf_channel rf_vals_3
+       {173, 0x61, 0, 9},
+ };
++/*
++ * RF value list for rt3xxx with Xtal20MHz
++ * Supports: 2.4 GHz (all) (RF3322)
++ */
++static const struct rf_channel rf_vals_xtal20mhz_3x[] = {
++      {1,    0xE2,     2,  0x14},
++      {2,    0xE3,     2,  0x14},
++      {3,    0xE4,     2,  0x14},
++      {4,    0xE5,     2,  0x14},
++      {5,    0xE6,     2,  0x14},
++      {6,    0xE7,     2,  0x14},
++      {7,    0xE8,     2,  0x14},
++      {8,    0xE9,     2,  0x14},
++      {9,    0xEA,     2,  0x14},
++      {10,   0xEB,     2,  0x14},
++      {11,   0xEC,     2,  0x14},
++      {12,   0xED,     2,  0x14},
++      {13,   0xEE,     2,  0x14},
++      {14,   0xF0,     2,  0x18},
++};
++
+ static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
+ {
+       struct hw_mode_spec *spec = &rt2x00dev->spec;
+@@ -5246,7 +5267,6 @@ 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) ||
+@@ -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;
++      } else if (rt2x00_rf(rt2x00dev, RF3322)) {
++              spec->num_channels = 14;
++              if (spec->clk_is_20mhz)
++                      spec->channels = rf_vals_xtal20mhz_3x;
++              else
++                      spec->channels = rf_vals_3x;
+       } else if (rt2x00_rf(rt2x00dev, RF3052)) {
+               spec->supported_bands |= SUPPORT_BAND_5GHZ;
+               spec->num_channels = ARRAY_SIZE(rf_vals_3x);
+@@ -5347,6 +5373,19 @@ static int rt2800_probe_hw_mode(struct r
+       return 0;
+ }
++int rt2800_probe_clk(struct rt2x00_dev *rt2x00dev)
++{
++      struct rt2x00_platform_data *pdata = rt2x00dev->dev->platform_data;
++      struct hw_mode_spec *spec = &rt2x00dev->spec;
++
++      if (!pdata)
++              return -EINVAL;
++
++      spec->clk_is_20mhz = pdata->clk_is_20mhz;
++
++      return 0;
++}
++
+ int rt2800_probe_hw(struct rt2x00_dev *rt2x00dev)
+ {
+       int retval;
+@@ -5372,6 +5411,15 @@ int rt2800_probe_hw(struct rt2x00_dev *r
+       rt2800_register_write(rt2x00dev, GPIO_CTRL, reg);
+       /*
++       * Probe SoC clock.
++       */
++      if (rt2x00_is_soc(rt2x00dev)) {
++              retval = rt2800_probe_clk(rt2x00dev);
++              if (retval)
++                      return retval;
++      }
++
++      /*
+        * Initialize hw specifications.
+        */
+       retval = rt2800_probe_hw_mode(rt2x00dev);
+--- a/drivers/net/wireless/rt2x00/rt2x00.h
++++ b/drivers/net/wireless/rt2x00/rt2x00.h
+@@ -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).
++ * @clk_is_20mhz: External crystal of WiSoC is 20MHz instead of 40MHz
+  */
+ struct hw_mode_spec {
+       unsigned int supported_bands;
+@@ -435,6 +436,7 @@ struct hw_mode_spec {
+       const struct channel_info *channels_info;
+       struct ieee80211_sta_ht_cap ht;
++      int clk_is_20mhz;
+ };
+ /*
+--- a/include/linux/rt2x00_platform.h
++++ b/include/linux/rt2x00_platform.h
+@@ -18,6 +18,7 @@ struct rt2x00_platform_data {
+       int disable_2ghz;
+       int disable_5ghz;
++      int clk_is_20mhz;
+ };
+ #endif /* _RT2X00_PLATFORM_H */
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 (file)
index 0000000..bb682ff
--- /dev/null
@@ -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 (file)
index 0000000..00bdbe1
--- /dev/null
@@ -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 (file)
index 0000000..2020178
--- /dev/null
@@ -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 (file)
index 0000000..fa0ffa5
--- /dev/null
@@ -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 (file)
index 0000000..d12b550
--- /dev/null
@@ -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 (file)
index 0000000..c7d40ef
--- /dev/null
@@ -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 (file)
index b1ebd02..0000000
+++ /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 (file)
index b84c42c..0000000
+++ /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 (file)
index 8015a12..0000000
+++ /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/623-rt2x00-rf_vals-rt3352-xtal20.patch b/package/mac80211/patches/623-rt2x00-rf_vals-rt3352-xtal20.patch
deleted file mode 100644 (file)
index 180872e..0000000
+++ /dev/null
@@ -1,115 +0,0 @@
---- 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
-       {173, 0x61, 0, 9},
- };
-+/*
-+ * RF value list for rt3xxx with Xtal20MHz
-+ * Supports: 2.4 GHz (all) (RF3322)
-+ */
-+static const struct rf_channel rf_vals_xtal20mhz_3x[] = {
-+      {1,    0xE2,     2,  0x14},
-+      {2,    0xE3,     2,  0x14},
-+      {3,    0xE4,     2,  0x14},
-+      {4,    0xE5,     2,  0x14},
-+      {5,    0xE6,     2,  0x14},
-+      {6,    0xE7,     2,  0x14},
-+      {7,    0xE8,     2,  0x14},
-+      {8,    0xE9,     2,  0x14},
-+      {9,    0xEA,     2,  0x14},
-+      {10,   0xEB,     2,  0x14},
-+      {11,   0xEC,     2,  0x14},
-+      {12,   0xED,     2,  0x14},
-+      {13,   0xEE,     2,  0x14},
-+      {14,   0xF0,     2,  0x18},
-+};
-+
- 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
-                  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) ||
-@@ -5157,6 +5177,12 @@ 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)) {
-+              spec->num_channels = 14;
-+              if (spec->clk_is_20mhz)
-+                      spec->channels = rf_vals_xtal20mhz_3x;
-+              else
-+                      spec->channels = rf_vals_3x;
-       } 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
-       return 0;
- }
-+int rt2800_probe_clk(struct rt2x00_dev *rt2x00dev)
-+{
-+      struct rt2x00_platform_data *pdata = rt2x00dev->dev->platform_data;
-+      struct hw_mode_spec *spec = &rt2x00dev->spec;
-+
-+      if (!pdata)
-+              return -EINVAL;
-+
-+      spec->clk_is_20mhz = pdata->clk_is_20mhz;
-+
-+      return 0;
-+}
-+
- int rt2800_probe_hw(struct rt2x00_dev *rt2x00dev)
- {
-       int retval;
-@@ -5275,6 +5314,15 @@ int rt2800_probe_hw(struct rt2x00_dev *r
-       rt2800_register_write(rt2x00dev, GPIO_CTRL, reg);
-       /*
-+       * Probe SoC clock.
-+       */
-+      if (rt2x00_is_soc(rt2x00dev)) {
-+              retval = rt2800_probe_clk(rt2x00dev);
-+              if (retval)
-+                      return retval;
-+      }
-+
-+      /*
-        * Initialize hw specifications.
-        */
-       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
-  * @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).
-+ * @clk_is_20mhz: External crystal of WiSoC is 20MHz instead of 40MHz
-  */
- struct hw_mode_spec {
-       unsigned int supported_bands;
-@@ -437,6 +438,7 @@ struct hw_mode_spec {
-       const struct channel_info *channels_info;
-       struct ieee80211_sta_ht_cap ht;
-+      int clk_is_20mhz;
- };
- /*
---- a/include/linux/rt2x00_platform.h
-+++ b/include/linux/rt2x00_platform.h
-@@ -18,6 +18,7 @@ struct rt2x00_platform_data {
-       int disable_2ghz;
-       int disable_5ghz;
-+      int clk_is_20mhz;
- };
- #endif /* _RT2X00_PLATFORM_H */
index 7ebc4f1..80fde27 100644 (file)
@@ -1,6 +1,6 @@
 --- a/drivers/net/wireless/mwl8k.c
 +++ b/drivers/net/wireless/mwl8k.c
 --- 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) = {
  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 (file)
index 0000000..890debc
--- /dev/null
@@ -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 (file)
index 0000000..ff25479
--- /dev/null
@@ -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;
index 55ab0aa..d8fb06d 100644 (file)
@@ -1,6 +1,6 @@
 --- a/drivers/net/wireless/b43/b43.h
 +++ b/drivers/net/wireless/b43/b43.h
 --- 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 */
        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,
  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);
        u32 mask, set;
  
        b43_maskset32(dev, B43_MMIO_MACCTL, ~B43_MACCTL_GPOUTSMSK, 0);
index f511795..5b4c22e 100644 (file)
@@ -11,7 +11,7 @@
  b43-$(CONFIG_B43_PCMCIA)      += pcmcia.o
 --- a/drivers/net/wireless/b43/main.c
 +++ b/drivers/net/wireless/b43/main.c
  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]);
                               dma_reason[0], dma_reason[1],
                               dma_reason[2], dma_reason[3],
                               dma_reason[4], dma_reason[5]);
index 551213d..8b6255f 100644 (file)
@@ -1,6 +1,6 @@
 --- a/drivers/net/wireless/b43/main.c
 +++ b/drivers/net/wireless/b43/main.c
 --- 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. */
                                  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. */
        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)
  
        /* Select the antennae */
        if (phy->ops->set_rx_antenna)
@@ -20,7 +20,7 @@
  
        if (phy->type == B43_PHYTYPE_B) {
                value16 = b43_read16(dev, 0x005E);
  
        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;
        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;
  
        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. */
        }
  
        /* Antennas for RX and management frame TX. */
@@ -42,7 +42,7 @@
  
        if (wl->radio_enabled != phy->radio_on) {
                if (wl->radio_enabled) {
  
        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;
  }
  
        return 0;
  }
  
@@ -90,7 +90,7 @@
  static const struct ieee80211_ops b43_hw_ops = {
        .tx                     = b43_op_tx,
        .conf_tx                = b43_op_conf_tx,
  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,
        .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.
  };
  
  /* 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;
  
        if (!wldev)
                goto out;
  
        wldev->use_pio = b43_modparam_pio;
        wldev->dev = dev;
        wldev->wl = wl;
        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;
  
  
        hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
  
        SET_IEEE80211_DEV(hw, dev->dev);
 --- a/drivers/net/wireless/b43/b43.h
 +++ b/drivers/net/wireless/b43/b43.h
        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 */
        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 */
index ce9ad7d..bd10f99 100644 (file)
@@ -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
 
 --- 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;
  }
  
        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 (file)
index f70a261..0000000
+++ /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 (file)
index b135c7d..0000000
+++ /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/850-brcmsmac-start-adding-support-for-core-rev-28.patch b/package/mac80211/patches/850-brcmsmac-start-adding-support-for-core-rev-28.patch
new file mode 100644 (file)
index 0000000..a84107d
--- /dev/null
@@ -0,0 +1,75 @@
+--- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
++++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
+@@ -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),
+       BCMA_CORETABLE_END
+ };
+ MODULE_DEVICE_TABLE(bcma, brcms_coreid_table);
+--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
++++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
+@@ -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 */
+-      if (D11REV_IS(wlc_hw->corerev, 17) || D11REV_IS(wlc_hw->corerev, 23)) {
++      if (D11REV_IS(wlc_hw->corerev, 17) || D11REV_IS(wlc_hw->corerev, 23) || D11REV_IS(wlc_hw->corerev, 28)) {
+               if (BRCMS_ISNPHY(wlc_hw->band))
+                       brcms_c_write_inits(wlc_hw, ucode->d11n0bsinitvals16);
+               else
+@@ -2257,7 +2257,7 @@ static void brcms_ucode_download(struct 
+       if (wlc_hw->ucode_loaded)
+               return;
+-      if (D11REV_IS(wlc_hw->corerev, 17) || D11REV_IS(wlc_hw->corerev, 23)) {
++      if (D11REV_IS(wlc_hw->corerev, 17) || D11REV_IS(wlc_hw->corerev, 23) || D11REV_IS(wlc_hw->corerev, 28)) {
+               if (BRCMS_ISNPHY(wlc_hw->band)) {
+                       brcms_ucode_write(wlc_hw, ucode->bcm43xx_16_mimo,
+                                         ucode->bcm43xx_16_mimosz);
+@@ -3207,7 +3207,7 @@ static void brcms_b_coreinit(struct brcm
+       sflags = bcma_aread32(core, BCMA_IOST);
+-      if (D11REV_IS(wlc_hw->corerev, 17) || D11REV_IS(wlc_hw->corerev, 23)) {
++      if (D11REV_IS(wlc_hw->corerev, 17) || D11REV_IS(wlc_hw->corerev, 23) || D11REV_IS(wlc_hw->corerev, 28)) {
+               if (BRCMS_ISNPHY(wlc_hw->band))
+                       brcms_c_write_inits(wlc_hw, ucode->d11n0initvals16);
+               else
+@@ -5663,6 +5663,8 @@ static bool brcms_c_chipmatch_soc(struct
+       if (chipinfo->id == BCMA_CHIP_ID_BCM4716)
+               return true;
++      if (chipinfo->id == BCMA_CHIP_ID_BCM5357)
++              return true;
+       pr_err("unknown chip id %04x\n", chipinfo->id);
+       return false;
+--- a/drivers/net/wireless/brcm80211/brcmsmac/main.h
++++ b/drivers/net/wireless/brcm80211/brcmsmac/main.h
+@@ -65,7 +65,7 @@
+ #define       SW_TIMER_MAC_STAT_UPD           30      /* periodic MAC stats update */
+ /* max # supported core revisions (0 .. MAXCOREREV - 1) */
+-#define       MAXCOREREV              28
++#define       MAXCOREREV              29
+ /* Double check that unsupported cores are not enabled */
+ #if CONF_MSK(D11CONF, 0x4f) || CONF_GE(D11CONF, MAXCOREREV)
+--- a/drivers/net/wireless/brcm80211/brcmsmac/types.h
++++ b/drivers/net/wireless/brcm80211/brcmsmac/types.h
+@@ -93,11 +93,11 @@
+ #define BOARD_GPIO_13         0x2000
+ /* **** Core type/rev defaults **** */
+-#define D11CONF               0x0fffffb0      /* Supported  D11 revs: 4, 5, 7-27
++#define D11CONF               0x1fffffb0      /* Supported  D11 revs: 4, 5, 7-27
+                                        * also need to update wlc.h MAXCOREREV
+                                        */
+-#define NCONF         0x000001ff      /* Supported nphy revs:
++#define NCONF         0x000002ff      /* Supported nphy revs:
+                                        *      0       4321a0
+                                        *      1       4321a1
+                                        *      2       4321b0/b1/c0/c1
diff --git a/package/mac80211/patches/851-brcmsmac-start-adding-support-for-core-rev-28.patch b/package/mac80211/patches/851-brcmsmac-start-adding-support-for-core-rev-28.patch
deleted file mode 100644 (file)
index 198af61..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
---- 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),
-       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),
-       BCMA_CORETABLE_END
- };
- 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 
-       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, 17) || D11REV_IS(wlc_hw->corerev, 23)) {
-+      if (D11REV_IS(wlc_hw->corerev, 17) || D11REV_IS(wlc_hw->corerev, 23) || D11REV_IS(wlc_hw->corerev, 28)) {
-               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, 17) || D11REV_IS(wlc_hw->corerev, 23)) {
-+      if (D11REV_IS(wlc_hw->corerev, 17) || D11REV_IS(wlc_hw->corerev, 23) || D11REV_IS(wlc_hw->corerev, 28)) {
-               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, 17) || D11REV_IS(wlc_hw->corerev, 23)) {
-+      if (D11REV_IS(wlc_hw->corerev, 17) || D11REV_IS(wlc_hw->corerev, 23) || D11REV_IS(wlc_hw->corerev, 28)) {
-               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
-       if (chipinfo->id == BCMA_CHIP_ID_BCM4716)
-               return true;
-+      if (chipinfo->id == BCMA_CHIP_ID_BCM5357)
-+              return true;
-       pr_err("unknown chip id %04x\n", chipinfo->id);
-       return false;
---- a/drivers/net/wireless/brcm80211/brcmsmac/main.h
-+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.h
-@@ -65,7 +65,7 @@
- #define       SW_TIMER_MAC_STAT_UPD           30      /* periodic MAC stats update */
- /* max # supported core revisions (0 .. MAXCOREREV - 1) */
--#define       MAXCOREREV              28
-+#define       MAXCOREREV              29
- /* Double check that unsupported cores are not enabled */
- #if CONF_MSK(D11CONF, 0x4f) || CONF_GE(D11CONF, MAXCOREREV)
---- a/drivers/net/wireless/brcm80211/brcmsmac/types.h
-+++ b/drivers/net/wireless/brcm80211/brcmsmac/types.h
-@@ -93,11 +93,11 @@
- #define BOARD_GPIO_13         0x2000
- /* **** Core type/rev defaults **** */
--#define D11CONF               0x0fffffb0      /* Supported  D11 revs: 4, 5, 7-27
-+#define D11CONF               0x1fffffb0      /* Supported  D11 revs: 4, 5, 7-27
-                                        * also need to update wlc.h MAXCOREREV
-                                        */
--#define NCONF         0x000001ff      /* Supported nphy revs:
-+#define NCONF         0x000002ff      /* Supported nphy revs:
-                                        *      0       4321a0
-                                        *      1       4321a1
-                                        *      2       4321b0/b1/c0/c1
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 (file)
index 0000000..33991bc
--- /dev/null
@@ -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 (file)
index 0000000..21b1e0e
--- /dev/null
@@ -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 (file)
index 0000000..1fafd63
--- /dev/null
@@ -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 (file)
index 0000000..79a4b68
--- /dev/null
@@ -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 (file)
index 0000000..9f5c4da
--- /dev/null
@@ -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 (file)
index 0000000..b596d79
--- /dev/null
@@ -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 (file)
index 0000000..0571932
--- /dev/null
@@ -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 (file)
index 0000000..2e7c166
--- /dev/null
@@ -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 (file)
index 0000000..fb10e1b
--- /dev/null
@@ -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 (file)
index 0000000..cbed0f1
--- /dev/null
@@ -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 (file)
index 0000000..34969ad
--- /dev/null
@@ -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 (file)
index 0000000..27dbfea
--- /dev/null
@@ -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 (file)
index 0000000..9c150b1
--- /dev/null
@@ -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 (file)
index 0000000..83b3aa8
--- /dev/null
@@ -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 (file)
index 0000000..d1c7407
--- /dev/null
@@ -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 (file)
index 0000000..dd1393a
--- /dev/null
@@ -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/b01-ath9k-allow-to-disable-bands-via-platform-data.patch b/package/mac80211/patches/b01-ath9k-allow-to-disable-bands-via-platform-data.patch
deleted file mode 100644 (file)
index 8b4ddef..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
---- a/include/linux/ath9k_platform.h
-+++ b/include/linux/ath9k_platform.h
-@@ -31,6 +31,9 @@ struct ath9k_platform_data {
-       bool endian_check;
-       bool is_clk_25mhz;
-+      bool disable_2ghz;
-+      bool disable_5ghz;
-+
-       int (*get_mac_revision)(void);
-       int (*external_reset)(void);
---- 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
-       }
-       eeval = ah->eep_ops->get_eeprom(ah, EEP_OP_MODE);
--      if ((eeval & (AR5416_OPFLAGS_11G | AR5416_OPFLAGS_11A)) == 0) {
--              ath_err(common,
--                      "no band has been marked as supported in EEPROM\n");
--              return -EINVAL;
-+
-+      if (eeval & AR5416_OPFLAGS_11A) {
-+              if (ah->disable_5ghz)
-+                      ath_warn(common, "disabling 5GHz band\n");
-+              else
-+                      pCap->hw_caps |= ATH9K_HW_CAP_5GHZ;
-       }
--      if (eeval & AR5416_OPFLAGS_11A)
--              pCap->hw_caps |= ATH9K_HW_CAP_5GHZ;
-+      if (eeval & AR5416_OPFLAGS_11G) {
-+              if (ah->disable_2ghz)
-+                      ath_warn(common, "disabling 2GHz band\n");
-+              else
-+                      pCap->hw_caps |= ATH9K_HW_CAP_2GHZ;
-+      }
--      if (eeval & AR5416_OPFLAGS_11G)
--              pCap->hw_caps |= ATH9K_HW_CAP_2GHZ;
-+      if ((pCap->hw_caps & (ATH9K_HW_CAP_2GHZ | ATH9K_HW_CAP_5GHZ)) == 0) {
-+              ath_err(common, "both bands are disabled\n");
-+              return -EINVAL;
-+      }
-       if (AR_SREV_9485(ah) || AR_SREV_9285(ah) || AR_SREV_9330(ah))
-               chip_chainmask = 1;
---- a/drivers/net/wireless/ath/ath9k/hw.h
-+++ b/drivers/net/wireless/ath/ath9k/hw.h
-@@ -927,6 +927,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 {
---- 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
-               ah->is_clk_25mhz = pdata->is_clk_25mhz;
-               ah->get_mac_revision = pdata->get_mac_revision;
-               ah->external_reset = pdata->external_reset;
-+              ah->disable_2ghz = pdata->disable_2ghz;
-+              ah->disable_5ghz = pdata->disable_5ghz;
-               if (!pdata->endian_check)
-                       ah->ah_flags |= AH_NO_EEP_SWAP;
-       }
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 (file)
index 4f06e79..0000000
+++ /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;
index 842926a..2236373 100644 (file)
@@ -25,6 +25,7 @@ ifneq ($(CONFIG_TARGET_ar71xx),)
 tools-y += lzma-old squashfs
 endif
 tools-y += lzma squashfs4
 tools-y += lzma-old squashfs
 endif
 tools-y += lzma squashfs4
+tools-y += b43-tools
 
 ifneq ($(CONFIG_PACKAGE_firmwarehotplug),)
 tools-y += sdcc
 
 ifneq ($(CONFIG_PACKAGE_firmwarehotplug),)
 tools-y += sdcc
diff --git a/tools/b43-tools/Makefile b/tools/b43-tools/Makefile
new file mode 100644 (file)
index 0000000..e25bfc2
--- /dev/null
@@ -0,0 +1,51 @@
+#
+# Copyright (C) 2012 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=b43-tools
+PKG_VERSION:=017
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
+PKG_SOURCE_URL:=git://git.bues.ch/b43-tools.git
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_SUBDIR:=$(PKG_NAME)
+PKG_SOURCE_VERSION:=691cd291afdb3dbfcf6b9624f8f4bd068af153d0
+#PKG_MIRROR_MD5SUM:=50ca3c763ee21ee213addd17cf1c1b86
+HOST_BUILD_DIR=$(BUILD_DIR_HOST)/$(PKG_NAME)
+
+include $(INCLUDE_DIR)/host-build.mk
+
+
+define Host/Compile
+       +$(MAKE) $(HOST_JOBS) -C $(HOST_BUILD_DIR)/fwcutter \
+               CFLAGS="$(HOST_CFLAGS) -include endian.h" \
+               $(HOST_MAKE_FLAGS) \
+               $(1) QUIET_SPARSE=:
+       +$(MAKE) $(HOST_JOBS) -C $(HOST_BUILD_DIR)/assembler \
+               CFLAGS="$(HOST_CFLAGS) -include endian.h" \
+               $(HOST_MAKE_FLAGS) \
+               LDFLAGS= \
+               $(1) QUIET_SPARSE=:
+endef
+
+define Host/Install
+       $(INSTALL_DIR) $(STAGING_DIR_HOST)/bin
+       $(INSTALL_BIN) $(HOST_BUILD_DIR)/fwcutter/b43-fwcutter $(STAGING_DIR_HOST)/bin/
+       $(INSTALL_BIN) $(HOST_BUILD_DIR)/assembler/b43-asm $(STAGING_DIR_HOST)/bin/
+       $(INSTALL_BIN) $(HOST_BUILD_DIR)/assembler/b43-asm.bin $(STAGING_DIR_HOST)/bin/
+       $(INSTALL_BIN) ./files/b43-fwsquash.py $(STAGING_DIR_HOST)/bin/
+endef
+
+define Host/Clean
+       rm -f $(STAGING_DIR_HOST)/bin/b43-fwcutter
+       rm -f $(STAGING_DIR_HOST)/bin/b43-asm
+       rm -f $(STAGING_DIR_HOST)/bin/b43-asm.bin
+       rm -f $(STAGING_DIR_HOST)/bin/b43-fwsquash.py
+endef
+
+$(eval $(call HostBuild))
diff --git a/tools/b43-tools/files/b43-fwsquash.py b/tools/b43-tools/files/b43-fwsquash.py
new file mode 100755 (executable)
index 0000000..cd88181
--- /dev/null
@@ -0,0 +1,122 @@
+#!/usr/bin/env python
+#
+# b43 firmware file squasher
+# Removes unnecessary firmware files
+#
+# Copyright (c) 2009 Michael Buesch <mb@bu3sch.de>
+#
+# Licensed under the GNU/GPL version 2 or (at your option) any later version.
+#
+
+import sys
+import os
+
+def usage():
+       print("Usage: %s PHYTYPES COREREVS /path/to/extracted/firmware" % sys.argv[0])
+       print("")
+       print("PHYTYPES is a comma separated list of:")
+       print("A         => A-PHY")
+       print("AG        => Dual A-PHY G-PHY")
+       print("G         => G-PHY")
+       print("LP        => LP-PHY")
+       print("N         => N-PHY")
+       print("HT        => HT-PHY")
+       print("LCN       => LCN-PHY")
+       print("")
+       print("COREREVS is a comma separated list of core revision numbers.")
+
+if len(sys.argv) != 4:
+       usage()
+       sys.exit(1)
+
+phytypes = sys.argv[1]
+corerevs = sys.argv[2]
+fwpath = sys.argv[3]
+
+phytypes = phytypes.split(',')
+try:
+       corerevs = map(lambda r: int(r), corerevs.split(','))
+except ValueError:
+       print("ERROR: \"%s\" is not a valid COREREVS string\n" % corerevs)
+       usage()
+       sys.exit(1)
+
+
+fwfiles = os.listdir(fwpath)
+fwfiles = filter(lambda str: str.endswith(".fw"), fwfiles)
+if not fwfiles:
+       print("ERROR: No firmware files found in %s" % fwpath)
+       sys.exit(1)
+
+required_fwfiles = []
+
+def revs_match(revs_a, revs_b):
+       for rev in revs_a:
+               if rev in revs_b:
+                       return True
+       return False
+
+def phytypes_match(types_a, types_b):
+       for type in types_a:
+               type = type.strip().upper()
+               if type in types_b:
+                       return True
+       return False
+
+revmapping = {
+       "ucode2.fw"             : (2,3,),
+       "ucode4.fw"             : (4,),
+       "ucode5.fw"             : (5,6,7,8,9,10,),
+       "ucode11.fw"            : (11,12,),
+       "ucode13.fw"            : (13,),
+       "ucode14.fw"            : (14,),
+       "ucode15.fw"            : (15,),
+       "ucode16_mimo.fw"       : (16,),
+       "ucode24_mimo.fw"       : (24,),
+       "ucode29_mimo.fw"       : (29,),
+       "pcm4.fw"               : (1,2,3,4,),
+       "pcm5.fw"               : (5,6,7,8,9,10,),
+}
+
+initvalmapping = {
+       "a0g1initvals5.fw"      : ( (5,6,7,8,9,10,),    ("AG",), ),
+       "a0g0initvals5.fw"      : ( (5,6,7,8,9,10,),    ("A", "AG",), ),
+       "b0g0initvals2.fw"      : ( (2,4,),             ("G",), ),
+       "b0g0initvals5.fw"      : ( (5,6,7,8,9,10,),    ("G",), ),
+       "b0g0initvals13.fw"     : ( (13,),              ("G",), ),
+       "n0initvals11.fw"       : ( (11,12,),           ("N",), ),
+       "n0initvals16.fw"       : ( (16,),              ("N",), ),
+       "lp0initvals13.fw"      : ( (13,),              ("LP",), ),
+       "lp0initvals14.fw"      : ( (14,),              ("LP",), ),
+       "lp0initvals15.fw"      : ( (15,),              ("LP",), ),
+       "lcn0initvals24.fw"     : ( (24,),              ("LCN",), ),
+       "ht0initvals29.fw"      : ( (29,),              ("HT",), ),
+       "a0g1bsinitvals5.fw"    : ( (5,6,7,8,9,10,),    ("AG",), ),
+       "a0g0bsinitvals5.fw"    : ( (5,6,7,8,9,10,),    ("A", "AG"), ),
+       "b0g0bsinitvals5.fw"    : ( (5,6,7,8,9,10,),    ("G",), ),
+       "n0bsinitvals11.fw"     : ( (11,12,),           ("N",), ),
+       "n0bsinitvals16.fw"     : ( (16,),              ("N",), ),
+       "lp0bsinitvals13.fw"    : ( (13,),              ("LP",), ),
+       "lp0bsinitvals14.fw"    : ( (14,),              ("LP",), ),
+       "lp0bsinitvals15.fw"    : ( (15,),              ("LP",), ),
+       "lcn0bsinitvals24.fw"   : ( (24,),              ("LCN",), ),
+       "ht0bsinitvals29.fw"    : ( (29,),              ("HT",), ),
+}
+
+for f in fwfiles:
+       if f in revmapping:
+               if revs_match(corerevs, revmapping[f]):
+                       required_fwfiles += [f]
+               continue
+       if f in initvalmapping:
+               if revs_match(corerevs, initvalmapping[f][0]) and\
+                  phytypes_match(phytypes, initvalmapping[f][1]):
+                       required_fwfiles += [f]
+               continue
+       print("WARNING: Firmware file %s not found in the mapping lists" % f)
+
+for f in fwfiles:
+       if f not in required_fwfiles:
+               print("Deleting %s" % f)
+               os.unlink(fwpath + '/' + f)
+
diff --git a/tools/b43-tools/patches/001-fw-dirname.patch b/tools/b43-tools/patches/001-fw-dirname.patch
new file mode 100644 (file)
index 0000000..e9bd032
--- /dev/null
@@ -0,0 +1,16 @@
+--- a/fwcutter/fwcutter.c
++++ b/fwcutter/fwcutter.c
+@@ -48,13 +48,8 @@
+ #include "fwcutter.h"
+ #include "fwcutter_list.h"
+-#if defined(__DragonFly__) || defined(__FreeBSD__)
+-#define V3_FW_DIRNAME "v3"
+-#define V4_FW_DIRNAME "v4"
+-#else
+ #define V3_FW_DIRNAME "b43legacy"
+ #define V4_FW_DIRNAME "b43"
+-#endif
+ static struct cmdline_args cmdargs;
diff --git a/tools/b43-tools/patches/002-no_libfl.patch b/tools/b43-tools/patches/002-no_libfl.patch
new file mode 100644 (file)
index 0000000..2e55b08
--- /dev/null
@@ -0,0 +1,14 @@
+--- a/assembler/main.c
++++ b/assembler/main.c
+@@ -1268,6 +1268,11 @@ static void initialize(void)
+ #endif /* YYDEBUG */
+ }
++int yywrap(void)
++{
++      return 1;
++}
++
+ int main(int argc, char **argv)
+ {
+       int err, res = 1;
diff --git a/tools/b43-tools/patches/100-b43-asm-fix-compile-error-undefined-reference-to-yyd.patch b/tools/b43-tools/patches/100-b43-asm-fix-compile-error-undefined-reference-to-yyd.patch
new file mode 100644 (file)
index 0000000..fc0553d
--- /dev/null
@@ -0,0 +1,27 @@
+--- a/assembler/Makefile
++++ b/assembler/Makefile
+@@ -30,7 +30,7 @@ BIN          = b43-asm.bin
+ SRCS          = parser.c scanner.c main.c initvals.c util.c args.c
+ # YACC related CFLAGS
+-CFLAGS                += -DYYSTYPE="void *" -DYYERROR_VERBOSE -DYYDEBUG -DYYENABLE_NLS=0 -DYYLTYPE_IS_TRIVIAL=0 -Wno-unused
++CFLAGS                += -DYYSTYPE="void *" -DYYERROR_VERBOSE -DYYDEBUG=1 -DYYENABLE_NLS=0 -DYYLTYPE_IS_TRIVIAL=0 -Wno-unused
+ .SUFFIXES:
+ .PHONY: all install clean distclean
+diff --git a/assembler/main.c b/assembler/main.c
+index afca996..a62a15e 100644
+--- a/assembler/main.c
++++ b/assembler/main.c
+@@ -1260,7 +1260,7 @@ static void initialize(void)
+ {
+       INIT_LIST_HEAD(&infile.sl);
+       INIT_LIST_HEAD(&infile.ivals);
+-#ifdef YYDEBUG
++#if YYDEBUG
+       if (IS_INSANE_DEBUG)
+               yydebug = 1;
+       else
+-- 
+1.7.10.4
+